私は2つのVGGネットをケラで組み合わせて分類タスクを作成します。プログラムを実行すると、エラーが表示されます。
RuntimeError:モデルで「予測」という名前が2回使用されています。すべてのレイヤー名は一意である必要があります。
私のコードではprediction
レイヤーを1回しか使用していないため、混乱しました。
_from keras.layers import Dense
import keras
from keras.models import Model
model1 = keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000)
model1.layers.pop()
model2 = keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000)
model2.layers.pop()
for layer in model2.layers:
layer.name = layer.name + str("two")
model1.summary()
model2.summary()
featureLayer1 = model1.output
featureLayer2 = model2.output
combineFeatureLayer = keras.layers.concatenate([featureLayer1, featureLayer2])
prediction = Dense(1, activation='sigmoid', name='main_output')(combineFeatureLayer)
model = Model(inputs=[model1.input, model2.input], outputs= prediction)
model.summary()
_
@putonspectaclesの助けをありがとう、私は彼の指示に従い、いくつかの興味深い部分を見つけました。 model2.layers.pop()
を使用し、 "model.layers.keras.layers.concatenate([model1.output, model2.output])
"を使用して2つのモデルの最後のレイヤーを組み合わせると、model.summary()
を使用して最後のレイヤー情報が引き続き表示されることがわかります。しかし、実際にはそれらは構造内に存在しません。したがって、代わりにmodel.layers.keras.layers.concatenate([model1.layers[-1].output, model2.layers[-1].output])
を使用できます。トリッキーに見えますが動作します。ログと構造の同期に関する問題だと思います。
まず、投稿したコードに基づいて、noレイヤーに名前属性 'predictions'があるため、このエラーはレイヤーとは何の関係もありませんDense
レイヤーprediction
:つまり:
prediction = Dense(1, activation='sigmoid',
name='main_output')(combineFeatureLayer)
VGG16
モデルには、Dense
name
を含むpredictions
レイヤーがあります。特にこの行:
x = Dense(classes, activation='softmax', name='predictions')(x)
また、これらのモデルの2つを使用しているため、重複した名前のレイヤーがあります。
あなたができることは、次のように、2番目のモデルのレイヤーの名前を予測以外の名前、おそらくpredictions_1
に変更することです。
model2 = keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000)
# now change the name of the layer inplace.
model2.get_layer(name='predictions').name='predictions_1'
レイヤーの名前はケラスで変更できます。「tensorflow.python.keras」は使用しないでください。
これが私のサンプルコードです:
from keras.layers import Dense, concatenate
from keras.applications import vgg16
num_classes = 10
model = vgg16.VGG16(include_top=False, weights='imagenet', input_tensor=None, input_shape=(64,64,3), pooling='avg')
inp = model.input
out = model.output
model2 = vgg16.VGG16(include_top=False,weights='imagenet', input_tensor=None, input_shape=(64,64,3), pooling='avg')
for layer in model2.layers:
layer.name = layer.name + str("_2")
inp2 = model2.input
out2 = model2.output
merged = concatenate([out, out2])
merged = Dense(1024, activation='relu')(merged)
merged = Dense(num_classes, activation='softmax')(merged)
model_fusion = Model([inp, inp2], merged)
model_fusion.summary()
例:
# Network for affine transform estimation
affine_transform_estimator = MobileNet(
input_tensor=None,
input_shape=(config.IMAGE_H // 2, config.IMAGE_W //2, config.N_CHANNELS),
alpha=1.0,
depth_multiplier=1,
include_top=False,
weights='imagenet'
)
affine_transform_estimator.name = 'affine_transform_estimator'
for layer in affine_transform_estimator.layers:
layer.name = layer.name + str("_1")
# Network for landmarks regression
landmarks_regressor = MobileNet(
input_tensor=None,
input_shape=(config.IMAGE_H // 2, config.IMAGE_W // 2, config.N_CHANNELS),
alpha=1.0,
depth_multiplier=1,
include_top=False,
weights='imagenet'
)
landmarks_regressor.name = 'landmarks_regressor'
for layer in landmarks_regressor.layers:
layer.name = layer.name + str("_2")
input_image = Input(shape=(config.IMAGE_H, config.IMAGE_W, config.N_CHANNELS))
downsampled_image = MaxPooling2D(pool_size=(2,2))(input_image)
x1 = affine_transform_estimator(downsampled_image)
x2 = landmarks_regressor(downsampled_image)
x3 = add([x1,x2])
model = Model(inputs=input_image, outputs=x3)
optimizer = Adadelta()
model.compile(optimizer=optimizer, loss=mae_loss_masked)