pytorch 笔记

news2024/11/25 2:50:01

1.python文件、python控制台Terminal、jupyter代码执行比较

在这里插入图片描述

2.Dataset和Dataloader

dataset存储数据集,dataloader从数据集中批量加载数据,如

把 dataset 放入 DataLoader
    loader = Data.DataLoader(
        dataset=torch_dataset,  # torch TensorDataset format
        batch_size=BATCH_SIZE,  # mini batch size 处理的数据个数
        shuffle=False,  # 要不要打乱数据 (打乱比较好)
        num_workers=0,  # 多线程来读数据
    )

3.tensorboard

一种显示图或表格的服务器

在这里插入图片描述
代码示例在这里插入图片描述
效果展示
在这里插入图片描述

4. transform结构及用法

通常用作转换图片格式/大小的模块,如

#ToTensor方法 是transforms中的一个类, 用于将PIL或ndarray类型转化为tensor类型
# 获取PIL图片 将其转化为tensor格式
img = Image.open('xx.jpg')
# 实例化对象
trans_to_Tensor = transforms.ToTensor()
# 使用方法进行转换
img_tensor = trans_to_Tensor(img)
# Normalize:图片归一化,修改tensor图片的一些参数,对色调影响很大
# Resize改变图片尺寸
# RandomCrop:随机裁剪,按照规定尺寸随机裁剪图片的任意位置, 传入和输出都是PIL图片
# Compose:可讲totensor方法和resize方法等一并调用

在这里插入图片描述
transform使用totensor的问题在这里插入图片描述

4.1常见的transforms案例

在这里插入图片描述
ToTensor: 将PIL图片转化为带神经网络参数的Tensor图片
在这里插入图片描述
将图片归一化Normalize在这里插入图片描述
归一化在tensorboard的效果在这里插入图片描述

4.2 常见的Transforms

resize-图片重置长和宽
transforms.resize传入的是PIL格式img在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
随机裁剪 RnadomCrop-参数PIL格式图片
在这里插入图片描述
汇总

from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

# transforms:Totensor--Normalize--Resize--RandomCrop
img = Image.open("images/img.png")
print(img)

# 得到ToTensor对象--ToTensor使用
trans_totensor = transforms.ToTensor()
# 将图像变为tensor格式的img
img_tensor = trans_totensor(img)

# 写入tensorboard
writer = SummaryWriter("logs")
writer.add_image("Totensor", img_tensor)

# Normalize 图片归一化。 归一化计算公式: output[channel] = (input[channel] - mean[channel]) / std[channel]
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([5, 2, 1], [1, 2, 2])
           #传入tensor格式的img
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("normalImg", img_norm,2)

# resize - img PIL格式
print(img.size)
trans_size = transforms.Resize((512, 512))
# img PIL -> resize -> img_resize PIL
img_resize = trans_size(img)

# img_resize PIL -> totensor - >img_resize tensor
img_resize = trans_totensor(img_resize)
print(img_resize)

writer.add_image("Resize",img_resize,0)

# resize2 - Compose
# 得到ToTensor对象--ToTensor使用
img = Image.open("images/img.png")
trans_totensor = transforms.ToTensor()
trans_size_2 = transforms.Resize(512)
# PIL -> PIL -> tensor              后一个参数的输入 要和前一个参数的输出一致
trans_compose = transforms.Compose([trans_size_2, trans_totensor])
img_resize_2 = trans_compose(img)

writer.add_image("Resize", img_resize_2,1)

# RandomCrop 随机裁剪
img = Image.open("images/img.png")
trans_totensor = transforms.ToTensor()
trans_random = transforms.RandomCrop(512)
trans_compose_2 = transforms.Compose([trans_random, trans_totensor])
for i in range(10):
    img_crop = trans_compose_2(img)
    writer.add_image("RandomCrop", img_crop, i)

writer.close()

5.torchvision

torchvision是Pytorch的一个图形库,主要用来构建计算机视觉模型,torchvision由以下四个部分构成:
1 torchvision.datasets:包括一些加载数据的函数和常用的数据集接口
2 torchvision.models:包含常用的模型结构(含预训练模型),例如AlexNet、ResNet等等
3 torchvision.transforms:包含一些常见的图片变换,例如裁剪、旋转等等
4 torchvision.utils:其他用法

torchvision使用dataset拉取pytorch官网数据集到本地
在这里插入图片描述
将官网下载的图片用 transforms 转化为tensor类型
在这里插入图片描述
在这里插入图片描述

