なかがわ電機サービス
Home

NNLedCube

概要

16ニューロン4層のニューラルネットワークに推論させてるときの中間層の出力を可視化するおもちゃを作成した。

https://github.com/ybasviel/NNLedCube

LEDCube

4x4x4 LED Cube (Arduino Uno) : 7 Steps (with Pictures) - Instructables を参考に、根気よくはんだ付けを行い作成した。上記サイトではGPIOに直接つないでいるが、LEDの数が4x4x4=8x8なのでシフトレジスタ2個で作成した。

プログラムのしやすさよりも配線のしやすさを優先したため、コンピュータから送られてくるデータの順序とLEDキューブの座標の対応が不規則になってしまった。しかたなく、次のようにswitch文と決め打ちで対応した。

uint8_t getLayerBitDensity(uint8_t data[64], uint8_t index, uint8_t density){
    switch(index){
        case 0:
            return ((data[63]>density)<<7 | (data[62]>density)<<6 | (data[59]>density)<<5 | (data[58]>density)<<4 | (data[55]>density)<<3 | (data[54]>density)<<2 | (data[50]>density)<<1 | (data[51]>density));
        case 1:
            return ((data[47]>density)<<7 | (data[46]>density)<<6 | (data[43]>density)<<5 | (data[42]>density)<<4 | (data[39]>density)<<3 | (data[38]>density)<<2 | (data[34]>density)<<1 | (data[35]>density));
        case 2:
            return ((data[31]>density)<<7 | (data[30]>density)<<6 | (data[27]>density)<<5 | (data[26]>density)<<4 | (data[23]>density)<<3 | (data[22]>density)<<2 | (data[18]>density)<<1 | (data[19]>density));
....

ニューラルネットワーク

全体のコードは https://github.com/ybasviel/NNLedCube にて公開する。
以下、抜粋して説明する。

まずモデルの訓練、16ニューロンx4層の中間層をもつニューラルネットワークを構築する。

model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(16, activation='relu'),  
    Dense(16, activation='relu'),
    Dense(16, activation='relu'),
    Dense(16, activation='relu'),
    Dense(10, activation='softmax')
])

中間層の出力を取得する。( @gen10nal(タクリュー) Kerasでの中間層出力の取得について #DeepLearning - Qiita )

# 各中間層の出力を取得して表示
# 中間層は1-4
for layer_index in range(1, 5):
    hidden_layer_model = Model(inputs=model.inputs, outputs=model.layers[layer_index].output)
    hidden_layer_output = hidden_layer_model.predict(input_data)

活性化関数にReLUを使っているので出力値をLEDの輝度の範囲(0-127)にスケーリングし、シリアル通信でArduinoに渡している。

感想

LEDの輝度調節機能が実装される以前は、出力値の実態にそぐわない動きをしている状態ではあったものの、進捗報告のつもりでツイートをしたところすこし伸びてしまい、複雑な心持ちである。

Tweet