AI-Lab5
理论内容回顾
PyTorch
重安装conda(虽然与pytorch没什么大关系)
由于我将ai实验移动到ubuntu里来做,所以我重新在这里安装一下conda。(先使用miniconda了)
1 |
|
安装完如果发现重启了终端也无法查找到 conda --version
,那么就输入命令:
1 |
|
然后再重启终端,发现可以查看到版本号了。
1 |
|
配置一下清华镜像源:
1 |
|
一些常用命令:
1. 环境管理
指令 | 功能 |
---|---|
conda create --name myenv python=3.9 |
创建名为 myenv 的 Python 3.9 环境 |
conda activate myenv |
激活 myenv 环境 |
conda deactivate |
退出当前环境 |
conda env list |
列出所有环境 |
conda remove --name myenv --all |
删除 myenv 环境 |
conda env export > environment.yml |
导出当前环境配置到 YAML 文件 |
conda env create -f environment.yml |
从 YAML 文件创建环境 |
2. 包管理
指令 | 功能 |
---|---|
conda install numpy |
安装包(如 numpy ) |
conda install -c conda-forge package_name |
从 conda-forge 渠道安装包 |
conda list |
列出当前环境所有已安装包 |
conda search numpy |
搜索包(查看可用版本) |
conda update numpy |
更新指定包 |
conda remove numpy |
卸载包 |
conda update --all |
更新所有包 |
3. Conda 自身管理
指令 | 功能 |
---|---|
conda --version |
查看 Conda 版本 |
conda update conda |
更新 Conda 到最新版本 |
conda clean --all |
清理缓存(减少占用空间) |
- 查看/修改配置
指令 | 功能 |
---|---|
conda config --show |
查看当前配置 |
conda config --remove-key channels |
恢复默认镜像源 |
conda config --set auto_activate_base false |
禁止自动激活 base 环境 |
pytorch安装
直接去官网Start Locally | PyTorch官网找到对应的版本号,然后复制命令安装即可。由于本人的电脑没有GPU,所有下载CPU版本。
linux+CPU:
1 |
|
资料
英文版:
PyTorch documentation — PyTorch 2.7 documentation
中文版:
PyTorch 文档 — PyTorch 2.7 文档 - PyTorch 深度学习库
主页 - PyTorch中文文档
tensor
- pytorch的基本数据类型,在使用torch框架进行操作时,对象一般都是要求是tensor类型
初始化tensor
直接初始化
通过原始数据转化
通过numpy数据转化
也可以通过
torch.zeros()
,torch.ones()
等创建指定大小的全0或全1张量初始化未指定数据类型时,tensor会根据数据本身的类型自行判断
梯度计算:
requires_grad=True
–pytorch会追踪该张量的所有计算(自动微分),以便后续进行反向传播计算梯度
维度变换:
torch.view()
或者torch.reshape()
维度重置(但总数要一致),若根据已有维度可推算出剩下的维度,可使用 -1 替代- 用于改变张量的形状,但是总元素的数量必须保持不变。
- 可以使用
-1
自动计算某一维度的大小
方法 | 是否共享内存 | 是否适用于非连续内存 | 适用场景 |
---|---|---|---|
view() |
✅ 是 | ❌ 只能在连续内存上使用 | 高效调整形状(不复制数据) |
reshape() |
✅ 是(如果可能) | ✅ 可以处理非连续内存 | 更通用,但可能触发数据复制 |
torch.reshape()
也可以重置维度- 压缩(删除)大小为 1 的维度。
- 如果不指定
dim
,则删除所有大小为 1 的维度。 - 如果指定
dim
,则只压缩该维度(该维度必须为 1,否则报错)。
1 |
|
- torch.squeeze(dim) 若不指定维度,则会将tensor中为1的dim压缩,若指定只会压缩对应的维度
- torch.unsqueeze(dim) 维度扩展
- 在指定位置插入一个大小为 1 的维度(与
squeeze
相反)。 - 常用于扩展维度,以适应某些操作(如矩阵乘法、卷积等)。
- 在指定位置插入一个大小为 1 的维度(与
torch.cat(List[tensor,tensor],dim)
向量拼接,需要指定维度- 输入一个张量列表
- dim指定沿哪个维度拼接
- 非拼接维度的形状必须相同,否则会报错
- 如果
dim=0
(行拼接),则其他维度(如列数)必须相同。 - 如果
dim=1
(列拼接),则行数必须相同。
1 |
|
torch.nn
自定义神经网络类的基本框架:继承 nn.Module 神经网络基本类,该类实例化后输入数据将自动调用 forward 前向计算
。有点没看懂。
网络训练一般步骤
实例化网络 net = Net() 后,定义网络优化器
- optim = nn.optim.Adam(net.parameters(), lr=lr)
计算得到 Loss, - loss=MSE(a,b)
在更新前,需清除上一步的梯度,即 - optim.zero_grad()
然后 Loss 反向传播: - loss.backward()
最后优化器更新: - optim.step()
CNN网络训练实例
手写数字识别作为样例
1.读入训练集和测试集中的数字图片信息以及对图片预处理
2.用pytorch搭建神经网络(包括卷积和全连接神经网络)
3.将一个batch的训练集中的图片输入至神经网络,得到所有数字的预测分类概率(总共10个数字,0123456789)
4.根据真实标签和预测标签,利用交叉熵损失函数计算loss值,并进行梯度下降
5.根据测试集计算准确率,如果准确率没收敛,跳转回步骤3
6.画出loss、测试集准确率的曲线图
参考视频:https://www.bilibili.com/video/BV1Vx411j7kT?p=19
参考代码:https://github.com/MorvanZhou/PyTorchTutorial/blob/master/tutorialcontents/401_CNN.py
CNN卷积网络卷了什么?
我们之前就知道图片的表示形式是一大堆数字(0-255),如果是灰色图数值代表的是灰度,而如果是彩色图记录的就是RGB颜色,使用三维张量或者三个矩阵来记录。
- 每一个矩阵可以称为图片的一个channel,用宽高深来描述。
传统的神经网络会导致物体如果处在同一个图片的不同位置,就可能会识别为不同物体,但是卷积神经网络可以捕捉图像中的局部特征而不受位置的影响。(不变性)
什么是卷积
在信号与系统课程中我们与卷积打了不少交道
连续:$F(x) = \int_{-\infty}^{\infty} f(\tau) g(x - \tau) d\tau$
在卷积神经网络中,卷积操作是将一个可移动的小窗口(滤波器/卷积核)与图像进行逐元素相乘然后相加的操作。滤波器相当于一组固定的权重。
例如:将一个 6*6
的网格滤波成 4*4
的网格,保留下来的是特征
这里的卷积核是一个 3*3
的矩阵,通过将黄色部分和卷积核进行卷积得到一个值填入到特征矩阵中,进行特征提取。
这个时候发现了边缘的特征丢失了
使用 padding
扩充方式,将 6*6
的像素图扩充成 8*8
的像素图(用0填充)
因此在设置卷积神经网络时,我们需要关注这些参数
- 步长stride:每次滑动的位置步长(也就是小窗口移动的距离)
- 卷积核的个数:决定输出的depth厚度
- 填充值zero-padding:在外围边缘用0填充(要使得总长能被步长整除)
动图:
https://i-blog.csdnimg.cn/blog_migrate/d0172774f7e42ae2f6310b63e59b4906.gif
卷积神经网络模型:
红色部分可以看做一个滤波器,多个滤波器叠加就成了卷积层
最大池化:(max pooling)
将图片特征进一步压缩,仅反映最突出的特点,也就是将图像切割成如图多个 2*2
的网格,取出每个小矩阵中最大的值。
池化后的数据保留了原始图片中最精华的特征
扁平化处理:
把池化后的数据进行扁平化处理:将两个 3*3
的像素图叠加转换为1维的数据条。
数据条作为输入,连接到全连接隐藏层,最终产生输出结果。(感觉做完转换后,得到的扁平化信息到最终输出结果就和MLP很类似了)
如果想进一步理解复杂的cnn模型:CNN Explainer
实验任务
中药图片分类任务
利用pytorch框架搭建神经网络实现中药图片分类,其中中药图片数据分为训练集 train
和测试集 test
,训练集仅用于网络训练阶段,测试集仅用于模型的性能测试阶段。训练集和测试集均包含五种不同类型的中药图片:baihe
、dangshen
、gouqi
、huaihua
、jinyinhua
。请合理设计神经网络架构,利用训练集完成网络训练,统计网络模型的训练准确率和测试准确率,画出模型的训练过程的loss曲线、准确率曲线。
提示
- 最后提交的代码只需包含性能最好的实现方法和参数设置. 只需提交一个代码文件, 请不要提交其他文件.
- 本次作业可以使用
pytorch
库、numpy
库、matplotlib
库以及python标准库. - 数据集可以在Github上下载。
- 模型的训练性能以及测试性能均作为本次作业的评分标准。
- 测试集不可用于模型训练。
- 不能使用开源的预训练模型进行训练。
实现过程
我们看到训练集和测试集都是彩色图,所以我们要采用三通道卷积的方式来表示。
也就是分别卷积后再相加得到结果。
n通道的卷积过程:
或
卷积层:
nn.Conv1d
- 输入:
(batch_size, channels, length)
- 处理一维序列数据(如时间序列、文本词向量)
- 例:音频波形、传感器数据、自然语言处理中的词嵌入序列。
- 输入:
nn.Conv2d
- 输入:
(batch_size, channels, height, width)
- 处理二维网格数据(如图像)。
- 例:RGB图像、二维频谱图。
- 输入:
nn.Conv3d
- 输入:
(batch_size, channels, depth, height, width)
- 处理三维体数据(如视频或医学扫描图像)。
- 例:视频帧(时间+空间)、CT/MRI扫描的3D体素数据。
- 输入:
Conv2d
:- 卷积核沿2个方向(高度和宽度)滑动,输出二维特征图。
- 卷积核尺寸:
(kernel_size, kernel_size)
(如3x3
)。
卷积类型 | 适用场景示例 |
---|---|
Conv1d |
文本分类(词序列)、语音识别(音频帧)、股票预测(时间序列) |
Conv2d |
图像分类、目标检测、风格迁移(2D图像处理) |
Conv3d |
视频动作识别、医学影像分析(3D体数据) |
1 |
|
- in_channels (int) – 输入图像中的通道数
- out_channels (int) – 卷积产生的通道数
- kernel_size (int 或 tuple) – 卷积核的大小
- stride (int 或 tuple, 可选的) – 卷积的步长。默认值:1
- padding (int, tuple 或 str, 可选的) – 输入四边添加的填充。默认值:0
- dilation (int 或 tuple, 可选的) – 内核元素之间的间距。默认值:1
- groups (int, 可选的) – 从输入通道到输出通道的组连接数。默认值:1
- bias (bool, 可选的) – 如果为
True
,则向输出添加一个可学习的偏置项。默认值:True
- padding_mode (str, 可选的) –
'zeros'
,'reflect'
,'replicate'
或'circular'
。默认值:'zeros'
池化层:
1 |
|
进行测试后发现,不够稳定:
尝试添加归一化函数nn.BatchNorm2d()
,并去掉了随机旋转和水平翻转(因为我观察到小规模测试集里的图片还是比较正的())
- 测试了一下50代,感觉效果一般
又尝试在预处理数据部分添加了归一化:
1 |
|
发现在epoches=50的情况下效果也好了很多,将进一步尝试更多代,寻找更加稳定的代数
资料:
【深度学习】一文搞懂卷积神经网络(CNN)的原理(超详细)_卷积神经网络原理-CSDN博客
python标准库 —— os模块_python中os库的作用-CSDN博客torch.nn — PyTorch 2.7 文档 - PyTorch 深度学习库