6.dataloader

dataset得到数据。dataloader加载器,把数据加载到神经网络,从dataset中取数据。
在这里插入图片描述
在这里插入图片描述
dataloader代码示例

import torchvision
# 测试集数据
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

test_data = torchvision.datasets.CIFAR10(root="./datasets", train=False, transform=torchvision.transforms.ToTensor())
# batch_size : 一次处理64个图片。 drop_last:false表示一次去除64,若数据集最后还有2张图片则只取两张,若为true,后两张不取
# shuffle:false表示取出来的两次图片集顺序一模一样。若为true则两次取出来的图片顺序不一样
test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=False)

# 测试集中第一张样品图片
img, target = test_data[0]
# torch.Size([3, 32, 32]):3代表rgb。32*32的图片
print("img.shape",img.shape)
# 3 代表索引为3的标签
print("target", 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

print("张数:", step)
writer.close()

7.神经网络的搭建

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

forward讲解:使用Pytorch的时候,模型训练时,不需要调用forward这个函数,只需要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数。但需要在定义类中引入"nn.Module",此时如vcoy.forward(x) 就等价于 vcoy(x)

在这里插入图片描述

8.卷积案例

在这里插入图片描述
代码示例
在这里插入图片描述
在这里插入图片描述


import torch.nn.functional as F
import torch
# tensor是张量
# input :  torch.Size([5, 5])
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.Size([3, 3])
kernel = torch.tensor([[1, 2, 1],
                       [0, 1, 0],
                       [2, 1, 0]])

# torch.Size([1, 1, 5, 5])
# reshape改变tensor对象的维度 二维变思维--》conv2d要求tensor输入为四维
input = torch.reshape(input, (1, 1, 5, 5))
# torch.Size([1, 1, 3, 3])
kernel = torch.reshape(kernel, (1, 1, 3, 3))

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

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

# padding 对输入的数据四周填充一层0
output1 = F.conv2d(input,kernel,stride=1,padding=1)
print(output1)

9.卷积层

在定义的神经网络模型中加入卷积层,使用pytorch官网的Conv2d卷积函数。
在这里插入图片描述


import torchvision
import torch
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("../p18_data", train=False, transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset, batch_size=64)

class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        # 定义一个卷积层。in_channels:输入 图像个数。out_channels:输出的卷积结果个数。kernel_size:卷积核为3*3
        self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)

    def forward(self, x):
        self.conv1(x)
        return x

vcoy = Vcoy()
writer = SummaryWriter("../logs")
step = 0
for data in dataloader:
    imgs, targets = data

    print(imgs.shape)
    out_img = vcoy.forward(imgs)
    print(out_img.shape)
    # torch_Size([64,3,32,32])
    writer.add_images("input",imgs,step)
    # torch_Size([64,6,30,30])
    writer.add_images("output",imgs,step)
    step = step + 1

writer.close()

10.最大池化

上采样:插值。下采样:抽样

池化核(3*3):kernel_size=3,则步长也为3,池化层尺寸默认等于步长

最大池化作用:最大限度的保留图片特征,同时减少数据量。加速训练速度。

在这里插入图片描述
reshape的作用:由于在卷积过程需要输入四维格式的图片,需要通过reshape进行转换。
在这里插入图片描述
神经网络中仅定义了池化,将输入矩阵经过神经网络得到最大池化的结果。
在这里插入图片描述

对CIFRA10数据集中的图像进行池化
在这里插入图片描述

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

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

writer = SummaryWriter("../logs_maxpool")

class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        # kernel_size=3: 池化核窗口大小,默认步长=池化核窗口尺寸
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)

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

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

writer.close()

池化效果
在这里插入图片描述

补充reshape

在这里插入图片描述

11.非线性激活

非线性激活Sigmoid(input)的使用,输入参数input为CIFAR10数据集图片。可在forward函数使用output = self.relu1(input)查看Relu函数效果
在这里插入图片描述


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

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

print(input.shape)
# reshape : -1代表不设置参数,根据后边3个自动生成。1代表数据只有一层。2,2表示两行两列.将input变为四维的,提供下边使用
input = torch.reshape(input, (-1, 1, 2, 2))
print(input.shape)

dataset = torchvision.datasets.CIFAR10("../p20_data", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)
class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        # 非线性变换--目的给网络中引入一些非线性特征,因为非线性越多,才能训练出符合各种特征/曲线的模型
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()

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

