FC2カウンター FPGAの部屋 DNN
FC2ブログ

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

FPGAの部屋

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

トランジスタ技術2018年11月号に記事を書きました

トランジスタ技術2018年11月号「第4章 MNIST向け固定小数点CNNの設計から,各種シミュレーション,実装まで 手書き数字認識用FPGAニューラル・ネットワーク・システムの製作」という記事を書きました。

MNIST を推論する畳み込みニューラル・ネットワークをFPGA で作ったという記事です。28 x 28 ピクセルの四角枠をキーボードで動かして、中に収めた手書き数字を判定するという回路です。ZYBO Z7-20 に実装しました。
ただし、カメラのMT9D111メガピクセルカメラモジュールが在庫切れです。
FPGAの部屋のブログの「2 Mega pixel Camera Module MT9D111 JPEG Out + HQ lens」2 Mega pixel Camera Module MT9D111 JPEG Out + HQ lensは在庫があるようです。

なお、第1章から第3章まではなひたふさんが記事を書かれていて、SDSoC を使ったニューラル・ネットワークの実装の記事もありますので、とてもおもしろいと思います。

Vivado HLSのソースコードがDVDに搭載されていませんでしたので、私のGitHubに上げておきました。
「トランジスタ技術2018年11月号の第4章「手書き数字認識用FPGAニューラル・ネットワーク・システムの製作」のVivado HLSのソースコードです」
よろしくお願いいたします。
  1. 2018年10月14日 04:58 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

SqueezeNet for MNIST で層の数を減らして、各層の出力をC のヘッダに出力

今まで SqueezeNet for MNIST をやってきたが、MNIST の手書き数字の分類を行うのにフルのSqueezeNet は大きすぎると思う。
そこで、SqueezeNet の特徴を残しながら、fire 層を 1 層にしたモデルをやってみた。

それとこれが重要なのだが、私は、Vivado HLS で畳み込み層などをC++ で独自に書く訳なのだが、そのコードが正しいという確証が現在、どこからも得られないという問題がある。これは重要な問題で、ニューラルネットワークはロバスト性がありすぎて、途中でコードが間違っていても、あまり結果が変わらないことがよくある。コレを解消するためにKeras で最初の1個のデータだけだが、各層の出力をヘッダとして出力するPython コードを開発した。このデータを使用して、自分で作ったC++ コードの出力するデータと比較することができる。

# SqueezeNet for MNIST
https://www.kaggle.com/somshubramajumdar/squeezenet-for-mnist
(Apache License 2.0)を引用してKeras 2に変更し独自のコードを加えた by marsee


```python
# SqueezeNet for MNIST
# 2018/08/02 by marsee
# Keras / Tensorflowで始めるディープラーニング入門 https://qiita.com/yampy/items/706d44417c433e68db0d
# のPythonコードを再利用させて頂いている
# https://www.kaggle.com/somshubramajumdar/squeezenet-for-mnist (Apache License 2.0)を引用して
# Keras 2に変更し独自のコードを加えた

import keras
from keras.datasets import mnist
from keras import backend as K
import pandas as pd
import numpy as np 
from keras.models import Model, Input
from keras.layers import Dense, Dropout, Flatten, Concatenate
from keras.layers import Conv2D, MaxPooling2D, Activation, AveragePooling2D
import keras.utils.np_utils as kutils

batch_size = 128
num_classes = 10
epochs = 10

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)

# Setup of SqueezeNet (http://arxiv.org/abs/1602.07360), which offers similar performance
# to AlexNet, while using drastically fewer parameters. Tested on CIFAR10, it also performs
# well on MNIST problem

# Uses the latest keras 1.0.2 Functional API

input_layer = Input(shape=(28, 28, 1), name="input")

#conv 1
conv1 = Conv2D(20, (3, 3), padding="valid", kernel_initializer="glorot_uniform", strides=(2, 2))(input_layer)
relu1 = Activation(activation='relu')(conv1)

#maxpool 1
maxpool1 = MaxPooling2D(pool_size=(2,2))(relu1)

#fire 1
fire2_squeeze = Conv2D(10, (1, 1), padding="same", kernel_initializer="glorot_uniform")(maxpool1)
relu2_squeeze = Activation(activation='relu')(fire2_squeeze)

fire2_expand1 = Conv2D(10, (1, 1), padding="same", kernel_initializer="glorot_uniform")(relu2_squeeze)
relu2_expand1 = Activation(activation='relu')(fire2_expand1)
fire2_expand2 = Conv2D(10, (3, 3), padding="same", kernel_initializer="glorot_uniform")(relu2_squeeze)
relu2_expand2 = Activation(activation='relu')(fire2_expand2)

merge1 = Concatenate()([relu2_expand1, relu2_expand2])
fire2 = Activation("linear")(merge1)

#conv 10
conv10 = Conv2D(10, (1, 1), padding="valid", kernel_initializer="glorot_uniform")(fire2)

# The original SqueezeNet has this avgpool1 as well. But since MNIST images are smaller (1,28,28)
# than the CIFAR10 images (3,224,224), AveragePooling2D reduces the image size to (10,0,0), 
# crashing the script.

#avgpool 1
#avgpool10 = AveragePooling2D((13,13))(conv10)

flatten = Flatten()(conv10)

softmax = Dense(10, activation="softmax")(flatten)

model = Model(inputs=input_layer, outputs=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))
```

    Using TensorFlow backend.


    x_train shape: (60000, 28, 28, 1)
    60000 train samples
    10000 test samples
    Train on 60000 samples, validate on 10000 samples
    Epoch 1/10
    60000/60000 [==============================] - 8s 128us/step - loss: 0.4393 - acc: 0.8600 - val_loss: 0.1674 - val_acc: 0.9492
    Epoch 2/10
    60000/60000 [==============================] - 7s 118us/step - loss: 0.1489 - acc: 0.9546 - val_loss: 0.1089 - val_acc: 0.9657
    Epoch 3/10
    60000/60000 [==============================] - 7s 118us/step - loss: 0.1123 - acc: 0.9660 - val_loss: 0.0884 - val_acc: 0.9727
    Epoch 4/10
    60000/60000 [==============================] - 7s 118us/step - loss: 0.0940 - acc: 0.9708 - val_loss: 0.0787 - val_acc: 0.9742
    Epoch 5/10
    60000/60000 [==============================] - 7s 120us/step - loss: 0.0820 - acc: 0.9753 - val_loss: 0.0665 - val_acc: 0.9794
    Epoch 6/10
    60000/60000 [==============================] - 7s 118us/step - loss: 0.0745 - acc: 0.9772 - val_loss: 0.0605 - val_acc: 0.9806
    Epoch 7/10
    60000/60000 [==============================] - 7s 119us/step - loss: 0.0689 - acc: 0.9793 - val_loss: 0.0637 - val_acc: 0.9816
    Epoch 8/10
    60000/60000 [==============================] - 7s 118us/step - loss: 0.0643 - acc: 0.9803 - val_loss: 0.0585 - val_acc: 0.9813
    Epoch 9/10
    60000/60000 [==============================] - 7s 117us/step - loss: 0.0600 - acc: 0.9814 - val_loss: 0.0569 - val_acc: 0.9809
    Epoch 10/10
    60000/60000 [==============================] - 7s 120us/step - loss: 0.0574 - acc: 0.9819 - val_loss: 0.0540 - val_acc: 0.9825



```python
# Keras / Tensorflowで始めるディープラーニング入門 https://qiita.com/yampy/items/706d44417c433e68db0d
# のPythonコードを再利用させて頂いている

%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt

plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

# plot the loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
```

SqNet_181013_output_2_0.png SqNet_181013_output_2_1.png 


```python
# 学習済みモデルの保存

from keras.models import load_model

model.save('squeezenet4mnist_model.h5')  # creates a HDF5 file 'my_model.h5'
```


```python
# 学習済みモデルの読み込み

from keras.models import load_model

model = load_model('squeezenet4mnist_model.h5')
```

    Using TensorFlow backend.



```python
# My Mnist CNN (Convolution layerの特徴マップは5個)
# Conv2D - ReLU - MaxPooling - Dence - ReLU - Dence
# 2018/05/25 by marsee
# Keras / Tensorflowで始めるディープラーニング入門 https://qiita.com/yampy/items/706d44417c433e68db0d
# のPythonコードを再利用させて頂いている

import keras
from keras.datasets import mnist
from keras import backend as K
import pandas as pd
import numpy as np 
from keras.models import Model, Input
from keras.layers import Dense, Dropout, Flatten, Concatenate
from keras.layers import Conv2D, MaxPooling2D, Activation, AveragePooling2D
import keras.utils.np_utils as kutils

batch_size = 128
num_classes = 10
epochs = 5

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)
```

    x_train shape: (60000, 28, 28, 1)
    60000 train samples
    10000 test samples



