#背景
畳み込みニューラルネットワークによる自前データのオートエンコーダで、エンコード前の画像形状とデコード後の画像形状が一致せず苦労した時に学んだことを備忘録として記載する。
#やったこと
畳み込みニューラルネットワークを組み、サマリーを表示
#畳み込みオートエンコーダ
#keras.layersからInput関数, Dense関数、Conv2D関数、MaxPooling関数、UpSampling関数、Activation関数をインポート
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D, Activation, Flatten
#keras.modelsからModel関数をインポート
from keras.models import Model
#keras.callbacksからEarlyStopping関数をインポート
from keras.callbacks import EarlyStopping
es_cb = EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')
##Encode部
input_img = Input(shape=(750, 750, 1)) #Input関数で入力として受け付けるデータの次元を指定
x = Conv2D(250, (3, 3), padding="same")(input_img) #受け付けたデータを250個からなるレイヤーに流す。3x3フィルター、ゼロパディングを使う
x = Activation("relu")(x)
x = MaxPooling2D((2, 2), padding="same") (x) #2x2に対してプーリングする
x = Conv2D(125, (3, 3), padding="same")(x) #125個のレイヤーに流す。3x3フィルター、ゼロパディングを使う
x = Activation("relu")(x)
x = MaxPooling2D((2, 2), padding="same") (x) #2x2に対してプーリングする
x = Conv2D(50, (3, 3), padding="same")(x) #50個のレイヤーに流す。3x3フィルター、ゼロパディングを使う
x = Activation("relu")(x)
x = MaxPooling2D((2, 2), padding="same") (x) #2x2に対してプーリングする
x = Conv2D(25, (3, 3), padding="same")(x) #25個のレイヤーに流す。3x3フィルター、ゼロパディングを使う
encoded = Activation("relu")(x)
##Decode部
x = Conv2D(25, (3, 3), padding="same")(encoded)
x = Activation("relu")(x)
x = UpSampling2D((2, 2)) (x)
x = Conv2D(50, (3, 3), padding="same")(x) #50個のレイヤーに流す。3x3フィルター、ゼロパディングを使う
x = Activation("relu")(x)
x = UpSampling2D((2, 2)) (x)
x = Conv2D(125, (3, 3), padding="same")(x) #125個のレイヤーに流す。3x3フィルター、ゼロパディングを使う
x = Activation("relu")(x)
x = UpSampling2D((2, 2)) (x)
x = Conv2D(250, (3, 3), padding="same")(x) #250個のレイヤーに流す。3x3フィルター、ゼロパディングを使う
x = Activation("relu")(x)
x = Conv2D(1, (3, 3), padding="same")(x) #3x3フィルター、ゼロパディングを使う
decoded = Activation("sigmoid")(x) #decoded変数に入れる
model = Model(input_img, decoded) #Model関数で入力と出力を指定。入力と出力が指定した引数のようになるモデルにするということ
model.compile(optimizer="adam", loss="binary_crossentropy")
model.summary()
Layer (type) Output Shape Param #
=================================================================
input_11 (InputLayer) [(None, 750, 750, 1)] 0
_________________________________________________________________
conv2d_67 (Conv2D) (None, 750, 750, 250) 2500
_________________________________________________________________
activation_62 (Activation) (None, 750, 750, 250) 0
_________________________________________________________________
max_pooling2d_30 (MaxPooling (None, 375, 375, 250) 0
_________________________________________________________________
conv2d_68 (Conv2D) (None, 375, 375, 125) 281375
_________________________________________________________________
activation_63 (Activation) (None, 375, 375, 125) 0
_________________________________________________________________
max_pooling2d_31 (MaxPooling (None, 188, 188, 125) 0
_________________________________________________________________
conv2d_69 (Conv2D) (None, 188, 188, 50) 56300
_________________________________________________________________
activation_64 (Activation) (None, 188, 188, 50) 0
_________________________________________________________________
max_pooling2d_32 (MaxPooling (None, 94, 94, 50) 0
_________________________________________________________________
conv2d_70 (Conv2D) (None, 94, 94, 25) 11275
_________________________________________________________________
activation_65 (Activation) (None, 94, 94, 25) 0
_________________________________________________________________
activation_66 (Activation) (None, 94, 94, 25) 0
_________________________________________________________________
conv2d_71 (Conv2D) (None, 94, 94, 25) 5650
_________________________________________________________________
activation_67 (Activation) (None, 94, 94, 25) 0
_________________________________________________________________
up_sampling2d_15 (UpSampling (None, 188, 188, 25) 0
_________________________________________________________________
conv2d_72 (Conv2D) (None, 188, 188, 50) 11300
_________________________________________________________________
activation_68 (Activation) (None, 188, 188, 50) 0
_________________________________________________________________
up_sampling2d_16 (UpSampling (None, 376, 376, 50) 0
_________________________________________________________________
conv2d_73 (Conv2D) (None, 376, 376, 125) 56375
_________________________________________________________________
activation_69 (Activation) (None, 376, 376, 125) 0
_________________________________________________________________
up_sampling2d_17 (UpSampling (None, 752, 752, 125) 0
_________________________________________________________________
conv2d_74 (Conv2D) (None, 752, 752, 250) 281500
_________________________________________________________________
activation_70 (Activation) (None, 752, 752, 250) 0
_________________________________________________________________
conv2d_75 (Conv2D) (None, 752, 752, 1) 2251
_________________________________________________________________
activation_71 (Activation) (None, 752, 752, 1) 0
=================================================================
#学んだこと
(None, 750, 750, 1)と(None, 752, 752, 1) が不一致のためエラーになったが、要因はmaxpoolingの際に375→188というところでズレが出ていること。
maxpoolingを3回やるなら、2の3乗の8の倍数になるようにする必要があり、その場合750ではなく760などにする必要がある。
しかし3次元のreshapeで掛け算のツジツマ合わせは難しいので、結論は、画像を例えば8の倍数のピクセルにしてから用いるのが良い。