實質上鼓勵一下吧

這一篇老早寫好,雖然這兩篇的點閱率極高,但是卻完全沒有回應,資訊人真的是……。

延伸閱讀:
類神經網路基礎篇
類神經網路設計篇

實用類神經網路架構最簡單,用途最廣的就是倒傳遞網路,它增加了以往所沒有的隱藏層觀念,使得網路可以表現出輸入單元間的交互影響,並且使用平滑可微分的轉換函數,使得網路可以應用最陡坡降法導出修正網路加權值的公式。

它的應用包括:
1.電子電路診斷
2.化工制程控制
3.自來水廠水質處理操作
4.股票市場預測(日本某大證券公司實際應用)
5.期貨交易
6.信用卡盜用判斷
7.債券分級
8.倒閉破產預測
9.閃電預測
10.心電圖分類
11.急性冠狀動脈栓塞診斷
12.皮膚病診斷系統
13.頭痛疾病診斷

先做神經元架構,請參考前面兩篇的說明,其中W()就是神經鍵的值,設計的時候就必須把序列化的問題考慮進去,因為數據量大,使用序列化的方式最容易將物件整個保存下來,

Public Class PElement

    Private mNetwork As PNetwork
    Private mLayerNo As Integer
    Private mUpperSize As Integer
    Private mOutValue As Double
    Private mDifValue As Double
    Private mInnerValue As Double = 1
    Public W() As Double

#Region "Init"

    '爲了能夠序列化必須要有的宣告
    Public Sub New()

    End Sub

    Public Sub New(ByVal Network As PNetwork, ByVal LayerNo As Integer, ByVal UpperSize As Integer)
        Init(Network, LayerNo, UpperSize)
    End Sub

    Public Sub Init(ByVal Network As PNetwork, ByVal LayerNo As Integer, ByVal UpperSize As Integer)
        mNetwork = Network
        mLayerNo = LayerNo
        mUpperSize = UpperSize

        '為了簡化程式,讓輸入層也使用標準神經元
        If mLayerNo > 0 Then
            ReDim W(mUpperSize - 1)
            For I As Integer = 0 To mUpperSize - 1
                W(I) = Rnd() - 0.5
            Next
        End If
    End Sub

#End Region

#Region "Property"

    '輸入層的輸出值就是整個網路的輸入值,所以必須要能夠寫入
    Public Property OutValue() As Double
        Get
            Return mOutValue
        End Get

        Set(ByVal value As Double)
            mOutValue = value
        End Set
    End Property

    '神經元輸出誤差值
    Public Property DifValue() As Double
        Get
            Return mDifValue
        End Get
        Set(ByVal value As Double)
            mDifValue = value
        End Set
    End Property

    '神經元內值
    Public Property InnerValue() As Double
        Get
            Return mInnerValue
        End Get
        Set(ByVal value As Double)
            mInnerValue = value
        End Set
    End Property

#End Region

    '神經元輸出運算式
    Public Sub Summation()
        mOutValue = -mInnerValue
        For I As Integer = 0 To mUpperSize - 1
            mOutValue += mNetwork.Layer(mLayerNo - 1).Element(I).OutValue * W(I)
        Next
        mOutValue = 1 / (1 + Math.Exp(-mOutValue))
    End Sub

End Class

最重要的就是輸出運算式的部份了,也就是最後面這一段,就是把上一層的值乘以神經鍵值全部加起來,再用雙彎曲曲綫函數把值修正到0和1之間,也就是下面這一行。

mOutValue = 1 / (1 + Math.Exp(-mOutValue))

再來製作神經層,神經層就是裏面包含了許多的神經元,看一下很容易懂的。

Public Class PLayer
    Private mNetwork As PNetwork
    Private mLayerNo As Integer
    Private mLayerSize As Integer
    Private mEle() As PElement

#Region "Init"

    Public Sub New()

    End Sub

    Public Sub New(ByVal Network As PNetwork, ByVal LayerNo As Integer, ByVal LayerSize As Integer)
        Init(Network, LayerNo, LayerSize)
    End Sub

    Public Sub Init(ByVal Network As PNetwork, ByVal LayerNo As Integer, ByVal LayerSize As Integer)
        mNetwork = Network
        mLayerNo = LayerNo
        mLayerSize = LayerSize

        ReDim mEle(LayerSize - 1)
        For I As Integer = 0 To LayerSize - 1
            If mLayerNo = 0 Then
                '輸入層
                mEle(I) = New PElement(mNetwork, mLayerNo, 0)
            Else
                '隱藏層及輸出層
                mEle(I) = New PElement(mNetwork, mLayerNo, mNetwork.Layer(LayerNo - 1).LayerSize)
            End If
        Next
    End Sub

#End Region

#Region "Property"

    Public ReadOnly Property Element(ByVal Index As Integer) As PElement
        Get
            Return mEle(Index)
        End Get
    End Property

    Public ReadOnly Property LayerSize() As Integer
        Get
            Return mLayerSize
        End Get
    End Property

