当前位置:   article > 正文

小土堆pytorch实战笔记

小土堆pytorch实战笔记

pytorch

学习的两大法宝函数-help()和dir()

  • help()可以查看某个函数的官方用法介绍
help(torch.cuda.is_available)
  • 1
  • dir()可以查看某个对象包含的各个方法
dir(torch.cuda)
dir(torch.cuda.is_available())
  • 1
  • 2

如何加载数据

  1. Dataset

    提供一种方式去获取数据及其label:1.如何获取每一个数据及其label 2.告诉我们总共有多少数据

    • 单个图片的加载

在这里插入图片描述

  • 获得整个数据集

在这里插入图片描述

#读取上述结构的数据集
from torch.utils.data import Dataset
import cv2
import os
from PIL import Image


class MyData(Dataset):
    # 继承Dataset类

    # 重写__init__函数
    def __init__(self, root_dir, label_dir):
        self.root_dir = root_dir
        self.label_dir = label_dir
        #os.path.join(self.root_dir, self.label_dir)-将两个路径给拼接起来
        self.path = os.path.join(self.root_dir, self.label_dir) 
        #os.listdir(self.path)-将该路径的所有图片转换成一个list
        self.img_path = os.listdir(self.path)

    # 重写,如果想让该函数通过index获得图片的话,就应该传入一个图片列表进去
    def __getitem__(self, index):
        img_name = self.img_path[index]
        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"
ants_label_dir = "ants"
bees_label_dir = "bees"
ants_dataset = MyData(root_dir, ants_label_dir)
bees_dataset = MyData(root_dir, bees_label_dir)

train_dataset=ants_dataset+bees_dataset
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  1. Dataloader(结合后面两节一起看)

为后面的网络提供不同的数据类型

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

test_set = torchvision.datasets.CIFAR10("./CIFAR10_dataset", train=False,
                                  transform=torchvision.transforms.ToTensor())
test_loader = DataLoader(dataset=test_set, batch_size=4, shuffle=True, num_workers=0, drop_last=False)

# 测试数据集中第一张图片及target
img, target = test_set[0]
print(img.shape)  # torch.Size([3, 32, 32])
print(target)  # 3

writer = SummaryWriter("dataloder")
step = 0
# 扫描两轮数据集
for epoch in range(2):
    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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

Tensorboard使用

  1. 简单绘图

writer.add_scalar()

功能:将标量添加到 summary

参数:

  • tag (string):数据标识符
  • scalar_value (float or string/blobname):要保存的数值
  • global_step (int):全局步值
  • walltime (float):可选参数,用于记录发生的时间,默认为 time.time()

参数理解:

  • 第一个参数可简单理解为保存到 tensorboard 日志文件中的标量图像的名称
  • 第二个参数可简单理解为图像的 y 轴数据
  • 第三个参数可简单理解为图像的 x 轴数据
  • 第四个参数都是可选参数,用于记录发生的时间,默认为 time.time()
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter("logs")#logs-文件夹名



# y=2x
for i in range(100):
    writer.add_scalar("y=2x", 2*i, i)

writer.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在terrminal输入:
在这里插入图片描述
在这里插入图片描述

2.复杂绘图

writer.add_image()

add_image(self, tag, img_tensor, global_step=None, walltime=None, dataformats=‘CHW’):绘制图片,可用于检查模型的输入,监测 feature map 的变化,或是观察 weight。
tag:就是保存图的名称
img_tensor:图片的类型要是torch.Tensor, numpy.array, or string这三种
global_step:第几张图片
dataformats=‘CHW’,默认CHW,tensor是CHW,numpy是HWC

利用OpenCV读取图片,获得numpy型图片数据

from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image
import cv2

writer = SummaryWriter("logs")
image_path = "../dataset/train/ants/6240338_93729615ec.jpg"
#这里没有使用opencv来读取图片,所以还是要将图片处理成numpy型
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)

#使用opencv
cv_img=cv2.imread(image_path)


print(type(img_array))
print(img_array.shape)

# 从PIL到numpy,需要在add_image()中指定shape中每一个数字/维表示的含义
writer.add_image("test00", img_array, 1, dataformats='HWC')
writer.add_image("test00",cv_img, 1, dataformats='HWC')