vcoy = Vcoy()

writer = SummaryWriter("../logs_relu")
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images("input1", imgs, global_step=step)
    output = vcoy(imgs)
    writer.add_images("output1", output, global_step=step)
    step = step + 1

writer.close()

在tensorboard上查看效果
在这里插入图片描述
在这里插入图片描述

12.线性层

线性层:训练后,要评价模型的好坏,通过将最后的一层替换成线性层。线性层一般在神经网络模型的后几层,一般为全连接,转化成结果分类数。一般经过卷积(conv2d)-非线性激活(relu)-最大池化(maxpool)-平铺(flatten)-线性变化(linear)。
以CIFAR10数据集的训练过程图为例:经过线性变化输出10个值对应该数据集的10个分类的概率
在这里插入图片描述
线性层案例,pytorch线性函数为Linear(in_feature,out_feature)
在这里插入图片描述

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

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

dataloader = DataLoader(dataset, batch_size=64,drop_last=True)

class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        self.linear1 = Linear(196608, 10)

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

vcoy = Vcoy()
# linear使用场景:在神经网络的前部分输入是二维矩阵,不需要摊平。而在神经网络的最后几层,需要将卷积层摊平平放到全连接里进行计算
for data in dataloader:
    imgs, targets = data
    # torch.Size([64, 3, 32, 32])
    print(imgs.shape)
    # 最后一个-1代表图像宽度自己拉伸,将图片原来的张量拉伸成长条。
    output = torch.reshape(imgs, (1, 1, 1, -1))
    # torch.Size([1, 1, 1, 196608])
    print(output.shape)
    output = vcoy.forward(output)
    # torch.Size([1, 1, 1, 10])
    print(output.shape)

上图这里torch.reshape(imgs, (1, 1, 1, -1))等价于使用 flatten函数
在这里插入图片描述
根据图片经典卷积过程套入公式反推出padding的填充值
在这里插入图片描述


##### 12.1简单神经网络的搭建

在这里插入图片描述
输出神经网络参数测试结果
在这里插入图片描述

简单神经网络搭建


import torch
from torch import nn
from torch.nn import Module, Conv2d, MaxPool2d, Flatten, Linear, Sequential


class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        # @前的是channels个数
        # 3代表in_channel,若图片是彩色则代表rgb就为3,若是灰色图像就是1
        # 32代表经过卷积要输出的通道channels个数,一般卷积后的通道数就是下一层的in_channel个数
        # 5代表卷积核尺寸5*5            --第一次卷积
        self.conv1 = Conv2d(3, 32, 5, stride=1, padding=2)
        # 图中池化核尺寸为2
        self.maxpool1 = MaxPool2d(2)
        #   第二次卷积  和 池化
        self.conv2 = Conv2d(32, 32, 5, stride=1, padding=2)
        self.maxpool2 = MaxPool2d(2)
        #   第三次卷积
        self.conv3 = Conv2d(32, 64, 5, stride=1, padding=2)
        self.maxpool3 = MaxPool2d(2)
        # 数据展平--作用同 output = torch.reshape(imgs, (1, 1, 1, -1))
        self.flatten = Flatten()
        # 第一个线性层 64*4*4 = 1024。第一个参数1024代表输入特征个数,第二个参数64代表输出特征个数
        self.linear1 = Linear(1024, 64)
        # 第二个线性层 输出10个结果
        self.linear2 = Linear(64, 10)


    def forward(self, x):
        x = self.conv1(x)
        x = self.maxpool1(x)
        x = self.conv2(x)
        x = self.maxpool2(x)
        x = self.conv3(x)
        x = self.maxpool3(x)
        x = self.flatten(x)
        x = self.linear1(x)
        x = self.linear2(x)
        return x

    def __str__(self):
        # 打印它的全部属性
        print('\n'.join(['{0}: {1}'.format(item[0], item[1]) for item in self.__dict__.items()]))

if __name__ == '__main__':
    vcoy = Vcoy()
    # 3和32和32 代表上边神经网络中输入的 3@32x32,即一张图片,3就是代表rgb为3个通道。 64表示batch_size=64即64张图片数据
    input = torch.ones((64, 3, 32, 32))
    output = vcoy.forward(input)
    print(output.shape)

Sequential的引入(封装)–效果同上
在这里插入图片描述
Sequential的引入


