是否可能/如何将新的卷积层添加到预训练的模型中进行转移学习?
我尝试重复使用预先训练的模型并添加一些新的卷积层。还要替换预训练的分类器。
1。预训练的模型看起来像这样:
input_shape = X_train.shape[1:] #(224, 224, 3)
num_classes = 500
model = Sequential()
model.add(Conv2D(32, kernel_size = (3, 3), input_shape=input_shape, activation='relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(32, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(128, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(128, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
2。尝试执行转移学习如下:
# mark loaded layers as not trainable
for layer in base_model.layers:
layer.trainable = False
x = base_model.layers[-3].output
# A`enter code here`dd new layers :
[line 47] x = tf.keras.layers.Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal')(x)
x = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2))(x)s
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.xPool2D(pool_size=(2, 2), strides=(2, 2))(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.xPool2D(pool_size=(2, 2), strides=(2, 2))(x)
x = Flatten()(x)
x = Dense(1024, activation='relu')(x)
output = Dense(class_number, activation='softmax')(x)
# define new model
new_model = Model(inputs=base_model.inputs, outputs=output)
new_model.summary()
遇到此错误:
ValueError: Input 0 of layer "conv2d_11" is incompatible with the layer: expected min_ndim=4, found ndim=2. Full shape received: (None, 256) [at line 47]
是否可能/如何将新的卷积层添加到用于转移学习的预训练模型中?
更新: 灵感来自( - 训练模型,转移学习,TensorFlow(LOAD_MODEL))
以下代码适合我的目的。
inputshape = (224, 224, 3)
# num_classes = y_train.shape[1]
num_classes = 2000
# Load Model
path = r'D:\00_twm_cnn_model\02_prt\02_outputs'
os.chdir(path)
ModelName = r'Model_CNN_VGG-16_chi_prt_100_2022-06-15_1.h5'
base_model = load_model(ModelName)
base_model.summary()
model = tf.keras.Sequential()
for layer in base_model.layers[0:-6]:
model.add(layer)
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_10'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_11'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_12'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2),name='max_pooling2d_4'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_13'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_14'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_15'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2),name='max_pooling2d_5'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.1))
#model.add(BatchNormalization())
model.add(Dense(num_classes, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
I try to reuse a pre-trained model and add some new convolution layers. The pre-trained classifier is also be replaced.
1. The pre-trained model looks like this:
input_shape = X_train.shape[1:] #(224, 224, 3)
num_classes = 500
model = Sequential()
model.add(Conv2D(32, kernel_size = (3, 3), input_shape=input_shape, activation='relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(32, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(128, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(128, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
2. Try to perform transfer learning as following:
# mark loaded layers as not trainable
for layer in base_model.layers:
layer.trainable = False
x = base_model.layers[-3].output
# A`enter code here`dd new layers :
[line 47] x = tf.keras.layers.Conv2D(256, kernel_size = (3, 3), activation = 'relu', padding = 'same',kernel_initializer='glorot_normal')(x)
x = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2))(x)s
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.xPool2D(pool_size=(2, 2), strides=(2, 2))(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same')(x)
x = tf.keras.layers.xPool2D(pool_size=(2, 2), strides=(2, 2))(x)
x = Flatten()(x)
x = Dense(1024, activation='relu')(x)
output = Dense(class_number, activation='softmax')(x)
# define new model
new_model = Model(inputs=base_model.inputs, outputs=output)
new_model.summary()
Encounter this error:
ValueError: Input 0 of layer "conv2d_11" is incompatible with the layer: expected min_ndim=4, found ndim=2. Full shape received: (None, 256) [at line 47]
Is it possible/how to add new convolution layers to a pre-trained model for transfer learning?
update:
inspired from(Remove top layer from pre-trained model, transfer learning, tensorflow (load_model))
Following codes work for my purpose.
inputshape = (224, 224, 3)
# num_classes = y_train.shape[1]
num_classes = 2000
# Load Model
path = r'D:\00_twm_cnn_model\02_prt\02_outputs'
os.chdir(path)
ModelName = r'Model_CNN_VGG-16_chi_prt_100_2022-06-15_1.h5'
base_model = load_model(ModelName)
base_model.summary()
model = tf.keras.Sequential()
for layer in base_model.layers[0:-6]:
model.add(layer)
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_10'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_11'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_12'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2),name='max_pooling2d_4'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_13'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_14'))
model.add(Conv2D(512, kernel_size = (3, 3), activation = 'relu', padding = 'same',input_shape=input_shape,name='conv2d_15'))
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2),name='max_pooling2d_5'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.1))
#model.add(BatchNormalization())
model.add(Dense(num_classes, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论