将矩阵乘积输入到keras中的两个模型的输出

时间:2017-09-14 07:50:23

标签: python machine-learning computer-vision deep-learning keras

我正在使用CNN开发分类模型,现在我想在我的问题中应用分类算法(Bilinear CNN Models for Fine-grained Visual Recognition Tsung-Yu Lin Aruni RoyChowdhury Subhransu Maji University of Massachusetts, Amherst)。

具体来说,现在我想对两个CNN模型的两个输出矩阵做外积,并且我完成了矩阵的转置,现在我只想在 keras 中乘以两个矩阵,其中尺寸为(无,512,49)和(无,49,512)。

我尝试在keras中使用合并图层,但出现了一些错误:

当我使用模式时,

  

ValueError:使用点模式的尺寸不兼容:49!= 512.图层   形状:(无,512,49),(无,49,512)

当我使用乘法模式时,

  

ValueError:只能使用mul合并具有相同输出形状的图层   模式。图层形状:[(无,512,49),(无,49,512)]

我不知道如何解决,请帮助我!以下是我的问题的一些代码:

t_model = applications.VGG16(weights='imagenet', include_top=False, 
                                input_shape=(224, 224, 3))
model_a = Sequential()
model_a.add(t_model)
def trans_1(conv):
    conv = tf.reshape(conv, [-1, 49, 512])
    return conv
model_a.add(Lambda(trans_1, output_shape=[49, 512]))

s_model = applications.VGG16(weights='imagenet', include_top=False, 
                                input_shape=(224, 224, 3))
model_b = Sequential()
model_b.add(s_model)
def trans_2(conv):
    conv = tf.reshape(conv, [-1, 49, 512])
    conv = tf.transpose(conv, perm = [0, 2, 1])
    return conv
model_b.add(Lambda(trans_2, output_shape=[512, 49]))

f_model = Sequential()
f_model.add(Merge([model_b, model_a], mode='dot'))

1 个答案:

答案 0 :(得分:1)

首先,当您的模型不是连续的时,请不要使用Sequential()。请改用functional API

此外,

  • 由于两个VGG16模型共享相同的输入图像,因此您可以使用input_tensor参数来提供共享输入。
  • 请注意,VGG16具有固定的图层名称。您必须更改其中一个模型的图层名称,以防止“所有图层名称应该是唯一的”。错误。
  • Keras有一个内置的Reshape图层,这里不需要使用TF。
  • 使用Dot代替弃用的Merge图层。

回到你的问题,axes中的Dot参数指定哪些轴将减少。所以在应用之前你不需要转置张量。

input_tensor = Input(shape=(224, 224, 3))
t_model = applications.VGG16(weights='imagenet', include_top=False, input_tensor=input_tensor)
t_output = Reshape((49, 512))(t_model.output)
s_model = applications.VGG16(weights='imagenet', include_top=False, input_tensor=input_tensor)
for layer in s_model.layers:
    layer.name += '_1'
s_output = Reshape((49, 512))(s_model.output)
merged = Dot(axes=1)([s_output, t_output])