我有2个numpy图片阵列,它们的形状相同但内容不同:
array1和array2。以下是两个不同的功能:
def c_model(input_shape, name):
c_conv1a = Conv2D(64, kernel_size=(7, 7), activation='relu')(input_shape)
c_conv1a = BatchNormalization(axis=-1)(c_conv1a)
c_conv1a = MaxPooling2D(pool_size=(2, 2))(c_conv1a)
flatten = Flatten()(c_conv1a)
fc = Dense(128, activation='relu')(flatten)
fc = Dropout(0.3)(fc)
fc = Dense(256, activation='relu')(fc)
fc = Dropout(0.3)(fc)
c_fc = Dense(1, activation='sigmoid', name=name)(fc)
return c_fc
def g_model(input_shape, name):
g_conv1a = Conv2D(64, kernel_size=(5, 5), activation='relu')(input_shape)
g_conv1a = BatchNormalization(axis=-1)(g_conv1a)
g_conv1a = MaxPooling2D(pool_size=(2, 2))(g_conv1a)
flatten = Flatten()(g_conv1a)
fc = Dense(128, activation='relu')(flatten)
fc = Dropout(0.3)(fc)
fc = Dense(256, activation='relu')(fc)
fc = Dropout(0.3)(fc)
g_fc = Dense(1, activation='sigmoid', name=name)(fc)
return g_fc
在以下几行之后:
shape1 = Input(shape=(64,64,3))
shape2 = Input(shape=(64,64,3))
cmodel = c_model(shape1, "c")
gmodel = g_model(shape2, "g")
m = Model(inputs=[shape1, shape2], outputs=[cmodel, gmodel])
m.compile(...)
m.fit(x=[array1, array2], y=[output1, output2])
我如何确保将array1装入cmodel中,将array2装入gmodel中?
答案 0 :(得分:1)
您的计算图已经确定是这种情况:您将2个不相交的模型c
和g
绑定到具有2个输入和2个输出的外部模型。 array1
会影响output1
的唯一方法是通过c
模型,而array2
则类似;因此,在训练时,相对于输出的渐变只会更新相应的模型。
您拥有的等同于:
shape1 = Input(shape=(64,64,3))
shape2 = Input(shape=(64,64,3))
cmodel_out = c_model(shape1, "c")
gmodel_out = g_model(shape2, "g")
cmodel = Model(shape1, cmodel_out)
gmodel = Model(shape2, gmodel_out)
# ... compile models
cmodel.fit(array1, output1)
gmodel.fit(array2, output2)
就计算图而言。
答案 1 :(得分:1)
它将按照您定义的顺序。您定义了[shape1, shape2]
,顺序就是这个。
您通过了[array1, array2]
,这就是命令。
您定义了[cmodel, gmodel]
,这就是订单。您以相同的顺序通过了[output1, output2]
。
答案 2 :(得分:0)
如果我正确理解您的问题,那么您所做的方式已经可以保证您想要的。如其他答案中所述,列表元素的顺序决定了哪个输入numpy数组将被馈送到哪个输入层,哪个输出层将与哪个输出numpy数组进行比较。
如果您在模型构造函数中添加第三个输入,例如m = Model(inputs=[shape1, shape2, shape3], ...)
,您还需要第三个输入numpy数组:m.fit(x=[array1, array2, array3], ...)
,否则会出现错误。
如果您在模型构造函数中添加第三个输出,例如m = Model(outputs=[cmodel, gmodel, amodel], ...)
,您还需要第三个输出numpy数组:m.fit(y=[output1, output2, output3], ...)
,否则会出现错误。
请注意,出于技术原因,输入和输出层数相同。只有为inputs
和x
传递的两个列表以及为outputs
和y
传递的两个列表的大小必须相同。
如果出于某种原因,您不想依靠此“按列表项位置进行匹配”,则可以选择将字典传递到m.fit
来将输入和输出层的名称映射到输入和输出numpy数组:
shape1 = Input(shape=(64,64,3), name="input1")
shape2 = Input(shape=(64,64,3), name="input2")
cmodel = c_model(shape1, "c")
gmodel = g_model(shape2, "g")
m = Model(inputs=[shape1, shape2], outputs=[cmodel, gmodel])
m.compile(...)
m.fit(x={"input2": array2, "input1": array1}, y={"c": output1, "g": output2})
一些注意事项:我建议使用不同的名称命名变量。您的变量shape1
和shape2
没有形状。它们是输入层(碰巧具有某种形状),因此我宁愿称它们为input1
和input2
或input_layer1
和input_layer2
。
同样,变量cmodel
和gmodel
都不是模型。它们是模型的输出层。相反,m
是您的模型。
正如在另一个答案中已经提到的那样,您的两个“模型”是完全隔离的,因此我看不出将它们组合成一个模型的理由(当然,除非您没有进一步说明某些联系)让问题简短)。
我还建议您看看Keras docs regarding multi-input and multi-output models。