PyTorch深度学习入门

目录

Python学习中的两大法宝函数(也可用于PyTorch)

理解Package结构及法宝函数的作用

实战运用两大法宝函数

PyCharm及Jupyter使用及对比

PyTorch加载数据

Dataset类代码实战

TensorBoard的使用 

1、TensorBoard的安装

2、add_scalar()的使用(常用来绘制train/val loss)​编辑

3、add_image()的使用(常用来观察训练结果)

Transforms的使用 

1、transforms用于对图形进行变换

2、常见的Transforms

1)transforms.ToTensor()

2)transforms.Composes()

3)transforms.Normalize()

4)transforms.Resize()

4)transforms.RandomCrop()

torchvision中的数据集使用

DataLoader的使用

神经网络的基本骨架:nn.Module的使用

卷积操作

神经网络-卷积层

神经网络-最大池化的使用

神经网络-非线性激活

神经网络-线性层及其他层介绍

神经网络-搭建小实战和Sequential的使用

损失函数与反向传播

优化器

现有网络模型的使用及修改

网络模型的保存与读取

完整的模型训练套路

利用GPU训练

方式一:

方式二:

完整的模型验证(测试,demo)套路

看看开源项目

Python学习中的两大法宝函数(也可用于PyTorch)

理解Package结构及法宝函数的作用

1.名称是pytorch的package

2、法宝函数

实战运用两大法宝函数

dir()

help()

eg.dir(torch)

help(torch.cuda.is_avaliable())注意:没有这个括号!

PyCharm及Jupyter使用及对比

pycharm控制台:回车——运行,shift+回车——换行

Jupyter:回车——换行,shift+回车——运行

PyTorch加载数据

数据集的组成形式:

(1)文件夹名称为这个文件夹内所有图片所对应的lable

(2)图片和lable对应两个文件夹

(3)图片的名称为这张图片所对应的lable

读取数据:

Dataset类代码实战

python控制台

Dataset类代码实战见read_data.python文件

TensorBoard的使用 

1、TensorBoard的安装

图像变换,即transform的使用。想要演示transform结果,运行完一个对应的方法,需要展示这个图像,就需要用到TensorBoard,探究不同阶段模型的输出。

用help()可以查看这个类SummaryWriter,在PyCharm中可以按Ctrl,然后点击SummaryWriter去查看

2、add_scalar()的使用(常用来绘制train/val loss)

from tensorboardX import SummaryWriter
#从这个工具包(tensorboardX)导入这个类(SummaryWriter)

writer = SummaryWriter("logs") #将对应的事件文件储存在log文件夹中

# writer.add_image()
for i in range(100):
    writer.add_scalar("y=x", i, i) #可以用tab键进行缩进
    
writer.close()

新开一个窗口显示:改函数变量,重命名tag。原窗口显示另一个函数:改函数变量。打开查看logs文件:在python终端输入tensorboard --logdir=logs,也可以指定端口名输入tensorboard --logdir=logs --port=6007

3、add_image()的使用(常用来观察训练结果)

python控制台:

add_image()默认图像shape:

如果输入shape是,需要设置

新开一个窗口显示:改路径,重命名tag。原窗口显示另一张图片:改路径,改步数(global_step,即第三个参数)。打开查看logs文件:在python终端输入tensorboard --logdir=logs。

通过这种方式,我们可以很直观的训练当中给model提供了那些数据,或者相对model进行测试时可以看每一阶段的输出结果。

Transforms的使用 

1、transforms用于对图形进行变换

即transforms.py文件(工具箱)里有很多定义的类(工具)

内置函数_ _ call _ _的作用:

2、常见的Transforms

1)transforms.ToTensor()

定义:

PIL Image的读取:

numpy.ndarray的读取:

使用:

2)transforms.Composes()

定义:

使用:后一个参数的输入与前一个参数的输出必须匹配

3)transforms.Normalize()

定义:

使用:

输出:

4)transforms.Resize()

定义:

使用:

输出:

4)transforms.RandomCrop()

定义:

使用:

torchvision中的数据集使用

之前使用transforms对单个图片进行处理,但真正使用transforms要对数据集中的每一个图片进行处理。这节讲如何将transforms与数据集结合在一起,以及标准数据集如何下载组织查看使用。

pytorch官方文档:

有的数据集没有显示下载地址,如何查看:按住ctrl键,鼠标点击CIFAR10,url路径就是下载链接

代码实战:

