web-dev-qa-db-ja.com

ウェイトをロードした後、kerasで新しいレイヤーを追加および削除する方法は?

転移学習をしようとしています。そのために、ニューラルネットワークの最後の2つの層を削除し、さらに2つの層を追加します。これは、同じエラーを出力するサンプルコードです。

from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model

in_img = Input(shape=(3, 32, 32))
x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
x = Activation('relu', name='relu_conv2')(x)
x = GlobalAveragePooling2D()(x)
o = Activation('softmax', name='loss')(x)
model = Model(input=in_img, output=[o])
model.compile(loss="categorical_crossentropy", optimizer="adam")
#model.load_weights('model_weights.h5', by_name=True)
model.summary()

model.layers.pop()
model.layers.pop()
model.summary()
model.add(MaxPooling2D())
model.add(Activation('sigmoid', name='loss'))

pop()を使用してレイヤーを削除しましたが、その出力を追加しようとしたときにこのエラーが発生しました

AttributeError: 'Model'オブジェクトには属性 'add'がありません

エラーの最も可能性の高い理由は、model.add()の不適切な使用です。他にどんな構文を使うべきですか?

編集:

ケラスでレイヤーを削除/追加しようとしましたが、外部ウェイトを読み込んだ後に追加することはできません。

from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model
in_img = Input(shape=(3, 32, 32))

def gen_model():
    in_img = Input(shape=(3, 32, 32))
    x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
    x = Activation('relu', name='relu_conv1')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
    x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
    x = Activation('relu', name='relu_conv2')(x)
    x = GlobalAveragePooling2D()(x)
    o = Activation('softmax', name='loss')(x)
    model = Model(input=in_img, output=[o])
    return model

#parent model
model=gen_model()
model.compile(loss="categorical_crossentropy", optimizer="adam")
model.summary()

#saving model weights
model.save('model_weights.h5')

#loading weights to second model
model2=gen_model()
model2.compile(loss="categorical_crossentropy", optimizer="adam")
model2.load_weights('model_weights.h5', by_name=True)

model2.layers.pop()
model2.layers.pop()
model2.summary()

#editing layers in the second model and saving as third model
x = MaxPooling2D()(model2.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)
model3 = Model(input=in_img, output=[o])

このエラーを表示

RuntimeError: Graph disconnected: cannot obtain value for tensor input_4 at layer "input_4". The following previous layers were accessed without issue: []
32
Eka

最後のモデルのoutputを取得して、新しいモデルを作成できます。下層は同じままです。

model.summary()
model.layers.pop()
model.layers.pop()
model.summary()

x = MaxPooling2D()(model.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)

model2 = Model(input=in_img, output=[o])
model2.summary()

チェック 転送を学習するためにkeras.applicationsのモデルを使用する方法?

編集時に更新:

新しいエラーは、以前のモデル作成では実際には使用されなかったグローバルin_imgで新しいモデルを作成しようとしているためです。実際にローカルin_imgを定義しています。したがって、グローバルin_imgは、シンボリックグラフの上位層に明らかに接続されていません。そして、それは荷重の重みとは関係ありません。

この問題をよりよく解決するには、代わりにmodel.inputを使用して入力を参照する必要があります。

model3 = Model(input=model2.input, output=[o])

43
indraforyou

別の方法

from keras.models import Model

layer_name = 'relu_conv2'
model2= Model(inputs=model1.input, outputs=model1.get_layer(layer_name).output)
9
Wesam Na