前回から随分経ってしまいましたが,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モデルに慣れておいた方が,より自由度の高いモデルを記述できるようです.
次は,途中で合流するモデルを作成してみたいと思います.