import torchvision
from tensorboardX import SummaryWriter

dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])
train_set = torchvision.datasets.CIFAR10(root="./dataset_", transform=dataset_transform,train=True, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset_", transform=dataset_transform,train=False, 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()

writer = SummaryWriter("p10")
for i in range(10):
    img,target = test_set[i]
    writer.add_image("test_set",img,i)

writer.close()

DataLoader的使用

自定义的dataset:告诉程序数据集在什么地方,第一张数据是什么,第二张数据是什么,dataset总共有多少张数据。

 按住ctrl键,鼠标点击CIFAR10,找到_ _getitem_ _可以知道其返回值

代码实战:

输出结果为:

第一个batch的第一张图片标签为2,而test_set【0】的标签为3,可知DataLoader的采样方式为随机采样。

代码实战:

import torchvision
from torch.utils.data import DataLoader
from tensorboardX import SummaryWriter

test_data = torchvision.datasets.CIFAR10("./dataset_", train=False, transform=torchvision.transforms.ToTensor())

test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=False, num_workers=0, drop_last=True)

# 测试数据集中第一张图片及target
img, target = test_data[0]
print(img.shape)
print(target)
print(len(test_data))

writer = SummaryWriter("p11")
for epoch in range(2):
        step=0
        for data in test_loader:
                imgs,targets = data
                # print(imgs.shape)
                # print(targets)
                writer.add_images("Epoch: {}".format(epoch), imgs, step)
                step=step+1

writer.close()

神经网络的基本骨架:nn.Module的使用

卷积操作

代码实战:

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]])

input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))

print(input.shape)
print(kernel.shape)

output = F.conv2d(input, kernel, stride=1)
print(output)

output2 = F.conv2d(input, kernel, stride=2)
print(output2)

output3 = F.conv2d(input, kernel, stride=1, padding=1)
print(output3)

输出:

torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[10, 12, 12],
          [18, 16, 16],
          [13,  9,  3]]]])
tensor([[[[10, 12],
          [13,  3]]]])
tensor([[[[ 1,  3,  4, 10,  8],
          [ 5, 10, 12, 12,  6],
          [ 7, 18, 16, 16,  8],
          [11, 13,  9,  3,  4],
          [14, 13,  9,  7,  4]]]])

神经网络-卷积层

dilation:用于空洞卷积,默认值为1

groups:用于分组卷积,默认值为1

代码实战:

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./dataset_",train=False,transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset,batch_size=64)

class Mengyuan(nn.Module):
    def __init__(self):
        super(Mengyuan, self).__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

mengyuan = Mengyuan()
print(mengyuan)

输出:

代码实战:

import torch
import torchvision
from tensorboardX import SummaryWriter
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./dataset_",train=False,transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset,batch_size=64)

class Mengyuan(nn.Module):
    def __init__(self):
        super(Mengyuan, self).__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

mengyuan = Mengyuan()
#print(mengyuan)
writer = SummaryWriter("./nn")
step = 0
for data in dataloader:
    imgs,targets = data
    output = mengyuan(imgs)
    print(imgs.shape) #torch.Size([64,3,32,32])
    writer.add_images("input",imgs,step)
    print(output.shape) #torch.Size([64,6,30,30])
    # 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
from torch import nn
from torch.nn import MaxPool2d

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 Mengyuan(nn.Module):
    def __init__(self):
        super(Mengyuan, self).__init__()
        self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)

    def forward(self,input):
        output = self.maxpool1(input)
        return output

mengyuan = Mengyuan()
output = mengyuan(input)
print(output)

输出:

代码实战:

import torch
import torchvision
from tensorboardX import SummaryWriter
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader

# 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)


dataset = torchvision.datasets.CIFAR10("./dataset_", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())

dataloader = DataLoader(dataset, batch_size=64)

class Mengyuan(nn.Module):
    def __init__(self):
        super(Mengyuan, self).__init__()
        self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)

    def forward(self,input):
        output = self.maxpool1(input)
        return output

mengyuan = Mengyuan()
# output = mengyuan(input)
# print(output)

writer = SummaryWriter("./logs_maxpool")
step = 0

for data in dataloader:
    imgs, targets = data
    writer.add_images("input", imgs, step)
    output = mengyuan(imgs)
    writer.add_images("output", output, step)
    step = step + 1

writer.close()

输出:

神经网络-非线性激活

代码实战:

输出:

代码实战:

import torch
import torchvision
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from tensorboardX import SummaryWriter

