- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍦 参考文章:365天深度学习训练营-第P2周:彩色识别
- 🍖 原作者:K同学啊|接辅导、项目定制
目录
一、课题背景和开发环境
📌第P2周:彩色图片识别📌
- 难度:小白入门⭐
- 语言:Python3、Pytorch
🍺 要求:
- 学习如何编写一个完整的深度学习程序
- 手动推导卷积层与池化层的计算过程
🔔本次的重点在于学会构建CNN网络
开发环境
- 电脑系统:Windows 10
- 语言环境:Python 3.8.2
- 编译器:无(直接在cmd.exe内运行)
- 深度学习环境:Pytorch
- 显卡及显存:NVIDIA GeForce GTX 1660 Ti 12G
- CUDA版本:Release 10.0, V10.0.130(
cmd
输入nvcc -V
或nvcc --version
指令可查看)
二、前期准备
1.设置GPU
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import torchvision
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print('Device', device, '\n')
# device(type='cuda')
Device cuda
2.导入数据
使用torchvision.datasets.CIFAR10
下载CIFAR10数据集,并划分好训练集与测试集
import os
ROOT_FOLDER = 'data'
CIFAR10_FOLDER = os.path.join(OOT_FOLDER, 'cifar-10-batches-py')
if not os.path.exists(CIFAR10_FOLDER) or not os.path.isdir(CIFAR10_FOLDER):
print('开始下载数据集')
# 下载训练集
train_ds = torchvision.datasets.CIFAR10(ROOT_FOLDER,
train=True,
transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensor
download=True)
# 下载测试集
test_ds = torchvision.datasets.CIFAR10(ROOT_FOLDER,
train=False,
transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensor
download=True)
else:
print('数据集已下载 直接读取')
# 读取已下载的训练集
train_ds = torchvision.datasets.CIFAR10(ROOT_FOLDER,
train=True,
transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensor
download=False)
# 读取已下载的测试集
test_ds = torchvision.datasets.CIFAR10(ROOT_FOLDER,
train=False,
transform=torchvision.transforms.ToTensor(), # 将数据类型转化为Tensor
download=False)
使用torch.utils.data.DataLoader
加载数据,并设置batch_size=32
batch_size = 32
# 从 train_ds 加载训练集
train_dl = torch.utils.data.DataLoader(train_ds,
batch_size=batch_size,
shuffle=True)
# 从 test_ds 加载测试集
test_dl = torch.utils.data.DataLoader(test_ds,
batch_size=batch_size)
# 取一个批次查看数据格式
# 数据的shape为:[batch_size, channel, height, weight]
# 其中batch_size为自己设定,channel,height和weight分别是图片的通道数,高度和宽度。
imgs, labels = next(iter(train_dl))
print('Image shape: ', imgs.shape, '\n')
# torch.Size([32, 3, 32, 32]) # 所有数据集中的图像都是32*32的RGB图
Image shape: torch.Size([32, 3, 32, 32])
3.数据可视化
import numpy as np
# 指定图片大小,图像大小为20宽、5高的绘图(单位为英寸inch)
plt.figure('Data Visualization', figsize=(20, 5))
for i, imgs in enumerate(imgs[:20]):
# 维度顺序调整 [3, 32, 32]->[32, 32, 3]
npimg = imgs.numpy().transpose((1, 2, 0))
# 将整个figure分成2行10列,绘制第i+1个子图。
plt.subplot(2, 10, i+1)
plt.imshow(npimg, cmap=plt.cm.binary)
plt.axis('off')
三、构建简单的CNN网络
对于一般的CNN网络来说,都是由特征提取网络和分类网络构成,其中特征提取网络用于提取图片的特征,分类网络用于将图片进行分类。
⭐1. torch.nn.Conv2d()
详解
函数原型:
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’, device=None, dtype=None)
参数说明:
- in_channels ( int ) – 输入图像中的通道数
- out_channels ( int ) – 卷积产生的通道数
- kernel_size ( int or tuple ) – 卷积核的大小
- stride ( int or tuple , optional ) – 卷积的步幅。默认值:
1
- padding ( int , tuple或str , optional ) – 添加到输入的所有四个边的填充。默认值:
0
- padding_mode (字符串,可选) –
'zeros'
,'reflect'
,'replicate'
或'circular'
。默认:'zeros'
⭐2. torch.nn.Linear()
详解
函数原型:
torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
参数说明:
- in_features:每个输入样本的大小
- out_features:每个输出样本的大小
⭐3. torch.nn.MaxPool2d()
详解
函数原型:
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
参数说明:
- kernel_size:最大的窗口大小
- stride:窗口的步幅,默认值为
kernel_size
- padding:填充值,默认为
0
- dilation:控制窗口中元素步幅的参数
⭐4. 关于卷积层、池化层的计算
下面是一个简单的卷积过程展示,卷积核大小为3*3:
[[1, 0, 1],
[0, 1, 0],
[1, 0, 1]]
网络数据shape变化过程的推导:
- 符号定义:
input: W 1 × W 2 \ \ \ \ \ W_1 × W_2 W1×W2
kernel: K 1 × K 2 \ \ \ \ K_1 × K_2 K1×K2
padding: P 1 × P 2 \ P_1 × P_2 P1×P2
stride: S 1 × S 2 \ \ \ \ \ S_1 × S_2 S1×S2
dilation: D 1 × D 2 \ \ D_1 × D_2 D1×D2
- 通过卷积层时,shape的变化
⌊ W 1 + P 1 ∗ 2 − ( K 1 − 1 ) − 1 S 1 ⌋ + 1 × ⌊