俺俺DLフレームワークを作るにはKeras一択のような気がしてきました。
KerasでNNに特定のデータを入れた時に、狙った層の出力をnumpy形式で出力する方法です。やりかたはKeras FAQをみました。簡単です。
https://keras.io/ja/getting-started/faq/#_1
やってること
http://d.hatena.ne.jp/natsutan/20170212/1486862458
ここで作ったNNに一枚絵を入れて、その途中の計算結果を取り出しました。入力データはひらがなデータを入れていますが、やっていることはNNも含めてMNISTと完全に同じです。
モデルと学習結果を読み込む
学習後に保存したjsonファイルとhd5ファイルを読み込みます。ファイルの作り方はここを参照。
http://d.hatena.ne.jp/natsutan/20170212/1486862458
json_string = open('output/cnn.json', 'r').read() model = model_from_json(json_string) model.load_weights('output/cnn.h5')
画像の読み込み
「い」が入ったデータを読み込みます。行列の形を合わせる必要があります。255から引いている所はネガポジ反転なので、データがすでに直接入力できる形式になっていれば不要です。
# load image images = np.empty([0, 28, 28], np.float32) img_ori = Image.open('data/I.png') img_gray = ImageOps.grayscale(img_ori) img_ary = np.asarray(img_gray) img_ary = 255 - img_ary images = np.append(images, [img_ary], axis=0) images = images.reshape(1, 28, 28, 1)
一枚の識別
model.predictで一枚だけ識別します。
ret = model.predict(images, 1, 1) print(ret)
実行結果
1/1 [==============================] - 0s [[ 9.66260362e-18 1.00000000e+00 1.46393750e-16 3.83880911e-21 1.73906418e-14 2.77851445e-13 2.60705761e-21 2.42816259e-22 9.78005010e-10 9.94229803e-16 2.92022889e-13 2.50225903e-12 1.87606130e-20 9.82728684e-17 4.47857970e-22 6.36410264e-16 2.89718408e-16 9.22273868e-15 1.46329236e-20 1.10161611e-16 3.02622735e-19 4.96133791e-18 4.64741527e-13 2.02620950e-12 5.23028010e-11 2.72302085e-14 3.31416961e-09 8.62797342e-16 3.77434917e-15 3.23395878e-13 8.63702926e-16 1.50429401e-18 1.54558563e-13 6.33530894e-10 1.18054563e-24 1.71215462e-14 1.62872005e-12 8.14889678e-20 4.88564665e-19 8.62093701e-15 4.40518906e-17 6.88677597e-16 4.34340205e-16 1.31322590e-17 4.82810310e-18 1.39269949e-18]]
入力した文字が「い」に対して、softamx出力の2番目が最大値になっているので識別できてますね。
中間層の出力を取り出す。
https://keras.io/ja/getting-started/faq/#_1 を参考に。
K.functionを使って、特定の層(例えばConvolution2D)の入出力を取り出す関数を作ります。その関数に対して、入力データを指定すると、それを処理した出力を受け取ることができます。numpy形式なので、そのままファイルに落とせます。
# output get_1st_layer_output = K.function([model.layers[0].input], [model.layers[0].output]) layer_output = get_1st_layer_output([images,]) print(layer_output[0].shape) np.save('output/convolution2d_out.npy', layer_output[0], allow_pickle=False)
全ソースコード
import numpy as np from PIL import Image from PIL import ImageOps from keras.models import model_from_json from keras import backend as K json_string = open('output/cnn.json', 'r').read() model = model_from_json(json_string) model.load_weights('output/cnn.h5') # load image images = np.empty([0, 28, 28], np.float32) img_ori = Image.open('data/I.png') img_gray = ImageOps.grayscale(img_ori) img_ary = np.asarray(img_gray) img_ary = 255 - img_ary images = np.append(images, [img_ary], axis=0) images = images.reshape(1, 28, 28, 1) # predict ret = model.predict(images, 1, 1) print(ret) # output get_1st_layer_output = K.function([model.layers[0].input], [model.layers[0].output]) layer_output = get_1st_layer_output([images,]) print(layer_output[0].shape) np.save('output/convolution2d_out.npy', layer_output[0], allow_pickle=False)