当前位置:网站首页>【深度学习21天学习挑战赛】3、使用自制数据集——卷积神经网络(CNN)天气识别
【深度学习21天学习挑战赛】3、使用自制数据集——卷积神经网络(CNN)天气识别
2022-08-04 05:28:00 【不负卿@】
活动地址:CSDN21天学习挑战赛
通过前两课的学习,加上私底下恶补基础,照猫画虎的基本算是掌握了卷积神经网络-CNN搭建模型的基本方法。
之前使用的,都是使用的现成的数据集,想想,如果今后真的需要应用,肯定需要使用自制数据集来训练模型,刚好k同学啊老师,就安排了这么一课,课程直达。
现将学习总结如下:(完整代码附后)
1、数据分析
从老师那下载的数据,weather_photos文件夹下共四类(四个目录):
- cloudy (阴天/多云) :
300
张图片 - rain(雨天):
215
张图片 - shine (阳光明媚):
253
张图片 - sunrise(日出/朝霞):
357
张图片
图片都是jpg格式
同时,也可以看到,数据图片的尺寸各异。
通过分析,可知,在使用数据集之前,至少提前做好三件事:
- 加载数据
- 统一尺寸
- 分配标签
2、加载数据
data_dir = "./weather_photos/" # 路径变量
data_dir = pathlib.Path(data_dir) # 构造pathlib模块下的Path对象
image_count = len(list(data_dir.glob('*/*.jpg'))) # 使用Path对象glob方法获取所有jpg格式图片
print("图片总数为:",image_count)
- 我是放到程序同目录下,所以路径是
"./weather_photos/"
,你也可以根据实际路径,如:data_dir = "D:/datasets/weather_photos/"
- 更多用法,自己去补一下路径处理库pathlib使用详解
显示图片:
roses = list(data_dir.glob('sunrise/*.jpg')) # 使用Path对象glob方法获取sunrise目录下所有jpg格式图片
PIL.Image.open(str(roses[6])) #显示一张图片
3、数据预处理
3.1、预处理
先定义几个重要变量:
batch_size = 32
img_height = 180
img_width = 180
- batch_size:深度学习,是把数据分批喂入神经网络的,所以,我们来定义,每批多少条数据
- img_height:定义图片高度,之前说过,自制数据图片尺寸不一,所以,我们来把图片进行统一处理
- img_width:定义图片宽度,之前说过,自制数据图片尺寸不一,所以,我们来把图片进行统一处理
使用: tf.keras.preprocessing.image_dataset_from_directory
将文件夹中的数据加载到tf.data.Dataset中,且加载的同时会打乱数据
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir, # 上面定义好的变量
validation_split=0.2, # 保留20%当做测试集
subset="training",
seed=123,
image_size=(img_height, img_width),# 上面定义好的变量
batch_size=batch_size) # 上面定义好的变量
参数:
- directory: 数据所在目录。
- validation_split: 0和1之间的数,可保留一部分数据用于验证。如:0.2=20%
- subset:
training
或validation
。仅在设置validation_split时使用。 - image_size:从磁盘读取数据后将其重新调整大小。
- batch_size: 数据批次的大小。默认值:32
后调用class_names将返回以目录同名的类名
class_names = train_ds.class_names
print(class_names)
3.2、可视化
plt.figure(figsize=(20, 10))
for images, labels in train_ds.take(1):
for i in range(20):
ax = plt.subplot(5, 10, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
for image_batch, labels_batch in train_ds:
print(image_batch.shape)
print(labels_batch.shape)
break
- image_batch: (32, 180, 180, 3) 第一个32是批次尺寸,180是我们修改后的宽高,3是RGB三个通道
- labels_batch:(32,) 一维,32个标签
3.3、配置数据集
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE) #
- shuffle:数据乱序
- prefetch:预取数据加速运行
- cache:数据集缓存到内存中,加速
4、构建CNN网络
我们之前学习的,输入数据集形状都是(28, 28, 1)
,也就是说,28*28的图像,只有一个颜色通道(灰度)
今天的数据,明显是180*180的图片,并且是RGB三个维度
所以我们需要在声明第一层时定义数据形状,参数:input_shape
num_classes = 4
model = models.Sequential([
layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
layers.Conv2D(16, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)), # 卷积层1,卷积核3*3
layers.AveragePooling2D((2, 2)), # 池化层1,2*2采样
layers.Conv2D(32, (3, 3), activation='relu'), # 卷积层2,卷积核3*3
layers.AveragePooling2D((2, 2)), # 池化层2,2*2采样
layers.Conv2D(64, (3, 3), activation='relu'), # 卷积层3,卷积核3*3
layers.Dropout(0.3),
layers.Flatten(), # Flatten层,连接卷积层与全连接层
layers.Dense(128, activation='relu'), # 全连接层,特征进一步提取
layers.Dense(num_classes) # 输出层,输出预期结果
])
model.summary() # 打印网络结构
- 关于model.summary()打印形状,可以看这个
- layers.Dropout(0.4) 作用是防止过拟合,提高模型的泛化能力。什么是过拟合
- 关于Dropout层的更多介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/115826689
5、配置模型
opt = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(optimizer=opt,
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
这里没什么好说的,和之前用到的损失函数、优化器一样
使用:learning_rate=0.001
是设置学习率
- sgd默认为0.01
- adam默认为0.001
6、训练模型
epochs = 10
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
validation_data:指定测试集数据
epochs :训练迭代次数
输出说明:loss:训练集损失值
accuracy:训练集准确率
val_loss:测试集损失值
val_accruacy:测试集准确率
7、模型评估
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
- history :训练返回的数据,字典类型,字段:accuracy、loss、val_loss、val_accuracy
8、完整源码
import matplotlib.pyplot as plt
import os,PIL
# 设置随机种子尽可能使结果可以重现
import numpy as np
np.random.seed(1)
# 设置随机种子尽可能使结果可以重现
import tensorflow as tf
tf.random.set_seed(1)
from tensorflow import keras
from tensorflow.keras import layers,models
import pathlib
data_dir = "./weather_photos/"
data_dir = pathlib.Path(data_dir)
image_count = len(list(data_dir.glob('*/*.jpg')))
print("图片总数为:",image_count)
roses = list(data_dir.glob('sunrise/*.jpg'))
PIL.Image.open(str(roses[0]))
batch_size = 32
img_height = 180
img_width = 180
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
class_names = train_ds.class_names
print(class_names)
plt.figure(figsize=(20, 10))
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
for images, labels in train_ds.take(1):
for i in range(20):
ax = plt.subplot(5, 10, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
for image_batch, labels_batch in train_ds:
print(image_batch.shape)
print(labels_batch.shape)
break
# AUTOTUNE = tf.data.AUTOTUNE
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
num_classes = 4
model = models.Sequential([
layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
layers.Conv2D(16, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)), # 卷积层1,卷积核3*3
layers.AveragePooling2D((2, 2)), # 池化层1,2*2采样
layers.Conv2D(32, (3, 3), activation='relu'), # 卷积层2,卷积核3*3
layers.AveragePooling2D((2, 2)), # 池化层2,2*2采样
layers.Conv2D(64, (3, 3), activation='relu'), # 卷积层3,卷积核3*3
layers.Dropout(0.3),
layers.Flatten(), # Flatten层,连接卷积层与全连接层
layers.Dense(128, activation='relu'), # 全连接层,特征进一步提取
layers.Dense(num_classes) # 输出层,输出预期结果
])
model.summary() # 打印网络结构
# 设置优化器
opt = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(optimizer=opt,
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
epochs = 10
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
学习日记
1,学习知识点
a、自制数据集的基本使用方法
b、pathlib模块的基本使用
c、tf.keras.preprocessing.image_dataset_from_directory基本使用方法
2,学习遇到的问题
继续啃西瓜书,恶补基础
边栏推荐
猜你喜欢
随机推荐
跨域问题的解决
什么是跨域和同源
自动化运维工具Ansible(1)基础
Kubernetes基本入门-名称空间资源(三)
yolov3中数据读入(一)
NFT市场开源系统
IvNWJVPMLt
剑指 Offer 2022/7/3
iptables防火墙
超详细MySQL总结
网络大作业心得笔记
剑指 Offer 2022/7/11
npm install dependency error npm ERR! code ENOTFOUNDnpm ERR! syscall getaddrinfonpm ERR! errno ENOTFOUND
攻防世界MISC—MISCall
剑指 Offer 2022/7/9
自己学习爬虫写的基础小函数
对象存储-分布式文件系统-MinIO-3:MinIo Client(mc)
Kubernetes集群安装
多项式回归(PolynomialFeatures)
剑指 Offer 2022/7/8