# y=x
for i in range(100):
    writer.add_scalar("y=2x", 2 * i, i)

writer.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

Transform的使用

Transform的主要作用是对图片进行一些变换.

对于transforms的使用要关注三个点:输入数据类型,输出数据类型,作用

简单使用:

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

# 通过trasnforms.ToTensor
# 1.transforms该如何使用


image_path = "dataset/train/ants/5650366_e22b7e1065.jpg"
img_PIL = Image.open(image_path)

writer = SummaryWriter("logs")

# 1.transforms该如何使用
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img_PIL)

writer.add_image("Tensor_img", tensor_img)
writer.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

transforms常用方法:

1.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作。

2.transforms.ToTensor()类。

(1)将 PIL Image 或 numpy.ndarray 转为 tensor

(2)如果 PIL Image 属于 (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1) 中的一种图像类型,或者 numpy.ndarray 格式数据类型是 np.uint8 ,则将 [0, 255] 的数据转为 [0.0, 1.0] ,也就是说将所有数据除以 255 进行归一化。

(3)将 HWC 的图像格式转为 CHW 的 tensor 格式。

3.transforms.Normalize()类。用平均值和标准差对张量图像进行归一化处理。

output[channel] = (input[channel] - mean[channel]) / std[channel]

4.transforms.Resize()类。用于将 PIL.Image 转换成指定大小的图像。

这个类的主要参数如下:

size:指定输出图像的大小,可以是一个整数(表示将图像的较小边缩放到指定的大小,较大边按比例缩放),也可以是一个二元组 (height, width)(表示将图像缩放到指定的高度和宽度)。例如,size=224 将图像的较小边缩放到 224,size=(224, 224) 将图像缩放到高度和宽度均为 224。

5.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作。Compose里面的参数实际上就是个列表,而这个列表里面的元素就是你想要执行的transform操作。要注意每个transform操作的输入输出的类型匹配。

6.transforms.RandomCrop()类。用于将PIL.Image随机裁剪指定大小

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

writer = SummaryWriter("logs")
img = Image.open("dataset/train/ants/7759525_1363d24e88.jpg")

print(img)  # <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=500x333 at 0x20CE4F20EB0>
# ToTensor
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
writer.add_image("Tensor", tensor_img)

# Normalize
print(tensor_img[0][0][0])  #tensor(0.8863)
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(tensor_img)
print(img_norm[0][0][0])   #tensor(0.7725)
writer.add_image("Normalize", img_norm)

#Resize

print(img.size)  #(500, 333)
trans_resize=transforms.Resize((512,512))
img_reszie=trans_resize(img)
print(img_reszie)  #<PIL.Image.Image image mode=RGB size=512x512 at 0x20CE4F8B280>
img_reszie=tensor_trans(img_reszie)
writer.add_image("Resize", img_reszie,0)


#Compose
trans_resize2=transforms.Resize(512)
trans_compose=transforms.Compose([trans_resize2,tensor_trans])
img_reszie_2=trans_compose(img)
writer.add_image("Resize",img_reszie_2,1)


#RandomCrop
trans_random=transforms.RandomCrop(128)
trans_compose_2=transforms.Compose([trans_random,tensor_trans])
for i in range(10):
    img_crop=trans_compose_2(img)
    writer.add_image("RandomCrop",img_crop,i)
writer.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

TorchVersion 中数据集的使用

以CIFA10数据集为例,对实现transform的数据集操作。

在这里插入图片描述

import torchvision
from torch.utils.tensorboard import SummaryWriter

train_set = torchvision.datasets.CIFAR10("./CIFAR10_dataset", train=True, download=True)
test_set = torchvision.datasets.CIFAR10("./CIFAR10_dataset", train=False, download=True)

# 查看数据集属性
# print(test_set[0])  # (<PIL.Image.Image image mode=RGB size=32x32 at 0x195D8A8BD90>, 3)--第一个为图片,第二个为target
# print(test_set.classes)  # ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
#
# img, target = test_set[0]
# print(img)  # <PIL.Image.Image image mode=RGB size=32x32 at 0x195D8A8BE80>
# print(target)  # 3
# print(test_set.classes[target])  # cat


# 使用transform对数据集操作
dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()

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

writer.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

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

在这里插入图片描述

