【畳込みニューラルネット No.3】Functional モデルの書き方

シェアする

前回から随分経ってしまいましたが,Tensorflow/Kerasの勉強した内容をまとめてます.

今回はFunctional モデルの書き方.

前回はSequentialモデルで書いてましたが,これは非常に簡単に記述できる反面,複雑なモデルの記述には適していないとのこと.ちなみに前回はこちら↓

そこで,今回はFunctionalモデルで前回と同じプログラムを構築します.

Sequential モデルの場合

先ず,前回の超シンプルな画像フィルタのプログラムです

import numpy as np
from keras.layers import Input, Conv2D
from keras.models import Sequential

#モデルの定義
model1 = Sequential()
model1.add(Input((5,5,1)))  #入力画像は5×5の1チャネル
model1.add(Conv2D(1, (3,3), padding='same'))  #3×3のフィルタが1つのみ.画像の周囲に0の枠を入れる

# フィルタの重みを設定
w = model1.layers[0].get_weights()
w[0] = np.array([[1,1,1],[1,1,1],[1,1,1]])[:,:,None,None]
w[1] = np.array([-1]) #バイアスの設定
model1.layers[0].set_weights(w)

#モデルの中身を表示
model1.summary()

これを実行すると,

このようになりました.ここで,レイヤーはconv2dのみというのがポイントです.

ここで,5×5の画像として,すべての要素の値が1の画像を入力して,フィルタリングします.

input_img = np.ones((5,5))[None,:,:,None]
output_img = model1.predict(input_img)
print(output_img[0,:,:,0])

実行結果は,以下のようになりました.

バイアスを-1に設定してあるので,すべてのピクセル値が1減算されています.

Functional モデルの場合

全く同じことをFunctional モデルで記述します.

import numpy as np
from keras.layers import Input, Conv2D
from keras import Model

#モデルの定義
input_img = Input(shape=(5,5,1))
output_img = Conv2D(1, (3,3), padding='same')(input_img)
model2 = Model(input_img, output_img)

# フィルタの重みを設定
w = model2.layers[1].get_weights() # conv2Dは1番目のレイヤーなので注意(Sequentialでは0番目)
print(w[0].shape)
w[0] = np.array([[1,1,1],[1,1,1],[1,1,1]])[:,:,None,None]
w[1] = np.array([-1])
model2.layers[1].set_weights(w)

# モデルの中身を表示
model2.summary()

これを実行すると以下のようになります.

先ほどはconv2dレイヤーのみ表示されましたが,今回はinputレイヤーとconv2dレイヤーの2つあります.なので,重み設定のときも1番目のレイヤーの重みに値を設定しないとエラーになります(Sequentialモデルでは0番目のレイヤー).

それだけが注意事項で,あとは同じです.

Sequentialモデルと同様に,5×5の画像を入力して結果を表示してみます.

input_img = np.ones((5,5))[None,:,:,None]
output_img = model2.predict(input_img)
print(output_img[0,:,:,0])

以下のようになりました.

全く同じです!

Functionalモデルの方がやや複雑なモデル(途中で分岐したり合流する形)も記述できるので,Functionalモデルに慣れておいた方が,より自由度の高いモデルを記述できるようです.

次は,途中で合流するモデルを作成してみたいと思います.