#End Region

    Public Sub Summation()
        For Each Ele As PElement In mEle
            Ele.Summation()
        Next
    End Sub

End Class

最後製作神經網路,也是很簡單,也就是包含了輸入層、隱藏層、輸出層,並且同時宣告了標準值以提供後續學習的時候使用。

Public Class PNetwork
    Private mLayer() As PLayer
    Private mLayerCount As Integer
    Private mInpSize As Integer
    Private mOutSize As Integer
    Private mSpeed As Double
    Private mStdValue() As Double

#Region "Init"

    Public Sub New()

    End Sub

    Public Sub New(ByVal LayerCount As Integer, ByVal InpSize As Integer, ByVal OutSize As Integer, ByVal Speed As Double)
        Init(LayerCount, InpSize, OutSize, Speed)
    End Sub

    Public Sub Init(ByVal LayerCount As Integer, ByVal InpSize As Integer, ByVal OutSize As Integer, ByVal Speed As Double)
        mLayerCount = LayerCount
        mInpSize = InpSize
        mOutSize = OutSize
        mSpeed = Speed

        '簡化程式,讓輸出層之前每一層大小都等於輸入層
        ReDim mLayer(mLayerCount - 1)
        For I As Integer = 0 To mLayerCount - 2
            mLayer(I) = New PLayer(Me, I, mInpSize)
        Next
        mLayer(mLayerCount - 1) = New PLayer(Me, mLayerCount - 1, mOutSize)

        ReDim mStdValue(mOutSize)
    End Sub

#End Region

#Region "Property"

    Public ReadOnly Property Layer(ByVal Index) As PLayer
        Get
            Return (mLayer(Index))
        End Get
    End Property

    Public WriteOnly Property InpValue(ByVal index As Integer) As Double
        Set(ByVal value As Double)
            mLayer(0).Element(index).OutValue = value
        End Set
    End Property

    Public ReadOnly Property OutValue(ByVal Index As Integer) As Double
        Get
            Return mLayer(mLayerCount - 1).Element(Index).OutValue
        End Get
    End Property

    '標準值,用在學習的時候使用
    Public WriteOnly Property StdValue(ByVal Index As Integer)
        Set(ByVal value)
            mStdValue(Index) = value
        End Set
    End Property

#End Region

    Public Sub Summation()
        For I As Integer = 1 To mLayerCount - 1
            mLayer(I).Summation()
        Next
    End Sub

End Class

再製作一個機器人,用來進行測試使用。

Public Class PRobot
    Private mNetwork As PNetwork
    Private InpSize As Integer = 100
    Private OutSize As Integer = 10
    Private Speed As Double = 0.7 '學習速率

    Public Sub New()
        mNetwork = New PNetwork(4, InpSize, OutSize, Speed)
    End Sub

    Public Sub TestSummation()
        For I As Integer = 0 To InpSize - 1
            mNetwork.InpValue(I) = 1
        Next
        mNetwork.Summation()
        For I As Integer = 0 To OutSize - 1
            Debug.Print(String.Format("{0} : {1}", I, mNetwork.OutValue(I)))
        Next
    End Sub
End Class

只要在Form上面做個按鈕就可以進行測試了。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim Robot As New PRobot
    Robot.TestSummation()
End Sub

這一篇先寫運算輸出的部份,也就是說透過上面的這些程式碼就可以得到輸出結果,但是這樣只是一個腦死的網路,沒有進行學習的動作,下一篇再寫學習的程式碼,順便測試一下到底有沒有人會回應。

創作者介紹

人生四十宅開始 二號宅

漠哥 發表在 痞客邦 留言(18) 人氣()


留言列表 (18)

