使用TensorFlow和Keras对以ResNet50模型进行微调

以下是使用ResNet50进行微调以识别特定的新东西的代码演示。将使用TensorFlow和Keras进行这个任务。

数据集下载地址,解压到工程里面去:

https://www.kaggle.com/datasets/marquis03/cats-and-dogs

原始代码:

​ ```

from keras.applications import ResNet50
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Model
from keras import models
from keras.layers import Dense, GlobalAveragePooling2D, Dropout
from keras.optimizers import Adam
import os

# 加载ResNet50模型,并去掉顶层
base_model = ResNet50(weights='imagenet', include_top=False)

# 添加自定义顶层
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
x = Dropout(0.5)(x)  # 添加Dropout层以防止过拟合
predictions = Dense(2, activation='softmax')(x)  # 用于二分类任务,输出层有两个神经元

model = Model(inputs=base_model.input, outputs=predictions)

# 冻结大部分卷积层,只训练顶层
for layer in base_model.layers:
    layer.trainable = False

# 编译模型
model.compile(optimizer=Adam(learning_rate=0.01),  # 调整学习率
              loss='categorical_crossentropy',  # 使用categorical_crossentropy损失函数
              metrics=['accuracy'])

# 假设数据存储在train_data_dir和validation_data_dir中,并且每个类有一个文件夹
train_data_dir = 'D:\\py\\tvr_search_py\\robot\\test\\catanddog\\train'  # 替换为实际路径
validation_data_dir = 'D:\\py\\tvr_search_py\\robot\\test\\catanddog\\val'  # 替换为实际路径
img_height, img_width = 224, 224
batch_size = 32

# 检查目录是否存在
if not os.path.exists(train_data_dir):
    raise ValueError(f"训练数据目录不存在: {train_data_dir}")
if not os.path.exists(validation_data_dir):
    raise ValueError(f"验证数据目录不存在: {validation_data_dir}")

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_data_dir,
                                                    target_size=(img_height, img_width),
                                                    batch_size=batch_size,
                                                    class_mode='categorical')  # 用于二分类任务

validation_generator = test_datagen.flow_from_directory(validation_data_dir,
                                                        target_size=(img_height, img_width),
                                                        batch_size=batch_size,
                                                        class_mode='categorical')  # 用于二分类任务

# 确保steps_per_epoch和validation_steps不为零
if train_generator.samples == 0:
    raise ValueError(f"训练数据目录中没有找到图像: {train_data_dir}")
if validation_generator.samples == 0:
    raise ValueError(f"验证数据目录中没有找到图像: {validation_data_dir}")

steps_per_epoch = max(1, train_generator.samples // batch_size)
validation_steps = max(1, validation_generator.samples // batch_size)

epochs = 10  # 增加训练轮数

model.fit(train_generator,
          steps_per_epoch=steps_per_epoch,
          validation_data=validation_generator,
          validation_steps=validation_steps,
          epochs=epochs)

# model.summary()
# model.save('D:\\py\\tvr_search_py\\robot\\test\\model\\resnet50_model.keras')

# 解冻部分或全部的卷积层并继续训练
# 
for layer in base_model.layers[:]:
    layer.trainable = True
#
model.compile(optimizer=Adam(learning_rate=0.0001),  # 用较低的学习率
              loss='categorical_crossentropy',
              metrics=['accuracy'])
#
model.fit(train_generator,
          steps_per_epoch=train_generator.samples // batch_size,
          validation_data=validation_generator,
          validation_steps=validation_generator.samples // batch_size,
          epochs=20)

# # 再次保存模型
model.save('D:\\py\\tvr_search_py\\robot\\test\\model\\resnet50_finetuned_model.keras')
#
# # 加载模型
loaded_model = models.load_model('D:\\py\\tvr_search_py\\robot\\test\\model\\resnet50_finetuned_model.keras')
#
# # 打印模型结构
loaded_model.summary()

解析

  1. 安装必要的库

    pip3 install tensorflow keras
    
  2. 导入库

    import tensorflow as tf
    from tensorflow.keras.applications import ResNet50
    from tensorflow.keras.preprocessing.image import ImageDataGenerator
    from tensorflow.keras.models import Model
    from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
    from tensorflow.keras.optimizers import Adam
    
  3. 加载ResNet50模型,并去掉顶层

    base_model = ResNet50(weights='imagenet', include_top=False)
    
  4. 添加自定义顶层

    x = base_model.output
    x = GlobalAveragePooling2D()(x)
    x = Dense(1024, activation='relu')(x)
    predictions = Dense(num_classes, activation='softmax')(x)  # `num_classes`是新数据集的类别数
    
    model = Model(inputs=base_model.input, outputs=predictions)
    
  5. 冻结base_model的所有卷积层

    for layer in base_model.layers:
        layer.trainable = False
    
  6. 编译模型

    model.compile(optimizer=Adam(learning_rate=0.001),
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])
    
  7. 准备数据
    假设数据存储在train_data_dirvalidation_data_dir中,并且每个类有一个文件夹。

    train_data_dir = 'path_to_train_data'
    validation_data_dir = 'path_to_validation_data'
    img_height, img_width = 224, 224
    batch_size = 32
    
    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_data_dir,
                                                        target_size=(img_height, img_width),
                                                        batch_size=batch_size,
                                                        class_mode='categorical')
    
    validation_generator = test_datagen.flow_from_directory(validation_data_dir,
                                                            target_size=(img_height, img_width),
                                                            batch_size=batch_size,
                                                            class_mode='categorical')
    
  8. 训练模型

    epochs = 10
    
    model.fit(train_generator,
              steps_per_epoch=train_generator.samples // batch_size,
              validation_data=validation_generator,
              validation_steps=validation_generator.samples // batch_size,
              epochs=epochs)
    
  9. 解冻部分或全部的卷积层并继续训练

    for layer in base_model.layers[:]:
        layer.trainable = True
    
    model.compile(optimizer=Adam(learning_rate=0.0001<
参考资源链接:[使用预训练ResNet50进行图像分类:TensorFlowKeras高级API教程](https://wenku.csdn.net/doc/3hsnoid425?utm_source=wenku_answer2doc_content) 为了实现图像分类并利用预训练的ResNet50模型进行微调,你需要关注几个关键步骤,这些步骤将在《使用预训练ResNet50进行图像分类:TensorFlowKeras高级API教程》中详细讲解。首先,确保你的开发环境已经安装了TensorFlow库,并且能够访问TensorFlow官网上的预训练模型。接下来,导入必要的Keras模块,包括ResNet50模型结构、全连接层、全局平均池化层等,这些组件将帮助你构建自定义的分类模型。 在定义模型时,你需要使用预训练的ResNet50作为基础特征提取器,并在顶部添加新的全连接层以及全局平均池化层来适应你的分类任务。为了微调模型,通常会冻结模型的大部分基础层,仅训练顶层的权重。可以通过设置层的`trainable`属性为`False`来实现。这一步是关键,因为它允许模型保持已学习的通用特征,同时针对新的数据集学习特定的特征。 之后,你需要编译你的模型,选择合适的优化器(如Adam)、损失函数(如SparseCategoricalCrossentropy)评估指标(如SparseCategoricalAccuracy)。在训练模型之前,使用`ImageDataGenerator`对你的图像数据进行适当的预处理增强,以提高模型的泛化能力。 训练过程中,你将使用准备好的数据集来迭代模型,可能会使用数据增强来生成更多的训练样本。通过监控训练过程中的损失准确率指标,你可以调整超参数来优化模型性能。 最后,完成训练后,你可以用测试集评估模型的性能,并进行实际的图像分类预测。实践中,你还需要注意如何保存加载模型,以便在其他项目中复用或进一步调优。 这份教程将提供一个全面的指南,帮助你从头到尾完成从数据预处理到模型微调的整个流程。通过对教程的学习,你将能够深入理解并掌握如何使用高级API在深度学习项目中应用预训练模型。 参考资源链接:[使用预训练ResNet50进行图像分类:TensorFlowKeras高级API教程](https://wenku.csdn.net/doc/3hsnoid425?utm_source=wenku_answer2doc_content)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值