K同学[365天深度学习训练营]第二周记录T6好莱坞明星识别

>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/rbOOmire8OocQ90QM78DRA) 中的学习记录博客**
>- **🍖 原作者:[K同学啊 | 接辅导、项目定制](https://mtyjkh.blog.csdn.net/)** 

我的环境:

- 系统环境:WSL2+Ubuntu22.04

- 语言环境:Python3.8.18

- 编译器:vscode+jupyter notebook

- 深度学习环境:TensorFlow2.10.0

🍺 要求:
1. 使用categorical_crossentropy(多分类的对数损失函数)完成本次选题(完成)
2. 探究不同损失函数的使用场景与代码实现(完成)

🍻 拔高(可选):
1. 自己搭建VGG-16网络框架(完成)
2. 调用官方的VGG-16网络框架(完成)
3. 使用VGG-16算法训练该模型(完成)

🔎 探索(难度有点大)
1. 准确率达到60%(65.00%,完成)

本次项目开始使用在图像分类里面著名的VGG-16模型。

自己搭建的代码如下:

from tensorflow.keras import models, layers

# 构建VGG16模型
model = models.Sequential()

# 添加卷积层部分
model.add(layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)))

model.add(layers.Conv2D(64, (3, 3), activation='relu', input_shape=(img_height, img_width, 3), padding='same'))
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

# 添加全连接层部分
model.add(layers.Flatten())
model.add(layers.Dense(4096, activation='relu'))
model.add(layers.Dense(4096, activation='relu'))
model.add(layers.Dense(len(class_names), activation='softmax'))  # 输出层,使用softmax激活函数进行多类别分类

model.summary()

同时也可以使用直接从tensorflow库中调用的方法:

from tensorflow.keras.applications import VGG16

# 加载VGG16模型,不包括全连接层,使用ImageNet的权重
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(img_height, img_width, 3))

# 冻结VGG16的卷积层,不进行训练
base_model.trainable = False

# 在VGG16基础上添加自定义的全连接层
model = models.Sequential([
    base_model,
    layers.Flatten(),
    layers.Dense(128, activation='relu'),
    layers.Dense(len(class_names), activation='softmax)
])

model.summary()  # 打印网络结构

模型优化 

VGG-16有个严重的缺陷就是模型过于复杂,所以过拟合严重。

直接训练的结果:

Epoch 21/100
51/51 [==============================] - ETA: 0s - loss: 7.0076e-05 - accuracy: 1.0000
Epoch 21: val_accuracy did not improve from 0.41111
51/51 [==============================] - 21s 421ms/step - loss: 7.0076e-05 - accuracy: 1.0000 - val_loss: 6.0546 - val_accuracy: 0.4111
Epoch 22/100

训练准确率达到1,验证准确率只有0.4111,很明显的过拟合,来自于VGG16模型的复杂度过高

首先将调整模型,为模型加入标准化、L2正则化、dropout层:

from tensorflow.keras import models, layers

# 构建VGG16模型
model = models.Sequential()

# 添加卷积层部分
model.add(layers.experimental.preprocessing.Rescaling(1./255, input_shape=(224, 224, 3)))

model.add(layers.Conv2D(64, (3, 3), activation='relu', input_shape=(256, 256, 3), padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(256, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(512, (3, 3), activation='relu', padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2)))

# 添加全连接层部分
model.add(layers.Flatten())
model.add(layers.Dense(2048, activation='relu', kernel_regularizer='l2'))
model.add(layers.Dropout(0.3))  # 添加Dropout层
model.add(layers.Dense(1024, activation='relu', kernel_regularizer='l2'))
model.add(layers.Dense(len(class_names), activation='softmax'))  # 输出层,使用softmax激活函数进行多类别分类

model.summary()

再进行数据增强:

import tensorflow as tf

def augment_images(image, label):
    image = tf.image.random_flip_left_right(image)  # 随机水平翻转
    image = tf.image.random_contrast(image, lower=0.5, upper=1.5)  # 随机对比度
    image = tf.image.random_brightness(image, max_delta=0.2)  # 随机亮度
    image = tf.image.random_saturation(image, lower=0.5, upper=1.5)  # 随机饱和度
    noise = tf.random.normal(tf.shape(image), mean=0.0, stddev=0.1)
    image = tf.clip_by_value(image + noise, 0.0, 1.0)  # 添加高斯噪声并将像素值限制在0到1之间
    return image, label
# 对训练集数据进行增强
augmented_train_ds = train_ds.map(augment_images)

# 使用增强后的数据进行训练
history = model.fit(augmented_train_ds,
                    validation_data=val_ds,
                    epochs=epochs,
                    callbacks=[checkpointer, earlystopper])

训练结果:

Epoch 48/100
51/51 [==============================] - ETA: 0s - loss: 3.8111 - accuracy: 1.0000
Epoch 48: val_accuracy improved from 0.63889 to 0.65000, saving model to best_model.h5
51/51 [==============================] - 29s 572ms/step - loss: 3.8111 - accuracy: 1.0000 - val_loss: 5.2972 - val_accuracy: 0.6500

65.00%,完成任务

发布博文获得大额流量券

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

54afive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值