import torch
from torch import nn


class Module(nn.Module):

    def __init__(self):
        super(Module, self).__init__()

    def forward(self, input):
        outout = input + 1
        return outout


module = Module()
x = torch.tensor(1.0)
output = module(x)
print(output)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

卷积操作

在这里插入图片描述

在这里插入图片描述

pytorch之torch.nn.Conv2d()函数详解-CSDN博客

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

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

# 为了调用conv函数,对输入和卷积核数据形式进行改造
input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))
print(input.shape)
print(kernel.shape)

#调用conv函数
output = F.conv2d(input, kernel, stride=1)
print(output)

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

卷积层使用

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

import nn_Module

dataset = torchvision.datasets.CIFAR10("./CIFAR10_dataset", train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=64, shuffle=True, num_workers=0, drop_last=False)


class Module(nn.Module):
    def __init__(self):
        super(Module, self).__init__()
        self.conv1 = Conv2d(in_channels=3, out_channels=3, kernel_size=3, stride=1, padding=0)

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


module = Module()
print(module)
# Module(
#   (conv1): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
# )

writer = SummaryWriter("conv2d")
step = 0
for data in dataloader:
    imgs, target = data
    output = module(imgs)
    print(imgs.shape)  # torch.Size([64, 3, 32, 32])
    print(output.shape)  # torch.Size([64, 6, 30, 30])
    writer.add_images("input", imgs, step)
    # torch.reshape(output, (-1, 3, 30, 30))  # 填-1会根据后面的自适应
    writer.add_images("output", output, step)
    step = step + 1
writer.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

池化层使用

以最大池化为例

在这里插入图片描述

参数:

  • kernel_size(int or tuple) :max pooling的窗口大小
  • stride(int or tuple, optional):max pooling的窗口移动的步长。默认值是kernel_size
  • padding(int or tuple, optional) :输入的每一条边补充0的层数
  • dilation(int or tuple, optional):一个控制窗口中元素步幅的参数
  • return_indices :如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
  • ceil_mode :如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的
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("./CIFAR10_dataset", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=64, shuffle=True, num_workers=0, drop_last=False)


# 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)
# print(input.shape)
# input = torch.reshape(input, (-1, 1, 5, 5))
# print(input.shape)


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

    def forward(self, x):
        output = self.maxpool(x)
        return output

# output=moduel(input)
# print(output)
moduel = MOdule()
writer = SummaryWriter("logs_maxpool")
step = 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

非线性激活

以ReLU激活函数和sigmoid函数为例

在这里插入图片描述

在这里插入图片描述

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

dataset = torchvision.datasets.CIFAR10("./CIFAR10_dataset", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=64, shuffle=True, num_workers=0, drop_last=False)


#
# input = torch.tensor([[1, -0.5],
#                       [-1, 3]])
# input = torch.reshape(input, (-1, 1, 2, 2))
# print(input.shape)

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

    def forward(self, input):
        # output = self.relu1(input)
        output = self.sigmod1(input)

        return output

# output=module(input)
# print(output)
module = Module()

writer = SummaryWriter("logs_relu")
step = 0
for data in dataloader:
    imgs,targets=data
    writer.add_images("input",imgs,global_step=step)
    output=module(imgs)
    writer.add_images("output",output,global_step=step)
    step=step+1
writer.close()



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

线性层使用

在这里插入图片描述

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

dataset = torchvision.datasets.CIFAR10("./CIFAR10_dataset", train=False, download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=64, shuffle=True, num_workers=0, drop_last=True)


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

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

moduel = Module()
for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    # output = torch.reshape(imgs, (1, 1, 1, -1))
    output=torch.flatten(imgs)#将tensor拉成一行,效果同上行代码
    print(output.shape)
    output = moduel(output)
    print(output.shape)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

神经网络搭建实战

实现CFIAR10数据集的图像识别

在这里插入图片描述

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


class Module(nn.Module):
    def __init__(self):
        super(Module, self).__init__()
        # self.conv1=Conv2d(3,32,5,padding=2)
        # self.maxpool1=MaxPool2d(2)
        # self.conv2=Conv2d(32,32,5,padding=2)
        # self.maxpool2=MaxPool2d(2)
        # self.conv3=Conv2d(32,64,5,padding=2)
        # self.maxpool3=MaxPool2d(2)
        # self.flatten=Flatten()
        # self.linear1=Linear(1024,64)
        # self.linear2=Linear(64,10)
        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.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)
        x = self.model1(x)
        return x


