FC2カウンター FPGAの部屋 (目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る1(学習編)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

(目標)Vivado HLSで1クロック毎に結果を出力できるNNを作る1(学習編)

Vivado HLS を仕様して、1クロック毎に結果を出力できるニューラル・ネットワークを作るように努力してみよう。

VHDL を使った簡単なFPGA 回路であれば、5年前に作って技術論文に書いてある。その時は、重みを書いてあるテーブルをRuby でVHDLファイルに変換していた。それをVivado HLS でやってみようと思う。今回は、Jupyter Notebook を使用して MNIST データセットを使った2層の全結合層を持ったニューラル・ネットワークの学習を行って、重みとバイアスをC のヘッダファイルとして出力してみよう。

題材にするのは、MNIST の数字を認識するニューラル・ネットワークとする。全結合層2層で、全結合層1層目の出力は 20 出力とした。
all_deploy_afnet4mnist_3_190328.png

Python のプログラムを示す。

# Mnist NN
# Dence - ReLU - Dence
# 2019/03/21 by marsee
# Keras / Tensorflowで始めるディープラーニング入門 https://qiita.com/yampy/items/706d44417c433e68db0d
# のPythonコードを再利用させて頂いている

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Activation
from keras import backend as K

batch_size = 128
num_classes = 10
epochs = 20

img_rows, img_cols = 28, 28

(x_train, y_train), (x_test, y_test) = mnist.load_data()

#Kerasのバックエンドで動くTensorFlowとTheanoでは入力チャンネルの順番が違うので場合分けして書いています
if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

y_train = y_train.astype('int32')
y_test = y_test.astype('int32')
y_train = keras.utils.np_utils.to_categorical(y_train, num_classes)
y_test =  keras.utils.np_utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Flatten(input_shape=input_shape))
model.add(Dense(20,))
model.add(Activation(activation='relu'))
model.add(Dense(num_classes))
model.add(Activation(activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,
          verbose=1, validation_data=(x_test, y_test))


実行結果を示す。

x_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 1s 12us/step - loss: 0.4821 - acc: 0.8667 - val_loss: 0.2877 - val_acc: 0.9170
Epoch 2/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.2741 - acc: 0.9219 - val_loss: 0.2528 - val_acc: 0.9259
Epoch 3/20
60000/60000 [==============================] - 1s 12us/step - loss: 0.2440 - acc: 0.9307 - val_loss: 0.2278 - val_acc: 0.9331
Epoch 4/20
60000/60000 [==============================] - 1s 10us/step - loss: 0.2240 - acc: 0.9363 - val_loss: 0.2129 - val_acc: 0.9380
Epoch 5/20
60000/60000 [==============================] - 1s 12us/step - loss: 0.2082 - acc: 0.9405 - val_loss: 0.2069 - val_acc: 0.9391
Epoch 6/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1949 - acc: 0.9446 - val_loss: 0.1954 - val_acc: 0.9436
Epoch 7/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1845 - acc: 0.9472 - val_loss: 0.1850 - val_acc: 0.9443
Epoch 8/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1754 - acc: 0.9502 - val_loss: 0.1787 - val_acc: 0.9449
Epoch 9/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1675 - acc: 0.9523 - val_loss: 0.1692 - val_acc: 0.9489
Epoch 10/20
60000/60000 [==============================] - 1s 10us/step - loss: 0.1611 - acc: 0.9537 - val_loss: 0.1653 - val_acc: 0.9506
Epoch 11/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1551 - acc: 0.9557 - val_loss: 0.1641 - val_acc: 0.9508
Epoch 12/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1499 - acc: 0.9570 - val_loss: 0.1565 - val_acc: 0.9525
Epoch 13/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1447 - acc: 0.9580 - val_loss: 0.1548 - val_acc: 0.9547
Epoch 14/20
60000/60000 [==============================] - 1s 12us/step - loss: 0.1404 - acc: 0.9598 - val_loss: 0.1523 - val_acc: 0.9556
Epoch 15/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1366 - acc: 0.9604 - val_loss: 0.1507 - val_acc: 0.9567
Epoch 16/20
60000/60000 [==============================] - 1s 10us/step - loss: 0.1333 - acc: 0.9612 - val_loss: 0.1464 - val_acc: 0.9580
Epoch 17/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1301 - acc: 0.9622 - val_loss: 0.1483 - val_acc: 0.9574
Epoch 18/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1273 - acc: 0.9629 - val_loss: 0.1488 - val_acc: 0.9561
Epoch 19/20
60000/60000 [==============================] - 1s 10us/step - loss: 0.1240 - acc: 0.9639 - val_loss: 0.1463 - val_acc: 0.9587
Epoch 20/20
60000/60000 [==============================] - 1s 11us/step - loss: 0.1219 - acc: 0.9647 - val_loss: 0.1456 - val_acc: 0.9582


model の精度とロスのグラフを示す。
all_deploy_afnet4mnist_4_190328.png

model.summary を示す。
all_deploy_afnet4mnist_5_190328.png

全結合層1層目のパラメータを示す。

np.max(dense_layer1_weight) = 0.7293087244033813
np.min(dense_layer1_weight) = -0.7584445476531982
np.max(abs_dense_layer1_weight) = 0.7584445476531982
np.min(abs_dense_layer1_weight) = 4.789723334397422e-06
np.max(dense_layer1_bias) = 0.6915823221206665
np.min(dense_layer1_bias) = -0.4776344299316406
np.max(abs_dense_layer1_bias) = 0.6915823221206665
np.min(abs_dense_layer1_bias) = 0.003908126149326563
dense_layer1_output = (10000, 20)
np.std(dense_layer1_output) = 3.5381150245666504
np.max(dense_layer1_output) = 20.608829498291016
np.min(dense_layer1_output) = -19.995159149169922
np.max(abs_dense_layer1_output) = 20.608829498291016
np.min(abs_dense_layer1_output) = 5.525350570678711e-05


全結合層2層目のパラメータを示す。

np.max(dense_layer2_weight) = 1.0690280199050903
np.min(dense_layer2_weight) = -1.5573456287384033
np.max(abs_dense_layer2_weight) = 1.5573456287384033
np.min(abs_dense_layer2_weight) = 0.0014803161611780524
np.max(dense_layer2_bias) = 0.4283429980278015
np.min(dense_layer2_bias) = -0.5694308876991272
np.max(abs_dense_layer2_bias) = 0.5694308876991272
np.min(abs_dense_layer2_bias) = 0.01991107501089573
dense_layer2_output = (10000, 10)
np.std(dense_layer2_output) = 7.384382724761963
np.max(dense_layer2_output) = 26.466449737548828
np.min(dense_layer2_output) = -48.657554626464844
np.max(abs_dense_layer2_output) = 48.657554626464844
np.min(abs_dense_layer2_output) = 3.4905970096588135e-06


学習結果から、全結合層1層目、2層目の重みとバイアスを生成した。
all_deploy_afnet4mnist_6_190328.png
  1. 2019年03月28日 04:48 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/4483-e9f355ea
この記事にトラックバックする(FC2ブログユーザー)