Tensorflow 带第三分量误差的暹罗网络

Tensorflow 带第三分量误差的暹罗网络,tensorflow,keras,tf.keras,Tensorflow,Keras,Tf.keras,我能够创建一个暹罗网络,类似于: 如果我尝试添加第三个模型作为网络头部的输入,就会出现问题。 我将得到以下错误: ValueError: Shape must be rank 2 but is rank 3 for '{{node head/concatenate/concat}} = ConcatV2[N=3, T=DT_FLOAT, Tidx=DT_INT32](simple/Identity, simple_1/Identity, different/Identity, head/con

我能够创建一个暹罗网络,类似于:

如果我尝试添加第三个模型作为网络头部的输入,就会出现问题。 我将得到以下错误:

ValueError: Shape must be rank 2 but is rank 3 for '{{node head/concatenate/concat}} = ConcatV2[N=3, T=DT_FLOAT, Tidx=DT_INT32](simple/Identity, simple_1/Identity, different/Identity, head/concatenate/concat/axis)' with input shapes: [?,?], [?,?], [?,?,1], [].
这是下面的代码,有一件事我不太熟悉,那就是行processed_a=base_model1(input_a)以及它在检查Keras model文档之后所做的事情。我明白,如果我不这样做,我就无法获得所需的形状并为最终网络提供必要的输入

请注意,如果我用what is comment替换代码,只使用一个纯暹罗网络,它将正常工作。 知道需要更改什么来解决上述错误,以及base_model1(input_a)做了什么吗


注意初始化模型输入和输出时定义的维度。第一个维度总是批量大小(无),这可能会给您带来一些问题。下面是正确的示例:

def getModel1(input_shape):
    model_input = Input(shape=input_shape)
    layer = Dense(32, activation='relu')(model_input)
    layer = Flatten()(layer)
    return Model(inputs=model_input, outputs= layer, name="simple")

def getModel3(input_shape):
    model_input = Input(shape=input_shape)
    layer = Dense(1, activation='relu')(model_input)
    return Model(inputs=model_input, outputs=layer, name="different")

def outputModel(models):
    inputs = []
    for model in models:
        inputs.append(Input(shape=model.output_shape[1:]))
    layer = Concatenate()(inputs)
    layer = Dense(1)(layer)
    return Model(inputs=inputs, outputs=layer, name="head")

base_model1 = getModel1((128,3))
base_model3 = getModel3((3))

input_a = Input(shape=base_model1.input_shape[1:])
input_b = Input(shape=base_model1.input_shape[1:])
input_c = Input(shape=base_model3.input_shape[1:])

oModel = outputModel([base_model1, base_model1, base_model3])

processed_a = base_model1(input_a)
processed_b = base_model1(input_b)
processed_c = base_model3(input_c)

head = oModel([processed_a, processed_b, processed_c])
model = Model(inputs=[input_a, input_b, input_c], outputs=head, name="model")

optimizer = tf.keras.optimizers.RMSprop(0.001)
model.compile(loss='mse',
              optimizer=optimizer,
              metrics=['mae', 'mse'])

# create dummy data
n_sample = 5
train_dataset1 = np.random.uniform(0,1, (n_sample,128,3))
train_dataset3 = np.random.uniform(0,1, (n_sample,3))
y = np.random.uniform(0,1, n_sample)

model.fit([train_dataset1, train_dataset1, train_dataset3], y, epochs=3)
model.predict([train_dataset1, train_dataset1, train_dataset3]).shape

你好,马可,谢谢你对基本模型1的回复,我想要图片作为输入,因此128,3维度,对于模型2,它只是3个单一值。你的意思是基本模型1是(128,3),而基本模型2是(1,3)?我想是的,这意味着然后做基本模型3=getModel1((1,3,)和基本模型1=getModel1((128,3,)?它只需调用/使用基本_model1作为输入u pass,比你想象的不创建(你以前创建)更简单。它只需为每个输入u传递调用/使用相同的模型。这样,u可以对多个输入使用相同的权重(这是初始化初始暹罗分支的正确方法)。它有用吗?
def getModel1(input_shape):
    model_input = Input(shape=input_shape)
    layer = Dense(32, activation='relu')(model_input)
    layer = Flatten()(layer)
    return Model(inputs=model_input, outputs= layer, name="simple")

def getModel3(input_shape):
    model_input = Input(shape=input_shape)
    layer = Dense(1, activation='relu')(model_input)
    return Model(inputs=model_input, outputs=layer, name="different")

def outputModel(models):
    inputs = []
    for model in models:
        inputs.append(Input(shape=model.output_shape[1:]))
    layer = Concatenate()(inputs)
    layer = Dense(1)(layer)
    return Model(inputs=inputs, outputs=layer, name="head")

base_model1 = getModel1((128,3))
base_model3 = getModel3((3))

input_a = Input(shape=base_model1.input_shape[1:])
input_b = Input(shape=base_model1.input_shape[1:])
input_c = Input(shape=base_model3.input_shape[1:])

oModel = outputModel([base_model1, base_model1, base_model3])

processed_a = base_model1(input_a)
processed_b = base_model1(input_b)
processed_c = base_model3(input_c)

head = oModel([processed_a, processed_b, processed_c])
model = Model(inputs=[input_a, input_b, input_c], outputs=head, name="model")

optimizer = tf.keras.optimizers.RMSprop(0.001)
model.compile(loss='mse',
              optimizer=optimizer,
              metrics=['mae', 'mse'])

# create dummy data
n_sample = 5
train_dataset1 = np.random.uniform(0,1, (n_sample,128,3))
train_dataset3 = np.random.uniform(0,1, (n_sample,3))
y = np.random.uniform(0,1, n_sample)

model.fit([train_dataset1, train_dataset1, train_dataset3], y, epochs=3)
model.predict([train_dataset1, train_dataset1, train_dataset3]).shape