CNNにおけるループ処理の実装
質問
以下のような動作をするCNNをKerasまたはTensorFlowで実装したいです.
ループ部分と多数決部分の実装法を教えていただきたいです.(CNN部分は大丈夫です)
条件
- 学習するCNNは単一のものを2*2のブロックに適用したいです
- ブロックの分割は格子状に行います
- 多数決はCNNで導出した確率を元に行いたいです
発生している問題
実装の際に,途中のループ処理の部分の文法がわからず困っています.
通常の機械学習では画像一枚へCNNを一回適用して判定結果を出すのに対して
このモデルではCNNを2*2回適用して,集計結果を最終的な判断としているためループが必要となってしまいます.
ソースコード
def set_vgg_model():
inputs = Input(shape=(2174, 2174, 3)) #入力画像
x = Lambda(lambda image: tf.image.resize_images(image, (224*2, 224*2)))(inputs) #画像のリサイズでCNNの入力層に合わせる
x = Lambda(lambda image: block_transform(image, mode="channel"))(x) #ブロックに分割
#モデル作成でここからをループ処理にしたい
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(inputs)
x = BatchNormalization()(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block1_pool')(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
x = BatchNormalization()(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block2_pool')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
x = BatchNormalization()(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
x = BatchNormalization()(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block3_pool')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
x = BatchNormalization()(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
x = BatchNormalization()(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block4_pool')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
x = BatchNormalization()(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
x = BatchNormalization()(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), padding='same', name='block5_pool')(x)
flattened = Flatten(name='flatten')(x)
x = Dense(4096, activation='relu', name='fc1')(flattened)
x = Dropout(0.5, name='dropout1')(x)
x = Dense(4096, activation='relu', name='fc2')(x)
x = Dropout(0.5, name='dropout2')(x)
predictions = Dense(nb_classes, activation='softmax', name='predictions')(x)
#ループ処理はここまで
fin_pred = Lambda(lambda p: voting(p))(predictions) #多数決処理
model = Model(inputs=inputs, outputs=predictions)
return model
if __name__ == '__main__':
start = time.time()
# モデル作成
input_shape = (224, 224, 3)
model = set_vgg_model()
# モデルをプロットする。
from keras.utils import plot_model
plot_model(model, to_file='model.png',
show_shapes=True, show_layer_names=True)
#sys.exit()
# 多クラス分類を指定
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-5, momentum=0.9),#Adam(lr=0.1, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False),
metrics=['accuracy'])
x_train, y_train, x_test, y_test = set_tensor()
# Fine-tuning
history = model.fit(x_train,
y_train,
batch_size=batch_size,
epochs=nb_epoch,
validation_data=(x_test, y_test),
verbose=1,
shuffle=True)
実装上の疑問
- ループ処理はモデル定義内で実装することは可能なのか.(main内で実装することになるのか,またはそもそもKerasでは不可能なのか)