ResNet(二维图像)与全连接网络(一维输入)的连接
Concatenation of ResNet (2D images) with fully-connected network (1D input)
我通过以下方式在 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。理想情况下,两个网络同时接受训练,但我不知道这是否可能。
我可以为这两个选项调整我的模型吗?还是不行?
是的,这两个选项都有意义,并且可以通过 Keras 实现。对于 #2,您可以定义另一个模型,该模型将 20D 向量作为输入并将其传递给一个完全连接的层,然后将该输出与池化层的输出连接起来。对于这两个选项,您必须调整最终模型输入以包括 base_model 输入和 20D 矢量。
应该这样做,
注释掉 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 (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。理想情况下,两个网络同时接受训练,但我不知道这是否可能。
我可以为这两个选项调整我的模型吗?还是不行?
是的,这两个选项都有意义,并且可以通过 Keras 实现。对于 #2,您可以定义另一个模型,该模型将 20D 向量作为输入并将其传递给一个完全连接的层,然后将该输出与池化层的输出连接起来。对于这两个选项,您必须调整最终模型输入以包括 base_model 输入和 20D 矢量。
应该这样做, 注释掉 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())