input = torch.tensor([[1, -0.5],
                      [-1, 3]])

input = torch.reshape(input, (-1, 1, 2, 2))
print(input.shape)

dataset = torchvision.datasets.CIFAR10("./dataset_", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())

dataloader = DataLoader(dataset, batch_size=64)

class Mengyuan(nn.Module):
    def __init__(self):
        super(Mengyuan, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()

    def forward(self, input):
        output = self.sigmoid1(input)
        return output

mengyuan = Mengyuan()

writer = SummaryWriter("./logs_sigmoid")
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images("input", imgs, global_step=step)
    output = mengyuan(imgs)
    writer.add_images("output", output, step)
    step += 1

writer.close()

输出:

神经网络-线性层及其他层介绍

正则化:加快神经网络的训练速度

代码实战:

输出:

代码实战:

import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./dataset_", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())

dataloader = DataLoader(dataset, batch_size=64)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.linear1 = Linear(196608, 10)

    def forward(self, input):
        output = self.linear1(input)
        return output

tudui = Tudui()

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    output = torch.flatten(imgs)
    print(output.shape)
    output = tudui(output)
    print(output.shape)

输出:

神经网络-搭建小实战和Sequential的使用

搭建网络,代码实战:

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1 = Sequential(
            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, x):
        x = self.model1(x)
        return x

tudui = Tudui()
print(tudui)

输出:

检验网络是否搭建正确,代码实战:

输出:

符合上图CIFAR 10的模型,网络搭建正确。

tensorboard显示网络结构,代码实战:

输出:

将数据集输入网络,代码实战:

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("./dataset_", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=1)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1 = Sequential(
            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, x):
        x = self.model1(x)
        return x


# loss = nn.CrossEntropyLoss()
tudui = Tudui()
for data in dataloader:
    imgs, targets = data
    outputs = tudui(imgs)
    print(outputs)
    print(targets)
#     result_loss = loss(outputs, targets)
#     print("ok")

输出:

损失函数与反向传播

L1LOSSS:(绝对值之差)

代码实战:

输出:

MSELOSS:(均方差)

代码实战:

输出:

CROSSENTROPYLOSS:(交叉熵)

代码实战:

输出:

利用CROSSENTROPYLOSS(交叉熵)优化网络,代码实战:

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("./dataset_", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=1)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1 = Sequential(
            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, x):
        x = self.model1(x)
        return x


loss = nn.CrossEntropyLoss()
tudui = Tudui()
for data in dataloader:
    imgs, targets = data
    outputs = tudui(imgs)
    # print(outputs)
    # print(targets)
    result_loss = loss(outputs, targets)
    print(result_loss)

输出:(神经网络的输出和真实值之间的误差值)

反向传播:

没有用反向传播前:

运行反向传播:

运行反向传播:

选择合适的优化器,利用梯度对神经网络的参数进行更新。

优化器

代码实战:(学习速率:太大,模型训练起来很不稳定,太小,模型训练慢;所以开始用大一点的学习速率去训练,后期用小一点的学习速率去训练)

import torch
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.optim.lr_scheduler import StepLR
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./dataset_", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=1)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1 = Sequential(
            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, x):
        x = self.model1(x)
        return x


loss = nn.CrossEntropyLoss()
tudui = Tudui()
optim = torch.optim.SGD(tudui.parameters(), lr=0.01)
for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
            imgs, targets = data
            outputs = tudui(imgs)
            result_loss = loss(outputs, targets)
            optim.zero_grad() #梯度参数设为0
            result_loss.backward() #求每个节点的梯度
            optim.step() #利用梯度进行优化
            running_loss = running_loss + result_loss #求每一轮的误差总和
    print(running_loss)

输出:

现有网络模型的使用及修改

代码实战:

import torchvision

# train_data = torchvision.datasets.ImageNet("../data_image_net", split='train', download=True,
#                                            transform=torchvision.transforms.ToTensor())
from torch import nn

vgg16_false = torchvision.models.vgg16(pretrained=False) #网络权重为初始化参数
vgg16_true = torchvision.models.vgg16(pretrained=True)  #网络在imagenet数据集上预训练达到理想效果的权重

print(vgg16_true)

train_data = torchvision.datasets.CIFAR10('./dataset', train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True) #CIFAR10数据集是10个类,VGG网络最后输出是1000,所以需要修改网络

