web-dev-qa-db-ja.com

Kerasに特定の重量のみをロードする方法

重みをエクスポートしたトレーニング済みモデルがあり、別のモデルに部分的にロードしたい。私のモデルは、TensorFlowをバックエンドとして使用してKerasで構築されています。

現在、私は次のようにしています:

model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape, trainable=False))
model.add(Activation('relu', trainable=False))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3), trainable=False))
model.add(Activation('relu', trainable=False))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3), trainable=True))
model.add(Activation('relu', trainable=True))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])


model.load_weights("image_500.h5")
model.pop()
model.pop()
model.pop()
model.pop()
model.pop()
model.pop()


model.add(Conv2D(1, (6, 6),strides=(1, 1), trainable=True))
model.add(Activation('relu', trainable=True))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

確かに機能しますが、恐ろしい方法です。

最初の9つのレイヤーだけを読み込むにはどうすればよいですか?

16
BernardoGO

最初の9つのレイヤーに、元のトレーニング済みモデルと新しいモデルの間で一貫した名前が付けられている場合、model.load_weights()を_by_name=True_と共に使用できます。これにより、元のトレーニング済みモデルにある同じ名前のレイヤーを持つ新しいモデルのレイヤーでのみ重みが更新されます。

レイヤーの名前は、nameキーワードで指定できます。次に例を示します。

_model.add(Dense(8, activation='relu',name='dens_1'))
_
25
dhinckley

この呼び出し:

weights_list = model.get_weights()

numpy配列として、モデル内のすべてのウェイトテンソルのリストを返します。

次に行う必要があるのは、このリストを繰り返して適用することです。

for i, weights in enumerate(weights_list[0:9]):
    model.layers[i].set_weights(weights)

どこ model.layersは、モデルを構成するレイヤーのフラットリストです。この場合、最初の9つのレイヤーのウェイトを再ロードします。

詳細については、次を参照してください。

https://keras.io/layers/about-keras-layers/

https://keras.io/models/about-keras-models/

18
Philippe Remy