```python
model.summary()
```

    __________________________________________________________________________________________________
    Layer (type)                    Output Shape         Param #     Connected to                     
    ==================================================================================================
    input (InputLayer)              (None, 28, 28, 1)    0                                            
    __________________________________________________________________________________________________
    conv2d_1 (Conv2D)               (None, 13, 13, 20)   200         input[0][0]                      
    __________________________________________________________________________________________________
    activation_1 (Activation)       (None, 13, 13, 20)   0           conv2d_1[0][0]                   
    __________________________________________________________________________________________________
    max_pooling2d_1 (MaxPooling2D)  (None, 6, 6, 20)     0           activation_1[0][0]               
    __________________________________________________________________________________________________
    conv2d_2 (Conv2D)               (None, 6, 6, 10)     210         max_pooling2d_1[0][0]            
    __________________________________________________________________________________________________
    activation_2 (Activation)       (None, 6, 6, 10)     0           conv2d_2[0][0]                   
    __________________________________________________________________________________________________
    conv2d_3 (Conv2D)               (None, 6, 6, 10)     110         activation_2[0][0]               
    __________________________________________________________________________________________________
    conv2d_4 (Conv2D)               (None, 6, 6, 10)     910         activation_2[0][0]               
    __________________________________________________________________________________________________
    activation_3 (Activation)       (None, 6, 6, 10)     0           conv2d_3[0][0]                   
    __________________________________________________________________________________________________
    activation_4 (Activation)       (None, 6, 6, 10)     0           conv2d_4[0][0]                   
    __________________________________________________________________________________________________
    concatenate_1 (Concatenate)     (None, 6, 6, 20)     0           activation_3[0][0]               
                                                                     activation_4[0][0]               
    __________________________________________________________________________________________________
    activation_5 (Activation)       (None, 6, 6, 20)     0           concatenate_1[0][0]              
    __________________________________________________________________________________________________
    conv2d_5 (Conv2D)               (None, 6, 6, 10)     210         activation_5[0][0]               
    __________________________________________________________________________________________________
    flatten_1 (Flatten)             (None, 360)          0           conv2d_5[0][0]                   
    __________________________________________________________________________________________________
    dense_1 (Dense)                 (None, 10)           3610        flatten_1[0][0]                  
    ==================================================================================================
    Total params: 5,250
    Trainable params: 5,250
    Non-trainable params: 0
    __________________________________________________________________________________________________



```python
# 畳み込み層の重みをCヘッダファイルに書き出す
# 2018/05/31 by marsee

def fwrite_conv_weight(weight, wfile_name, float_wt_name, fixed_wt_name, MAGNIFICATION):
    import datetime
    import numpy as np
    
    f = open(wfile_name, 'w')
    todaytime = datetime.datetime.today()
    f.write('// '+wfile_name+'\n')
    strdtime = todaytime.strftime("%Y/%m/%d %H:%M:%S")
    f.write('// {0} by marsee\n'.format(strdtime))
    f.write("\n")
    
    f.write('const float '+float_wt_name+'['+str(weight.shape[0])+']['+str(weight.shape[1])+']['+str(weight.shape[2])+']['+str(weight.shape[3])+'] = \n{\n')
    for i in range(weight.shape[0]):
        f.write("\t{\n")
        for j in range(weight.shape[1]):
            f.write("\t\t{\n")
            for k in range(weight.shape[2]):
                f.write("\t\t\t{")
                for m in range(weight.shape[3]):
                    f.write(str(weight[i][j][k][m]))
                    if (m==weight.shape[3]-1):
                        f.write("}")
                    else:
                        f.write(",")
                
                if (k==weight.shape[2]-1):
                    f.write("\n\t\t}\n")
                else:
                    f.write(",\n")

            if (j==weight.shape[1]-1):
                f.write("\t}\n")
            else:
                f.write(",\n")
        
        
        if (i==weight.shape[0]-1):
            f.write("};\n")
        else:
            f.write("\t,\n")

    f.write("\n")
    f.write('const ap_fixed<'+str(int(np.log2(MAGNIFICATION))+1)+', 1, AP_TRN, AP_WRAP> '+fixed_wt_name+'['+str(weight.shape[0])+']['+str(weight.shape[1])+']['+str(weight.shape[2])+']['+str(weight.shape[3])+'] = \n{\n')
    for i in range(weight.shape[0]):
        f.write("\t{\n")
        for j in range(weight.shape[1]):
            f.write("\t\t{\n")
            for k in range(weight.shape[2]):
                f.write("\t\t\t{")
                for m in range(weight.shape[3]):
                    w_int = int(weight[i][j][k][m]*MAGNIFICATION+0.5)
                    if (w_int > MAGNIFICATION-1):
                        w_int = MAGNIFICATION-1
                    elif (w_int < -MAGNIFICATION):
                        w_int = -MAGNIFICATION
                    f.write(str(float(w_int)/float(MAGNIFICATION)))
                    if (m==weight.shape[3]-1):
                        f.write("}")
                    else:
                        f.write(",")
                
                if (k==weight.shape[2]-1):
                    f.write("\n\t\t}\n")
                else:
                     f.write(",\n")

            if (j==weight.shape[1]-1):
                f.write("\t}\n")
            else:
                f.write(",\n")
        
        
        if (i==weight.shape[0]-1):
            f.write("};\n")
        else:
            f.write("\t,\n")
 
    f.close()
```


```python
# 畳み込み層と全結合層のバイアスをCヘッダファイルに書き出す
# 2018/05/31 by marsee

def fwrite_bias(bias, wfile_name, float_b_name, fixed_wt_name, MAGNIFICATION):
    import datetime
    import numpy as np
    
    f = open(wfile_name, 'w')
    todaytime = datetime.datetime.today()
    f.write('// '+wfile_name+'\n')
    strdtime = todaytime.strftime("%Y/%m/%d %H:%M:%S")
    f.write('// {0} by marsee\n'.format(strdtime))
    f.write("\n")

    f.write('const float '+float_b_name+'['+str(bias.shape[0])+'] = {\n\t')
    for i in range(bias.shape[0]):
        f.write(str(bias[i]))
        if (i < bias.shape[0]-1):
            f.write(", ")
    f.write("\n};\n")

    f.write("\n")
    f.write('const ap_fixed<'+str(int(np.log2(MAGNIFICATION))+1)+', 1, AP_TRN, AP_WRAP> '+fixed_wt_name+'['+str(bias.shape[0])+'] = {\n\t')
    for i in range(bias.shape[0]):
        b_int = int(bias[i]*MAGNIFICATION+0.5)
        if (b_int > MAGNIFICATION-1):
            b_int = MAGNIFICATION-1
        elif (b_int < -MAGNIFICATION):
            b_int = -MAGNIFICATION
        f.write(str(float(b_int)/float(MAGNIFICATION)))
        if (i < bias.shape[0]-1):
            f.write(", ")
    f.write("\n};\n")

    f.close()
```


```python
# 層のデータを取得してCのヘッダ・ファイルに出力する(float)
# 2018/09/20 by marsee

def fwrite_layer_output(layer_out, wfile_name, layer_output_name):
    import datetime
    import numpy as np
    
    f = open(wfile_name, 'w')
    todaytime = datetime.datetime.today()
    f.write('// '+wfile_name+'\n')
    strdtime = todaytime.strftime("%Y/%m/%d %H:%M:%S")
    f.write('// {0} by marsee\n'.format(strdtime))
    f.write("\n")
    
    f.write('const float '+layer_output_name+'['+str(layer_out.shape[0])+']['+str(layer_out.shape[1])+']['+str(layer_out.shape[2])+']['+str(layer_out.shape[3])+'] = \n{\n')
    for i in range(layer_out.shape[0]):
        f.write("\t{\n")
        for j in range(layer_out.shape[1]):
            f.write("\t\t{\n")
            for k in range(layer_out.shape[2]):
                f.write("\t\t\t{")
                for m in range(layer_out.shape[3]):
                    f.write(str(layer_out[i][j][k][m]))
                    if (m==layer_out.shape[3]-1):
                        f.write("}")
                    else:
                        f.write(",")
                
                if (k==layer_out.shape[2]-1):
                    f.write("\n\t\t}\n")
                else:
                    f.write(",\n")

            if (j==layer_out.shape[1]-1):
                f.write("\t}\n")
            else:
                f.write(",\n")
        
        
        if (i==layer_out.shape[0]-1):
            f.write("};\n")
        else:
            f.write("\t,\n")

    f.write("\n")
    f.close()
```