vgg16_true.classifier.add_module('add_linear', nn.Linear(1000, 10)) #最后增加一个线性层
print(vgg16_true)

print(vgg16_false)
vgg16_false.classifier[6] = nn.Linear(4096, 10) #修改最后一层
print(vgg16_false)


网络模型的保存与读取

保存方式一:(既保存模型结构又保存模型参数)

输出将模型保存到左侧项目文件中,与该py文件同级

读取模型:

解决:实际上不需要将模型复制过来,将模型定义保存在一个文件中(同级),然后

from 模型文件名import   *

保存方式二:(只保存模型参数)

输出将模型保存到左侧项目文件中,与该py文件同级

读取模型:

tips:查看文件大小

完整的模型训练套路

创建并检验神经网络:同级,单独的文件夹

import torch
from torch import nn

# 搭建神经网络
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, 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__':
    tudui = Tudui()
    input = torch.ones((64, 3, 32, 32))
    output = tudui(input)
    print(output.shape)

训练网络:

首先引入创建的网络(同级)

argmax:

代码实战:

输出:

train()、eval():

训练网络代码实战:

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念

import torchvision
from torch.utils.tensorboard import SummaryWriter

from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoader

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)
# 如果train_data_size=10, 训练数据集的长度为:10
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)

# 创建网络模型
tudui = Tudui()

# 损失函数
loss_fn = nn.CrossEntropyLoss()

# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("../logs_train")

for i in range(epoch):
    print("-------第 {} 轮训练开始-------".format(i+1))

    # 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        outputs = tudui(imgs)
        loss = loss_fn(outputs, 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)

    # 测试步骤开始
    tudui.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():  #不计算梯度,只需要测试模型,不需要利用梯度去优化
        for data in test_dataloader:
            imgs, targets = data
            outputs = tudui(imgs)
            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(tudui, "tudui_{}.pth".format(i))
    print("模型已保存")

writer.close()

输出:

利用GPU训练

方式一:

终端输入nvidia-smi,会出现GPU的信息

代码实战:

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter

# from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoader

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)
# 如果train_data_size=10, 训练数据集的长度为:10
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)

# 创建网络模型
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, 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
tudui = Tudui()
if torch.cuda.is_available():
    tudui = tudui.cuda()

# 损失函数
loss_fn = nn.CrossEntropyLoss()
if torch.cuda.is_available():
    loss_fn = loss_fn.cuda()
# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("../logs_train")

for i in range(epoch):
    print("-------第 {} 轮训练开始-------".format(i+1))

    # 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        if torch.cuda.is_available():
            imgs = imgs.cuda()
            targets = targets.cuda()
        outputs = tudui(imgs)
        loss = loss_fn(outputs, 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)

    # 测试步骤开始
    tudui.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            if torch.cuda.is_available():
                imgs = imgs.cuda()
                targets = targets.cuda()
            outputs = tudui(imgs)
            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(tudui, "tudui_{}.pth".format(i))
    print("模型已保存")

writer.close()

输出:

方式二:

代码实战:

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter

# from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoader

# 定义训练的设备
device = torch.device("cuda")

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)
# 如果train_data_size=10, 训练数据集的长度为:10
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)

# 创建网络模型
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, 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
tudui = Tudui()
tudui = tudui.to(device)

# 损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)
# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("../logs_train")

for i in range(epoch):
    print("-------第 {} 轮训练开始-------".format(i+1))

    # 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        imgs = imgs.to(device)
        targets = targets.to(device)
        outputs = tudui(imgs)
        loss = loss_fn(outputs, 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)

    # 测试步骤开始
    tudui.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            imgs = imgs.to(device)
            targets = targets.to(device)
            outputs = tudui(imgs)
            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(tudui, "tudui_{}.pth".format(i))
    print("模型已保存")

writer.close()

完整的模型验证(测试,demo)套路

路径:

一个点:当前同级目录,两个点:返回上一级目录

代码实战:

# -*- coding: utf-8 -*-
# 作者:小土堆
# 公众号:土堆碎念
import torch
import torchvision
from PIL import Image
from torch import nn

image_path = "../imgs/airplane.png"
image = Image.open(image_path)
print(image)
image = image.convert('RGB')
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)),
                                            torchvision.transforms.ToTensor()])

image = transform(image)
print(image.shape)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, 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

model = torch.load("tudui_29_gpu.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))

输出:

查看类别:

看看开源项目

所以资料均来自小土堆b站视频,请关注b站up主:我是土堆

  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值