机器学习进阶(PyTorch 实战与调优《我是土堆》B站课程)
1. P9. Transforms 的使用(全部)
1.1 模块定位
transforms 是 torchvision 库中专门用于图像数据预处理和数据增强的模块(对图像的变换)(Transforms指的是Transforms.py这个python文件)。其输入类型支持 PIL Image、Tensor 以及部分 numpy array 操作,为图像数据在进入神经网络模型前的处理提供了便利。
1.2 核心组件
from torchvision import transforms
# 基础结构
transform_pipeline = transforms.Compose([
# 这里可以依次添加各种变换操作
])
其中,transforms.Compose 类用于将多个变换操作组合在一起,形成一个连贯的预处理流程。它接收一个由 Transform 对象组成的列表作为参数,在调用时会按照列表顺序依次对输入数据应用这些变换。
1.3 Transforms在python中的用法
1.3.1 Transforms使用(一)
from PIL import Image
from torchvision import transforms
img_path="7.22.1(1)/DJI_0010.JPG" #相对路径
img=Image.open(img_path) #Image是python中内置的打开图片的库
#transform如何使用↓
tensor_trans=transforms.ToTensor() #创建了一个ToTensor的对象
tensor_img=tensor_trans(img)
print(img)
运行结果:
1.3.2 Transforms使用(二)
# 1.导入必要的库
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
img_path="7.22.1(1)/DJI_0010.JPG" #相对路径 定义图像
# 2. 加载图像路径
try:
img = Image.open(img_path) #Image是python中内置的打开图片的库
print(f"成功加载图像: {img_path}")
except FileNotFoundError:
print(f"错误: 找不到图像文件 {img_path}")
# 如果找不到文件,直接退出程序,避免后续报错
import sys
sys.exit(1)
# 3.创建SummaryWriter对象
writer=SummaryWriter("logs")
#4.transform如何使用↓ (图像转换)
tensor_trans=transforms.ToTensor() #创建了一个ToTensor的对象
tensor_img=tensor_trans(img)
#5. 将图像写入 TensorBoard
writer.add_image(tag="DJI_0010_Image", img_tensor=tensor_img)
#6. 关闭 SummaryWriter
writer.close()
运行结果:
TensorBoard工作原理:在使用深度学习框架(以 PyTorch 为例)时,通过SummaryWriter
类(from torch.utils.tensorboard import SummaryWriter
)来记录想要可视化的数据。SummaryWriter
会将这些数据以特定的格式写入到指定的日志目录中。然后,启动 TensorBoard 并指定日志目录,它会读取这些日志文件,将数据解析并以可视化的形式展示在网页界面上(通常通过在浏览器中访问本地地址,如 http://localhost:6006/ )。
1.3.3 常见的Transforms
代码:
import os
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
# 确保路径正确
image_path = "7.22.1(1)/DJI_0010.JPG"
# 如果文件不存在,可以尝试使用绝对路径
if not os.path.exists(image_path):
print(f"警告: 文件 {image_path} 不存在")
# 这里可以添加你的绝对路径
# image_path = "/完整/绝对/路径/DJI_0010.JPG"
# 创建SummaryWriter
writer = SummaryWriter("logs")
# 打开图像并打印基本信息
img = Image.open(image_path)
print(f"图像格式: {img.format}")
print(f"图像尺寸: {img.size}")
print(f"图像模式: {img.mode}")
# 1. ToTensor转换
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("ToTensor", img_tensor, global_step=0)
# 2. Normalize归一化
print(f"归一化前第一个像素值: {img_tensor[0][0][0]}")
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print(f"归一化后第一个像素值: {img_norm[0][0][0]}")
writer.add_image("Normalization", img_norm, global_step=0)
# 3. 额外添加Resize操作示例
trans_resize = transforms.Resize((256, 256))
img_resized = trans_resize(img)
img_resized_tensor = trans_totensor(img_resized)
writer.add_image("Resized", img_resized_tensor, global_step=0)
# 4. 添加多个时间步示例(可选)
# for i in range(5):
# trans_rotate = transforms.RandomRotation(degrees=(i*10, i*10))
# img_rotated = trans_rotate(img)
# img_rotated_tensor = trans_totensor(img_rotated)
# writer.add_image("Rotation", img_rotated_tensor, global_step=i)
writer.close()
print("数据已写入TensorBoard日志目录")
运行结果:
1.4 Tensor数据类型
在深度学习领域,尤其是在使用 PyTorch 框架时,Tensor(张量)是一种极为关键的数据类型。
从本质上来说,Tensor 可以看作是一个多维数组 ,与 Python 中常见的列表(list
)以及 NumPy 中的数组(ndarray
)类似,但功能更强大。比如,它支持在 GPU 上进行高速运算,大大提升深度学习模型的训练效率;还能自动记录运算过程,用于自动求导,这对于神经网络的训练至关重要。
Tensor 有几个重要属性。形状(shape) 描述了它的维度信息,比如二维 Tensor 可表示矩阵,三维 Tensor 常用于表示图像(在 PyTorch 中,图像的 Tensor 通常是 [通道数, 高度, 宽度]
的形式 ) ;数据类型(dtype) 包括常见的浮点数(如 torch.float32
)、整数(如 torch.int64
)、布尔值(torch.bool
)等 ;设备(device) 指明了 Tensor 存储和运算的位置,如在 CPU 或者 GPU 上 ;是否需要梯度(requires_grad) 决定了该 Tensor 在运算过程中是否参与自动求导。
在深度学习模型训练中,Tensor 用于表示输入数据(如图片、文本等)、模型参数(权重和偏置等)、输出结果等。通过对 Tensor 进行各种数学运算(如加法、乘法、矩阵乘法等),以及利用自动求导机制计算梯度,不断调整模型参数,以达到模型性能优化的目的 。
2. CNN 模型构建(核心技术)
在计算机视觉领域,卷积神经网络(Convolutional Neural Network, CNN)是图像分类任务的核心技术。《我是土堆》课程 P13-18 章节围绕 CNN 的基本组件展开,系统讲解了卷积层、池化层、激活函数等关键模块的原理与作用,为理解 CNN 模型构建奠定了理论基础。
2. 1 CNN 的核心组件:从信号处理到特征提取
CNN 的设计灵感源于生物视觉机制,通过多层非线性变换自动提取图像特征。其核心组件包括:
(1)卷积层(Convolutional Layer)
功能:通过卷积核(Filter)与输入图像进行局部滑动卷积,提取空间特征(如边缘、纹理)。
关键参数:
1.卷积核大小(如 3×3、5×5):决定感知野范围;
2.步长(Stride):控制卷积核滑动间隔,影响输出特征图尺寸;
3.填充(Padding):保持特征图尺寸或扩大感知范围。
数学本质:将图像像素值与卷积核权重进行加权求和,实现特征的局部关联建模。
类比理解:可以把卷积层想象成 “挑挑拣拣的筛子” 。比如你在一堆混杂的水果(原始图像数据)里,用不同形状的模具(卷积核)去筛,圆形模具(检测圆形特征的卷积核)能把苹果挑出来,心形模具(检测心形特征的卷积核)能把草莓挑出来 。每一个模具在水果堆上滑动(卷积核在图像上滑动),把符合模具形状的水果特征 “筛” 出来,得到一堆代表不同特征的小堆(特征图),这些小堆就是对原始图像里特定特征的提取结果,帮我们聚焦图像里的关键信息,比如边缘、纹理、形状等。
(2)池化层(Pooling Layer)
功能:对卷积层输出的特征图进行下采样,降低维度并增强特征鲁棒性。
常见类型:
1.最大池化(Max Pooling):保留局部区域最大值,突出显著特征;
2.平均池化(Average Pooling):计算局部区域平均值,平滑特征。
作用:减少计算量,缓解过拟合,同时对图像平移、缩放具有一定不变性。
池化层类比理解:就当它是 “偷懒的简化师” 。假设卷积层筛出了一堆代表苹果的小堆(特征图),里面有很多苹果(特征点)。最大池化呢,就是在一小片区域里,只留下最大的那个苹果(保留局部最大值),相当于说 “这片里最大的苹果最能代表这里的特征,其他小的就简化掉” ,突出最显著的特征;平均池化则是把一小片区域的苹果数量平均一下,取个中间值(计算局部平均值),让特征没那么极端,变得平滑些。这么做是为了少处理些东西(减少计算量),还能避免过度关注细节(缓解过拟合),而且不管苹果在小区域里怎么挪位置(图像平移)、变大变小(图像缩放),简化后还能认出是苹果相关特征(一定不变性)。
鲁棒性类比理解:简单说就是 “抗造、皮实” 。比如训练好的模型识别苹果,不管苹果在图像里稍微歪一点(平移)、大一点小一点(缩放)、亮一点暗一点(光照变化),模型还能认出是苹果,这就说明模型对苹果这个特征的识别有鲁棒性,也就是面对一些干扰、变化,依然能稳定工作、准确识别的能力 ,放到图像任务里,池化层通过简化特征,一定程度上让模型没那么 “挑剔” 图像的细微变化,提升这种抗造的能力。
(3)激活函数(Activation Function)
功能:为神经网络引入非线性,解决线性模型表达能力不足的问题。
典型函数:
1.ReLU(Rectified Linear Unit):计算简单、缓解梯度消失,但存在 “死神经元” 问题;
2.Sigmoid/Softmax:用于二分类或多分类任务的输出层,输出概率分布;
3.Tanh:输出值域为 [-1,1],适用于需要对称激活的场景。
类比理解:把它想成 “给特征打鸡血的开关” 。卷积层筛出来的特征小堆,数值可能都很平淡。激活函数就像给这些数值灌了 “能量饮料” ,设定一个规则,比如数值超过某个阈值(像 ReLU 函数,大于 0 就保留,小于 0 变 0 ),就 “激活” 它们,让有用的特征数值变大、更突出,没用的就弱化甚至干掉。这样能给网络引入非线性,不然一堆线性计算叠加,再复杂的图像也没法很好区分,有了激活函数,才能让网络学会识别各种复杂的图案、物体。
2.2 组件协同:从单神经元到多层网络
CNN 通过多层组件的堆叠形成深度网络,其核心逻辑为:
2.2.1特征分层提取:
(1)浅层网络(如前 1-2 层)提取边缘、颜色等基础特征;
(2)深层网络逐步组合形成复杂特征(如物体部件、整体结构)。
2.2.2计算效率优化:
(1)权值共享(Weight Sharing):同一卷积核在图像不同位置共享参数,大幅减少参数量;
(2)局部连接(Local Connectivity):每个神经元仅与输入图像的局部区域相连,符合视觉信号的局部相关性。
2.3 图像分类的核心逻辑:从像素到语义
在图像分类任务中,CNN 的工作流程可概括为:
(1)输入层:将图像像素值标准化(如归一化至 [0,1] 或 [-1,1]),作为网络输入。
(2)卷积 - 激活 - 池化链:
通过多层 “卷积 + 激活 + 池化” 的组合,逐步提取层次化特征;
特征图数量(通道数)随层数增加而增多,尺寸逐渐缩小(如从 224×224 降至 7×7)。
(3)全连接层(Fully Connected Layer):
将最后一层特征图展平为一维向量,通过全连接层映射到类别空间;
输出层使用 Softmax 激活函数,输出各类别概率,通过交叉熵损失函数优化模型。