活动地址:CSDN21天学习挑战赛
卷积作用是为了进行特征提取
因为输入的信息中可能只有一小部分是对我们解决问题有帮助的,这些信息比较关键,这时候只提取这部分信息就可以了。对于计算机来说,进行特征提取后,需要处理的信息就急剧减少,可以极大的加快运行速度,当然这只是我认为其中比较重要的一个原因。
4x4的输入矩阵 I 和 3 × 3 的卷积核 K:
计算公式:
输出图片大小为:o x o
3*3
,p=0的卷积情况如下:当卷积函数中padding='same'时,会动态调整 p 值,确保 o=w ,即保证输入与输出一致。例如:输入是 28*28*1 输出也为 28*28*1 。
3*3
,padding='same'
的卷积情况如下:
使用CNN实现多云、下雨、晴、日出四种天气状态的识别。较上篇文章,本文为了增加模型的泛化能力,新增了Dropout层并且将最大池化层调整成了平均池化层。
- 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 = "D:/jupyter notebook/CSDN21天学习计划/weather_photos/"
-
- data_dir = pathlib.Path(data_dir)
可以看到图片总共为1125张。
- image_count = len(list(data_dir.glob('*/*.jpg')))
-
- print("图片总数为:",image_count)
-
- #图片总数为: 1125
-
- roses = list(data_dir.glob('sunrise/*.jpg'))
- PIL.Image.open(str(roses[0]))
查看一下第一张照片
参数解析:
inferred
(默认),则它应该包含子目录,每个目录包含一个类的图像。否则,将忽略目录结构。training
或validation
之一。仅在设置validation_split
时使用。(256,256)
。由于管道处理的图像批次必须具有相同的大小,因此该参数必须提供。32
作用:
tf.data.Dataset
中,且加载的同时会打乱数据。使用`image_dataset_from_directory`方法将磁盘中的数据加载到`tf.data.Dataset`中
- 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)
Found 1125 files belonging to 4 classes.Using 900 files for training.
- 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)
Found 1125 files belonging to 4 classes. Using 225 files for validation.
我们可以通过class_names输出数据集的标签。标签将按字母顺序对应于目录名称。
- class_names = train_ds.class_names
- print(class_names)
['cloudy', 'rain', 'shine', 'sunrise']
- 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
(32, 180, 180, 3)
(32,)
Image_batch
是形状的张量(32,180,180,3)。这是一批形状180x180x3的32张图片(最后一维指的是彩色通道RGB)。Label_batch
是形状(32,)的张量,这些标签对应32张图片- AUTOTUNE = tf.data.AUTOTUNE
-
- train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
- val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
参数解析:
作用:
卷积神经网络(CNN)的输入是张量 (Tensor) 形式的 (image_height, image_width, color_channels)
,包含了图像高度、宽度及颜色信息。不需要输入batch size
。color_channels 为 (R,G,B) 分别对应 RGB 的三个颜色通道(color channel)。在此示例中,我们的 CNN 输入,fashion_mnist 数据集中的图片,形状是 (28, 28, 1)
即灰度图像。我们需要在声明第一层时将形状赋值给参数input_shape
。
- num_classes = 5
-
- 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()
- from sklearn.metrics import confusion_matrix
- import seaborn as sns
- import pandas as pd
-
- # 定义一个绘制混淆矩阵图的函数
- def plot_cm(labels, predictions):
-
- # 生成混淆矩阵
- conf_numpy = confusion_matrix(labels, predictions)
- # 将矩阵转化为 DataFrame
- conf_df = pd.DataFrame(conf_numpy, index=class_names ,columns=class_names)
-
- plt.figure(figsize=(8,7))
-
- sns.heatmap(conf_df, annot=True, fmt="d", cmap="BuPu")
- # 用黑体显示中文
- plt.rcParams['font.sans-serif'] = ['SimHei']
- plt.title('混淆矩阵',fontsize=15)
- plt.ylabel('真实值',fontsize=14)
- plt.xlabel('预测值',fontsize=14)
- val_pre = []
- val_label = []
-
- for images, labels in val_ds:#这里可以取部分验证数据(.take(1))生成混淆矩阵
- for image, label in zip(images, labels):
- # 需要给图片增加一个维度
- img_array = tf.expand_dims(image, 0)
- # 使用模型预测图片中的人物
- prediction = model.predict(img_array)
-
- val_pre.append(class_names[np.argmax(prediction)])
- val_label.append(class_names[label])
- plot_cm(val_label, val_pre)
- # 保存模型
- model.save('model/17_model.h5')
- # 加载模型
- new_model = tf.keras.models.load_model('model/17_model.h5')
- # 采用加载的模型(new_model)来看预测结果
-
- plt.figure(figsize=(10, 5)) # 图形的宽为10高为5
- plt.suptitle("预测结果展示")
-
- for images, labels in val_ds.take(1):
- for i in range(15):
- ax = plt.subplot(3, 5, i + 1)
-
- # 显示图片
- plt.imshow(images[i].numpy().astype("uint8"))
- # 用黑体显示中文
- plt.rcParams['font.sans-serif'] = ['SimHei']
- # 需要给图片增加一个维度
- img_array = tf.expand_dims(images[i], 0)
-
- # 使用模型预测图片中的人物
- predictions = new_model.predict(img_array)
- plt.title(class_names[np.argmax(predictions)])
-
- plt.axis("off")
可以看到大部分预测都是准确的。
参考如下:
>- 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/k-vYaC8l7uxX51WoypLkTw) 中的学习记录博客
>- 参考文章地址: [🔗深度学习100例-卷积神经网络(CNN)天气识别 | 第5天](https://mtyjkh.blog.csdn.net/article/details/117186183)