import torch
from torch import nn
from torch.nn import Module, Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter


class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, stride=1, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, stride=1, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, stride=1, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

if __name__ == '__main__':
    vcoy = Vcoy()
    # 3和32和32 代表上边神经网络中输入的 3@32x32,即一张图片,3就是代表rgb为3个通道。 64表示batch_size=64即64张图片数据
    input = torch.ones((64, 3, 32, 32))
    output = vcoy(input)
    print(output.shape)

    writer = SummaryWriter("../logs_seq")
    writer.add_graph(vcoy, input)
    writer.close()

使用tensorboard查看搭建的神经网络结构
在这里插入图片描述
效果图
在这里插入图片描述
在这里插入图片描述

13.损失函数与反向传播

note:官方文档中参数N一般代表batch_size图片个数。

loss为实际输出和目标输出之间的差值,这个插值越小越好。3个pytorch官网求损失值的函数:在这里插入图片描述

损失函数

在这里插入图片描述

均方误差

在这里插入图片描述

import torch
from torch.nn import L1Loss
from torch import nn
inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)

inputs = torch.reshape(inputs, (1, 1, 1, 3))
targets = torch.reshape(targets, (1, 1, 1, 3))

loss = L1Loss()
result = loss(inputs, targets)
# 默认计算过程 result = ((1-1) + (2-2) + (5-3))/3
print("result ", result)

loss_mes = nn.MSELoss()
result_mse = loss_mes(inputs, targets)
print("result_mse", result_mse)


if __name__ == '__main__':

    x = torch.tensor([0.1, 0.2, 0.3])
    y = torch.tensor([1])
    # print(x)
    x = torch.reshape(x, (1, 3))
    # print(x)
	# 交叉熵损失函数
    loss_cross = nn.CrossEntropyLoss()
    result_cross = loss_cross(x, y)
    print(result_cross)
交叉熵损失函数识别Person- dog- car,通过CrossEntropyLoss计算的损失值过程,参数参考官网

在这里插入图片描述


交叉熵损失函数输入为2维,reshape将数据转化为二维
在这里插入图片描述
使用交叉熵计算识别 [Person- dog- car] 过程的损失函数。x为假设的网络模型输出的各个类别的概率,y为实际的类别的索引,1即是dog。通过该损失函数计算它们之间的损失值。
在这里插入图片描述
在这里插入图片描述


将12.1 列化后的简单神经网络序应用到CIFAR10数据集上,该数据集一共10个类别
在这里插入图片描述
在这里插入图片描述
计算损失值
在这里插入图片描述
梯度下降法:通过反向传播计算某点的梯度,根据当前点进行参数变化,使得梯度下降,损失值变小
在这里插入图片描述
使用backward计算出每个节点的grad-梯度参数
在这里插入图片描述
在这里插入图片描述
查看module-》grad(即梯度),然后通过优化器根据梯度对神经网络中的参数进行更新。
对应代码


import torch
from torch import nn
from torch.nn import Module, Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import torchvision

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

dataloader = DataLoader(dataset, batch_size=1)

class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, stride=1, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, stride=1, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, stride=1, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        x = self.model1(x)
        return x

if __name__ == '__main__':
    vcoy = Vcoy()
    loss = nn.CrossEntropyLoss()
    for data in dataloader:
        imgs, targets = data
        outputs = vcoy(imgs)
        result_loss = loss(outputs, targets)
        # print(result_loss)
        result_loss.backward()
        print("finish")



官方其他损失函数
在这里插入图片描述

14.优化器

官方文档
在这里插入图片描述
优化器降低损失值的过程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述存在损失值先降低后增长的问题:在顺序寻找loss最小值,误差小,识别率高。让误差变小,但在函数中很难找到最小值,能找到极小值,需要改变幅度,再次找到最小值。可以尝试降低学习率 lr再查看损失值变化。
在这里插入图片描述

15.现有模型的使用和修改:VGG16模型

在这里插入图片描述
在这里插入图片描述
修改vgg16模型内的参数
在这里插入图片描述
修改后
在这里插入图片描述
添加一步全连接层
在这里插入图片描述

16.网络模型的保存与加载

模型保存的两种方式及加载
保存
在这里插入图片描述
加载方式1:是正常的网络模型
在这里插入图片描述
加载方式2:打印的是一个个的字典形式,不再是网络模型,需要恢复成网络模型
在这里插入图片描述
加载方式2:加载网络模型
在这里插入图片描述
自定义模型保存
在这里插入图片描述
自定义模型加载
在这里插入图片描述

