简体   繁体   English

在 keras\tensorflow 中,如何将 CNN 层添加到在 imagenet 上进行预训练的 ResNet50V2 的最后一层

[英]In keras\tensorflow, How adding CNN layers to last layer of ResNet50V2 that pre-train on imagenet

I am trying to drop the last layer and add a simple CNN instead like the following,我正在尝试删除最后一层并添加一个简单的 CNN,如下所示,

model = Sequential()
base_model = ResNet50V2(include_top=False, weights="imagenet", input_shape=input_shape, pooling="avg")
base_model.trainable = False
model = Sequential()
model.add(base_model)

# I want to add the following CNN
model.add(Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(MaxPooling2D((2, 2), padding='same'))
model.add(Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(MaxPooling2D((2, 2), padding='same'))
model.add(Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(MaxPooling2D((2, 2), padding='same'))
model.add(Flatten())
model.add(Dense(128, activation='relu', kernel_initializer='he_uniform')) 
model.add(Dense(1, activation='sigmoid'))

I don't what I am missing in making this connection that I get the following error,我没有在建立此连接时缺少什么,我收到以下错误,

model.add(Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/training/tracking/base.py", line 522, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/keras/engine/sequential.py", line 228, in add
    output_tensor = layer(self.outputs[0])
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 970, in __call__
    input_list)
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 1108, in _functional_construction_call
    inputs, input_masks, args, kwargs)
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 840, in _keras_tensor_symbolic_call
    return self._infer_output_signature(inputs, args, kwargs, input_masks)
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 878, in _infer_output_signature
    self._maybe_build(inputs)
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 2600, in _maybe_build
    self.input_spec, inputs, self.name)
  File "/project/6035234/npiran/classification/venv_clf/lib/python3.7/site-packages/tensorflow/python/keras/engine/input_spec.py", line 235, in assert_input_compatibility
    str(tuple(shape)))
ValueError: Input 0 of layer conv2d is incompatible with the layer: : expected min_ndim=4, found ndim=2. Full shape received: (None, 2048)

Update Version更新版本

If you want to use CNN that exists in ResNet50V2 , Instead of using base_model. trainable = False如果要使用ResNet50V2中存在的CNN ,而不是使用base_model. trainable = False base_model. trainable = False for all layers, do like below and train some layers. base_model. trainable = False对于所有层,像下面一样训练一些层。 Then use option_2 and pass it to tf.keras.layers.Flatten() .然后使用option_2并将其传递给tf.keras.layers.Flatten()

for idx, layer in enumerate(base_model.layers):
    print(f'The name of {idx} layers is   {layer.name}')
# The name of 142 layers is   conv4_block6_out
# The name of 143 layers is   conv5_block1_1_conv
# The name of 144 layers is   conv5_block1_1_bn
...
# The name of 173 layers is   conv5_block3_add
# The name of 174 layers is   conv5_block3_out
# The name of 175 layers is   avg_pool

for layer in base_model.layers[:143]:
    layer.trainable = False

for layer in base_model.layers[143:]:
    layer.trainable = True

Old Version: You have two options:旧版本:您有两种选择:

  1. Use tf.keras.layers.Reshape((2,2,512)) and reshape (None, 2048) -> (None, 2, 2 ,512) .使用tf.keras.layers.Reshape((2,2,512))和 reshape (None, 2048) -> (None, 2, 2 ,512) (But in the ResNet50V2 , we have CNN why do you need more CNN!) (但在ResNet50V2中,我们有 CNN,为什么还需要更多 CNN!)
  2. Pass output of ResNet50V2 to tf.keras.layers.Flatten() .ResNet50V2的输出传递给tf.keras.layers.Flatten() You can try like below:您可以尝试如下:

Network for option_1: option_1 的网络:

model.add(base_model)
model.add(tf.keras.layers.Reshape((2,2,512)))
model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
model.add(tf.keras.layers.Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
model.add(tf.keras.layers.Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_uniform', padding='same'))
model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=.2))    
model.add(tf.keras.layers.Dense(256, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=.2))
model.add(tf.keras.layers.Dense(10, activation='softmax'))

Full code and Network for option_2: option_2 的完整代码和网络:

import tensorflow as tf
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0

base_model = tf.keras.applications.ResNet50(weights="imagenet", 
                                            include_top=False,
                                            pooling="avg", 
                                            input_shape=(32,32,3))

base_model.trainable = False

model = tf.keras.Sequential()
model.add(base_model)
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=.2))    
model.add(tf.keras.layers.Dense(256, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=.2))
model.add(tf.keras.layers.Dense(10, activation='softmax'))        
model.compile(loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              optimizer='Adam', 
              metrics=['accuracy'])
model.fit(X_train, y_train, batch_size=256, epochs=2, validation_split=.2)

Output:输出:

Epoch 1/2
157/157 [==============================] - 10s 47ms/step - loss: 2.2472 - accuracy: 0.1683 - val_loss: 2.0121 - val_accuracy: 0.2772
Epoch 2/2
157/157 [==============================] - 6s 40ms/step - loss: 2.0074 - accuracy: 0.2566 - val_loss: 1.9161 - val_accuracy: 0.2934

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用 16 位图像训练 keras ResNet50V2? - Train keras ResNet50V2 with 16-bit images? 如何从预训练的 ResNet50V2 Keras model 中删除多个层 - How to remove multiple layers from pretrained ResNet50V2 Keras model 使用预训练 vgg19 tensorflow,Keras 在 CNN 自动编码器中定义自定义损失(感知损失) - Define custom loss (perceptual loss) in CNN autoencoder with pre-train vgg19 tensorflow,Keras 向 RESNET50 添加层以构建 JOIN CNN 模型 - Adding layers to RESNET50 in order to build a JOIN CNN Model 将变量添加到Keras / TensorFlow CNN密集层中 - Adding a variable into Keras/TensorFlow CNN dense layer Tensorflow:如何将预训练 model 已经嵌入的数据输入到 LSTM model 中? - Tensorflow: How to input data already embedded by pre-train model into a LSTM model? 我需要微调艺术 CNN 模型(如 ResNet50)的 state 中的最后一个卷积层吗? - Do i Need to fine tune the last convolutional layers in a state of art CNN models like ResNet50? 如何在功能性 tensorflow ResNet50 model 中添加一层? - How to add a layer in a functional tensorflow ResNet50 model? 如何预训练统一语言模型(UniLm) - How to pre-train the unified language model (UniLm) Tensorflow / keras:如何使用自定义图像文件(.FITS 图像)训练 CNN - Tensorflow / keras: How to train CNN with custom image files (.FITS images)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM