20251011_Pytorch深度学习(快速预览)
入门体验
1
安装包 Anaconda安装 进行py环境管理;
- 配置环境变量,conda安装路径;
conda -V,默认虚拟环境base;
安装VSCode,安装插件;
- 中文包
- python
- jupyter notebook
"conda常用命令"
conda -V
conda update conda
conda list
conda create -n env_name python=3.9
conda activate env_name
conda deactivate
conda remove -n env_name --all
conda install xxx
conda uninstall xxx
conda config --add channels htttps://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels htttps://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
conda config --add channels htttps://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
conda config --add channels htttps://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch
conda config --show channels
conda config --remove channels https://link
conda config --set show_channel_urls yes
pip config set global.index-url htttps://pypi.tuna.tsinghua.edu.cn/simple
安装pytorch
- nvidia-smi 查看cuda版本,实际安装的需要小于这个版本号
- 如果尚未安装cuda,可以到Nvidia官网 下载Cuda进行安装(以及显卡驱动的安装)
- nvcc是CUDA编译器;
nvcc -V查看版本;
- 官网 查看安装命令;
py
import torch
torch.__version__
torch.cuda.is_available()
conda install nb_conda_kernels
pip install ipykernel
2
Nvidia显卡 官网下载显卡驱动(如果驱动没有正确安装)
where nvidia-smi可以检查NVSMI的路径;
3
深度学习
4
神经网络算法
- 前向传播
- 计算损失
- 反向传播 计算梯度
- 梯度下降 更新参数
5
数据处理和加载:具体库的使用,可移步pytorch官网查阅详细文档;
py
# 代码示意
from torchvision import datasets,transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# 定义数据预处理
transform = transforms.compose([ # 定义一个图像预处理的组合操作
transformtransforms.Grayscale(num output channels=1),#转为灰度图
transforms.ToTensor(),#将图像转换为张量(并缩放0~1)
transforms.Normalize([0.5],[0.5]) # 标准化图像数据,对于灰度图像,只需要一个通道的标准化(-1~1)
])
#使用torchvision里面的的ImageFolder加载自定义格式的MNIST训练数据集
# test/0/idx_x.png
# test/1/idx_x.png
# test/2/idx_x.png
train_dataset = datasets.ImageFolder(root='./mnist_images/train', transform=transform)
test_dataset = datasets.ImageFolder(root='./mnist_images/test', transform=transform)
#创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=64,shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
#从train dataset中取一张图像和对应标签
image, label = train_dataset[0]
# 因为image是Tensor,灰度图shape是(1,H,W),用squeeze()去掉通道维
plt.imshow(image.squeeze(),cmap='gray')#显示图像
plt.title(f"Label:{label}")# 设置图像的标题为标签值,例如:Label:8
plt.axis('off')#关闭图像的坐标轴,让图像显示得更清晰,不显示x和y轴刻度
plt.show() #弹出图像窗口并显示图像
6
模型构建
py
# 代码示意
import torch
import torch.nn as nn
# 自定义神经网络模型
class QYnet(nn.Module):
def __init__(self):
super().__init__()# 定义全连接层
self.fc1= nn.Linear(28*28,256) # 输入是28x28的灰度图像,输出是256个神经元
self.fc2 = nn.Linear(256,128)
self.fc3 = nn.Linear(128,64)
self.fc4 = nn.Linear(64,10)
def forward(self, x):
x=torch.flatten(x,start_dim=1)
x= torch.relu(self.fc1(x)) # 第一层 + ReLU激活
x= torch.relu(self.fc2(x))
x= torch.relu(self.fc3(x))
x= self.fc4(x) #第四层(输出层,不需要激活函数)
# nn.CrossEntropyLoss作为损失函数的话 会在内部进行softmax操作
#x= torch.softmax(x,dim=1) # 使用 softmax 激活函数1代表对类别维度进行softmax
return X
model = QYnet()
input = torch.randn(1,1,28,28)
output = model(input)
print("output的值:",output)
print("output的形状:",output.shape)
7
模型训练
py
# 示意代码
import torch.nn as nn
import torch.optim as optim
from tqdm import tqdm
#检查是否有可用的 GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(f"Using device: {device}")
#初始化模型,并将模型移动到GPU上
model = QYnet().to(device)
#定义损失函数和优化器
criterion=nn.CrossEntropyLoss()#交叉熵# 使用Adam优化器,学习率为8.801
optimizer = optim.Adam(model.parameters(),lr=0.001)
#用于保存训练过程中的损失和准确率
train_losses =[]
train_accuracies =[]
test_accuracies =[]
# 训练模型
epochs = 10
best_accuracy=0.0 # 记录最佳验证集准确率
# 保存最佳模型的路径 最佳权重文件路径
best_model_path ='best_mnist_model.pth'
#训练10个
for epoch in range(epochs):
running_loss= 0.0
correct_train=0 #正确预测的数量
total_train=0 #样本总数
# 训练过程
model.train() # 设定模型为训练模式
for inputs, labels in tqdm(train_loader,desc=f"Epoch {epoch+1}/{epochs} - Training"): # desc参数
inputs,labels =inputs.to(device), labels.to(device) # 将数据移动到GPU上
optimizer.zero_grad() #梯度清零
# 前向传播
outputs = model(inputs)
# 计算损失
loss = criterion(outputs, labels)
loss.backward() #反向传播
optimizer.step() #更新参数
#累加损失
running_loss += loss.item()
#计算训练集上的准确率
# torch.max(outputs,1)模型输出的一个二维张量,形状是[batch size,num_classes],取1代表类别维度,
_, predicted= torch.max(outputs,1)# 获取预测结果【0,0.1.0.2,0,8,0,0.5,8.2,8,0】
total_train += labels.size(0) #累加样本数量#累加止确预测的数晕
correct_train += (predicted == labels).sum().item()
#计算训练集上的准确率
train_accuracy= correct_train / total_train
train_losses.append(running_loss /len(train_loader))#记录每个epoch的平均损失,len(train loader)为批次数,
train_accuracies.append(train_accuracy) #记录每个epoch的训练集准确率
print(f"Epoch {epoch+1}/{epochs}, Loss: {running_loss/len(train_loader):.4f}, Train Accuracy: {train_accuracy:.2%})
#在测试集上评估模型
model.eval() #设定模型为评估模式
correct=0 #正确的预测数量
total=0 #样本总数
with torch.no_grad(): # 关闭梯度计算
for inputs, labels in tqdm(test loader,desc=f"Epoch {epoch+1}/{epochs} - Testing"):
inputs,labels =inputs.to(device),labels.to(device) # 将数据移动到GPU上
outputs=model(inputs) #前向传播,
_, predicted=torch.max(outputs,1) #获取预测结果
total += labels.size(0) # 累加样本数量
correct +=(predicted == labels).sum().item()
#计算测试集上的准确率
test_accuracy = correct / total
test_accuracies.append(test_accuracy) # 记录每个 epoch 的测试集准确率
print(f"Epoch {epoch+1}/{epochs},Test Accuracy: {test_accuracy:.2%}")
#如果测试集准硫率提高,保存当前模型的权重
if test_accuracy > best_accuracy:
best_accuracy = test_accuracy
torch.save(model.state_dict(), best_model_path)
print(f"Best model saved with accuracy: {best accuracy:.2%}")
print(f"Best Accuracy on test set: {best accuracy:.2%}")
#绘制并保存损失和准确率曲线
plt.figure(figsize=(12,5))
#绘制损失曲线
plt.subplot(1,2,1)#选择第一个子图
plt.plot(train_losses,label='Training Loss')# 传入数据、设置标签为Training Loss
plt.xlabel('Epoch')# x轴数据
plt.ylabel('Loss')
plt.title('Training Loss over Epochs')
plt.legend()# 添加图例
plt.grid(True)# 添加网格
# 绘制训练集和测试集准确率曲线
plt.subplot(1,22)
plt.plot(train_accuracies, label='Train Accuracy')
plt.plot(test accuracies, label='Test Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy")
plt.title('Train and Test Accuracy over Epochs')
plt.legend()
plt.grid(True)
#保存图像
plt.tight_layout()
plt.savefig('loss_and_accuracy_curves.png')
plt.show()