admin管理员组文章数量:1647008
本博文来自b站非常棒的一个入门教程:PyTorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】
前置环境条件
Anaconda安装
官网地址:anaconda
本帖按照Python3.6版本示例,故安装anaconda3
安装教程:Anaconda安装-超详细版(2023)
显卡驱动+CUDA+CUDNN
参考教程:CUDA、CUDNN在windows下的安装及配置
环境搭建
Anaconda基础环境
创建
Anaconda可以创建一个独立的环境,在这环境里可以任意配置python、pytorch等等
创建命令:
conda create -n pytorch python=3.6
创建了一个名为pytorch的指定python版本的初始环境
激活
conda activate pytorch
命令行左侧表明当前环境名称
可以通过下面的命令查看当前环境下都有哪些基础包,这时候是没有pytorch的
pip list
pytorch安装
安装选择:pytorch
根据自己CUDA的版本进行选择,如果是老版本的可以在下面这里选择:
根据CUDA的版本选择!!!
注意:这里最好不要用conda安装,用pip,conda我下载后是用不了cuda的,比如使用下面这条:
pytorch验证
按照如下方式验证:
如果这里不是true的话就要检查自己的cuda和pytorch的版本是否有问题了,问题解决可以参考:torch.cuda.is_available()返回false——解决办法
编辑器选择
PyCharm
Pycharm下载
下载:win下载地址
这里下载社区版即可:
详细的pycharm的教程可以自己找一下
PyCharm导入环境
new project后按照如下方式:
重点注意Environment要选择我们刚刚在anaconda中创建好的名字叫pytorch的环境,这个里面我们刚刚是已经导入了pytorch的,然后create就可以了。
创建好后可以在python的console里验证一下环境是否有问题:
每一步执行都可以在右边看到当前存储的变量详情
至此pycharm的基础环境搭建已经完成
Jupyter
jupyter安装
单独安装jupyter的话可以自行找一下教程,如果是安装了Anaconda的话,就已经默认附带安装了jupyter了
jupyter导入环境
jupyter默认在base环境,由于我们当前需要使用pytorch的,所以这里有两种解决方案:
1.在base环境中安装pytorch(不推荐)
2.在已安装pytorch的环境中安装jupyter(推荐)
安装方式是在已安装pytorch的环境中(这里是举例是刚刚创建的pytorch环境)执行以下命令:
conda install nb_conda
这样就安装好Jupyter了,安装完成后通过以下命令启动Jupyter:
jupyter notebook
启动好后,新建一个文件,选择pytorch环境,如下:
可以验证下我们的pytorch的cuda是否可用:
每一步都可以独立执行并看到结果
至此,Jupyter的环境配置完成
两个重要的学习函数
dir()
dir()函数可以让我们知道工具箱以及工具箱中的分隔区有什么东西
以学习pytorch为例
dir(torch)
dir(torch.cuda)
dir(torch.cuda.is_available)
以上三条命令均可打印出对应的工具箱里都存放了哪些工具和分割区
help()
help()函数能让我们知道每个工具的使用方法
以学习torch.cuda.is_available为例
help(torch.cuda.is_available)
注意:上面的is_available虽然是一个函数工具,但是使用help的时候需要把括号()去掉!
Pytorch加载数据
Dataset类的使用
测试数据集
示例数据下载地址:蚂蚁蜜蜂/练手数据集:链接: https://pan.baidu/s/1jZoTmoFzaTLWh4lKBHVbEA 密码: 5suq
数据集引入
引入:
from torch.utils.data import Dataset
可以通过help(Dataset)以及Dataset??的方式查看Dataset的官方解释
图片读取
图片读取(以PIL为例):
from PIL import Image
# 注意windows路径中的反斜杠\需要通过反斜杠转义符来转义
img_path = "D:\\workspaces\\learn_pytorch\\learn_pytorch\\dataset\\train\\ants\\0013035.jpg"
img = Image.open(img_path)
img.show()
文件阅读
# python中用来阅读文件流的工具
import os
from PIL import Image
root_dir = "dataset/train"
label_dir = "ants"
path = os.path.join(root_dir, label_dir)
img_path = os.listdir(path)
idx = 0
img_name = img_path[idx]
img_item_path = os.path.join(root_dir, label_dir, img_name)
img = Image.open(img_item_path)
img.show()
使用实例:
import os
from torch.utils.data import Dataset
from PIL import Image
class MyData(Dataset):
def __init__(self, root_dir, label_dir):
self.root_dir = root_dir
self.label_dir = label_dir
self.path = os.path.join(self.root_dir, self.label_dir)
self.img_path = os.listdir(self.path)
def __getitem__(self, idx):
img_name = self.img_path[idx]
img_item_path = os.path.join(self.root_dir, self.label_dir, img_name)
img = Image.open(img_item_path)
label = self.label_dir
return img, label
def __len__(self):
return len(self.img_path)
root_dir = "dataset/train"
# 这里只是因为图片都是同一个标签所以这样做,一般来说是会有同步的label文件夹,txt文件名称与img名称一致,内容为label值
ants_label_dir = "ants"
ants_dataset = MyData(root_dir, ants_label_dir)
img,label = ants_dataset[0]
TensorBoard
可视化的训练过程工具
简单使用
数据坐标图
from torch.utils.tensorboard import SummaryWriter
# 这里是指存放的文件路径
writer = SummaryWriter("logs")
# writer.add_image()
# y = x
for i in range(100):
# 添加图标的标量,依次是标题,y,x
writer.add_scalar("y = x", i, i)
writer.close()
运行成功后可以看到本地多了一个logs文件夹,其中生成了文件
文件打开命令:
tensorboard --logdir=logs
指定端口号:
tensorboard --logdir=logs --port=6007
如果生成的图像保留了上一次的结果,可以删掉logs里的文件,并且重启tensorbaord即可
图像
示例:
from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image
writer = SummaryWriter("logs")
image_path = "data/train/ants_image/0013035.jpg"
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)
print(type(img_array))
print(img_array.shape)
# 可以ctrl+点击方法进入查看方法详情和example
# 参数分别对应名称 图片(使用opencv的方式可以用Tensor参数) 第几步 数据三位对应含义模式
writer.add_image("train", img_array, 3, dataformats="HWC")
for i in range(100):
writer.add_scalar("y = x", 2*i, i)
writer.close()
Transforms
tensor图像类型
tensor数据类型是包含了一些神经网络必要参数的图片格式
from PIL import Image
from torchvision import transforms
img_path = "data/train/ants_image/0013035.jpg"
img = Image.open(img_path)
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
print(tensor_img)
通过opencv处理得到的图片结果是tensor格式,opencv的安装:
pip install opencv-python
由于我们这里的python版本比较低,所以应该安装一个低版本的opencv:
pip install opencv-python==4.3.0.38
使用opencv的时候使用
cv.imread()
即可返回tensor类型的图片
简单使用方法
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img_path = "data/train/ants_image/0013035.jpg"
img = Image.open(img_path)
print(img)
# toTensor
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("ToTensor", img_tensor)
# Normalize
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([6,3,2],[9, 3, 5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize", img_norm, 2)
# Resize
print(img.size)
trans_resize = transforms.Resize((512,512))
# img PIL-> resize -> img_resize PIL
img_resize = trans_resize(img)
# img_resize PIL -> totensor ->img)resize tensor
img_resize = trans_totensor(img_resize)
writer.add_image("Resize", img_resize, 0)
print(img_resize)
torchvision中的数据集
文档
使用
这里以体积比较小的CIFAR10为例
import torchvision
from torch.utils.tensorboard import SummaryWriter
dataset_transform = torchvision.transforms.Compose([
torchvision.transforms.ToTensor()
])
# 如果要运行下面被注掉的print代码,要把这里的transform去掉,因为这里会转换成tensor格式
# 下载对应的数据集到指定目录下,如果已有则不再下载
train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, transform=dataset_transform, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=dataset_transform, download=True)
# print(test_set[0])
# print(test_set.classes)
#
# img, target = test_set[0]
# print(img)
# print(target)
# print(test_set.classes[target])
# img.show()
#
# print(test_set[0])
writer = SummaryWriter("logs")
for i in range(10):
img, target = test_set[i]
writer.add_image("test_set", img, i)
writer.close()
dataloader
dataloader定义了以什么样的方式从dataset中取值,例子:
import torchvision
# 准备的测试数据集
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
test_data = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor())
# 参数:数据集、一次取的数量、是否乱序、进程数、最后不足一个batch的时候是否丢弃
test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=True)
# 测试数据集中第一张图片以及target
img, target = test_data[0]
print(img.shape)
print(target)
writer = SummaryWriter("logs")
for epoch in range(2):
step = 0
for data in test_loader:
imgs, targets = data
writer.add_images("Epoch: {}".format(epoch), imgs, step)
step = step + 1
writer.close()
神经网络的搭建
nn.Module的使用
这个是pytorch提供的一个搭建神经网络的壳子,一些如激活函数、forword、backword等神经网络因素均可在此定义,简单应用如下:
import torch
from torch import nn
class Test(nn.Module):
# 重写方法可以用code中的generate一件生成
def __init__(self):
super().__init__()
# 前向
def forward(self, input):
output = input + 1
return output
# 这步会调用init
test = Test()
x = torch.tensor(1.0)
# 这步会调用forward
output = test(x)
print(output)
卷积操作
# 卷积操作
import torch
import torch.nn.functional as F
# 输入
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
# 卷积核
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
# 化为标准尺寸 batch_size 二维没有深度 5,5
input = torch.reshape(input, (1,1,5,5))
kernel = torch.reshape(kernel, (1,1,3,3))
# stride:步长,填一个值就是横向纵向一样 padding:填充
output = F.conv2d(input, kernel, stride=1, padding=1)
print(output)
卷积层
示例:
import torch
import torchvision.datasets
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataLoader = DataLoader(dataset, batch_size=64)
class Test(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
def forward(self, x):
x = self.conv1(x)
return x
test = Test()
writer = SummaryWriter("logs")
step = 0
for data in dataLoader:
imgs, targets = data
output = test.conv1(imgs)
print(imgs.shape)
print(output.shape)
# torch.Size([64, 3, 32, 32])
writer.add_images("input", imgs, step)
# torch.Size([64, 6, 30, 30]) -> ([xxx, 3, 30, 30])
output = torch.reshape(output, (-1, 3, 30, 30))
writer.add_images("output", output, step)
step = step + 1
writer.close()
池化层
这里以最大池化层为例,池化就是用一个核去比对输入,选择其中最大的值(最大池化)作为结果的一个值,这样就可以有效减少数据
import torch
import torchvision.datasets
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 这里把数据类型指定为了浮点型,这是池化能处理的类型
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]], dtype=torch.float32)
input = torch.reshape(input, (-1, 1, 5, 5))
print(input.shape)
class Test(nn.Module):
def __init__(self):
super().__init__()
# ceil_mode是指如果输入不够核匹配的时候是否丢弃
self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)
def forward(self, input):
output = self.maxpool1(input)
return output
test = Test()
# output = test(input)
# print(output)
# 使用图片做个例子
dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset, batch_size=64)
writer = SummaryWriter("logs")
step = 0
for data in dataloader:
img, target = data
output = test.maxpool1(img)
writer.add_images("maxpool_input", img, step)
writer.add_images("maxpool_output",output,step)
step = step + 1
writer.close()
非线性激活
以sigmoid和relu函数为例:
import torchvision.datasets
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64)
class Test(nn.Module):
def __init__(self):
super().__init__()
# 这里的relu不传参中默认replace为false,即不改变input本身的值,需要一个output来接收结果
self.relu = ReLU()
self.sigmoid = Sigmoid()
def forward(self, input):
output = self.relu(input)
return output
test = Test()
writer = SummaryWriter("logs")
step = 0
for data in dataloader:
imgs, targets = data
writer.add_images("relu_input", imgs, global_step=step)
output = test(imgs)
writer.add_images("relu_output", output, global_step=step)
step = step + 1
writer.close()
线性激活
import torch
import torchvision.datasets
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataLoader = DataLoader(dataset, batch_size=64)
class Test(nn.Module):
def __init__(self):
super().__init__()
# input尺寸 output尺寸
self.linear = Linear(196608, 10)
def forward(self, input):
output = self.linear(input)
return output
test = Test()
for data in dataLoader:
imgs, targets = data
print(imgs.shape)
# 数据展平
output = torch.flatten(imgs)
print(output.shape)
output = test(output)
print(output.shape)
完整的简单例子和Sequential的使用
这里以CIFAR model为例:
其中卷积层的各参数的计算公式:
例子:
import torch
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.tensorboard import SummaryWriter
class Test(nn.Module):
def __init__(self):
super().__init__()
self.model = Sequential(
# 神经网路图中并未给出padding和stride的大小,但是可以根据已有的数据带入公式求出
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self, input):
output = self.model(input)
return output
test = Test()
print(test)
input = torch.ones((64, 3, 32, 32))
output = test(input)
print(output.shape)
# 可以通过tensorboard查看model的详情展示
writer = SummaryWriter("logs")
writer.add_graph(test, input)
writer.close()
损失函数与反向传播
import torch
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataLoader = DataLoader(dataset, batch_size=1)
class Test(nn.Module):
def __init__(self):
super().__init__()
self.model = Sequential(
# 神经网路图中并未给出padding和stride的大小,但是可以根据已有的数据带入公式求出
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self, input):
output = self.model(input)
return output
# 交叉熵误差
loss = nn.CrossEntropyLoss()
test = Test()
for data in dataLoader:
imgs, targetes = data
outputs = test(imgs)
result_loss = loss(outputs, targetes)
# 梯度下降法
result_loss.backward()
优化器
import torch
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataLoader = DataLoader(dataset, batch_size=1)
class Test(nn.Module):
def __init__(self):
super().__init__()
self.model = Sequential(
# 神经网路图中并未给出padding和stride的大小,但是可以根据已有的数据带入公式求出
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self, input):
output = self.model(input)
return output
# 交叉熵误差
loss = nn.CrossEntropyLoss()
test = Test()
# 优化器(随机梯度下降法)
optim = torch.optim.SGD(test.parameters(), lr=0.01)
for epoch in range(20):
running_loss = 0.0
for data in dataLoader:
imgs, targetes = data
outputs = test(imgs)
result_loss = loss(outputs, targetes)
# 每次都要把梯度先归零
optim.zero_grad()
# 梯度下降法
result_loss.backward()
# 执行优化
optim.step()
running_loss = running_loss + result_loss
print(running_loss)
现有网络模型的修改
以VGG为例
import torchvision
from torch import nn
vgg16_false = torchvision.models.vgg16(pretrained=False)
vgg16_true = torchvision.models.vgg16(pretrained=True)
print(vgg16_true)
train_data = torchvision.datasets.CIFAR10("data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
# 给vgg16_false的classifier部分新增一步
vgg16_true.classifier.add_module("add_linear", nn.Linear(1000, 10))
print(vgg16_true)
print(vgg16_false)
# 修改vgg16_false原本classifier中的第六步
vgg16_false.classifier[6] = nn.Linear(4096, 10)
print(vgg16_false)
网络模型的保存与读取
保存
import torch
import torchvision.models
from torch import nn
vgg16 = torchvision.models.vgg16(pretrained=False)
# 保存方式1(模型结构+模型参数)
torch.save(vgg16, "vgg16_method1.pth")
# 保存方式2(模型参数)
torch.save(vgg16.state_dict(), "vgg16_method2.pth")
# 陷阱
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=3)
def forward(self, x):
x = self.conv1(x)
return x
test = Test()
torch.save(test, "test_method1.pth")
读取
import torch
import torchvision.models
from torch import nn
from model_save import *
# 方式1加载模型
model = torch.load("vgg16_method1.pth")
print(model)
# 方式2加载模型
vgg16 = torchvision.models.vgg16(pretrained=False)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
model = torch.load("vgg16_method2.pth")
print(vgg16)
# 陷阱1
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=3)
def forward(self, x):
x = self.conv1(x)
return x
# 原来这里不可以创建 现在版本可以了 不影响了 不是陷阱了
test = Test()
model1 = torch.load("test_method1.pth")
print(model1)
完整的模型训练套路
以Vgg16为例:
model:
import torch
from torch import nn
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4, 64),
nn.Linear(64, 10)
)
def forward(self, x):
x = self.model(x)
return x
# 验证网络的正确性(输入输出的尺寸)
if __name__ == '__main__':
test = Test()
input = torch.ones((64, 3, 32, 32))
output = test(input)
print(output.shape)
train:
import torch.optim
import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoader
# GPU训练的第二种方式,如果用GPU不能用就改为cpu
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
train_data = torchvision.datasets.CIFAR10(root="data", train=True, transform=torchvision.transforms.ToTensor(), download=True)
test_data = torchvision.datasets.CIFAR10(root="data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
# length长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))
# 利用DataLoader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
# 创建网络模型
test = Test()
# 利用GPU进行训练
# if torch.cuda.is_available():
# test = test.cuda()
# GPU训练的第二种方式
test = test.to(device)
# 损失函数
loss_fn = nn.CrossEntropyLoss()
# 利用GPU进行训练
# if torch.cuda.is_available():
# loss_fn = loss_fn.cuda()
# GPU训练的第二种方式
loss_fn.to(device)
# 优化器(0.01)
learning_rate = 1e-2
optimizer = torch.optim.SGD(test.parameters(), lr=learning_rate)
# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10
# 添加tensorboard
writer = SummaryWriter("chart")
for i in range(epoch):
print("-------------第 {} 轮训练开始------------".format(i+1))
# 训练步骤开始
test.train()
for data in train_dataloader:
imgs, targets = data
ouputs = test(imgs)
# 利用GPU进行训练
# if torch.cuda.is_available():
# imgs = imgs.cuda()
# outputs = outputs.cuda()
# GPU训练的第二种方式
imgs = imgs.to(device)
targets = targets.to(device)
loss = loss_fn(ouputs, targets)
# 优化器优化模型
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{}, Loss:{}".format(total_train_step, loss.item()))
writer.add_scalar("train_loss", loss.item(), total_train_step)
# 测试步骤开始
test.eval()
total_test_loss = 0
total_accuracy = 0
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
outputs = test(imgs)
# 利用GPU进行训练
# if torch.cuda.is_available():
# imgs = imgs.cuda()
# outputs = outputs.cuda()
# GPU训练的第二种方式
imgs = imgs.to(device)
targets = targets.to(device)
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss.item()
accuracy = (outputs.argmax(1) == targets).sum()
total_accuracy = total_accuracy + accuracy
print("整体测试集上的Loss:{}".format(total_test_loss))
print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))
writer.add_scalar("test_loss", total_test_loss, total_test_step)
writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
total_test_step = total_test_step + 1
torch.save(test, "test_{}.pth".format(i))
print("模型已保存")
writer.close()
# 训练数据集的长度为:50000
# 测试数据集的长度为:10000
# -------------第 1 轮训练开始------------
# 训练次数:100, Loss:2.2875332832336426
# 训练次数:200, Loss:2.2817461490631104
# 训练次数:300, Loss:2.2471563816070557
# 训练次数:400, Loss:2.1874866485595703
# 训练次数:500, Loss:2.132857322692871
# 训练次数:600, Loss:2.0947699546813965
# 训练次数:700, Loss:1.998453974723816
# 整体测试集上的Loss:311.0058389902115
# 整体测试集上的正确率:0.29330000281333923
# 模型已保存
# -------------第 2 轮训练开始------------
# 训练次数:800, Loss:1.8712564706802368
# 训练次数:900, Loss:1.8552746772766113
# 训练次数:1000, Loss:1.9931343793869019
# 训练次数:1100, Loss:2.0174198150634766
# 训练次数:1200, Loss:1.7257994413375854
# 训练次数:1300, Loss:1.652297854423523
# 训练次数:1400, Loss:1.7540465593338013
# 训练次数:1500, Loss:1.8159812688827515
# 整体测试集上的Loss:302.5420438051224
# 整体测试集上的正确率:0.30820000171661377
# 模型已保存
# -------------第 3 轮训练开始------------
# 训练次数:1600, Loss:1.725656270980835
# 训练次数:1700, Loss:1.6797170639038086
# 训练次数:1800, Loss:1.9214810132980347
# 训练次数:1900, Loss:1.6856346130371094
# 训练次数:2000, Loss:1.9710376262664795
# 训练次数:2100, Loss:1.5192266702651978
# 训练次数:2200, Loss:1.479805827140808
# 训练次数:2300, Loss:1.7519457340240479
# 整体测试集上的Loss:270.47529923915863
# 整体测试集上的正确率:0.3765999972820282
# 模型已保存
# -------------第 4 轮训练开始------------
# 训练次数:2400, Loss:1.7157604694366455
# 训练次数:2500, Loss:1.3676215410232544
# 训练次数:2600, Loss:1.6065953969955444
# 训练次数:2700, Loss:1.6743344068527222
# 训练次数:2800, Loss:1.512872338294983
# 训练次数:2900, Loss:1.5963021516799927
# 训练次数:3000, Loss:1.3251683712005615
# 训练次数:3100, Loss:1.5172301530838013
# 整体测试集上的Loss:268.4225286245346
# 整体测试集上的正确率:0.3808000087738037
# 模型已保存
# -------------第 5 轮训练开始------------
# 训练次数:3200, Loss:1.3438873291015625
# 训练次数:3300, Loss:1.479296088218689
# 训练次数:3400, Loss:1.4665098190307617
# 训练次数:3500, Loss:1.57560133934021
# 训练次数:3600, Loss:1.5602474212646484
# 训练次数:3700, Loss:1.3665083646774292
# 训练次数:3800, Loss:1.2847181558609009
# 训练次数:3900, Loss:1.4571285247802734
# 整体测试集上的Loss:256.30487501621246
# 整体测试集上的正确率:0.4120999872684479
# 模型已保存
# -------------第 6 轮训练开始------------
# 训练次数:4000, Loss:1.416244626045227
# 训练次数:4100, Loss:1.447770595550537
# 训练次数:4200, Loss:1.5056679248809814
# 训练次数:4300, Loss:1.2424676418304443
# 训练次数:4400, Loss:1.1738076210021973
# 训练次数:4500, Loss:1.3533822298049927
# 训练次数:4600, Loss:1.3864424228668213
# 整体测试集上的Loss:242.49723303318024
# 整体测试集上的正确率:0.4397999942302704
# 模型已保存
# -------------第 7 轮训练开始------------
# 训练次数:4700, Loss:1.3078216314315796
# 训练次数:4800, Loss:1.5058083534240723
# 训练次数:4900, Loss:1.3374627828598022
# 训练次数:5000, Loss:1.4076875448226929
# 训练次数:5100, Loss:0.9756096601486206
# 训练次数:5200, Loss:1.3260319232940674
# 训练次数:5300, Loss:1.219860315322876
# 训练次数:5400, Loss:1.3333754539489746
# 整体测试集上的Loss:228.80793249607086
# 整体测试集上的正确率:0.46939998865127563
# 模型已保存
# -------------第 8 轮训练开始------------
# 训练次数:5500, Loss:1.1971160173416138
# 训练次数:5600, Loss:1.1699522733688354
# 训练次数:5700, Loss:1.1365596055984497
# 训练次数:5800, Loss:1.2375069856643677
# 训练次数:5900, Loss:1.3294936418533325
# 训练次数:6000, Loss:1.5747617483139038
# 训练次数:6100, Loss:1.0562301874160767
# 训练次数:6200, Loss:1.13783860206604
# 整体测试集上的Loss:215.84799444675446
# 整体测试集上的正确率:0.5037999749183655
# 模型已保存
# -------------第 9 轮训练开始------------
# 训练次数:6300, Loss:1.4156008958816528
# 训练次数:6400, Loss:1.1690418720245361
# 训练次数:6500, Loss:1.5879621505737305
# 训练次数:6600, Loss:1.1197248697280884
# 训练次数:6700, Loss:1.0698397159576416
# 训练次数:6800, Loss:1.1453744173049927
# 训练次数:6900, Loss:1.1327089071273804
# 训练次数:7000, Loss:0.8645357489585876
# 整体测试集上的Loss:205.44150614738464
# 整体测试集上的正确率:0.536899983882904
# 模型已保存
# -------------第 10 轮训练开始------------
# 训练次数:7100, Loss:1.2320799827575684
# 训练次数:7200, Loss:0.9454939961433411
# 训练次数:7300, Loss:1.1817400455474854
# 训练次数:7400, Loss:0.7851381897926331
# 训练次数:7500, Loss:1.2794373035430908
# 训练次数:7600, Loss:1.3157795667648315
# 训练次数:7700, Loss:0.8761026859283447
# 训练次数:7800, Loss:1.2188628911972046
# 整体测试集上的Loss:197.47857344150543
# 整体测试集上的正确率:0.5537999868392944
# 模型已保存
样本验证
随机存储一张图片,利用已经训练好的模型进行识别验证:
import torch
from PIL import Image
import torchvision
img_path = "img.png"
image = Image.open(img_path)
image = image.convert("RGB")
print(image)
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
torchvision.transforms.ToTensor()])
image = transform(image)
print(image.shape)
model = torch.load("test_9。pth", map_location=torch.device("cpu"))
print(model)
image = torch.reshape(image, [1, 3, 32, 32])
model.eval()
with torch.no_grad():
output = model(image)
print(output)
print(output.argmax(1))
end,感谢土堆
版权声明:本文标题:PyTorch深度学习快速入门教程 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1729476963a1202185.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论