我想结合两个预先训练的模型(DenseNet169和InceptionV3),也可以是两个模型。遵循了以下链接中的步骤,但是没有用。尝试同时连接和同时连接,仍然会出错。我可能在某个地方犯了一些错误。这是我的第一个stackoverflow问题,将不胜感激。 https://datascience.stackexchange.com/questions/39407/how-to-make-two-parallel-convolutional-neural-networks-in-keras 第一种情况:我尝试不合并
model1 = DenseNet169(weights='imagenet', include_top=False, input_shape=(300,300,3))
out1 = model1.output
model2 = InceptionV3(weights='imagenet', include_top=False, input_shape=(300,300,3))
out2 = model2.output
from keras.layers import concatenate
from keras.layers import Concatenate
x = concatenate([out1, out2]) # merge the outputs of the two models
out = Dense(10, activation='softmax')(x) # final layer of the network
我收到此错误:
ValueError:Concatenate
层需要输入(除了concat轴以外)具有匹配的形状。得到了输入形状:[(无,9,9,1664),(无,8,8,2048)]
第二种情况:尝试使用平均池,可以串联但在训练过程中出错
model1 = DenseNet169(weights='imagenet', include_top=False, pooling='avg', input_shape=(300,300,3))
out1 = model1.output
model2 = InceptionV3(weights='imagenet', include_top=False, pooling='avg', input_shape=(300,300,3))
out2 = model2.output
x = concatenate([out1, out2]) # merge the outputs of the two models
out = Dense(10, activation='softmax')(x) # final layer of the network
model = Model(inputs=[model1.input, model2.input], outputs=[out])
model.compile(optimizer=Adam(), loss='categorical_crossentropy',metrics=['accuracy'])
history = model.fit_generator(generator=data_generator_train,
validation_data=data_generator_val,
epochs=20,
verbose=1
)
第二种情况下的错误: ValueError:检查模型输入时出错:传递给模型的Numpy数组列表不是模型期望的大小。预计会看到2个数组,但获得了以下1个数组的列表:[array([[[[0.17074525,0.10469133,0.08226486] [0.19852941、0.13124999、0.11642157], [0.36528033、0.3213197、0.3085095], ..., [0.19082414、0.17801011、0.15840226 ...
答案 0 :(得分:0)
第二种情况::由于您的模型需要两个输入,因此您的data_generator_train
和data_generator_val
应该为对应的模型和输出返回/产生两个输入的列表。您可以通过更新__data_generation
方法
def __data_generation(...):
...
# consider X as input image and y as the label of your model
return [X, X], keras.utils.to_categorical(y, num_classes=self.n_classes)
第一种情况::由于model2 (8x8)
输出的空间大小与model1输出(9x9)
不同(较小),因此您可以先对model2输出应用零填充串联。
out1 = model1.output
out2 = model2.output
out2 = ZeroPadding2D(((0,1), (0,1)))(out2)
x = concatenate([out1, out2])
对于第一种情况,您也需要像第二种情况一样修改数据生成器。
答案 1 :(得分:0)
第二个案例结构为True,但是请考虑将两个模型连接起来,并且如果两个模型的输入相似,则每个模型都有自己的输入,只需通过重复输入即可使模型适合:
model.fit([X_train,X_train], y_train)
我本人可以解决您的问题,并且效果很好。
model1 = DenseNet169(weights='imagenet', include_top=False)
model2 = InceptionV3(weights='imagenet', include_top=False)
model1_out = model1.output
model1_out=GlobalAveragePooling2D()(model1_out)
model2_out = model2.output
model2_out=GlobalAveragePooling2D()(model2_out)
x = concatenate([model1_out, model2_out])
x = Dense(10, activation='softmax')(x)
model=Model(inputs=[model1.input,model2.input],outputs=x)
model.fit([X_train,X_train], y_train)