我在Keras (TensorFlow 2)中使用预构建的ResNet:
from tensorflow.keras.applications.resnet50 import ResNet50
base_model = ResNet50(weights=None, include_top=False, input_shape=(39,39,3))
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dropout(0.5)(x)
output_tensor = Dense(self.num_classes, activation='softmax')(x)
cnn_model = Model(inputs=base_model.input, outputs=output_tensor)
opt = Adam(lr=0.001)
cnn_model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy', tf.keras.metrics.AUC()])
模型(base_model.input
)的输入是39 x 39 x 3
图像。此外,我现在还想为模型提供一个带有附加信息的20维向量(即20 x 1
)。我可以用两种不同的方式来完成:
- 在
GlobalAveragePooling2D
步骤后附加20维矢量 - 为20维矢量创建一个额外的全连接网络,并在
GlobalAveragePooling2D
步骤后将这个全连接网络的输出连接到上述ResNet。理想情况下,两个网络同时训练,但我不知道这是否可能。
我可以为这两个选项调整我的模型吗?
应该可以了,注释掉Dense Layer,以便在全局平均池化之后将它们连接起来。
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.layers import GlobalAveragePooling2D, Dropout, Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Model
import tensorflow as tf
base_model = ResNet50(weights=None, include_top=False, input_shape=(39, 39, 3))
x1 = base_model.output
x1 = GlobalAveragePooling2D()(x1)
x1 = Dropout(0.5)(x1)
input_2 = tf.keras.layers.Input(shape=(20, 1))
x2 = tf.keras.layers.Flatten()(input_2)
# comment this if needed.
x2 = tf.keras.layers.Dense(16, activation='relu')(x2)
x = tf.keras.layers.Concatenate()([x1, x2])
output_tensor = Dense(self.num_classes, activation='softmax')(x)
cnn_model = Model(inputs=[base_model.input, input_2], outputs=output_tensor)
opt = Adam(lr=0.001)
cnn_model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy', tf.keras.metrics.AUC()])
print(cnn_model.summary())
是的,这两个选项都有意义,并且可以使用Keras。对于#2,您可以定义另一个模型,该模型将20D向量作为输入,并将其传递给完全连接的层,然后将该输出与池化层的输出连接起来。对于这两种选择,你都必须调整最终的模型输入,以包括base_model输入和20D向量。