17.完整模型训练套路(数据集CIFAR10)

在这里插入图片描述

17.1搭建神经网络模型并测试

模型
在这里插入图片描述
测试模型输出
在这里插入图片描述
model.py

import torch
from torch import nn

# 搭建神经网络模型
class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(kernel_size=2),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.MaxPool2d(kernel_size=2),
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            # 64*4*4=1024
            nn.Linear(in_features=64*4*4, out_features=64),
            nn.Linear(64, 10)
        )

    def forward(self,x):
        x = self.model(x)
        return x

if __name__ == '__main__':
    # 测试网络正确性
    vcoy = Vcoy()
    # 参数说明:64--batch-size 3--in_channels通道数 32*32的图片尺寸
    input = torch.ones((64, 3, 32, 32))
    output = vcoy(input)
    # 输出 torch.Size([64, 10]):64表示64张图片,10表示每个图片在10个类别中的概率(CIFAR10数据集为10个类别)
    print(output.shape)

17.2 模型进行训练、测试、保存每次训练的模型

训练
在这里插入图片描述
在这里插入图片描述

训练结果并保存每一轮训练后的模型。第76行需要变动为 total_test_loss = total_test_loss + loss.item()。 loss格式是 tensor(x)格式,loss.item()是数据x
在这里插入图片描述
train.py

import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import *
from torch.utils.data import DataLoader
# 准备数据集
train_data = torchvision.datasets.CIFAR10("../train_data", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
test_data = torchvision.datasets.CIFAR10("../train_data", train=False, transform=torchvision.transforms.ToTensor(),
                                          download=True)

# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 若train_data_size=10 则训练数据集的长度为10。 测试集长度10000 训练集50000
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)

# 创建网络模型
vcoy = Vcoy()

# 损失函数:分类问题可使用 交叉熵 损失函数
loss_fn = nn.CrossEntropyLoss()

# 优化器: 采用随机梯度下降
# learning_rate = 1e-2 :1e-2 = 1x(10)^(-2) = 1/100 = 0.01
learning_rate = 0.01
optimizer = torch.optim.SGD(vcoy.parameters(), lr=learning_rate)

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

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