發表留言
  • 悄悄話
  • 歐文
  • 喔~~
  • 路人n號
  • 因為宅男生性木枘
    所以不知該留些什麼

    期待後續文章 ^^
  • student
  • 漠哥....可以請問你一個問題嗎,你這個類神經的程式應用是你自己本身工作需要的嗎?
  • 不是,完全是興趣做出來的,當然這個只是粗胚,實際跑的程式還更有效率一些!

    漠哥 於 2009/07/01 21:27 回覆

  • student
  • 那可以請問一下,你知道哪裡找的到有關類神經原始碼的網站嗎?
  • 據我所知,目前市面上並沒有任何類神經網路的原始碼釋出!
    或許可以到簡體網站找找,不過這個學問在大陸並不熱門,找到的機會不大。

    漠哥 於 2009/07/01 23:21 回覆

  • student
  • 因為我們專題是以這個為主
    所以要找這方面的資料
    妳寫的文章是我第一個找到裡面有原始碼的
    不然就是從書裡面,可是他是用C寫的
    所以才有此一問。
    在借問一個
    請問你有做出哪方面的相關成品嗎?
  • 我的程式純粹是因為有研究的興趣,而且微軟的SQL Server也應用了這個技術,所以才有寫出來的動機,實際測試過的案例有XOR、七節顯示器、樂透預測、股市預測,XOR與七節顯示器完全沒有問題,在合理的學習速率下大約一百次學習就可以讓輸出變得相當精確,而其他兩個因為我的機器不夠快,還沒有找到最佳化網路架構。
    其實我早就知道學生有在針對這個主題進行研究,但是網路上能找到的資源有限,也就是說你們的指導教授應該也看過我寫的這一系列文章,如果你試圖直接拿我的原始程式碼去交件,恐怕會出大亂子。雖然我沒有把運算公式寫出來,但是基本上已經把類神經網路的精神,以及寫程式時需要注意的地方交代清楚了,建議你將我程式裏面提升效能的部份拿掉,別管繼承和多執行緒的部份,重新撰寫一次,這樣拿出去的程式才不會有問題,就算教授要你解釋程式碼,你也才能夠說得出口。

    漠哥 於 2009/07/02 05:17 回覆

  • student
  • 那請問有相關的書籍可以介紹嗎?
    我們是要用LVQ來作主要核心
    可是網路上幾乎都是以導傳遞為主
    很少有LVQ這方面的資訊,那請問妳有這方面的資訊嗎?
    順帶一提,漠大網路機器人(網路機器人、網路蜘蛛與網
    路爬蟲)這個方面有研究嗎?
  • 當你使用LVQ在Google進行查詢時,就可以找到一大堆相關資訊,不過這方面的研究似乎大陸比較多,而且大多使用matlab,最好先能夠弄懂matlab再去看比較容易有結果。
    至於您提到的網路機器人,有幾個重點,一是抓取網頁內容,這個程式很單純,最多就是是否要使用多執行緒來使得效能提高,二是使用正則運算式分析網頁內容,這個就比較麻煩了,因為正則運算式是個相當不友善的程式語言,入門就要花上很長的時間,要能夠運用自如,必須要有很長的時間研究才成。雖然我已經使用正則運算式很久了,但自認還是在入門階段,也就是只能夠用來驗證字串,更深入的應用還沒辦法應用自如。
    當然不用正則運算式也是可以做到,但是所花的時間應該不會比學習正則運算式來得短,而且程式會變得很大,錯誤很難抓出來,是研究這個課題需要的知識與風險。
    我手頭上有幾本類神經相關書籍,但是細看了以後才會知道裏面的內容有問題,比較有用而且正確率比較高的只有一本,裏面有些手算過程,對於程式的正確性驗證比較有幫助,儒林ISBN:957-652-444-X,但這個書是1993年的,恐怕現在買不到了。

    漠哥 於 2009/07/02 11:23 回覆

  • student
  • 那有沒有可能可以用網路機器人與LVQ做結合呢?
    漠大,那這正規表示法有沒有比較迅速的入門方法呢
  • 程式與程式之間的結合有很多種方法,最好當然是可以直接使用一種語言,最差就是使用檔案來做資料交換,這要你自己去研究。
    如果說正則運算式有速成的方法,那麼我也不會說我只是入門了,程式語言都是苦功夫,一定只有親身去嘗試,經過自己消化之後才有辦法融會貫通。

    漠哥 於 2009/07/02 22:44 回覆

  • student
  • 漠大,能介紹幾本跟正規表示法有規的書籍資料嗎?
  • 類神經新手
  • 感謝你的分享^^
    學到很多!!!!!!!!
  • nanoeye
  • 這是什麼程式語言寫的? 是虛擬碼嗎??
  • VB.NET是確實可以執行的,比較完整的程式碼請看最新的一篇

    漠哥 於 2009/10/15 23:26 回覆

  • 光羽
  • 一般來說要使用大量字元進行訓練的時候 , 是不是有什麼條件限制呢 ? 還是純粹要看電腦浮點運算的能力呢 ? 謝謝 !!
  • William
  • kindly good share
  • 訪客
  • THX 學習中
  • windeagle
  • 念書有碰過類神經網路,只是一直沒有真的實現...現在想把它應用在SSD的wear-leveling演算法中
    漠大的文章給我的一些實現的概念,謝謝喔
  • 您的暱稱 ...
  • 對不起昨天才剛看到漠哥您的文章
    我是剛考完學測 準備就讀資訊工程學系的高三生
    之前寫uVA寫到膩了
    想看一下類神經網路的資料而來 結果非常有收獲!
    感謝大大分享 希望未來能夠看到更多如此高品質文章
    (搞不懂想要抄程式碼的人的心態==這種東西自己研究比較有意義吧
  • Rider
  • 謝謝你的分享,最近在做相關的研究
  • 朱庭鋒
  • hihi~請問這個是c#嗎?我目前只學過c/ c++,在學習你這篇之前我需要先學你這個語言~哈!