深度学习笔记08-猫狗识别(Tensorflow)
发布时间
阅读量:
阅读量
- 🍦 本文属于🔗365天深度学习训练营平台发布的学习笔记博客。
- 肉 原始文章的作者是K同学啊。
目录
一、前期工作
1.导入数据并查看
编辑
二、图片预处理
1.加载数据
编辑
2.再一次检查数据
编辑
3.配置数据集
4.可视化数据
三、构建VGG网络
编辑四、编译模型
五、模型训练
六、模型评估
七、预测指定图片
八、总结
一、前期工作
1.导入数据并查看
import matplotlib.pyplot as plt
import os,PIL,pathlib
import warnings
import tensorflow as tf
from tensorflow import keras
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签,'font.sans-serif'是matplotlib中用于设置默认字体的参数,而'SimHei'是黑体的字体名称。
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
#隐藏警告
warnings.filterwarnings('ignore')
data_dir = pathlib.Path("./T8")
image_count = len(list(data_dir.glob('*/*')))
print("图片总数为:",image_count)

二、图片预处理
1.加载数据
batch_size = 64
img_height = 224
img_width = 224
"""
关于image_dataset_from_directory()的详细介绍可以参考文章:
"""
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=12,
image_size=(img_height, img_width),
batch_size=batch_size)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=12,
image_size=(img_height, img_width),
batch_size=batch_size)

class_names = train_ds.class_names
print(class_names)

2.再一次检查数据
for i,l in train_ds:
print(i.shape)
print(l.shape)
break

3.配置数据集
AUTOTUNE = tf.data.AUTOTUNE
def preprocess_image(image,label):
return (image/255.0,label)
# 归一化处理
train_ds = train_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
val_ds = val_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
4.可视化数据
plt.figure(figsize=(10, 10)) # 图形的宽为10高为10
for images, labels in train_ds.take(1):
for i in range(10):
ax = plt.subplot(1, 10, i + 1)
plt.imshow(images[i])
plt.title(class_names[labels[i]])
plt.axis("off")
三、构建VGG网络
from tensorflow.keras import layers, models, Input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout
def VGG16(nb_classes, input_shape):
input_tensor = Input(shape=input_shape)
# 1st block
x = Conv2D(64, (3,3), activation='relu', padding='same',name='block1_conv1')(input_tensor)
x = Conv2D(64, (3,3), activation='relu', padding='same',name='block1_conv2')(x)
x = MaxPooling2D((2,2), strides=(2,2), name = 'block1_pool')(x)
# 2nd block
x = Conv2D(128, (3,3), activation='relu', padding='same',name='block2_conv1')(x)
x = Conv2D(128, (3,3), activation='relu', padding='same',name='block2_conv2')(x)
x = MaxPooling2D((2,2), strides=(2,2), name = 'block2_pool')(x)
# 3rd block
x = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv1')(x)
x = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv2')(x)
x = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv3')(x)
x = MaxPooling2D((2,2), strides=(2,2), name = 'block3_pool')(x)
# 4th block
x = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv1')(x)
x = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv2')(x)
x = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv3')(x)
x = MaxPooling2D((2,2), strides=(2,2), name = 'block4_pool')(x)
# 5th block
x = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv1')(x)
x = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv2')(x)
x = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv3')(x)
x = MaxPooling2D((2,2), strides=(2,2), name = 'block5_pool')(x)
# full connection
x = Flatten()(x)
x = Dense(4096, activation='relu', name='fc1')(x)
x = Dense(4096, activation='relu', name='fc2')(x)
output_tensor = Dense(nb_classes, activation='softmax', name='predictions')(x)
model = Model(input_tensor, output_tensor)
return model
model=VGG16(1000, (img_width, img_height, 3))
model.summary()

