csv_Functionsモジュールの実装|Excel VBAでMNIST機械学習

本ページでは実際に自身の描いた手描き文字の識別を行うための準備を行います。
手書き文字をニューラルネットワークに読み込ませるには、MNISTデータと同じように入力データ(手書き文字データ)を28×28の計784個の数値に変換する必要があります。

というわけで、ここでは選択したbmpファイルを読み込み、数値として変換するための「csv_Functions」というモジュールを実装していきます。

 icon-warning 注意 

本ページからはニューラルネットワークによる推論フェーズの内容です。
ニューラルネットワークの実装ができていない方はメインページの「ニューラルネットワーク作成編」を参考にニューラルネットワークの実装を先に行ってください。

 

csv_Functionsモジュールの実装

まずは標準モジュールで「csv_Functions」というモジュールを作成します。

ニューラルネットワーク作成編で実装したっモジュールは「Option Base 1」を使っていましたが、ここでは使わないので注意して下さい。

以下はcsv_Functionsモジュールの全コードです。

'VBA csv_Functions(module)
Option Explicit
'――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Function bmp_to_csv() As Long()

    Application.ScreenUpdating = False
    
    Dim FilePath As Variant
    FilePath = Application.GetOpenFilename
    If FilePath = False Then
        End
    End If

    Dim FileSize As Long
    FileSize = FileLen(FilePath)
    If FileSize = 0 Then
        MsgBox "選択したファイルは有効ではありません。"
        Exit Function
    End If

    
    Dim FileID As Integer
    FileID = FreeFile

    Open FilePath For Binary As #FileID

    Dim BinaryData() As Byte
    ReDim BinaryData(0 To FileSize - 1)

    Get #FileID, , BinaryData
    Close #FileID
    
    If Not (BinaryData(0) = 66 And BinaryData(1) = 77) Then
        MsgBox "bmp画像を選択してください。"
        Exit Function
    End If


    'バイナリデータからピクセル値データのみを抜き取る
    
    Dim i As Long
    Dim Data() As Long
    Dim RGBData() As Long
    Dim GrayData() As Long
    
    ReDim Data(UBound(BinaryData) - 53)
    ReDim RGBData(UBound(BinaryData) - 53) 'NNで使うため配列の1番目から値を格納(0番目は空にする)

    For i = 1 To UBound(RGBData)
        RGBData(i) = BinaryData(i + 53)
    Next i
    
    
    'RGBデータをグレースケールデータに変換(学習データと入力値を揃える)
    
    ReDim GrayData(UBound(RGBData) / 3) '0番目は空にする
    
    For i = 1 To UBound(GrayData)
            GrayData(i) = Abs((RGBData((i - 1) * 3 + 1) * 0.11 + _
                               RGBData((i - 1) * 3 + 1 + 1) * 0.59 + _
                               RGBData((i - 1) * 3 + 1 + 2) * 0.3) - 255)
    Next i
    
    Data = AlignBinaryData(GrayData)

    Application.ScreenUpdating = True
    
    bmp_to_csv = Data

End Function
'――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
Function AlignBinaryData(ByRef Data() As Long) As Long()

    Dim i As Long
    Dim j As Long
    Dim cnt As Long
    
    Dim out() As Long
    ReDim out(UBound(Data))
    
    cnt = 1
    For i = 28 To 1 Step -1
        For j = 27 To 0 Step -1
            out(cnt) = Data((i * 28) - j)
            cnt = cnt + 1
        Next j
    Next i
    
    AlignBinaryData = out

End Function

以下では各関数で何を行っているかを解説していきます。

 

Function bmp_to_csv

関数「bmp_to_csv」は読み込まれたbmpファイルを数値化する関数です。

bmp画像をバイナリファイルとして読み取ることで、bmp画像の各ピクセルのRGB値を取得することができます。これを利用し、各ピクセルのグレースケールデータの値をすべて取得します。
(この手法については下記ページでまとめているので合わせて参照ください)

 
入力する画像はMNISTデータと同様の28×28(px)が前提なので、この関数により784個のグレースケール値の入った配列が出力されます。(この配列がニューラルネットワークの入力値となります)

ちなみにRGBをグレースケールに変換するには以下のような式を使います。
(コード内では数字を丸めていますが特に問題はありません)

 icon-code RGBをグレースケールに変換 

K = R × 0.299 + G ×0.587 + B × 0.114

 

Function AlignBinaryData

関数「AlignBinaryData」は入力した配列の順番を反転することのできる関数です。

バイナリデータから単純に各ピクセルのグレースケール値を取得すると、上下が反転してしまっている状態です。(詳しくは【バイナリデータ】VBAでBMP画像を読み込みExcel上でドット絵を作成する方法参照)

しかし、ニューラルネットワークに推論させるには、学習させたMNISTデータと同じ形式でデータを入力する必要があります。要するに画像が上下反転しているとうまく推論ができないということです。

この関数ではその上下反転しているデータを正常な向きのデータに変換することができます。

 

まとめ

ここでは手書き文字データをニューラルネットワークに入力するために、画像を数値に変換するための関数を実装しました。
今回実装したcsv_Functionsモジュールの機能をまとめると以下の通りです。

Function bmp_to_csv:開いたbmpファイルを数値に変換する
Function AlignBinaryData:入力された配列の順番を反転する

ニューラルネットワークの実装と今回の関数さえ実装できれば、後は今回の関数によって出力される値をニューラルネットワークに入れるだけです。
 

メインページ
 

 icon-book 参考書籍

 

 

2021年1月3日AI,Deep Learning,Excel,VBA