for i in range(epoch):
    print("------第{}轮训练开始------".format(i+1))
    # 训练步骤开始
    for data in train_dataloader:
        imgs, targets = data
        # 训练数据放到网络当中
        output = vcoy(imgs)
        # 根据训练结果得到和真实值的误差--损失值。output:通过神经网络模型后的值,targets是真实值。如猫的图片的targets=猫
        loss = loss_fn(output, targets)

        # 优化器优化模型
        # 梯度清0
        optimizer.zero_grad()
        # 清0的时候,用求出的损失的反向传播得到每个参数节点的梯度
        loss.backward()
        # 进行优化
        optimizer.step()
        # 训练次数+1
        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))
            # 记录每一步训练的损失值 显示到tensorboard上
            writer.add_scalar("train_loss", loss.item(), total_train_step)
    # 如何知道模型有没有训练好,达到想要的需求效果。:每训练完一次课使用测试数据进行测试,测试过程不需要调优
    # 没有梯度时候测试-保证没有在进行调优。测试步骤开始:
    total_test_loss = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            outputs = vcoy(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()

    print("整体测试集上的Loss:{}".format(total_test_loss))
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    # 测试步骤+1
    total_test_step + total_train_step + 1

    # 保存每一轮的训练结果模型
    torch.save(vcoy, "vcoy_{}.pth".format(i))
    print("模型已保存")

writer.close()

训练结果

Files already downloaded and verified
Files already downloaded and verified
训练数据集的长度:50000
测试数据集的长度:10000
------第1轮训练开始------
训练次数:100,Loss:2.2880163192749023
训练次数:200,Loss:2.2714011669158936
训练次数:300,Loss:2.2264020442962646
训练次数:400,Loss:2.1325900554656982
训练次数:500,Loss:2.0504238605499268
训练次数:600,Loss:1.9959642887115479
训练次数:700,Loss:2.049309492111206
整体测试集上的Loss:322.9267883300781
模型已保存
------第2轮训练开始------
训练次数:800,Loss:1.9377368688583374
训练次数:900,Loss:1.8804967403411865

结果优化问题
在这里插入图片描述
argmax案例:利用argmax将上图中outputs转化到preds
在这里插入图片描述
预测值和实际值比较
在这里插入图片描述
利用上述转化过程可对17.1和17.2的模型训练进一步优化,计算出整体的正确率
在这里插入图片描述

改进的train.py,model代码不变

import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import *
from torch.utils.data import DataLoader
# 准备数据集
train_data = torchvision.datasets.CIFAR10("../train_data", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
test_data = torchvision.datasets.CIFAR10("../train_data", train=False, transform=torchvision.transforms.ToTensor(),
                                          download=True)

# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 若train_data_size=10 则训练数据集的长度为10。 测试集长度10000 训练集50000
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)

# 创建网络模型
vcoy = Vcoy()

# 损失函数:分类问题可使用 交叉熵 损失函数
loss_fn = nn.CrossEntropyLoss()

# 优化器: 采用随机梯度下降
# learning_rate = 1e-2 :1e-2 = 1x(10)^(-2) = 1/100 = 0.01
learning_rate = 0.01
optimizer = torch.optim.SGD(vcoy.parameters(), lr=learning_rate)

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

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

for i in range(epoch):
    print("------第{}轮训练开始------".format(i+1))
    # 训练步骤开始
    for data in train_dataloader:
        imgs, targets = data
        # 训练数据放到网络当中
        output = vcoy(imgs)
        # 根据训练结果得到和真实值的误差--损失值。output:通过神经网络模型后的值,targets是真实值。如猫的图片的targets=猫
        loss = loss_fn(output, targets)

        # 优化器优化模型
        # 梯度清0
        optimizer.zero_grad()
        # 清0的时候,用求出的损失的反向传播得到每个参数节点的梯度
        loss.backward()
        # 进行优化
        optimizer.step()
        # 训练次数+1
        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))
            # 记录每一步训练的损失值 显示到tensorboard上
            writer.add_scalar("train_loss", loss.item(), total_train_step)
    # 如何知道模型有没有训练好,达到想要的需求效果。:每训练完一次课使用测试数据进行测试,测试过程不需要调优
    # 没有梯度时候测试-保证没有在进行调优。测试步骤开始:
    total_test_loss = 0
    # 整体正确率
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            # imgs加载的图片数组 targets加载的图片对应的真实标签值
            imgs, targets = data
            outputs = vcoy(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.item()

    print("整体测试集上的Loss:{}".format(total_test_loss))
    print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))
    # 将每轮的测试【损失值】和【正确率】画成图存入tensorboard
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
    # 测试步骤+1
    total_test_step + total_train_step + 1
    # 保存每一轮的训练结果模型
    torch.save(vcoy, "vcoy_{}.pth".format(i))
    print("模型已保存")
writer.close()

在这里插入图片描述

启动tensorboard查看
在这里插入图片描述
在这里插入图片描述
准确率
在这里插入图片描述
进一步完善网络模型,只添加红圈内,其余不变
在这里插入图片描述

17.3 利用GPU训练

训练方式1:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
gpu训练方式2
在这里插入图片描述
代码 实现
在这里插入图片描述
在这里插入图片描述

17.4 读取一张狗的图片输入模型

在这里插入图片描述
代码部分
在这里插入图片描述
在这里插入图片描述
第一次训练模型准确率可能不高,可切换到vcoy_8.pth模型进行测试
在这里插入图片描述
reshape目的在这里插入图片描述
加载的数据集标签对应的索引,输出的是5对应dog的索引
在这里插入图片描述
识别狗的神经网络代码

import torch
from PIL import Image
import torchvision
from torch import nn

img_path = "../images/dog.png"

image = Image.open(img_path)
# 输出的是:<PIL.WebPImagePlugin.WebPImageFile image mode=RGB size=800x500 at 0x1B6A9F475E0>
print(image)

# png图片格式是四个通道,除了RGB还有一个透明通道,使用convert(rgb)保留颜色通道。
# 若图片本来是三个颜色通道,经过convert不变。但加上这一步可适应各种png jpg格式图片
image = image.convert('RGB')

# Compose:把几个transform连接在一起
transform = torchvision.transforms.Compose(
	# 转化成CIFAR10数据集中图片大小32*32,适应该网络模型输入的参数
    [torchvision.transforms.Resize((32, 32)),
     torchvision.transforms.ToTensor()]
)

image = transform(image)
# 输出:torch.Size([3, 32, 32])
print(image.shape)