module = Module()
print(module)
input = torch.ones((64, 3, 32, 32))
output = module(input)
print(output.shape)

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

损失函数与反向传播

以L1LOSS、MSELOSS和CROSSENTROPYLOSS为例
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

交叉熵损失函数原理详解-CSDN博客

import torch
from torch.nn import L1Loss, MSELoss, CrossEntropyLoss

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)
print(result)

loss_mse = MSELoss()
result_mes = loss_mse(inputs, targets)
print(result_mes)

x = torch.tensor([0.1, 0.2, 0.7])
y = torch.tensor([1])
x = torch.reshape(x, (1, 3))
loss_cross = CrossEntropyLoss()
result_cross = loss_cross(x, y)
print(result_cross)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在网络中引入损失函数

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

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


class Module(nn.Module):
    def __init__(self):
        super(Module, 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()
module = Module()
for data in dataloader:
    imgs, targets = data
    output = module(imgs)
    result_loss=loss(output,targets)
    result_loss.backward()
    


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

优化器

以随机梯度下降为例

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

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


class Module(nn.Module):
    def __init__(self):
        super(Module, 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()
module = Module()
optim = torch.optim.SGD(module.parameters(), lr=0.01)  # 优化器
for epoch in range(20):
    running_loss=0.0
    for data in dataloader:
        imgs, targets = data
        output = module(imgs)
        result_loss = loss(output, targets)
        optim.zero_grad()  # 梯度清零
        result_loss.backward()
        optim.step()
        running_loss=running_loss+result_loss
    print(running_loss)


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

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

以VGG为例

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

vgg16_false = torchvision.models.vgg16()
train_dataset = torchvision.datasets.CIFAR10("./CIFAR10_dataset", train=True, download=True,
                                             transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=train_dataset, batch_size=1)

print(vgg16_false)

#添加
# vgg16_false.classifier.add_module("add_linear", nn.Linear(1000, 10))  # 在vgg16的classifier部分添加一层
#修改
vgg16_false.classifier[6]=nn.Linear(4096,10)
print(vgg16_false)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

模型的保存和加载

#保存文件

import torch
import torchvision

vgg16 = torchvision.models.vgg16()

# 保存方式1
torch.save(vgg16, "vgg16_method1.pth")  # 保存对象+保存文件路径(后缀一般为.pth )---保存了网络模型的结构与参数

# 保存方式2(官方)
torch.save(vgg16.state_dict(), "vgg16_method2.pth")  # 将模型参数保存成python中字典的形式

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
#加载文件

import torch
# 加载模型方式1-》保存方式1
import torchvision.models

model1 = torch.load("vgg16_method1.pth")
print(model1)

# 加载模型方式2-》保存方式2
model2 = torch.load("vgg16_method2.pth")

vgg16 = torchvision.models.vgg16()
vgg16.load_state_dict(model2)
print(vgg16)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

完整的模型训练套路

以CIFAR10数据集为例

train.py
import torch.optim
import torchvision.datasets

# 4引入model文件
from torch.utils.tensorboard import SummaryWriter

from model import *
# 1准备数据集

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)

train_data_size = len(train_data)
test_data_size = len(test_data)

# 2加载数据集

train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 5创建网络模型

model = Module()

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

# 7优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

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

#11添加tensorboard
writer = SummaryWriter("logs_train")

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

    # 训练步骤开始
    for data in train_dataloader:
        imgs, targets = data
        outputs = model(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)
    # 10每一轮训练后在测试数据集上跑一次,评估现在模型训练好了没,所以不需要对原有模型进行调优,使用 with torch.no_grad():
    total_test_loss = 0
    total_accuracy=0
    with torch.no_grad():

        for data in test_dataloader:
            imgs, targets = data
            outputs = model(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_step + loss.item()
            accuracy=(outputs.argmax(1)==targets).sum()
            # argmax函数功能,返回最大值的索引;若axis=1,表明按行比较,输出每行中最大值的索引,若axis=0,则输出每列中最大值的索引。
            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

        #12保存每一轮模型
        torch.save(model,"model_{}.pth".format(i))
        print("模型保存")

writer.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
model.py

#3搭建神经网络
import torch
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Linear, Flatten


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


if __name__ == '__main__':
    # 验证网络正确性
    model = Module()
    input = torch.ones((64, 3, 32, 32))
    output = model(input)
    print(output.shape)  # torch.Size([64, 10])



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

使用GPU训练

第一种方式:

对于模型,数据,损失函数调用.cuda()

import torch.optim
import torchvision.datasets

# 4引入model文件
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Linear, Flatten
from torch.utils.tensorboard import SummaryWriter

# from model import *
# 1准备数据集

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)

train_data_size = len(train_data)
test_data_size = len(test_data)

# 2加载数据集

train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

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


model = Module()
#使用GPU
if torch.cuda.is_available():
    model=model.cuda()

# 6损失函数
loss_fn = nn.CrossEntropyLoss()
if torch.cuda.is_available():
    loss_fn=loss_fn.cuda()#使用GPU

# 7优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

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

#11添加tensorboard
writer = SummaryWriter("logs_train")

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

    # 训练步骤开始
    for data in train_dataloader:
        imgs, targets = data
        if torch.cuda.is_available():
            imgs=imgs.cuda()
            targets=targets.cuda()
        outputs = model(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)
    # 10每一轮训练后在测试数据集上跑一次,评估现在模型训练好了没,所以不需要对原有模型进行调优,使用 with torch.no_grad():
    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 = model(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_step + loss.item()
            accuracy=(outputs.argmax(1)==targets).sum()
            # argmax函数功能,返回最大值的索引;若axis=1,表明按行比较,输出每行中最大值的索引,若axis=0,则输出每列中最大值的索引。
            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

        #12保存每一轮模型
        torch.save(model,"model_{}.pth".format(i))
        print("模型保存")

writer.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120

第二种方式:对模型、数据、损失函数调用.to(device)---->device=torch.device(“cuda”)

import torch.optim
import torchvision.datasets

# 4引入model文件
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Linear, Flatten
from torch.utils.tensorboard import SummaryWriter

# from model import *
# 1准备数据集

from torch.utils.data import DataLoader
#定义训练的设备
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)

train_data_size = len(train_data)
test_data_size = len(test_data)

# 2加载数据集

train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

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


model = Module()
#使用GPU
model=model.to(device)

# 6损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn=loss_fn.to(device)#使用GPU

# 7优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

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

#11添加tensorboard
writer = SummaryWriter("logs_train")

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

    # 训练步骤开始
    for data in train_dataloader:
        imgs, targets = data
        imgs=imgs.to(device)
        targets=targets.to(device)
        outputs = model(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)
    # 10每一轮训练后在测试数据集上跑一次,评估现在模型训练好了没,所以不需要对原有模型进行调优,使用 with torch.no_grad():
    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 = model(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_step + loss.item()
            accuracy=(outputs.argmax(1)==targets).sum()
            # argmax函数功能,返回最大值的索引;若axis=1,表明按行比较,输出每行中最大值的索引,若axis=0,则输出每列中最大值的索引。
            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

        #12保存每一轮模型
        torch.save(model,"model_{}.pth".format(i))
        print("模型保存")

writer.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119

完整的模型测试流程

import torch
import torchvision.transforms
from PIL import Image
from torch import nn
from torch.nn import Sequential, MaxPool2d, Conv2d, Flatten, Linear
#1准备验证数据
image_path="img/img.png"
image=Image.open(image_path)
#png图片是四通道的,需要调用convert()函数保留RGB通道
image=image.convert('RGB')

transform=torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
                                          torchvision.transforms.ToTensor()])
image=transform(image)
print(image.shape)

#2加载训练好的模型
class Module(nn.Module):
    def __init__(self):
        super(Module, 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
#3验证模型
model=torch.load("model_9.pth")
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))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

其他

python中内置__call__()函数的作用

__call__()的本质是将一个类变成一个函数(使这个类的实例可以像函数一样调用)

一个类实例要变成一个可调用对象,只需要实现一个特殊方法__call__()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/51834
推荐阅读
相关标签
  

闽ICP备14008679号