無限不可能性ドライブ

『ニューラルネットワーク自作入門』に刺激されてExcelVBAでニューラルネットワークを作ってみたものの、やっぱり数学やらなきゃと思い少しずつやってきたのもあって、自分の知識の整理とかそういった感じです。

【VBA編】ニューラルネットワーク(ML)

演算用モジュール

活性化関数や損失関数を実装します。

'[ML - マシンラーニング演算用モジュール]
Option Explicit
Option Base 1

'活性化関数 ReLU
'[引数] <- aU : Double / ユニットの u
'[戻り値] -> actReLU : Double / ReLU適用後の値
Public Function actReLU(ByVal aU As Double) As Double

    actReLU = WorksheetFunction.max(aU, 0)

End Function

'活性化関数 Softmax
'[引数] <- aUList() : Double / 出力層のすべての出力値のリスト, aIndex : Long / 対象のユニットのインデックス
'[戻り値] -> actSoftmax : Double / Softmax適用後の値
Public Function actSoftmax(ByRef aUList() As Double, ByRef aIndex As Long) As Double
    Dim i As Long
    Dim max As Double
    Dim sum As Double

    'オーバーフロー対策ですべての出力値から最大値を引く必要があるため最大値を求めておく
    max = WorksheetFunction.max(aUList)
    
    '分母部分の計算
    sum = 0
    For i = 1 To UBound(aUList)
        sum = sum + Exp(aUList(i) - max)
    Next

    '該当ユニットの出力値を全出力値で割る
    actSoftmax = Exp(aUList(aIndex) - max) / sum
    
End Function

'-1 < num < 1 で0以外のランダム値を返す
'[戻り値] -> getRandom() : Double / -1 より大きく 1 より小さいランダム値(0以外)
Public Function getRandom() As Double
    Dim i As Long
    Dim res As Double
    
    Randomize
        
    Do
        res = (Rnd * 2) - 1
    Loop Until res <> 0
    
    getRandom = res

End Function

'損失関数 クロスエントロピーエラー
'[引数] <- aT() : Long / 正解ラベル(one-hot表現された教師データ),
'        aZ : Double / ニューラルネットワークの出した予想確率(出力層ユニットの出力値)
'[戻り値] -> crossEntropyError : Double / crossEntropyErrorの値
Public Function crossEntropyError(ByRef aT() As Long, ByRef aZ() As Double) As Double
    Dim i As Long
    Dim res As Double

    res = 0
    For i = 1 To UBound(aT)
        res = res + (aT(i) * Log(aZ(i) + 0.0000001))        'エラー回避のために微小な値を足している
    Next

    res = res * -1

    crossEntropyError = res
End Function


f:id:celaeno42:20181212233850p:plain