# 搭建神经网络模型
class Vcoy(nn.Module):

    def __init__(self):
        super(Vcoy, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),
            nn.MaxPool2d(kernel_size=2),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.MaxPool2d(kernel_size=2),
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            # 64*4*4=1024
            nn.Linear(in_features=64*4*4, out_features=64),
            nn.Linear(64, 10)
        )

    def forward(self,x):
        x = self.model(x)
        return x

# 加载训练过一次的模型
models = torch.load("vcoy_0.pth")
print(models)
# 1指的是batch_size 3只rgb三通道 32是图片大小
image = torch.reshape(image, (1, 3, 32, 32))
# 当前模型是GPU训练 所以进行输入要将image加入gpu中
image = image.cuda()
# 网络模型要求张量的阶数为4,即(batch_size,channel,height,weight),一般图片输入为3阶张量,即(channel:3,Hight:32,Weight:32)
models.eval()
# 节约性能
with torch.no_grad():
    output = models(image)
print(output)
print(output.argmax(1))

gpu训练的模型放到cpu运行
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/426088.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MIPI D-PHYv2.5笔记(17) -- Global Operation Flow Diagram、数据速率依赖参数

声明&#xff1a;作者是做嵌入式软件开发的&#xff0c;并非专业的硬件设计人员&#xff0c;笔记内容根据自己的经验和对协议的理解输出&#xff0c;肯定存在有些理解和翻译不到位的地方&#xff0c;有疑问请参考原始规范看 Global Operation Flow Diagram 图1 Data Lane Mod…

【Linux】线程概念详析

我们已经了解了Linux操作系统进程部分相关知识&#xff1a; 博主有关Linux进程相关介绍的文章&#xff1a; &#x1f4a5;[Linux] 系统进程相关概念、系统调用、Linux进程详析、进程查看、fork()初识 &#x1f4a5;[Linux] 进程状态相关概念、Linux实际进程状态、进程优先级 …

【超算/先进计算学习】日报1

目录今日已完成任务列表遇到的问题及解决方案任务完成详细笔记Darknet框架优化介绍darknet介绍YOLO高性能计算与超级计算机简介算力超级计算机概念与体系结构并行编程技术Linux常用操作命令Linux操作系统与指令使用机器信息查询文件、目录和权限文件内容查看环境变量使用对自己…

15.枚举

枚举 枚举是Java1.5引入的新特性&#xff0c;通过关键字enum来定义枚举类。枚举类是一种特殊类&#xff0c;它和普通类一样可以使用构造方法、定义成员变量和方法&#xff0c;也能实现接口,但枚举类不能继承其他类。枚举是一个被命名的整型常数的集合&#xff0c;用于声明一组…

Linux系统下安装zookeeper教程

将下载好的zookeeper上传到linux服务器上&#xff0c;这里使用的是FileFilla 解压&#xff1a;[rootcentos7964 software]# tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz 进入刚刚解压后的文件夹&#xff0c;创建一个名字为data的文件夹&#xff0c;如下&#xff1a; [rootc…

分库分表--shardingjdbc

文章目录前言一、shardingjdbc简介作用二、如何使用1.我有个表现在体量太大了,我想做分库分表2.开始改造1 引入shardingjdbc2 更改yml文件3 测试看效果3.旧数据迁移4.其他分库类型5 部分配置说明总结前言 当项目开始的时候,没有想到后续的分库分表的话,其实对于后续的分库分表…

MYSQL学习 - DDL数据库操作

前言 从今天开始, 健哥就带各位小伙伴学习数据库技术。数据库技术是Java开发中必不可少的一部分知识内容。也是非常重要的技术。本系列教程由浅入深, 全面讲解数据库体系。 非常适合零基础的小伙伴来学习。 ------------------------------前戏已做完&#xff0c;精彩即开始---…

【数据结构】树和二叉树——堆

目录 &#x1f349;一.树的概念及结构&#x1f349; 1.树的概念 2.树的相关术语 3.树的表示 4.树在实际中的应用 &#x1f34a;二.二叉树的概念和结构&#x1f34a; 1.二叉树的概念 2.特殊的二叉树 2.1.满二叉树 2..2.完全二叉树 3.二叉树的性质 4.二叉树的存储结构 …

限流算法(计数器、滑动时间窗口、漏斗、令牌)原理以及代码实现

