tensorflow resnet50 复现网络结构 不使用预训练模型 二分类 训练自己的数据集 添加防止过拟合操作(例如冻结全连接层等)保存训练结果 预测 代码
时间: 2024-03-01 09:50:15 浏览: 87
好的,以下是基于 TensorFlow 复现 ResNet50 网络的代码。代码中包含自己的数据集的二分类训练,以及防止过拟合的操作(冻结全连接层)。
```python
import tensorflow as tf
from tensorflow.keras import layers, models, optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# 定义 ResNet50 网络结构
def resnet50_model(input_shape=(224, 224, 3), num_classes=2):
input_tensor = layers.Input(shape=input_shape)
# Stage 1
x = layers.Conv2D(filters=64, kernel_size=(7, 7), strides=(2, 2), padding='same', name='conv1')(input_tensor)
x = layers.BatchNormalization(name='bn_conv1')(x)
x = layers.Activation('relu')(x)
x = layers.MaxPool2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)
# Stage 2
x = conv_block(x, filters=[64, 64, 256], stage=2, block='a', strides=(1, 1))
x = identity_block(x, filters=[64, 64, 256], stage=2, block='b')
x = identity_block(x, filters=[64, 64, 256], stage=2, block='c')
# Stage 3
x = conv_block(x, filters=[128, 128, 512], stage=3, block='a')
x = identity_block(x, filters=[128, 128, 512], stage=3, block='b')
x = identity_block(x, filters=[128, 128, 512], stage=3, block='c')
x = identity_block(x, filters=[128, 128, 512], stage=3, block='d')
# Stage 4
x = conv_block(x, filters=[256, 256, 1024], stage=4, block='a')
x = identity_block(x, filters=[256, 256, 1024], stage=4, block='b')
x = identity_block(x, filters=[256, 256, 1024], stage=4, block='c')
x = identity_block(x, filters=[256, 256, 1024], stage=4, block='d')
x = identity_block(x, filters=[256, 256, 1024], stage=4, block='e')
x = identity_block(x, filters=[256, 256, 1024], stage=4, block='f')
# Stage 5
x = conv_block(x, filters=[512, 512, 2048], stage=5, block='a')
x = identity_block(x, filters=[512, 512, 2048], stage=5, block='b')
x = identity_block(x, filters=[512, 512, 2048], stage=5, block='c')
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(units=num_classes, activation='softmax', name='fc' + str(num_classes))(x)
# Create model.
model = models.Model(inputs=input_tensor, outputs=x, name='resnet50')
return model
# 定义 identity block
def identity_block(input_tensor, filters, stage, block):
filters1, filters2, filters3 = filters
block_name = 'res' + str(stage) + block + '_branch'
x = layers.Conv2D(filters=filters1, kernel_size=(1, 1), name=block_name + '2a')(input_tensor)
x = layers.BatchNormalization(name=block_name + '2b')(x)
x = layers.Activation('relu')(x)
x = layers.Conv2D(filters=filters2, kernel_size=(3, 3), padding='same', name=block_name + '2c')(x)
x = layers.BatchNormalization(name=block_name + '2d')(x)
x = layers.Activation('relu')(x)
x = layers.Conv2D(filters=filters3, kernel_size=(1, 1), name=block_name + '2e')(x)
x = layers.BatchNormalization(name=block_name + '2f')(x)
x = layers.add([input_tensor, x])
x = layers.Activation('relu')(x)
return x
# 定义 conv block
def conv_block(input_tensor, filters, stage, block, strides=(2, 2)):
filters1, filters2, filters3 = filters
block_name = 'res' + str(stage) + block + '_branch'
x = layers.Conv2D(filters=filters1, kernel_size=(1, 1), strides=strides, name=block_name + '2a')(input_tensor)
x = layers.BatchNormalization(name=block_name + '2b')(x)
x = layers.Activation('relu')(x)
x = layers.Conv2D(filters=filters2, kernel_size=(3, 3), padding='same', name=block_name + '2c')(x)
x = layers.BatchNormalization(name=block_name + '2d')(x)
x = layers.Activation('relu')(x)
x = layers.Conv2D(filters=filters3, kernel_size=(1, 1), name=block_name + '2e')(x)
x = layers.BatchNormalization(name=block_name + '2f')(x)
shortcut = layers.Conv2D(filters=filters3, kernel_size=(1, 1), strides=strides, name=block_name + '1')(input_tensor)
shortcut = layers.BatchNormalization(name=block_name + '2')(shortcut)
x = layers.add([shortcut, x])
x = layers.Activation('relu')(x)
return x
# 加载数据
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
'train',
target_size=(224, 224),
batch_size=32,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
'test',
target_size=(224, 224),
batch_size=32,
class_mode='categorical')
# 创建 ResNet50 模型
model = resnet50_model(input_shape=(224, 224, 3), num_classes=2)
# 冻结全连接层
for layer in model.layers[:-1]:
layer.trainable = False
# 编译模型
model.compile(optimizer=optimizers.Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
# 训练模型
history = model.fit_generator(
train_generator,
steps_per_epoch=train_generator.samples // train_generator.batch_size,
epochs=10,
validation_data=validation_generator,
validation_steps=validation_generator.samples // validation_generator.batch_size)
# 保存模型
model.save('resnet50_model.h5')
# 预测
from tensorflow.keras.preprocessing import image
import numpy as np
img_path = 'example.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = x / 255.0
preds = model.predict(x)
print('Predicted:', preds[0])
```
使用该代码,你可以复现 ResNet50 网络结构,并对自己的数据集进行二分类训练。此外,你还可以添加防止过拟合的操作,如冻结全连接层,以提高模型的泛化能力。最后,你还可以保存训练结果和进行预测。
阅读全文