```python
# 層の出力データを取得する(conv2d_1だけのテスト用)
from keras.models import Model

conv_layer_name = 'conv2d_1'

conv_layer = model.get_layer(conv_layer_name)
conv_layer_wb = conv_layer.get_weights()

conv_layer_model = Model(inputs=model.input,
                                 outputs=model.get_layer(conv_layer_name).output)
x_test_limit = x_test[:1]
y_test_limit = y_test[:10]
print(y_test_limit)
conv_output = conv_layer_model.predict(x_test_limit, verbose=1)
print(conv_output.shape)
fwrite_layer_output(conv_output, 'conv2d_1_output.h', 'conv2d_1_output')
```

    [[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
     [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
     [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
     [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
     [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
     [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]
    1/1 [==============================] - 0s 74ms/step
    (1, 13, 13, 20)


# 層の統計情報


```python
# Convolution layerの中間出力を取り出す 
from keras.models import Model
import numpy as np

x_test_limit = x_test[:1]
for num in range(1, 6):
    conv_layer_name = 'conv2d_' + str(num)

    conv_layer = model.get_layer(conv_layer_name)
    conv_layer_wb = conv_layer.get_weights()

    conv_layer_model = Model(inputs=model.input,
                                     outputs=model.get_layer(conv_layer_name).output)
    conv_output = conv_layer_model.predict(x_test, verbose=1)

    conv_layer_weight = conv_layer_wb[0]
    conv_layer_bias = conv_layer_wb[1]

    print(conv_layer_name)
    print(conv_layer_weight.shape)
    print(conv_layer_weight.transpose(3,2,0,1).shape)
    print(conv_layer_bias.shape)
    print(conv_output.shape)

    print("np.max(conv_layer_weight) = {0}".format(np.max(conv_layer_weight)))
    print("np.min(conv_layer_weight) = {0}".format(np.min(conv_layer_weight))) 
    abs_conv_layer_weight = np.absolute(conv_layer_weight)
    print("np.max(abs_conv_layer_weight) = {0}".format(np.max(abs_conv_layer_weight)))
    print("np.min(abs_conv_layer_weight) = {0}".format(np.min(abs_conv_layer_weight))) 

    print("np.max(conv_layer_bias) = {0}".format(np.max(conv_layer_bias)))
    print("np.min(conv_layer_bias) = {0}".format(np.min(conv_layer_bias))) 
    abs_conv_layer_bias = np.absolute(conv_layer_bias)
    print("np.max(abs_conv_layer_bias) = {0}".format(np.max(abs_conv_layer_bias)))
    print("np.min(abs_conv_layer_bias) = {0}".format(np.min(abs_conv_layer_bias))) 

    print("conv_output = {0}".format(conv_output.shape))
    print("np.std(conv_output) = {0}".format(np.std(conv_output)))
    print("np.max(conv_output) = {0}".format(np.max(conv_output)))
    print("np.min(conv_output) = {0}".format(np.min(conv_output))) 

    abs_conv_output = np.absolute(conv_output)
    print("np.max(abs_conv) = {0}".format(np.max(abs_conv_output)))
    print("np.min(abs_conv) = {0}".format(np.min(abs_conv_output))) 
    print("")
    
    # 2018/06/05 修正 畳み込み層の重みの配列は(カーネルサイズh,カーネルサイズw, 入力チャネル, 出力チャネル)ということなので、Pythonコードを修正した。@NORA__0013 さんありがとうございました。

    MAGNIFICATION_CONV = 2 ** (9-1)
    fwrite_conv_weight(conv_layer_weight.transpose(3,2,0,1), 'conv'+str(num)+'_weight.h', 'conv'+str(num)+'_fweight', 'conv'+str(num)+'_weight', MAGNIFICATION_CONV)

    fwrite_bias(conv_layer_bias, 'conv'+str(num)+'_bias.h', 'conv'+str(num)+'_fbias', 'conv'+str(num)+'_bias', MAGNIFICATION_CONV)
    
    conv_output = conv_layer_model.predict(x_test_limit, verbose=1)
    fwrite_layer_output(conv_output, 'conv'+str(num)+'_output.h', 'conv'+str(num)+'output')
```

    10000/10000 [==============================] - 0s 38us/step
    conv2d_1
    (3, 3, 1, 20)
    (20, 1, 3, 3)
    (20,)
    (10000, 13, 13, 20)
    np.max(conv_layer_weight) = 0.4946177303791046
    np.min(conv_layer_weight) = -0.5343244671821594
    np.max(abs_conv_layer_weight) = 0.5343244671821594
    np.min(abs_conv_layer_weight) = 0.00023465760750696063
    np.max(conv_layer_bias) = 0.057732950896024704
    np.min(conv_layer_bias) = -0.08072157949209213
    np.max(abs_conv_layer_bias) = 0.08072157949209213
    np.min(abs_conv_layer_bias) = 2.5581393856555223e-05
    conv_output = (10000, 13, 13, 20)
    np.std(conv_output) = 0.303703248500824
    np.max(conv_output) = 1.8376622200012207
    np.min(conv_output) = -1.7203431129455566
    np.max(abs_conv) = 1.8376622200012207
    np.min(abs_conv) = 4.842877388000488e-08
    
    1/1 [==============================] - 0s 0us/step
    10000/10000 [==============================] - 0s 40us/step
    conv2d_2
    (1, 1, 20, 10)
    (10, 20, 1, 1)
    (10,)
    (10000, 6, 6, 10)
    np.max(conv_layer_weight) = 0.913070023059845
    np.min(conv_layer_weight) = -0.9718273878097534
    np.max(abs_conv_layer_weight) = 0.9718273878097534
    np.min(abs_conv_layer_weight) = 0.0080069899559021
    np.max(conv_layer_bias) = 0.10839419811964035
    np.min(conv_layer_bias) = -0.04171771556138992
    np.max(abs_conv_layer_bias) = 0.10839419811964035
    np.min(abs_conv_layer_bias) = 0.010898223146796227
    conv_output = (10000, 6, 6, 10)
    np.std(conv_output) = 0.9102568626403809
    np.max(conv_output) = 4.971376895904541
    np.min(conv_output) = -2.940309762954712
    np.max(abs_conv) = 4.971376895904541
    np.min(abs_conv) = 1.1175870895385742e-08
    
    1/1 [==============================] - 0s 0us/step
    10000/10000 [==============================] - 0s 44us/step
    conv2d_3
    (1, 1, 10, 10)
    (10, 10, 1, 1)
    (10,)
    (10000, 6, 6, 10)
    np.max(conv_layer_weight) = 0.8710610270500183
    np.min(conv_layer_weight) = -0.6806471347808838
    np.max(abs_conv_layer_weight) = 0.8710610270500183
    np.min(abs_conv_layer_weight) = 0.0008496924419887364
    np.max(conv_layer_bias) = 0.1616363525390625
    np.min(conv_layer_bias) = -0.11668514460325241
    np.max(abs_conv_layer_bias) = 0.1616363525390625
    np.min(abs_conv_layer_bias) = 0.0003539775207173079
    conv_output = (10000, 6, 6, 10)
    np.std(conv_output) = 1.006908655166626
    np.max(conv_output) = 4.752679347991943
    np.min(conv_output) = -3.4257307052612305
    np.max(abs_conv) = 4.752679347991943
    np.min(abs_conv) = 2.9848888516426086e-07
    
    1/1 [==============================] - 0s 999us/step
    10000/10000 [==============================] - 1s 56us/step
    conv2d_4
    (3, 3, 10, 10)
    (10, 10, 3, 3)
    (10,)
    (10000, 6, 6, 10)
    np.max(conv_layer_weight) = 0.6119384765625
    np.min(conv_layer_weight) = -0.6267021894454956
    np.max(abs_conv_layer_weight) = 0.6267021894454956
    np.min(abs_conv_layer_weight) = 0.000530939141754061
    np.max(conv_layer_bias) = 0.09105820208787918
    np.min(conv_layer_bias) = -0.13521511852741241
    np.max(abs_conv_layer_bias) = 0.13521511852741241
    np.min(abs_conv_layer_bias) = 0.000247095333179459
    conv_output = (10000, 6, 6, 10)
    np.std(conv_output) = 1.4005329608917236
    np.max(conv_output) = 7.894415378570557
    np.min(conv_output) = -7.611080169677734
    np.max(abs_conv) = 7.894415378570557
    np.min(abs_conv) = 6.484333425760269e-08
    
    1/1 [==============================] - 0s 0us/step
    10000/10000 [==============================] - 1s 63us/step
    conv2d_5
    (1, 1, 20, 10)
    (10, 20, 1, 1)
    (10,)
    (10000, 6, 6, 10)
    np.max(conv_layer_weight) = 1.1239129304885864
    np.min(conv_layer_weight) = -0.9796998500823975
    np.max(abs_conv_layer_weight) = 1.1239129304885864
    np.min(abs_conv_layer_weight) = 0.0004102856619283557
    np.max(conv_layer_bias) = 0.3322758972644806
    np.min(conv_layer_bias) = -0.23224467039108276
    np.max(abs_conv_layer_bias) = 0.3322758972644806
    np.min(abs_conv_layer_bias) = 0.021110178902745247
    conv_output = (10000, 6, 6, 10)
    np.std(conv_output) = 1.4941357374191284
    np.max(conv_output) = 9.327534675598145
    np.min(conv_output) = -11.037702560424805
    np.max(abs_conv) = 11.037702560424805
    np.min(abs_conv) = 1.5832483768463135e-07
    
    1/1 [==============================] - 0s 999us/step



DNN/Keras/squeezenet4mnist2 ディレクトリの内容を示す。層ごとの出力ファイルの conv?_output.h ができているのが分かる。
squeezenet_69_181013.png

1層目の出力ファイルの conv1_output.h の一部を示す。
squeezenet_70_181013.png
  1. 2018年10月13日 06:55 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

icrawler で学習用画像を収集する

機械学習用の画像を集めるのにicrawlerが便利だった”で icrawler を使って学習用画像を収集していたが、なかなかうまく行かなかったので、顛末を書く。

icrawler のインストールはAnaconda の場合は、conda でインストール出来て、そちらはWindows だったが、動作して問題なかった。
pip の場合は、
pip install icrawler
でインストールを行った。
cralwer_1_180929.png
cralwer_2_180929.png

機械学習用の画像を集めるのにicrawlerが便利だった”のコードを少し変えて試してみたが、"Couldn't find a tree builder with the features you requested: lxml."というエラーだった。
cralwer_3_180929.png

色々と調べたところ、”BeautifulSoup4でlxmlが使えない”で、

lxmlのバージョンを3.7.3まで下げるとエラーは消えます。(3.8.0だとNG)

ということだったので、lxml の 3.7.3 をインストールした。
sudo pip install 'lxml==3.7.3'
cralwer_5_180929.png

cralwer_6_180929.png

これで、icrawler を動作させると動いた。
cralwer_4_180929.png

もう一度、
sudo pip install 'lxml==4.2.5'
で戻しても動作したのはなぜだろうか?

icrawler でグーグルを使って収集した猫の写真を示す。
cralwer_7_180929.png
  1. 2018年09月29日 11:40 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

SqueezeNet for MNIST のVivado HLS での試行3

SqueezeNet for MNIST のVivado HLS での試行2”の続き。

前回はSqueezeNet for MNISTで、どのくらいのリソースが必要なのかを探ってみようということで、C コードの合成を行って、結果を調べた。今回は、Vivado synthesis, place and route にチェックを入れてExport RTL を行い、合成結果と比較した。

Vivado synthesis, place and route にチェックを入れて、Vivado 2017.4 のインプリメンテーションを行って、レポートを確認した。結果を示す。
squeezenet_vhls_12_180908.png

その結果は LUT が 26930 個で、FF が 30836 個、DSP が 194 個、BRAM が 3 個だった。
CP achieved post-implementation は 10.283 ns だった。

C コードの合成時のレポートを示す。
squeezenet_vhls_2_180906.png

まずは、BRAM 3 個と DSP 194 個は変化が無い。FF はC コードの合成時が 33233 個に対して、Vivado 合成時には 30836 個だった。Vivado 合成時の使用率のパーセンテージは、約 29 % だった。C コードの合成時が 31 % だったので、それほどの変更はない。
LUT はどうかというと、C コードの合成時には、66650 個で、Vivado 合成時には、26930 個だった。Vivado 合成時のパーセンテージは、約 51 % だった。C コードの合成時には、125 % だったので、大幅に低下して実装可能となった。
しかし、これだけでは SqueezeNet のほんの一部分しか実装できていないので、無理そうだ。

次回は、今はチャネル数分の幅のHLS ストリームを使用しているが、チャネルの幅を変更できるように、すでにテンプレートを書き換えてあるので、それについてブログに書いてみたい。
  1. 2018年09月08日 06:43 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

SqueezeNet for MNIST のVivado HLS での試行2

SqueezeNet for MNIST のVivado HLS での試行1”の続き。

SqueezeNet for MNIST 3(層の統計情報とC ヘッダ・ファイルへの出力)”で層の統計情報と重みやバイアスの C ヘッダ・ファイルを出力したので、それらを使用して、SqueezeNet for MNISTで、どのくらいのリソースが必要なのかを探ってみようということで、前回はソースコードを示した。今回はC コードの合成結果を示す。

さて、都合(reVISION-ZYBO-Z7-20 を動かす関係上)により、Vivado HLS 2017.4 で合成した時の結果を示す。
squeezenet_vhls_2_180906.png

Estimated は 11.46 ns で Target の 10.00 ns をオーバーしている。
Latency は 63527 クロックだった。
Instance は conv_layer1_U0 、 max_pooling_U0 、 relu_conv1_U0 のインスタンスがある。
リソース使用量は BRAM_18K が 3 個、DSP48E が 194 個、FF が 33233 個、LUT が 66650 個だった。
LUT が 125 % でオーバーしている。やはり、出力ストームの 96 チャネルを並列に計算しているので、リソースが足りない。

次に、Instance の conv_layer1_U0 をクリックして、畳み込み層の合成結果を見てみよう。
squeezenet_vhls_3_180906.png

Estimated は 11.46 ns で畳み込み層が全体の足を引っ張っていることがわかる。
ここでのLatency は 63527 クロックで、全体のレイテンシと同じだ。
BRAM_18K は 1 個、 DSP48E は 194 個、FF は 14752 個、 FF は 37433 個使用している。
FF は全体の 70 % を使用している。

次に conv_layer_template.h のリソース使用量を確認するために、Detail -> Instance の grp_conv_layer_template_fu_1426 をクリックした。
squeezenet_vhls_4_180906.png

Latency は 63526 クロックだった。
Detail -> Loop を見ると、Loop_y_Loop_pix_mat_nd の Initiation Interval の achieved が 81 クロックで Target の 1 から大きくかけ離れている。
やはり、96 Channel を一度に実装するのは無理があるようだ。
BRAM_18K は 1 個、 DSP48E は 194 個、FF は 14747 個、 FF は 36483 個使用している。

最初のレポートに戻って、max_pooling_U0 をクリックした。今度はマックス・プーリングを見ていこう。
squeezenet_vhls_8_180907.png

こちらのEstimated は 6.89 ns だった。これは要求を満たしている。
Latency は 16278 クロックだった。
リソース使用量は、BRAM_18K は 1 個、 DSP48E は 0 個、FF は 8986 個、 FF は 13993 個使用している。
マックス・プーリングも結構リソースを消費している。

max_pooling_template.h の状況を見るために grp_max_pooling_template_fu_2756 を見ていこう。
squeezenet_vhls_9_180907.png

Detail -> Loop を見ると、Loop1 の Initiation Interval の achieved が 48 クロックで、Loop2_Loop3 のそれが、96 クロックだった。Loop2_Loop3 は チャネルごとにシリアライズされている感じだ。

最後に、最初のレポートに戻って、relu_conv1_U0 をクリックして見てみよう。
squeezenet_vhls_10_180907.png

Estimated は 6.89 ns だった。
Latency は 16445 クロックで、マックス・プーリングよりも使用クロック数が少し多い。
リソース使用量は、BRAM_18K が 1 個、DSP48E が 0 個、FF が 8447 個、LUT が 10632 個使用してる。

relu_template.h のリソース使用量を確認するために、Detail -> Instance の grp_relu_template_fu_2756 をクリックした。
squeezenet_vhls_11_180907.png

Detail -> Loop を見ると、Loop1 の Initiation Interval の achieved が 48 クロックで、Loop2_Loop3 のそれが、97 クロックだった。こちらの Loop2_Loop3 もチャネルごとにシリアライズされている感じだ。

C コードの合成結果からは、SqueezeNet for MNIST の 96 チャネル並列演算でZYBO Z7-20 では使い物にならないことが分かった。リソース使用量が大きすぎる。
だが、テンプレートを使用するとVivado HLS はリソース使用量の見積もりが甘くなることはすでに経験済みだ。よって、次回はExport RTL をやってみて、どのくらいの変化があるかを検証してみよう。
  1. 2018年09月07日 07:08 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

SqueezeNet for MNIST のVivado HLS での試行1

SqueezeNet for MNIST 3(層の統計情報とC ヘッダ・ファイルへの出力)”で層の統計情報と重みやバイアスの C ヘッダ・ファイルを出力したので、それらを使用して、SqueezeNet for MNISTで、どのくらいのリソースが必要なのかを探ってみた。
とりあえずは、層の内の第1層目の畳み込み層、ReLU, MaxPooling の 3 つを実装してみよう。
なお、実装には、conv_layer_template.h, relu_template.h, max_pooling_template.h を使用している。

最初に conv_layer1.cpp を示す。

// conv_layer1.cpp
// 2018/08/22 by marsee
// conv layer1 for squeeze4mnist
//

#include "conv_layer_template.h"
#include "conv1_weight.h"
#include "conv1_bias.h"

int conv_layer1(hls::stream<ap_fixed_axis<9,1,1,1> >& ins,
        hls::stream<ap_fixed_axis<11,1,96,1> >& outs){
//#pragma HLS DATA_PACK variable=outs
//#pragma HLS DATA_PACK variable=ins
    return(conv_layer_template<9,1,16,2,11,1,9,1,1,96,3,3,0,0,2,28,28>(ins, outs, conv1_weight, conv1_bias));
}


次に、relu_conv1.cpp を示す。

// relu_conv1.cpp
// 2018/05/06 by marsee
// relu after conv1
//

#include "relu_template.h"

int relu_conv1(hls::stream<ap_fixed_axis<11,1,96,1> >& ins,
        hls::stream<ap_fixed_axis<11,1,96,1> >& outs){
//#pragma HLS DATA_PACK variable=outs
//#pragma HLS DATA_PACK variable=ins
    return(relu_template<11,1,96,13,13>(ins, outs));
}


max_pooling.cpp を示す。

// max_pooling.cpp
// 2018/05/10 by marsee
//

#include "max_pooling_template.h"

int max_pooling(hls::stream<ap_fixed_axis<11,1,96,1> >& ins,
        hls::stream<ap_fixed_axis<11,1,96,1> >& outs){
//#pragma HLS DATA_PACK variable=outs
//#pragma HLS DATA_PACK variable=ins
    return(max_pooling_template<11,1,96,2,2,2,13,13>(ins, outs));
}


squeezenet4mnist1.cpp を示す。

// squeezenet4mnist1.cpp
// 2018/08/28 by marsee
//

#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include <hls_video.h>

#include "layer_general.h"

int conv_layer1(hls::stream<ap_fixed_axis<9,1,1,1> >& ins,
    hls::stream<ap_fixed_axis<11,1,96,1> >& outs);
int relu_conv1(hls::stream<ap_fixed_axis<11,1,96,1> >& ins,
    hls::stream<ap_fixed_axis<11,1,96,1> >& outs);
int max_pooling(hls::stream<ap_fixed_axis<11,1,96,1> >& ins,
    hls::stream<ap_fixed_axis<11,1,96,1> >& outs);

int squeezenet4mnist1(hls::stream<ap_fixed_axis<9,1,1,1> >& ins, hls::stream<ap_fixed_axis<11,1,96,1> >& outs){
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS DATAFLOW
    hls::stream<ap_fixed_axis<11,1,96,1> > outs_conv_layer1;
    hls::stream<ap_fixed_axis<11,1,96,1> > outs_relu_conv1;

    conv_layer1(ins, outs_conv_layer1);
    relu_conv1(outs_conv_layer1, outs_relu_conv1);
    max_pooling(outs_relu_conv1, outs);

    return(0);
}


Vivado HLS 2017.4 で squeezenet4mnist1 プロジェクトを作成した。
squeezenet_vhls_1_180906.png
  1. 2018年09月06日 05:06 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

SqueezeNet for MNIST 3(層の統計情報とC ヘッダ・ファイルへの出力)

SqueezeNet for MNIST 2”の続き。

前回は、model accuracy と model loss を示し、model.summary() を示した。今回は、層の統計情報を取って、各層の重みとバイアスのC ヘッダ・ファイルを出力する。

畳み込み層の重みをCヘッダファイルに書き出すPython コードは”TensorFlow + Kerasを使ってみた9(畳み込み層の重みをC のヘッダに変換)”のPython コードを使用した。
畳み込み層バイアスをCヘッダファイルに書き出すPython コードは”TensorFlow + Kerasを使ってみた10(バイアスをC のヘッダに変換)”のPython コードを使用した。

それから、層の統計情報出力し、重みとバイアスをC ヘッダ・ファイルに出力した。
squeezenet4mnist_11_180828.png
squeezenet4mnist_12_180828.png

Python コードを貼っておく。

# Convolution layerの中間出力を取り出す 
from keras.models import Model
import numpy as np

for num in range(1, 27):
    conv_layer_name = 'conv2d_' + str(num)

    conv_layer = model.get_layer(conv_layer_name)
    conv_layer_wb = conv_layer.get_weights()

    conv_layer_model = Model(inputs=model.input,
                                     outputs=model.get_layer(conv_layer_name).output)
    conv_output = conv_layer_model.predict(x_test, verbose=1)

    conv_layer_weight = conv_layer_wb[0]
    conv_layer_bias = conv_layer_wb[1]

    print(conv_layer_name)
    print(conv_layer_weight.shape)
    print(conv_layer_weight.transpose(3,2,0,1).shape)
    print(conv_layer_bias.shape)
    print(conv_output.shape)

    print("np.max(conv_layer_weight) = {0}".format(np.max(conv_layer_weight)))
    print("np.min(conv_layer_weight) = {0}".format(np.min(conv_layer_weight))) 
    abs_conv_layer_weight = np.absolute(conv_layer_weight)
    print("np.max(abs_conv_layer_weight) = {0}".format(np.max(abs_conv_layer_weight)))
    print("np.min(abs_conv_layer_weight) = {0}".format(np.min(abs_conv_layer_weight))) 

    print("np.max(conv_layer_bias) = {0}".format(np.max(conv_layer_bias)))
    print("np.min(conv_layer_bias) = {0}".format(np.min(conv_layer_bias))) 
    abs_conv_layer_bias = np.absolute(conv_layer_bias)
    print("np.max(abs_conv_layer_bias) = {0}".format(np.max(abs_conv_layer_bias)))
    print("np.min(abs_conv_layer_bias) = {0}".format(np.min(abs_conv_layer_bias))) 

    print("conv_output = {0}".format(conv_output.shape))
    print("np.std(conv_output) = {0}".format(np.std(conv_output)))
    print("np.max(conv_output) = {0}".format(np.max(conv_output)))
    print("np.min(conv_output) = {0}".format(np.min(conv_output))) 

    abs_conv_output = np.absolute(conv_output)
    print("np.max(abs_conv) = {0}".format(np.max(abs_conv_output)))
    print("np.min(abs_conv) = {0}".format(np.min(abs_conv_output))) 
    print("")
    
    # 2018/06/05 修正 畳み込み層の重みの配列は(カーネルサイズh,カーネルサイズw, 入力チャネル, 出力チャネル)ということなので、Pythonコードを修正した。@NORA__0013 さんありがとうございました。

    MAGNIFICATION_CONV = 2 ** (9-1)
    fwrite_conv_weight(conv_layer_weight.transpose(3,2,0,1), 'conv'+str(num)+'_weight.h', 'conv'+str(num)+'_fweight', 'conv'+str(num)+'_weight', MAGNIFICATION_CONV)

    fwrite_bias(conv_layer_bias, 'conv'+str(num)+'_bias.h', 'conv'+str(num)+'_fbias', 'conv'+str(num)+'_bias', MAGNIFICATION_CONV)


生成された重みとバイアスを示す。
squeezenet4mnist_13_180828.png

全統計情報を示す。

10000/10000 [==============================] - 1s 137us/step
conv2d_1
(3, 3, 1, 96)
(96, 1, 3, 3)
(96,)
(10000, 13, 13, 96)
np.max(conv_layer_weight) = 0.23241539299488068
np.min(conv_layer_weight) = -0.2830057442188263
np.max(abs_conv_layer_weight) = 0.2830057442188263
np.min(abs_conv_layer_weight) = 0.00018287629063706845
np.max(conv_layer_bias) = 0.19594410061836243
np.min(conv_layer_bias) = -0.06709111481904984
np.max(abs_conv_layer_bias) = 0.19594410061836243
np.min(abs_conv_layer_bias) = 0.0003071741375606507
conv_output = (10000, 13, 13, 96)
np.std(conv_output) = 0.1008128821849823
np.max(conv_output) = 0.657059371471405
np.min(conv_output) = -0.7351041436195374
np.max(abs_conv) = 0.7351041436195374
np.min(abs_conv) = 1.3969838619232178e-09

10000/10000 [==============================] - 1s 84us/step
conv2d_2
(1, 1, 96, 16)
(16, 96, 1, 1)
(16,)
(10000, 6, 6, 16)
np.max(conv_layer_weight) = 0.41374555230140686
np.min(conv_layer_weight) = -0.4286271035671234
np.max(abs_conv_layer_weight) = 0.4286271035671234
np.min(abs_conv_layer_weight) = 0.00025720358826220036
np.max(conv_layer_bias) = 0.07645587623119354
np.min(conv_layer_bias) = -0.04433523118495941
np.max(abs_conv_layer_bias) = 0.07645587623119354
np.min(abs_conv_layer_bias) = 0.0009641082142479718
conv_output = (10000, 6, 6, 16)
np.std(conv_output) = 0.29928353428840637
np.max(conv_output) = 1.535873293876648
np.min(conv_output) = -1.057706356048584
np.max(abs_conv) = 1.535873293876648
np.min(abs_conv) = 1.825392246246338e-07

10000/10000 [==============================] - 1s 111us/step
conv2d_3
(1, 1, 16, 64)
(64, 16, 1, 1)
(64,)
(10000, 6, 6, 64)
np.max(conv_layer_weight) = 0.3813319504261017
np.min(conv_layer_weight) = -0.3624926209449768
np.max(abs_conv_layer_weight) = 0.3813319504261017
np.min(abs_conv_layer_weight) = 0.0003253854811191559
np.max(conv_layer_bias) = 0.08430161327123642
np.min(conv_layer_bias) = -0.06795598566532135
np.max(abs_conv_layer_bias) = 0.08430161327123642
np.min(abs_conv_layer_bias) = 0.0005309522384777665
conv_output = (10000, 6, 6, 64)
np.std(conv_output) = 0.19837331771850586
np.max(conv_output) = 1.1776185035705566
np.min(conv_output) = -0.9223350882530212
np.max(abs_conv) = 1.1776185035705566
np.min(abs_conv) = 7.450580596923828e-09

10000/10000 [==============================] - 1s 107us/step
conv2d_4
(3, 3, 16, 64)
(64, 16, 3, 3)
(64,)
(10000, 6, 6, 64)
np.max(conv_layer_weight) = 0.23302672803401947
np.min(conv_layer_weight) = -0.23958751559257507
np.max(abs_conv_layer_weight) = 0.23958751559257507
np.min(abs_conv_layer_weight) = 3.953342002205318e-06
np.max(conv_layer_bias) = 0.09260329604148865
np.min(conv_layer_bias) = -0.07423409074544907
np.max(abs_conv_layer_bias) = 0.09260329604148865
np.min(abs_conv_layer_bias) = 4.278140841051936e-05
conv_output = (10000, 6, 6, 64)
np.std(conv_output) = 0.3154037594795227
np.max(conv_output) = 1.8085815906524658
np.min(conv_output) = -2.099088191986084
np.max(abs_conv) = 2.099088191986084
np.min(abs_conv) = 2.2351741790771484e-08

10000/10000 [==============================] - 1s 109us/step
conv2d_5
(1, 1, 128, 16)
(16, 128, 1, 1)
(16,)
(10000, 6, 6, 16)
np.max(conv_layer_weight) = 0.3283624053001404
np.min(conv_layer_weight) = -0.32311302423477173
np.max(abs_conv_layer_weight) = 0.3283624053001404
np.min(abs_conv_layer_weight) = 9.099296585191041e-05
np.max(conv_layer_bias) = 0.11211202293634415
np.min(conv_layer_bias) = -0.023712079972028732
np.max(abs_conv_layer_bias) = 0.11211202293634415
np.min(abs_conv_layer_bias) = 0.00019536164472810924
conv_output = (10000, 6, 6, 16)
np.std(conv_output) = 0.39457967877388
np.max(conv_output) = 3.2098631858825684
np.min(conv_output) = -1.4322690963745117
np.max(abs_conv) = 3.2098631858825684
np.min(abs_conv) = 2.9802322387695312e-08

10000/10000 [==============================] - 1s 116us/step
conv2d_6
(1, 1, 16, 64)
(64, 16, 1, 1)
(64,)
(10000, 6, 6, 64)
np.max(conv_layer_weight) = 0.3472273051738739
np.min(conv_layer_weight) = -0.3461221754550934
np.max(abs_conv_layer_weight) = 0.3472273051738739
np.min(abs_conv_layer_weight) = 2.151904845959507e-05
np.max(conv_layer_bias) = 0.11182372272014618
np.min(conv_layer_bias) = -0.07308819890022278
np.max(abs_conv_layer_bias) = 0.11182372272014618
np.min(abs_conv_layer_bias) = 9.089573723031208e-05
conv_output = (10000, 6, 6, 64)
np.std(conv_output) = 0.28788891434669495
np.max(conv_output) = 2.15021014213562
np.min(conv_output) = -1.765142560005188
np.max(abs_conv) = 2.15021014213562
np.min(abs_conv) = 1.4901161193847656e-08

10000/10000 [==============================] - 1s 134us/step
conv2d_7
(3, 3, 16, 64)
(64, 16, 3, 3)
(64,)
(10000, 6, 6, 64)
np.max(conv_layer_weight) = 0.25860607624053955
np.min(conv_layer_weight) = -0.22963279485702515
np.max(abs_conv_layer_weight) = 0.25860607624053955
np.min(abs_conv_layer_weight) = 5.8508041547611356e-05
np.max(conv_layer_bias) = 0.08639949560165405
np.min(conv_layer_bias) = -0.08458155393600464
np.max(abs_conv_layer_bias) = 0.08639949560165405
np.min(abs_conv_layer_bias) = 8.820320363156497e-05
conv_output = (10000, 6, 6, 64)
np.std(conv_output) = 0.4426092207431793
np.max(conv_output) = 2.844907522201538
np.min(conv_output) = -2.9819791316986084
np.max(abs_conv) = 2.9819791316986084
np.min(abs_conv) = 1.1175870895385742e-08

10000/10000 [==============================] - 1s 142us/step
conv2d_8
(1, 1, 128, 32)
(32, 128, 1, 1)
(32,)
(10000, 6, 6, 32)
np.max(conv_layer_weight) = 0.3010956645011902
np.min(conv_layer_weight) = -0.31097307801246643
np.max(abs_conv_layer_weight) = 0.31097307801246643
np.min(abs_conv_layer_weight) = 4.14710957556963e-05
np.max(conv_layer_bias) = 0.11694670468568802
np.min(conv_layer_bias) = -0.049082059413194656
np.max(abs_conv_layer_bias) = 0.11694670468568802
np.min(abs_conv_layer_bias) = 0.00034066737862303853
conv_output = (10000, 6, 6, 32)
np.std(conv_output) = 0.4840845465660095
np.max(conv_output) = 2.9063262939453125
np.min(conv_output) = -3.1062679290771484
np.max(abs_conv) = 3.1062679290771484
np.min(abs_conv) = 7.182825356721878e-08

10000/10000 [==============================] - 2s 157us/step
conv2d_9
(1, 1, 32, 128)
(128, 32, 1, 1)
(128,)
(10000, 6, 6, 128)
np.max(conv_layer_weight) = 0.2580183744430542
np.min(conv_layer_weight) = -0.2867690324783325
np.max(abs_conv_layer_weight) = 0.2867690324783325
np.min(abs_conv_layer_weight) = 5.197449354454875e-06
np.max(conv_layer_bias) = 0.08810567855834961
np.min(conv_layer_bias) = -0.10537270456552505
np.max(abs_conv_layer_bias) = 0.10537270456552505
np.min(abs_conv_layer_bias) = 0.0009785539004951715
conv_output = (10000, 6, 6, 128)
np.std(conv_output) = 0.21309173107147217
np.max(conv_output) = 1.4621883630752563
np.min(conv_output) = -1.9276840686798096
np.max(abs_conv) = 1.9276840686798096
np.min(abs_conv) = 1.862645149230957e-09

10000/10000 [==============================] - 2s 198us/step
conv2d_10
(3, 3, 32, 128)
(128, 32, 3, 3)
(128,)
(10000, 6, 6, 128)
np.max(conv_layer_weight) = 0.24369853734970093
np.min(conv_layer_weight) = -0.23873521387577057
np.max(abs_conv_layer_weight) = 0.24369853734970093
np.min(abs_conv_layer_weight) = 2.737535396590829e-06
np.max(conv_layer_bias) = 0.06724698841571808
np.min(conv_layer_bias) = -0.08158554136753082
np.max(abs_conv_layer_bias) = 0.08158554136753082
np.min(abs_conv_layer_bias) = 0.00012395322846714407
conv_output = (10000, 6, 6, 128)
np.std(conv_output) = 0.4583068788051605
np.max(conv_output) = 3.0841262340545654
np.min(conv_output) = -3.095609426498413
np.max(abs_conv) = 3.095609426498413
np.min(abs_conv) = 5.587935447692871e-09

10000/10000 [==============================] - 2s 208us/step
conv2d_11
(1, 1, 256, 32)
(32, 256, 1, 1)
(32,)
(10000, 3, 3, 32)
np.max(conv_layer_weight) = 0.2613295018672943
np.min(conv_layer_weight) = -0.2657088041305542
np.max(abs_conv_layer_weight) = 0.2657088041305542
np.min(abs_conv_layer_weight) = 6.479893636424094e-05
np.max(conv_layer_bias) = 0.08481862396001816
np.min(conv_layer_bias) = -0.04361288622021675
np.max(abs_conv_layer_bias) = 0.08481862396001816
np.min(abs_conv_layer_bias) = 0.0018431995995342731
conv_output = (10000, 3, 3, 32)
np.std(conv_output) = 0.6534223556518555
np.max(conv_output) = 4.2715630531311035
np.min(conv_output) = -3.003734827041626
np.max(abs_conv) = 4.2715630531311035
np.min(abs_conv) = 6.174668669700623e-07

10000/10000 [==============================] - 2s 233us/step
conv2d_12
(1, 1, 32, 128)
(128, 32, 1, 1)
(128,)
(10000, 3, 3, 128)
np.max(conv_layer_weight) = 0.24686792492866516
np.min(conv_layer_weight) = -0.245181143283844
np.max(abs_conv_layer_weight) = 0.24686792492866516
np.min(abs_conv_layer_weight) = 0.00010391152318334207
np.max(conv_layer_bias) = 0.1275489628314972
np.min(conv_layer_bias) = -0.09533561766147614
np.max(abs_conv_layer_bias) = 0.1275489628314972
np.min(abs_conv_layer_bias) = 0.0002949666231870651
conv_output = (10000, 3, 3, 128)
np.std(conv_output) = 0.30596160888671875
np.max(conv_output) = 2.30812931060791
np.min(conv_output) = -1.7490240335464478
np.max(abs_conv) = 2.30812931060791
np.min(abs_conv) = 6.332993507385254e-08

10000/10000 [==============================] - 2s 231us/step
conv2d_13
(3, 3, 32, 128)
(128, 32, 3, 3)
(128,)
(10000, 3, 3, 128)
np.max(conv_layer_weight) = 0.16889545321464539
np.min(conv_layer_weight) = -0.1818806380033493
np.max(abs_conv_layer_weight) = 0.1818806380033493
np.min(abs_conv_layer_weight) = 5.960464477539063e-08
np.max(conv_layer_bias) = 0.10003684461116791
np.min(conv_layer_bias) = -0.07217587530612946
np.max(abs_conv_layer_bias) = 0.10003684461116791
np.min(abs_conv_layer_bias) = 6.108602974563837e-06
conv_output = (10000, 3, 3, 128)
np.std(conv_output) = 0.38053178787231445
np.max(conv_output) = 2.981738805770874
np.min(conv_output) = -2.0631744861602783
np.max(abs_conv) = 2.981738805770874
np.min(abs_conv) = 4.470348358154297e-08

10000/10000 [==============================] - 2s 229us/step
conv2d_14
(1, 1, 256, 48)
(48, 256, 1, 1)
(48,)
(10000, 3, 3, 48)
np.max(conv_layer_weight) = 0.22013017535209656
np.min(conv_layer_weight) = -0.2426384836435318
np.max(abs_conv_layer_weight) = 0.2426384836435318
np.min(abs_conv_layer_weight) = 5.409237928688526e-06
np.max(conv_layer_bias) = 0.127075657248497
np.min(conv_layer_bias) = -0.07448185980319977
np.max(abs_conv_layer_bias) = 0.127075657248497
np.min(abs_conv_layer_bias) = 6.410764763131738e-05
conv_output = (10000, 3, 3, 48)
np.std(conv_output) = 0.4870619773864746
np.max(conv_output) = 4.841851711273193
np.min(conv_output) = -3.36439847946167
np.max(abs_conv) = 4.841851711273193
np.min(abs_conv) = 5.21540641784668e-07

10000/10000 [==============================] - 2s 246us/step
conv2d_15
(1, 1, 48, 192)
(192, 48, 1, 1)
(192,)
(10000, 3, 3, 192)
np.max(conv_layer_weight) = 0.2446354627609253
np.min(conv_layer_weight) = -0.212723970413208
np.max(abs_conv_layer_weight) = 0.2446354627609253
np.min(abs_conv_layer_weight) = 1.650952617637813e-05
np.max(conv_layer_bias) = 0.10810786485671997
np.min(conv_layer_bias) = -0.11747808754444122
np.max(abs_conv_layer_bias) = 0.11747808754444122
np.min(abs_conv_layer_bias) = 0.0001598717353772372
conv_output = (10000, 3, 3, 192)
np.std(conv_output) = 0.2135731279850006
np.max(conv_output) = 2.3861021995544434
np.min(conv_output) = -1.382702112197876
np.max(abs_conv) = 2.3861021995544434
np.min(abs_conv) = 7.450580596923828e-09

10000/10000 [==============================] - 3s 274us/step
conv2d_16
(3, 3, 48, 192)
(192, 48, 3, 3)
(192,)
(10000, 3, 3, 192)
np.max(conv_layer_weight) = 0.1449326127767563
np.min(conv_layer_weight) = -0.13954271376132965
np.max(abs_conv_layer_weight) = 0.1449326127767563
np.min(abs_conv_layer_weight) = 4.5239175960887223e-08
np.max(conv_layer_bias) = 0.0911775752902031
np.min(conv_layer_bias) = -0.07379891723394394
np.max(abs_conv_layer_bias) = 0.0911775752902031
np.min(abs_conv_layer_bias) = 7.930440187919885e-05
conv_output = (10000, 3, 3, 192)
np.std(conv_output) = 0.26481249928474426
np.max(conv_output) = 2.032439708709717
np.min(conv_output) = -2.2265918254852295
np.max(abs_conv) = 2.2265918254852295
np.min(abs_conv) = 7.450580596923828e-09

10000/10000 [==============================] - 3s 278us/step
conv2d_17
(1, 1, 384, 48)
(48, 384, 1, 1)
(48,)
(10000, 3, 3, 48)
np.max(conv_layer_weight) = 0.18762683868408203
np.min(conv_layer_weight) = -0.17972998321056366
np.max(abs_conv_layer_weight) = 0.18762683868408203
np.min(abs_conv_layer_weight) = 2.5248411475331523e-05
np.max(conv_layer_bias) = 0.1976175457239151
np.min(conv_layer_bias) = -0.056839194148778915
np.max(abs_conv_layer_bias) = 0.1976175457239151
np.min(abs_conv_layer_bias) = 8.029816672205925e-05
conv_output = (10000, 3, 3, 48)
np.std(conv_output) = 0.4208807051181793
np.max(conv_output) = 4.762706756591797
np.min(conv_output) = -2.9888551235198975
np.max(abs_conv) = 4.762706756591797
np.min(abs_conv) = 7.450580596923828e-09

10000/10000 [==============================] - 3s 304us/step
conv2d_18
(1, 1, 48, 192)
(192, 48, 1, 1)
(192,)
(10000, 3, 3, 192)
np.max(conv_layer_weight) = 0.2371293008327484
np.min(conv_layer_weight) = -0.2002277970314026
np.max(abs_conv_layer_weight) = 0.2371293008327484
np.min(abs_conv_layer_weight) = 1.3661010598298162e-06
np.max(conv_layer_bias) = 0.11516989022493362
np.min(conv_layer_bias) = -0.11722267419099808
np.max(abs_conv_layer_bias) = 0.11722267419099808
np.min(abs_conv_layer_bias) = 0.0005882936529815197
conv_output = (10000, 3, 3, 192)
np.std(conv_output) = 0.18415993452072144
np.max(conv_output) = 1.7632944583892822
np.min(conv_output) = -1.28092360496521
np.max(abs_conv) = 1.7632944583892822
np.min(abs_conv) = 1.1175870895385742e-08

10000/10000 [==============================] - 3s 308us/step
conv2d_19
(3, 3, 48, 192)
(192, 48, 3, 3)
(192,)
(10000, 3, 3, 192)
np.max(conv_layer_weight) = 0.12958909571170807
np.min(conv_layer_weight) = -0.15907122194766998
np.max(abs_conv_layer_weight) = 0.15907122194766998
np.min(abs_conv_layer_weight) = 1.0321384280587154e-07
np.max(conv_layer_bias) = 0.11025165766477585
np.min(conv_layer_bias) = -0.10412546247243881
np.max(abs_conv_layer_bias) = 0.11025165766477585
np.min(abs_conv_layer_bias) = 0.0005223090411163867
conv_output = (10000, 3, 3, 192)
np.std(conv_output) = 0.2775069773197174
np.max(conv_output) = 2.5127899646759033
np.min(conv_output) = -2.445796489715576
np.max(abs_conv) = 2.5127899646759033
np.min(abs_conv) = 3.725290298461914e-08

10000/10000 [==============================] - 3s 323us/step
conv2d_20
(1, 1, 384, 64)
(64, 384, 1, 1)
(64,)
(10000, 3, 3, 64)
np.max(conv_layer_weight) = 0.17044414579868317
np.min(conv_layer_weight) = -0.1799185425043106
np.max(abs_conv_layer_weight) = 0.1799185425043106
np.min(abs_conv_layer_weight) = 1.3735225365962833e-06
np.max(conv_layer_bias) = 0.11707722395658493
np.min(conv_layer_bias) = -0.07737477868795395
np.max(abs_conv_layer_bias) = 0.11707722395658493
np.min(abs_conv_layer_bias) = 0.0006104373605921865
conv_output = (10000, 3, 3, 64)
np.std(conv_output) = 0.373676598072052
np.max(conv_output) = 3.9217896461486816
np.min(conv_output) = -2.750190496444702
np.max(abs_conv) = 3.9217896461486816
np.min(abs_conv) = 2.0116567611694336e-07

10000/10000 [==============================] - 3s 333us/step
conv2d_21
(1, 1, 64, 256)
(256, 64, 1, 1)
(256,)
(10000, 3, 3, 256)
np.max(conv_layer_weight) = 0.18047918379306793
np.min(conv_layer_weight) = -0.17668132483959198
np.max(abs_conv_layer_weight) = 0.18047918379306793
np.min(abs_conv_layer_weight) = 1.4669767551822588e-06
np.max(conv_layer_bias) = 0.04918604716658592
np.min(conv_layer_bias) = -0.10770349204540253
np.max(abs_conv_layer_bias) = 0.10770349204540253
np.min(abs_conv_layer_bias) = 0.00023276149295270443
conv_output = (10000, 3, 3, 256)
np.std(conv_output) = 0.1407841295003891
np.max(conv_output) = 1.3393429517745972
np.min(conv_output) = -1.2819019556045532
np.max(abs_conv) = 1.3393429517745972
np.min(abs_conv) = 1.862645149230957e-09

10000/10000 [==============================] - 4s 381us/step
conv2d_22
(3, 3, 64, 256)
(256, 64, 3, 3)
(256,)
(10000, 3, 3, 256)
np.max(conv_layer_weight) = 0.16038639843463898
np.min(conv_layer_weight) = -0.15026776492595673
np.max(abs_conv_layer_weight) = 0.16038639843463898
np.min(abs_conv_layer_weight) = 1.719431566016283e-07
np.max(conv_layer_bias) = 0.05694166570901871
np.min(conv_layer_bias) = -0.07688959687948227
np.max(abs_conv_layer_bias) = 0.07688959687948227
np.min(abs_conv_layer_bias) = 0.0001346934586763382
conv_output = (10000, 3, 3, 256)
np.std(conv_output) = 0.31745824217796326
np.max(conv_output) = 3.5984885692596436
np.min(conv_output) = -2.2447152137756348
np.max(abs_conv) = 3.5984885692596436
np.min(abs_conv) = 7.334165275096893e-08

10000/10000 [==============================] - 4s 384us/step
conv2d_23
(1, 1, 512, 64)
(64, 512, 1, 1)
(64,)
(10000, 1, 1, 64)
np.max(conv_layer_weight) = 0.19756470620632172
np.min(conv_layer_weight) = -0.19377626478672028
np.max(abs_conv_layer_weight) = 0.19756470620632172
np.min(abs_conv_layer_weight) = 1.454010543966433e-06
np.max(conv_layer_bias) = 0.08133905380964279
np.min(conv_layer_bias) = -0.0322188101708889
np.max(abs_conv_layer_bias) = 0.08133905380964279
np.min(abs_conv_layer_bias) = 0.001015845569781959
conv_output = (10000, 1, 1, 64)
np.std(conv_output) = 0.9502997398376465
np.max(conv_output) = 6.56773042678833
np.min(conv_output) = -3.0976979732513428
np.max(abs_conv) = 6.56773042678833
np.min(abs_conv) = 6.351619958877563e-07

10000/10000 [==============================] - 4s 392us/step
conv2d_24
(1, 1, 64, 256)
(256, 64, 1, 1)
(256,)
(10000, 1, 1, 256)
np.max(conv_layer_weight) = 0.2581574618816376
np.min(conv_layer_weight) = -0.21347056329250336
np.max(abs_conv_layer_weight) = 0.2581574618816376
np.min(abs_conv_layer_weight) = 7.390540758933639e-06
np.max(conv_layer_bias) = 0.09020012617111206
np.min(conv_layer_bias) = -0.06578623503446579
np.max(abs_conv_layer_bias) = 0.09020012617111206
np.min(abs_conv_layer_bias) = 7.086795812938362e-05
conv_output = (10000, 1, 1, 256)
np.std(conv_output) = 0.649179220199585
np.max(conv_output) = 3.7935266494750977
np.min(conv_output) = -3.0759589672088623
np.max(abs_conv) = 3.7935266494750977
np.min(abs_conv) = 6.146728992462158e-08

10000/10000 [==============================] - 4s 406us/step
conv2d_25
(3, 3, 64, 256)
(256, 64, 3, 3)
(256,)
(10000, 1, 1, 256)
np.max(conv_layer_weight) = 0.17148838937282562
np.min(conv_layer_weight) = -0.13356263935565948
np.max(abs_conv_layer_weight) = 0.17148838937282562
np.min(abs_conv_layer_weight) = 1.862645149230957e-07
np.max(conv_layer_bias) = 0.11338628083467484
np.min(conv_layer_bias) = -0.05885875225067139
np.max(abs_conv_layer_bias) = 0.11338628083467484
np.min(abs_conv_layer_bias) = 2.0896652131341398e-05
conv_output = (10000, 1, 1, 256)
np.std(conv_output) = 0.4251912832260132
np.max(conv_output) = 2.2752349376678467
np.min(conv_output) = -1.4251927137374878
np.max(abs_conv) = 2.2752349376678467
np.min(abs_conv) = 2.4959444999694824e-07

10000/10000 [==============================] - 4s 416us/step
conv2d_26
(1, 1, 512, 10)
(10, 512, 1, 1)
(10,)
(10000, 1, 1, 10)
np.max(conv_layer_weight) = 0.2454858422279358
np.min(conv_layer_weight) = -0.24298278987407684
np.max(abs_conv_layer_weight) = 0.2454858422279358
np.min(abs_conv_layer_weight) = 5.791342118754983e-06
np.max(conv_layer_bias) = 0.05678941309452057
np.min(conv_layer_bias) = -0.04499662294983864
np.max(abs_conv_layer_bias) = 0.05678941309452057
np.min(abs_conv_layer_bias) = 0.001525017200037837
conv_output = (10000, 1, 1, 10)
np.std(conv_output) = 4.045248031616211
np.max(conv_output) = 13.264505386352539
np.min(conv_output) = -17.079362869262695
np.max(abs_conv) = 17.079362869262695
np.min(abs_conv) = 6.483122706413269e-05


  1. 2018年08月28日 05:25 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0
»