# 1.CIFAR 10 model 网络模型
import torch
import torchvision.datasets
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 2.DataLoader加载数据集
# 准备数据集
train_data = torchvision.datasets.CIFAR10(root='D:/PyCharm/CIFAR10', train=True,
transform=torchvision.transforms.ToTensor())
test_data = torchvision.datasets.CIFAR10(root='D:/PyCharm/CIFAR10', train=False,
transform=torchvision.transforms.ToTensor())
# 数据集的长度
train_data_length = len(train_data)
test_data_length = len(test_data)
print(f"训练集的长度:{train_data_length}")
print(f"测试集的长度:{test_data_length}")
# 利用dataloader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64)
# 3.测试网络的正确性
# 搭建神经网络
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.model = nn.Sequential(
Conv2d(3, 32, 5, 1, 2),
MaxPool2d(2),
Conv2d(32, 32, 5, 1, 2),
MaxPool2d(2),
Conv2d(32, 64, 5, 1, 2),
MaxPool2d(2),
Flatten(), # 展平后变成 64*4*4 了
Linear(1024, 64),
Linear(64, 10)
)
def forward(self, x):
x = self.model(x)
return x
model1 = MyModel()
input = torch.ones([64, 3, 32, 32])
output = model1(input)
print(output.shape) # 输出的特征数是10,是我们要的
# 4.网络训练数据
# 实例化一个模型
model2 = MyModel()
# 损失函数
loss_fn = nn.CrossEntropyLoss() # 交叉熵,fn 是 fuction 的缩写
# 优化器
learning_rate = 0.01
optimizer = torch.optim.SGD(model2.parameters(), learning_rate) # 随机梯度下降
# 设置网络的一些参数
total_train_step = 0 # 记录训练的次数
total_test_step = 0 # 记录测试的次数
# 训练的伦次
epoch = 10
# 开始循环
# for i in range(epoch):
# print(f"开始第{i + 1}轮训练")
# for data in train_dataloader:
# imgs, targets = data
# outputs = model2(imgs)
# loss = loss_fn(outputs, targets) # 计算实际输出与目标输出的差距
#
# # 优化器对模型优化
# # 梯度清零
# optimizer.zero_grad()
# # 反向传播
# loss.backward()
# # 更新梯度
# optimizer.step()
#
# total_train_step += 1
# print(f"训练次数:{total_train_step},Loss:{loss}")
# 5.item作用
# a=torch.tensor([1,2,3]) #会报错only one element tensors can be converted to Python scalars
a = torch.tensor(0)
print(a)
print(a.item()) # 只能取一个元素
# 查看训练损失
# 在pytorch中,tensor有一个requires_grad参数,如果设置为True,则反向传播时,该tensor就会自动求导。
# tensor的requires_grad的属性默认为False,若一个节点(叶子变量:自己创建的tensor)requires_grad被设置为True,
# 那么所有依赖它的节点requires_grad都为True(即使其他相依赖的tensor的requires_grad = False)
# 当requires_grad设置为False时,反向传播时就不会自动求导了,因此大大节约了显存或者说内存。
# with torch.no_grad的作用在该模块下,所有计算得出的tensor的requires_grad都自动设置为False。(意思是局部关闭自动求导)
# 即使一个tensor(命名为x)的requires_grad = True,在with torch.no_grad计算,
# 由x得到的新tensor(命名为w-标量)requires_grad也为False,且grad_fn也为None,即不会对w求导。
# torch.no_grad():停止计算梯度,不能进行反向传播。
# 添加tensorboard
# writer = SummaryWriter("logs15")
# 开始循环
# for i in range(epoch):
# print(f"--------第{i + 1}轮训练---------")
# # 训练步骤开始
# for data in train_dataloader:
# imgs, targets = data
# outputs = model2(imgs)
# loss = loss_fn(outputs, targets)
#
# # 优化器
# optimizer.zero_grad()
# loss.backward()
# optimizer.step()
#
# total_train_step += 1
# # 100次训练打印一次
# if total_train_step % 100 == 0:
# print(f"训练次数:{total_train_step},Loss:{loss}")
# writer.add_scalar("train_loss", loss, total_train_step)
#
# # 每一轮训练完成后,都查看再测试集上的loss情况
# # 测试步骤开始
# total_test_loss = 0 # 记录所以loss
# # 关闭局部求导
# with torch.no_grad():
# for data in test_dataloader:
# imgs, targets = data
# outputs = model2(imgs)
# loss = loss_fn(outputs, targets)
# total_test_loss = total_test_loss + loss.item() # 所以loss
#
# print(f"整体测试集上的Loss:{total_test_loss}")
# writer.add_scalar("test_loss", total_test_loss, total_test_step)
# total_test_step += 1
#
# # 将每一轮的参数保存
# torch.save(model2, f"D:/PyCharm/model/model2_{i}") # 将每一轮训练后的结果进行保存
# print("模型保存完成")
# writer.close()
# 8.argmax作用
x = torch.tensor([[0.1, 0.2],
[0.05, 0.4]])
print(x.argmax(0)) # 竖着看,最大值的索引
print(x.argmax(1)) # 横着看,最大值的索引
preds = x.argmax(0)
target = torch.tensor([0, 1])
print((preds == target).sum()) # 对应位置相等的个数
# 9.打印正确率
writer = SummaryWriter("logs16")
for i in range(epoch):
print(f"---------第{i + 1}轮训练----------")
# 训练步骤开始
for data in train_dataloader:
imgs, targets = data
outputs = model2(imgs)
loss = loss_fn(outputs, targets)
# 优化器
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_train_step += 1
if total_train_step % 100 == 0:
print(f"训练次数:{total_train_step},Loss:{loss}")
writer.add_scalar("train_loss", loss.item(), total_train_step)
# 测试步骤开始
total_test_loss = 0 # 记录整体损失
total_test_accuracy = 0 # 记录整体准确率之和
for data in test_dataloader:
imgs, targets = data
outputs = model2(imgs)
loss = loss_fn(outputs, targets)
total_test_loss += loss.item()
accuracy = (outputs.argmax(1) == targets).sum() # 计算模型在当前批次数据上的准确率
total_test_accuracy += accuracy
print(f"整体测试集上的Loss:{total_test_loss}")
print(f"整体测试集上的准确率:{total_test_accuracy / test_data_length}")
writer.add_scalar("test_loss", total_test_loss, total_test_step)
writer.add_scalar("test_accuracy", total_test_accuracy / test_data_length, total_test_step)
total_test_step += 1
torch.save(model2, f"D:/PyCharm/model/model2_{i}")
print("模型保存完毕")
writer.close()
完整模型训练套路
最新推荐文章于 2024-05-28 17:04:20 发布