無限不可能性ドライブ

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

【VBA編】入力層の作成

f:id:celaeno42:20181201115558p:plain

入力層の作成?

まず手始めに入力層のコードを書いていきます。
が、、実は入力層はデータを受け取って隠れ層1層めに渡しているだけなので、なくても大丈夫です。
もし、入力層の作成が面倒だったり、計算資源を無駄にしたくない>< 場合などは、入力層の作成は省略していただいて構いません。

入力層の作成

では、気を取り直して入力層を作成していきましょう。
入力層は層の管理として「classInputLayer」を、ユニットとして「classInputUnit」を使用します。
入力層は単純にデータを隠れ層1層めに渡しているだけで、重みやバイアスといったパラメータもないので、
他の層とは異なる設計にしています。

入力用ユニットクラス

入力用のユニットクラスです。
1つのユニットにつき、1つの入力しかありません。出力も1つです。
そのため、プロパティのみを定義しています。

'[classInputUnit - 入力用ユニットクラス]
Option Explicit

Dim mX As Double

'入力データをセットする
'[引数] <- inputData : Double / 入力データ
Public Property Let X(ByRef aInputData As Double)
    mX = aInputData
End Property

'入力データを返す
'[戻り値] -> X : Double / 入力データ
Public Property Get X() As Double
    X = mX
End Property

入力層クラス

入力用ユニットを管理する入力層のクラスです。
入力用ユニットのインスタンスを生成し、渡されてきた入力データを入力用ユニットにセットします。
また、隠れ層1層めに渡すために、入力用ユニットの出力を配列としてまとめます。

'[classInputLayer - 入力用ユニットを管理するためのクラス]
Option Explicit
Option Base 1

Dim mInUnitList() As classInputUnit     'ユニット格納用リスト
Dim mInUnitCount As Long                  '入力層のユニット数

'入力層のユニットに入力値を格納する
'[引数] <- aInputDataList() : Double / 入力値のリスト
Public Sub DataInput(ByRef aInputDataList() As Double)
    Dim i As Long
    Dim cInUnit As classInputUnit
    
    mInUnitCount = UBound(aInputDataList)
    
    ReDim mInUnitList(mInUnitCount)
    
    For i = 1 To mInUnitCount
        Set mInUnitList(i) = New classInputUnit
        mInUnitList(i).X = aInputDataList(i)
    Next
    
End Sub

'入力層のユニットの出力値を得る
'[戻り値] -> OutputDataList() : Double / 出力値のリスト
Public Function OutputDataList() As Double()
    Dim i As Long
    Dim outputDatas() As Double
    
    ReDim outputDatas(mInUnitCount)
    
    For i = 1 To mInUnitCount
        outputDatas(i) = mInUnitList(i).X
    Next
    
    OutputDataList = outputDatas()
    
End Function

(他の層でも)コードが書きやすいように、[ Option Base 1 ] で配列のインデックスを 「1 始まり」にしています。
「DataInput()」プロシージャでは、
入力データ数(配列のサイズ)を元に、入力用ユニットの個数を設定し、
[ mInUnitCount = UBound(aInputDataList) ] で入力用ユニットを格納する配列を作成しています。
作成した配列に入力用ユニットのインスタンスを格納していき、その際にプロパティ「 X 」に入力値をセットしています。
「OutputDataList()」プロシージャでは、
入力用ユニットの個数サイズの配列を作成し、各ユニットのプロパティ「 X 」の値を取得しています。


入力層については、重みやバイアスといった更新するべきパラメータもないので、これで完成です。
次回からはユニットについてみていこうと思います。


f:id:celaeno42:20181212233850p:plain