前提・実現したいこと
大きいサイズの同一画像から複数かつ同程度の矩形範囲をクロップしてきて
CNNにクロップ数分だけ入力し複数の判定から多数決をとりクロップ元の画像の種類を推定したい。
質問
上記のように複数の入力画像から単一の画像の推定をしたい場合どのようにして実装するべきでしょうか。
可能であればkeras APIを用いた実装を教えてください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
入力層を複数持つモデルの作り方
Keras API のドキュメント通りにやればできます。
入力層を2つ持つモデルを作成する例
python
1input1 = Input(shape=(400,)) 2input2 = Input(shape=(400,)) 3... 省略 4model = Model(inputs=[input1, input2], outputs=output)
学習時は、fit() の x 引数に各入力層 input1, input2 に与えるデータ x1, x2 をリストで指定してあげます。
python
1history = model.fit([x1, x2], y_train, 2 epochs=50, batch_size=128)
MNIST の例
(28, 28) の MNIST 画像を (20, 20) でランダムに2枚切り抜いたデータを入力として学習させた例です。
複数の入力を持つモデルを作ることが目的のため、パラメータ等は適当です。
データの作成
python
1from keras import backend as K 2from keras.datasets import mnist 3from keras.layers import Activation, Add, BatchNormalization, Dense, Dropout, Input 4from keras.models import Model 5from keras.utils.np_utils import to_categorical 6import matplotlib.pyplot as plt 7import numpy as np 8 9# MNIST データを取得する。 10(x_train, y_train), (x_test, y_test) = mnist.load_data() 11 12def random_crop(img, size): 13 h, w = img.shape 14 left = np.random.randint(0, h - size[0]) 15 top = np.random.randint(0, w - size[1]) 16 return img[top:top + size[1], left:left + size[0]] 17 18def convert_crop_data(data, size): 19 crop_data = [] 20 for x in data: 21 crop1 = random_crop(x, size) 22 crop2 = random_crop(x, size) 23 crop_data.append([crop1, crop2]) 24 return np.array(crop_data) 25 26# 各画像からランダムに2枚切り抜く。 27x_train = convert_crop_data(x_train, size=(20, 20)) 28x_test = convert_crop_data(x_test, size=(20, 20)) 29print('x_train.shape', x_train.shape) # x_train.shape (60000, 2, 20, 20) 30print('x_test.shape', x_test.shape) # x_test.shape (10000, 2, 20, 20) 31 32# 1つ目のサンプルを描画する。 33fig, [axes1, axes2] = plt.subplots(1, 2, figsize=(6, 6)) 34axes1.set_axis_off() 35axes1.imshow(x_train[0][0], cmap=plt.cm.gray) 36axes2.set_axis_off() 37axes2.imshow(x_train[0][1], cmap=plt.cm.gray) 38plt.show() 39 40# (N, 2, 28, 28) -> (N, 2, 400) にする 41x_train = x_train.reshape(len(x_train), 2, -1) 42x_test = x_test.reshape(len(x_test), 2, -1) 43 44# one-hot 表現に変換する。 45y_train = to_categorical(y_train) 46y_test = to_categorical(y_test)
モデルの作成及び学習
python
1# モデルを作成する。 2input1 = Input(shape=(400,)) 3input2 = Input(shape=(400,)) 4 5x1 = Dense(10)(input1) 6x1 = BatchNormalization()(x1) 7x1 = Activation('relu')(x1) 8 9x2 = Dense(10)(input2) 10x2 = BatchNormalization()(x2) 11x2 = Activation('relu')(x2) 12 13merge = Add()([x1, x2]) 14x = Dense(10)(merge) 15x = BatchNormalization()(x) 16x = Activation('relu')(x) 17 18x = Dense(10)(x) 19x = BatchNormalization()(x) 20output = Activation('softmax')(x) 21model = Model(inputs=[input1, input2], outputs=output) 22 23model.compile(optimizer='adam', 24 loss='categorical_crossentropy', 25 metrics=['accuracy']) 26# モデルを可視化する。 27from keras.utils import plot_model 28plot_model(model, to_file='model.png') 29 30# 学習する。 31history = model.fit([x_train[:, 0], x_train[:, 1]], y_train, 32 epochs=40, batch_size=128, 33 validation_data=([x_test[:, 0], x_test[:, 1]], y_test))
Train on 60000 samples, validate on 10000 samples Epoch 1/40 60000/60000 [==============================] - 2s 36us/step - loss: 1.6728 - acc: 0.4403 - val_loss: 1.3126 - val_acc: 0.5732 Epoch 2/40 60000/60000 [==============================] - 1s 14us/step - loss: 1.1701 - acc: 0.6318 - val_loss: 1.0355 - val_acc: 0.6815 ...省略 Epoch 39/40 60000/60000 [==============================] - 1s 14us/step - loss: 0.5389 - acc: 0.8286 - val_loss: 0.5555 - val_acc: 0.8226 Epoch 40/40 60000/60000 [==============================] - 1s 14us/step - loss: 0.5365 - acc: 0.8288 - val_loss: 0.5556 - val_acc: 0.8237
投稿2018/09/25 14:55
総合スコア21956
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/09/26 11:53