私が持っている(変更できない)コードは、my_input_tensor
をinput_tensorとしてResnetを使用しています。
model1 = keras.applications.resnet50.ResNet50(input_tensor=my_input_tensor, weights='imagenet')
ソースコード を調べると、ResNet50関数はmy_input_tensor
で新しいkeras入力レイヤーを作成し、残りのモデルを作成します。これは、自分のモデルでコピーしたい動作です。 h5ファイルからモデルをロードします。
model2 = keras.models.load_model('my_model.h5')
このモデルにはすでに入力レイヤーがあるため、my_input_tensor
で定義された新しい入力レイヤーに置き換えたいと思います。
入力レイヤーを置き換えるにはどうすればよいですか?
次を使用してモデルを保存したとき:
old_model.save('my_model.h5')
以下を保存します:
そのため、モデルをロードすると:
res50_model = load_model('my_model.h5')
同じモデルを取得する必要があります。次を使用して同じことを確認できます。
res50_model.summary()
res50_model.get_weights()
これで、入力レイヤーをポップし、以下を使用して独自のレイヤーを追加できます。
res50_model.layers.pop(0)
res50_model.summary()
新しい入力レイヤーを追加します。
newInput = Input(batch_shape=(0,299,299,3)) # let us say this new InputLayer
newOutputs = res50_model(newInput)
newModel = Model(newInput, newOutputs)
newModel.summary()
res50_model.summary()
残念ながら、@ MilindDeoreの解決策はうまくいきませんでした。新しいモデルの概要を印刷できますが、予測時に「Matrix size incompatible」エラーが表示されます。高密度層の新しい入力形状は、古い高密度層の重みの形状と一致しないため、これは理にかなっていると思います。
したがって、ここに別の解決策があります。私にとっての鍵は、「レイヤー」の代わりに「_レイヤー」を使用することでした。後者はコピーを返すだけのようです。
import keras
import numpy as np
def get_model():
old_input_shape = (20, 20, 3)
model = keras.models.Sequential()
model.add(keras.layers.Conv2D(9, (3, 3), padding="same", input_shape=old_input_shape))
model.add(keras.layers.MaxPooling2D((2, 2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(1, activation="sigmoid"))
model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.Adam(lr=0.0001), metrics=['acc'], )
model.summary()
return model
def change_model(model, new_input_shape=(None, 40, 40, 3)):
# replace input shape of first layer
model._layers[1].batch_input_shape = new_input_shape
# feel free to modify additional parameters of other layers, for example...
model._layers[2].pool_size = (8, 8)
model._layers[2].strides = (8, 8)
# rebuild model architecture by exporting and importing via json
new_model = keras.models.model_from_json(model.to_json())
new_model.summary()
# copy weights from old model to new one
for layer in new_model.layers:
try:
layer.set_weights(model.get_layer(name=layer.name).get_weights())
except:
print("Could not transfer weights for layer {}".format(layer.name))
# test new model on a random input image
X = np.random.Rand(10, 40, 40, 3)
y_pred = new_model.predict(X)
print(y_pred)
return new_model
if __name__ == '__main__':
model = get_model()
new_model = change_model(model)