文章目录前言1、计数器&#xff08;固定时间窗口&#xff09;算法原理代码实现存在的问题2、滑动时间窗口算法原理代码实现存在的问题3、漏桶算法原理代码实现存在的问题4、令牌桶算法原理代码实现最后本文会对这4个限流算法进行详细说明&#xff0c;并输出实现限流算法的代码示…

一文了解Java ArrayList (源码逐行解析)

介绍 ArrayList 是最常用的 List 实现类&#xff0c;内部是通过数组实现的&#xff0c;它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔&#xff0c;当数组大小不满足时需要增加存储能力&#xff0c;就要将已经有数组的数据复制到新的存储空间中。当从 Arr…

c++积累5-lock_guard使用

1、std:mutex 在了解lock_guard之前&#xff0c;需要先学习下std:mutex,因为lock_guard内部就是使用的std:mutex std:mutex&#xff1a;是一个用于保护共享数据不会同时被多个线程访问的类&#xff0c;它叫做互斥量。我们可以把它看作一把锁&#xff0c;基本使用如下&#xff…

【致敬未来的攻城狮计划】— 连续打卡第四天:e2 studio 使用教程

系列文章目录 1.连续打卡第一天&#xff1a;提前对CPK_RA2E1是瑞萨RA系列开发板的初体验&#xff0c;了解一下 2.开发环境的选择和调试&#xff08;从零开始&#xff0c;加油&#xff09; 3.欲速则不达&#xff0c;今天是对RA2E1 基础知识的补充学习。 文章目录 系列文章目录 文…

Flutter成不了“顶流明星”的7大理由

Flutter是一款由Google推出的跨平台移动应用开发框架&#xff0c;近年来备受关注。尽管Flutter在某些方面表现出色&#xff0c;但仍然有一些人对它的发展前景表示怀疑。近期一些文章针对Flutter的发展提出了不少质疑和批评&#xff0c;称其难以成为移动应用开发的“顶流明星”&…

【计算机网络—— 安装packet tracer的教程,管理MAC地址和配置路由器的实验步骤以及心得体会】

文章目录安装packet tracer的教程管理MAC地址实验目的 &#xff1a;管理MAC地址实验内容及过程记录&#xff08;一&#xff09;运行Cisco Packet Tracer软件&#xff08;二&#xff09;选择PC终端&#xff08;三&#xff09;运行终端&#xff08;四&#xff09;按表内容对交换机…

Spring Cloud Nacos使用总结

目录 安装Nacos服务器 服务发现与消费 服务发现与消费-添加依赖 服务发现-配置文件 服务发现-注解 服务发现-Controller 服务消费-配置文件 服务消费-注解与Ribbon消费代码 服务消费-运行 配置管理 配置管理-添加依赖 配置管理-配置文件 配置管理-注解 配置管理-…

Raft一致性算法(精简和扩展)

raft一致性算法 文章目录raft一致性算法一、raft简介1.1 raft涉及到的名词1.2 Rpc请求1.3 复制状态机二、raft⼀致性算法2.0 摘要2.0.1 所有服务器需遵守的规则2.0.2 跟随者2.0.3 候选⼈2.0.4 领导人2.0.5 状态2.0.6 特性2.1 raft基础2.2 leader选举2.2.1 集群启动时选举2.2.2 …

微电网两阶段鲁棒优化经济调度方法(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

清华大学ChatGLM-6B部署运行

一、模型介绍 开源项目&#xff1a; GitHub - THUDM/ChatGLM-6B: ChatGLM-6B&#xff1a;开源双语对话语言模型 | An Open Bilingual Dialogue Language Model ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型&#xff0c;基于 General Language Model (GLM) 架构&…

PLC高精度定时器(T法测速功能块)

S7-200 SMART PLC时间间隔指令BGN_ITIME,和CAL_ITIME采用的是系统自带的1ms高精度定时器,PLC里只能调用一次。T法测速和M法测速应用时,都需要高精度时序定时器的支持(当然你也可以采用定时中断的方式获取高精度时序),时间间隔指令请参看下面的博客文章: SMART PLC时间间…

keil5使用c++编写stm32控制程序

keil5使用c编写stm32控制程序一、前言二、配置图解三、std::cout串口重定向四、串口中断服务函数五、结尾废话一、前言 想着搞个新奇的玩意玩一玩来着&#xff0c;想用c编写代码来控制stm32&#xff0c;结果在keil5中&#xff0c;把踩给我踩闷了&#xff0c;这里简单记录一下。…