四、编译模型
model.compile(optimizer="adam",
loss =tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics =['accuracy'])
五、模型训练
from tqdm import tqdm
import tensorflow.keras.backend as K
epochs = 10
lr = 1e-4
# 记录训练数据,方便后面的分析
history_train_loss = []
history_train_accuracy = []
history_val_loss = []
history_val_accuracy = []
for epoch in range(epochs):
train_total = len(train_ds)#获取训练数据集train_ds和验证数据集val_ds的长度,即样本总数。
val_total = len(val_ds)
"""
使用tqdm创建一个进度条,total参数设置为训练样本总数,
mininterval设置进度条更新的最小时间间隔,以秒为单位(默认值:0.1),
desc参数设置进度条的描述,ncols设置进度条的宽度。
"""
with tqdm(total=train_total, desc=f'Epoch {epoch + 1}/{epochs}',mininterval=1,ncols=100) as pbar:
lr = lr*0.92
model.optimizer.learning_rate = lr
for image,label in train_ds:
"""
训练模型,简单理解train_on_batch就是:它是比model.fit()更高级的一个用法
想详细了解 train_on_batch 的同学,
可以看看:https://www.yuque.com/mingtian-fkmxf/hv4lcq/ztt4gy
"""
history = model.train_on_batch(image,label)
train_loss = history[0]
train_accuracy = history[1]
pbar.set_postfix({"loss": "%.4f"%train_loss,
"accuracy":"%.4f"%train_accuracy,
"lr": f"{K.get_value(model.optimizer.learning_rate):.4e}"})
pbar.update(1)
history_train_loss.append(train_loss)
history_train_accuracy.append(train_accuracy)
print('开始验证!')
with tqdm(total=val_total, desc=f'Epoch {epoch + 1}/{epochs}',mininterval=0.3,ncols=100) as pbar:
for image,label in val_ds:
history = model.test_on_batch(image,label)
val_loss = history[0]
val_accuracy = history[1]
pbar.set_postfix({"loss": "%.4f"%val_loss,
"accuracy":"%.4f"%val_accuracy})
pbar.update(1)
history_val_loss.append(val_loss)
history_val_accuracy.append(val_accuracy)
print('结束验证!')
print("验证loss为:%.4f"%val_loss)
print("验证准确率为:%.4f"%val_accuracy)

六、模型评估
epochs_range=rang(epochs)
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
plt.plot(epochs_range,history_train_accuracy,label='Train accuracy')
plt.plot(epochs_range,history_val_accuracy,label='Validation accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1,2,2)
plt.plot(epochs_range,history_train_loss,label='Train loss')
plt.plot(epochs_range,history_val_accuracy,label='Validation loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')

七、预测指定图片
import numpy as np
# 采用加载的模型(new_model)来看预测结果
plt.figure(figsize=(18, 3)) # 图形的宽为18高为5
plt.suptitle("预测结果展示")
for images, labels in val_ds.take(1):
for i in range(8):
ax = plt.subplot(1,8, i + 1)
# 显示图片
plt.imshow(images[i].numpy())
# 需要给图片增加一个维度
img_array = tf.expand_dims(images[i], 0)
# 使用模型预测图片中的人物
predictions = model.predict(img_array)
plt.title(class_names[np.argmax(predictions)])
plt.axis("off")

八、总结
1、
tqdm是一款Python的进度条库,在Python长循环中能够提供进度提示功能。
2、
在训练模型时出现错误,在向AI寻求帮助后了解到动态调整学习率需要注意版本兼容问题。TensorFlow的优化器属性因软件版本不同而发生变化:新版本中可使用model.optimizer.learning_rate.assign(lr),而旧版本则可采用K.set_value(model.optimizer.lr, lr)进行设置。此外,请确保学习率数据类型为浮点数(float),以避免因数据类型不符导致错误的发生。通过采取兼容不同版本的方式不仅提升了代码的稳定性还能为后续模型优化提供更加灵活的解决方案
3、model.train_on_batch介绍
使用TensorFlow中的fit()或fit_generator()方法可以实现模型的训练过程。这两个API对于刚开始学习深度学习的人来说非常友好且便利。然而由于其设计过于深入,在需要自定义训练流程时显得不够灵活,并且对于像GAN这样的需要分步完成整个训练流程的模型也无法直接通过fit或fit_generator完成训练。因此TensorFlow提供了train_on_batch这个API,在处理一个mini-batch的数据时能够实现梯度更新的操作。
优点:
- 采用更精细的自定义训练方案
- 更加精确地收集与评估损失函数和性能指标
- 利用多GPU架构显著降低了模型存储的复杂性
- 引入多样化的数据加载策略以提升模型泛化能力
函数原型


全部评论 (0)
还没有任何评论哟~
