【问题标题】:Concatenate an input before Dense layer. [Keras with TF backend]在密集层之前连接一个输入。 [带有 TF 后端的 Keras]
【发布时间】:2019-06-03 06:28:33
【问题描述】:

所以,在进入密集层之前,我需要将输入连接到扁平层。 我正在使用带有 TF 的 Keras 作为后端。

model.add(Flatten())
aux_input = Input(shape=(1, )) 
model.add(Concatenate([model, aux_input])) 
model.add(Dense(512,kernel_regularizer=regularizers.l2(weight_decay)))

我有这样的场景:X_train、y_train、aux_train。 y_train 和 aux_train 的形状相同 (1, )。一张图片有一个 ground-truth 和一个 aux_input。

如何在做 model.fit 时将此 aux_input 添加到模型中?

正如答案中所建议的,我使用功能 api 更改了我的模型。但是,现在,我收到以下错误。

ValueError: Layer dense_1 被调用的输入不是 符号张量。接收类型:.全输入: []。全部 该层的输入应该是张量。

这是该部分的代码。

flatten = Flatten()(drop_5)
aux_rand = Input(shape=self.aux_shape)
concat = Concatenate([flatten, aux_input])

fc1 = Dense(512, kernel_regularizer=regularizers.l2(weight_decay))(concat)

辅助输入的形状

aux_shape = (1,)

然后调用模型如下

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')

aux_rand = np.random.rand(y_train.shape[0])
model_inst = cifar10vgg()
x_train_input = Input(shape=(32,32,3))
aux_input = Input(shape=(1,))
model = Model(inputs=[x_train_input, aux_input], output=model_inst.build_model())
model.fit(x=[x_train, aux_rand], y=y_train, batch_size=batch_size, steps_per_epoch=x_train.shape[0] // batch_size,
                epochs=maxepoches, validation_data=(x_test, y_test),
                callbacks=[reduce_lr, tensorboard], verbose=2)

model_inst.build_model() 返回Activation('softmax')(fc2),这是要输入模型的输出(据我所知)

【问题讨论】:

  • 您将 x_train(numpy 数组)输入模型,这是不正确的! Model 的输入和输出应该是 Tensor。
  • 那么应该是 Input(shape=(image.shape)) 吗?
  • 使用 model_inst.outputs 而不是 build_model()
  • cifar10vgg() 是一个具有 build_model 方法的类,它返回模型的输出。
  • 更新了模型以使用张量(希望这是正确的做法)。仍然出现错误

标签: tensorflow keras conv-neural-network vgg-net


【解决方案1】:

正如我从您的代码中看到的,您使用 sequential API 实现模型,在这种情况下这不是一个好的选择。如果您有一些辅助输入,实现此类功能的最佳方法是使用functional API

这是example from Keras website

from keras.layers import Input, Embedding, LSTM, Dense
from keras.models import Model

main_input = Input(shape=(100,), dtype='int32', name='main_input')

x = Embedding(output_dim=512, input_dim=10000, input_length=100)(main_input)

lstm_out = LSTM(32)(x)

auxiliary_output = Dense(1, activation='sigmoid', name='aux_output')(lstm_out)
auxiliary_input = Input(shape=(5,), name='aux_input')
x = keras.layers.concatenate([lstm_out, auxiliary_input])

x = Dense(64, activation='relu')(x)

main_output = Dense(1, activation='sigmoid', name='main_output')(x)

model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])

根据描述,我认为下面的代码可以给你一些直觉:

x1 = Input(shape=(32, 32, 3))
flatten1 = Flatten()(x1)

x2 = Input(shape=(244, 244, 3))
vgg = VGG19(weights='imagenet', include_top=False)(x2)
flatten2 = Flatten()(vgg)

concat = Concatenate()([flatten1, flatten2])
d = Dense(10)(concat)

model = Model(inputs=[x1, x2], outputs=[d])
model.compile('adam', 'categorical_crossentropy')
model.fit(x=[x_train1, x_train2],outputs=y_labels)

【讨论】:

  • 我为此使用 VGGNet,对 Concatenate 进行了一些自定义。
  • @nirvair 没有区别!如果您有多个输入/输出顺序 API,那就麻烦了!
  • 本质上,只有多个输入。我不需要多个输出。我将使用函数式 API 重写模型。
  • @nirvair 是的,但是在模型中间添加了辅助输入。
  • 所以,我重写了网络。但是,如何根据我的场景编写这个 Model() ?模型(输入=[X_train,aux_input],输出=[main_output])。我应该把 y_train 放在哪里?
猜你喜欢
  • 2016-03-24
  • 1970-01-01
  • 2021-07-20
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 2018-02-22
  • 2017-07-31
  • 1970-01-01
相关资源
最近更新 更多