深度学习--pytorch

pytorch安装

windows安装pytorch环境 并支持CUDA,cuDNN - 知乎

Anaconda | The World’s Most Popular Data Science Platform

先安装虚拟环境anaconda

注意版本

安装成功的标志

可以使用工具包调整pytorch的环境与python版本


conda create -n pytorch python=3.6

安装成功之后如果激活可以使用上述两个指令

激活成功

可用工具包中并没有pytorch,接下来安装pytorch

PyTorch

选择好相应版本粘贴命令

然后需要循环进行命令使用,一次安装可能不成功

需要持续进行空格进行安装


nvidia-smi

命令行中输入上述指令,进行版本检查,此处需要大于396才能使用,否则需要修改








  1. 首先安装Cuda

首先我们要确定本机是否有独立显卡。在计算机-管理-设备管理器-显示适配器中,查看是否有独立显卡。

CUDA Toolkit Archive | NVIDIA Developer

直接打开解压安装

接着就是安装过程,双击打开显示临时解压目录,不需要改变,默认即可。

接下来,进入NVIDIA安装过程,在这安装过程中,我一开始直接选择的精简安装,但由于VS的原因,导致无法正常安装,于是我换成了自定义的安装方式,并将VS勾给去掉,便可以正常安装了,至于CUDA的安装目录,大家默认安装在C盘即可

添加环境变量

  1. 安装CUDNN

Log in | NVIDIA Developer

(需要注册账号并且填写调查问卷)

下载之后,解压缩,将CUDNN压缩包里面的bin、clude、lib文件直接复制到CUDA的安装目录下,直接覆盖安装即可。

  1. pytorch-gpu的安装

直接来到Pytorch的官网,此处,因为根据自己的配置进行选择,我试过用conda安装,但是conda安装老是不成功,也替换过清华镜像源,但速度实在是龟速,半天没动静。虽然pip下载也蛮慢,但至少可以安装成功。这里我对pip的安装方式,稍作修改,让其直接从清华镜像源下载。然后慢慢等待安装成功即可。

Start Locally | PyTorch

然后命令行验证pytorch是否正常安装成功,这里可以正常打印出版本号,安装没问题。


import torch
 
print(torch.__version__)

print(torch.cuda.is_available())

尝试调用CUDA

TRUE表示成功

在PYcharm中进行运行

然后运行代码片段


def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.
    print(torch.__version__)
    print(torch.cuda.is_available())

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('PyCharm')

成功

安装报错

解决方式

PackagesNotFoundError: The following packages are not available from current channels的解决办法-CSDN博客

去官网寻找安装包

Pytorch :: Anaconda.org

找到对应版本进行安装



练习路径

anaconda安装之后jupter默认安装

但是jupyter是安装在base环境中的,需要转换成pytorch环境再重新安装jupyter

这样才能在pytorch中使用jupyter

pytorch环境中没有jupyter

安装包

启动jupyter notebook

选择这个

成功使用jupyter,并且jupyter使用pytorch环境

查看分隔区

查看函数

添加python解释器

///

使用DateSet类

获取数据及其label

如何获取每一个数据及其label

告诉我们总共有多少个数据

使用DataLoader类

为网络提供不同的数据形式

读取数据集

首先创建read_data.py文件

先在控制台中进行模拟


 from PIL import Image
 img_path = "E:\\pytorch\\pytorch exercise\\hymenoptera_data\\hymenoptera_data\\train\\ants\\0013035.jpg"
 img = Image.open(img_path)
 img.show()

其中"E:\\pytorch\\pytorch exercise\\hymenoptera_data\\hymenoptera_data\\train\\ants\\0013035.jpg"

是文件的相对路径

img.show() 打开文件

使用DataSet类进行导入数据集


from torch.utils.data import Dataset
from PIL import Image
import os
import cv2
# root_dir = "hymenoptera_data/hymenoptera_data/train"
# label_dir = "ants"
# path = os.path.join(root_dir,label_dir)
class Mydata(Dataset):
#初始化数据集,self表示当前类,root_dir表示当前的相对根路径,label_dir表示其中的子路径
    def __init__(self, root_dir, label_dir):
        self.root_dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(root_dir,label_dir)#拼接路径
        self.img_path = os.listdir(self.path)
    def __getitem__(self, idx):
        img_name = self.img_path[idx]#单个图片的路径
        img_item_path = os.path.join(self.root_dir,self.label_dir,img_name)
        img = Image.open(img_item_path)
        label = self.label_dir
        return img,label

    def __len__(self):
        return len(self.img_path)

只要输入好路径,输入Dataset类,就能创建数据集


root_dir = "hymenoptera_data/hymenoptera_data/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)

add_scalar的使用

添加函数


from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter("logs")
#writer.add_image()
#y=x
for i in range(100):
    writer.add_scalar("y=x",i,i)#(函数图像,x轴长度,y轴长度)


writer.close()

运行上述代码,会生成一个logs文件

在命令行中选择打开文件


tensorboard --logdir=logs

返回出页面的结果,点进去

add_image的使用

img_tensor的数据类型


from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image
image_path="hymenoptera_data/hymenoptera_data/train/ants/0013035.jpg"
img_PTL = Image.open(image_path)
img_array = np.array(img_PTL)
print(type(img_array))
print(img_array.shape)
writer = SummaryWriter("logs")
writer.add_image("test",img_array,1,dataformats="HWC")

运行结果

此时发现网页中多出了一个IMAGE

TransForm的使用

首先查看TransForm的源码

使用python工具中的structure进行查看文件结构

会发现好多类

注意compose类

to tensor


from PIL import Image
from torchvision import transforms

#python 的用法   tensor数据类型
#通过 transform.ToTensor去看两个问题
#1.transform该如何使用(python)
#2.为什么我们需要 Tensor数据类型
#绝对路径  E:\pytorch\pytorch exercise\hymenoptera_data\hymenoptera_data\train\ants\0013035.jpg
#相对路径    hymenoptera_data/hymenoptera_data/train/ants/0013035.jpg
img_path = "hymenoptera_data/hymenoptera_data/train/ants/0013035.jpg"
img = Image.open(img_path)
print(img)

图片显示被正确读取


    def __call__(self, pic):
        """
        Args:
            pic (PIL Image or numpy.ndarray): Image to be converted to tensor.

        Returns:
            Tensor: Converted image.
        """

使用的时候只要传入一个图片就会返回一个tensor类型图片


tensor_trans = transforms.ToTensor()#直接在transform工具箱当中调用ToTensor工具
tensor_img = tensor_trans(img)
print(tensor_img)

将图片转换成tensor类型

查看日志


tensorboard --logdir=logs

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

#python 的用法   tensor数据类型
#通过 transform.ToTensor去看两个问题
#1.transform该如何使用(python)
#2.为什么我们需要 Tensor数据类型
#绝对路径  E:\pytorch\pytorch exercise\hymenoptera_data\hymenoptera_data\train\ants\0013035.jpg
#相对路径    hymenoptera_data/hymenoptera_data/train/ants/0013035.jpg
img_path = "hymenoptera_data/hymenoptera_data/train/ants/0013035.jpg"
img = Image.open(img_path)
#print(img)
tensor_trans = transforms.ToTensor()#直接在transform工具箱当中调用ToTensor工具
tensor_img = tensor_trans(img)
#print(tensor_img)
writer = SummaryWriter("logs")

writer.add_image("Tensor_img",tensor_img)#添加tensor类型数据
writer.close()

添加成功

CALL方法的使用


#call方法的使用
class Person:
    def __call__(self, name):
        print("__call__"+"Hello " + name)
    def hello(self,name):
        print("hello"+ name)


person = Person()
person("wangxinyu")
person.hello("xinyu")

call方法就是直接使用对象直接传入参数就可以调用

ctrl+p查看方法需要哪些参数

也叫类对象调用


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      E:\pytorch\ancaonda\python.exe "E:/pytorch/pytorch exercise/p10_UsefulTransform.py"
__call__Hello wangxinyu
helloxinyu

Process finished with exit code 0


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

writer = SummaryWriter("logs")
#img = Image.open("hymenoptera_data/0013035.jpg")
img_path = "hymenoptera_data/hymenoptera_data/train/ants/0013035.jpg"
img = Image.open(img_path)
print(img)

先输出图片


# #ToTensor使用
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("ToTensor",img_tensor)
writer.close()

加入ToTensor


#Normallize
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize",img_norm)
writer.close()

增加Normalize模块


#Resize
print(img.size)
trans_resize = transforms.Resize((512,512))
# img PIL ->resize -> img_resize PIL
img_resize = trans_resize(img)
#img _resize PIL -> totensor -> img_resize tensor
img_resize = trans_totensor(img_resize)
writer.add_image("Resize",img_resize,0)
print(img_resize)

Resize的使用



import torchvision

dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])
#root表示数据集存放什么位置
#train默认就是true
#download=True表示下载
train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, transform=dataset_transform, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=dataset_transform, download=True)

print(test_set[0])

可以看到已经下载数据集

如果下载的慢,把链接放在迅雷当中

Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./dataset\cifar-10-python.tar.gz


print(test_set[0])
print(test_set.classes)
img,target = test_set[0]
print(img)
print(target)

使用Tensorboard添加Tensor图片


#使用tensorboard进行显示

writer = SummaryWriter("p10")
for i in range (10):
    img,target = test_set[i]
#添加数据,添加图片
    writer.add_image("test_set",img,i)
writer.close()

dataloader的使用

主要作用是从dataset中读取数据集


import torchvision
from torch.utils.data import DataLoader

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

for data in test_loader:
    imgs, targets = data
    print(imgs.shape)
    print(targets)

主要对batch_size=4进行讲解

主要为把dataset数据集4个一组4个一组打包读取

第一个4表示有4个这样类型的数据

并且tensor也都进行了标号


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

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

#drop_last是对batch_size不能整除的数的处理
#shuffle对读取同一个数据集采用不同的方式
test_loader = DataLoader(dataset=test_set, batch_size=64, shuffle=True, num_workers=0, drop_last=False)
img,target = test_set[0]
print(img.shape)
print(target)
writer = SummaryWriter("dataloader")
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()

正常训练读取数据流程


import torch
from torch import nn

#创建神经网络模型,nn.Moudle表示继承moudle类,#definit表示重写初始化方法
class xinyu(nn.Module):
    def __init__(self):
        super().__init__()
#前馈方法,表示输入进入的时候做出改变的函数
    def forward(self,input):
        output = input + 1
        return  output
#创建一个神经网络
XINYU = xinyu()
x = torch.tensor(1.0)
output = XINYU(x)
print(output)

使用调试器先看一下步骤

实例化模型的时候首先要进行init初始化方法

输入参数的时候进入forward方法


import torch
import torch.nn.functional as F

#首先定义一个网格图像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]])
#3*3的卷积核
kernel = torch.tensor([[1,2,1],
                        [0,1,0],
                        [2,1,0]])
#修改格式,使用神经网络需要4个参数,2参变4参
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)

import torch
import torch.nn.functional as F

#首先定义一个网格图像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]])
#3*3的卷积核
kernel = torch.tensor([[1,2,1],
                        [0,1,0],
                        [2,1,0]])
#修改格式,使用神经网络需要4个参数,2参变4参
input = torch.reshape(input,(1,1,5,5))
kernel = torch.reshape(kernel,(1,1,3,3))
#输出形状
print(input.shape)
print(kernel.shape)
#输入到神经网络中进行输出
#stride=1每次移动一个路径
output = F.conv2d(input,kernel,stride=1)
print(output)
#stride=1每次移动两个路径
output = F.conv2d(input,kernel,stride=2)
print(output)
#使用padding参数,padding表示填充参数,填充图像的边缘部分
output = F.conv2d(input,kernel,stride=1,padding=1)
print(output)

填充的边缘部分

卷积层的通道数

CNN的卷积核通道数 = 卷积输入层的通道数;CNN的卷积输出层通道数 = 卷积核的个数


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

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


class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        # 二维卷积处理
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)

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


writer = SummaryWriter("conv_logs")
mymodule = MyModule()
step = 0
for data in dataloader:
    imgs, targets = data
    output = mymodule(imgs)
    # torch.Size([64, 3, 32, 32])
    print(imgs.shape)
    # torch.Size([64, 6, 30, 30]), 如果直接输出为RGB图像会出错,因为channel数不对(为6)
    print(output.shape)
    writer.add_images("input", imgs, step)

    # [64, 6, 30, 30]  -> [128, 3, 30, 30] 使用reshape()将输出的 6 通道转化为 3 通道
    #因为彩色图片如果显示只能是3通道,6通道会显示不出来无法识别,强制转换成3通道
    output = torch.reshape(output, (-1, 3, 30, 30))
    writer.add_images("output", output, step)

    step = step + 1

writer.close()

池化

最大池化的使用

1.理解池化

参数:

(stride的默认值是核的尺寸)

dilation 空洞卷积。如图

cell_mode可以选择Floor 和 Ceiling模式,默认为False(Floor)模式

计算方式

计算公式


import torch
from torch import nn
from torch.nn import MaxPool2d
#dtype=torch.float32 把数据修改成浮点类型的数据
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)
#注意修改数据类型,否则报错:"max_pool2d" not implemented for 'Long'
input = torch.reshape(input, (-1,1,5,5))

class XINYU(nn.Module):
    def __init__(self):
        super(XINYU, self).__init__()
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)
    def forward(self, input):
        output = self.maxpool1(input)
        return output
xinyu = XINYU()
output = xinyu(input)
print(output)

八、非线性激活

ReLU函数


import torch
from torch import nn
from torch.nn import ReLU

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

class XINYU(nn.Module):
    def __init__(self):
        super(XINYU, self).__init__()
        self.relu1 = ReLU() #inplace默认为False
        # 意思是不在原数据上改动
    def forward(self, input):
        output = self.relu1(input)
        return output

xinyu = XINYU()
output = xinyu(input)
print(output)

relu的作用小于1的全部被舍弃

对图像改变,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('dataset', train=False, download=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)
class ZYJ(nn.Module):
    def __init__(self):
        super(ZYJ, self).__init__()
        self.relu1 = ReLU() #inplace默认为False
        # 意思是不在原数据上改动
        self.sigmoid1 = Sigmoid()
    def forward(self, input):
        output = self.sigmoid1(input)
        return output
zyj = ZYJ()
writer = SummaryWriter("logs_sigmoid")
step = 0
for data in dataloader:
    imgs, target = data
    writer.add_images("input", imgs, global_step=step)
    output = zyj(imgs)
    writer.add_images("output", output, global_step=step)
    step = step + 1
writer.close()

九、线性层及其他层的介绍

1.正则化层——BatchNorm2d

2.Recurrent Layers

用得不多

3.Transformer Layers

用得不多

4.Linear Layers(重点)

下图为线性层,对应的in_feature = d, out_feature = L ,bias = True


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, transform=torchvision.transforms.ToTensor()
                                       , download=False)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)
class XINYU(nn.Module):
    def __init__(self):
        super(XINYU, self).__init__()
        self.linear1 = Linear(196608,10)

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

for data in dataloader:
    imgs, targets = data
    print(imgs.shape)
    output = torch.reshape(imgs, (1, 1, 1, -1))
    #上行代码可以用 output = torch.flatten(imgs)替代
    #效果一样,最后得到的数据维数不一样
    print(output.shape)
    output = xinyu(output)
    print(output.shape)

5.Dropout Layers

防止过拟合

6.Sparse Layers

自然语言处理使用得多

7.Distance Function

计算两个值的误差

8.Loss Function

首先输入3通道32x32,经过卷积变成32通道x32x32,然后池化变成32通道x16x16,然后以此类推


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


class XINYU(nn.Module):
    def __init__(self):
        super(XINYU, self).__init__()
        #Sequential把所有的自定义写的网络过程全都封装在Sequential当中
        # ,直接形成moudel然后调用model
        self.model = Sequential(
            #进入3通道,出去32通道,卷积核大小5,计算的padding等于2
            Conv2d(3, 32, 5, padding=2),
            #池化层的池化核大小为2
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            #把所有数据进行平铺
            Flatten(),
            #线性函数
            Linear(1024, 64),
            Linear(64, 10)

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

xinyu = XINYU()
input = torch.ones(64, 3, 32, 32)
output = XINYU(input)
print(output.shape)

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

损失函数和反向传播

损失函数的作用

1.计算实际输出和目标之间的差距

2.为我们更新输出提供一定的依据(反向传播)

L1Loss 和 MSELoss

此版本torch(1.12.0)对输入和目标shape无要求,均为(*)

但input.shape和target.shape要一致

输入和目标的数据要为浮点型


# torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean')
# L1Loss类对输入和目标shape无要求,都是(*)
import torch
from torch.nn import L1Loss
from torch import nn

# L1Loss要求输入数据是浮点形
inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)

loss = L1Loss() # 默认 reduction = “mean"
result = loss(inputs, targets) 
print(result)
# tensor(0.6667)
#算出的差值除以3


# torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')
# # MSELoss类对输入和目标shape无要求,都是(*)

# 平方差Loss
loss_mse = nn.MSELoss()
result2 = loss_mse(inputs, targets) 


print(result2)
# tensor(1.3333)


# 交叉熵Loss
input = torch.tensor([0.1, 0.2, 0.3])

CrossEntropyLoss

交叉熵Loss

适用于分类问题中

torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction=‘mean’, label_smoothing=0.0)

按照输入shape为 (N, C),目标shape为 (N)

其中C= number of classes ; N = batch size

举例


# 交叉熵Loss
# CrossEntropyLoss()
# 按照输入shape为(N, C),目标shape为(N)
# 其中N = number of classes  N = batch size
import torch
from torch import nn

input = torch.tensor([0.1, 0.2, 0.3])
target = torch.tensor([1])
loss_cross = nn.CrossEntropyLoss()
# 输入shape需要为(N, C)
input = torch.reshape(input, (1, 3))
result3 = loss_cross(input, target)
print(result3)

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, download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=1)

class MyModule(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.model1 = Sequential(
            Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10),
        )

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

myModule = MyModule()
# 交叉熵损失
loss = nn.CrossEntropyLoss()
for data in dataloader:
    imgs, targets = data
    outputs = myModule(imgs)
    # outputs --> tensor([[-0.1541, -0.0937, -0.0411,  0.0405,  0.0265, -0.0111,  0.0820, -0.1124,
    #           0.0817, -0.0898]], grad_fn=<AddmmBackward0>)
    # targets --> tensor([7])
    result_loss = loss(outputs, targets) # result_loss --> tensor(2.2170, grad_fn=<NllLossBackward0>)
    # 反向传播,计算节点梯度,根据梯度来优化网络参数,
    # 把每一个节点的梯度计算出来,这样之后使用优化器可以进行优化
    result_loss.backward()
    print(result_loss)

优化器

简单使用

优化器根据梯度对参数进行调整,降低损失

*torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False, , maximize=False, foreach=None)
参数params代表网络模型中的参数
参数lr = learining rate,学习速率。
lr不能太大,也不能太小,太大会造成模型训练起来不稳定,太小训练比较慢。
建议刚开始lr大一些,后面就小一些。
其余参数为算法SGD本身特有的,初学时可以直接使用默认即可。
使用三步走:
对每个节点对应的梯度清0。 optim.zero_grad()
反向传播,计算节点梯度。result_loss.backward()
根据节点中的梯度对参数进行调优。optim.step()


# torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False, *, maximize=False, foreach=None)
# 参数params代表网络模型中的参数
# 参数lr = learining rate,学习速率。
# lr不能太大,也不能太小,太大会造成模型训练起来不稳定,太小训练比较慢。
# 建议刚开始lr大一些,后面就小一些。
# 其余参数为算法SGD本身特有的,初学时可以直接使用默认即可。
import torch
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader

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

class MyModule(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.model1 = Sequential(
            Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10),
        )

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

myModule = MyModule()

# 损失函数
loss = nn.CrossEntropyLoss()
# 优化器
optim = torch.optim.SGD(myModule.parameters(), lr = 0.01)
for data in dataloader:
    imgs, targets = data
    outputs = myModule(imgs)
    result_loss = loss(outputs, targets)
    # 对每个节点对应的梯度清0,由于上一次的梯度对于本次的梯度更新是没有用处的。
    optim.zero_grad()
    # 反向传播,计算节点梯度
    result_loss.backward()
    # 根据节点中的梯度对参数进行调优
    optim.step()

3行之前的weight,grad不为none(非首次循环)

43行运行完毕,gard清零,data不变

45行运行完毕,grad被重新计算,data不变

47行运行完毕,grad不变,data更新(data就是模型中的参数)

epoch - 多轮训练(类似于多打几轮牌)

  • 单纯进行一轮训练,没有任何意义,需要进行多轮训练。

  • 损失看的是进行一轮训练损失的总和。


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

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

class MyModule(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.model1 = Sequential(
            Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(in_channels=32, out_channels=32, kernel_size=5, stride=1, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10),
        )

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

myModule = MyModule()

# 损失函数
loss = nn.CrossEntropyLoss()
# 优化器
optim = torch.optim.SGD(myModule.parameters(), lr = 0.01)

for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        imgs, targets = data
        outputs = myModule(imgs)
        result_loss = loss(outputs, targets)
        # 对每个节点对应的梯度清0,由于上一次的梯度对于本次的梯度更新是没有用处的。
        optim.zero_grad()
        # 反向传播,计算节点梯度
        result_loss.backward()
        # 根据节点中的梯度对参数进行调优
        optim.step()
        running_loss = running_loss + result_loss
    print(running_loss)

现有网络模型的改变和修改

1、参数pretrained 为false和true时的区别

vgg16_false = torchvision.models.vgg16(pretrained = False)

#False,下载的是网络模型,默认参数

vgg16_true = torchvision.models.vgg16(pretrained = True)

#True,下载的是网络模型,并且在数据集上面训练好的参数。

pretrained=False时,只是加载网络模型,把神经网络的代码加载了进来,其中的参数都是默认的参数,不需要下载。
pretrained=True时,它就要去从网络中下载,比如说卷积层对应的参数时多少,池化层对应的参数时多少等。这些参数都是在 ImageNet 数据集中训练好的。

torchvision-models

vgg16:

vgg16_f=torchvision.models.vgg16(pretrained=False)

vgg16_t=torchvision.models.vgg16(pretrained=True)

vgg16_t的weight:

vgg16_f的weight:

2、现有网络模型的使用与修改

如何利用现有的网络,改变网络的框架来符合我们的需求?

我们之前使用的数据集CIFAR10只分为10个类别

如果我们加载了vgg16模型,我们如何应用这个网络模型呢?

有两个方法:

(1)将 (6): Linear(in_features=4096, out_features=1000, bias=True)改为Linear(in_features=4096, out_features=10, bias=True)

(2)再加一个线性层 Linear(in_features=1000, out_features=10, bias=True)


import torchvision



# 利用现有的网络改动
from torch import nn

vgg16_false = torchvision.models.vgg16(pretrained=False)
vgg16_true = torchvision.models.vgg16(pretrained=True)
print(vgg16_true)

train_data = torchvision.datasets.CIFAR10('./dataset_ts', train=True, transform=torchvision.transforms.ToTensor(),download=True)

# 在vgg16的classifier下加一层模型,名叫add_linear,module名,in_feature=1000,out_feature=10
vgg16_true.add_module('add_linear', nn.Linear(1000, 10))
print(vgg16_true)

print(vgg16_false)
# 修改最后一行结构为out_feature=10
vgg16_false.classifier[6] = nn.Linear(4096, 10)
print(vgg16_false)

p26网络模型的保存与读取

保存:(以vgg16为例)


import torch
import torchvision
vgg16=torchvision.models.vgg16(pretrained=False)
#方式1(.pth不是必须的)
torch.save(vgg16,"vgg16.pth")
#方式2:将参数保存为字典格式(官方推荐)
torch.save(vgg16.state_dict(),"vgg16_2.pth")

读取:


import torch
import torchvision
vgg16=torchvision.models.vgg16(pretrained=False)
#方式一=》保存方式一(路径)
model=torch.load("vgg16.pth")
print(model)
#方式2=》字典格式
#注意方式2要printvgg16这个模型,不能model=xxx,print(model)
vgg16.load_state_dict(torch.load("vgg16_2.pth"))
print(vgg16)

注意,以方式一形式读取自定义模型时要先将该模型复制或引用到读取文件中,否则会报错

p27-29完整模型训练

载入模型、数据

加载数据

创建网络模型

初始化损失函数、优化器

设置训练网络的参数(训练、测试次数、轮数)

添加tensorboard(可视化)

for epoch:

for data in trainset:

分割数据,loss,清零,优化

for data in testset:

分割数据,计算准确度

展现每轮总loss,特定步数loss,保存模型

准确度计算思路:找出最大预测结果与target相同的图片数量,用其除以图片总数


import torch
import torchvision
#引入model模块,import * 表示引入model文件中的所有部分
from torch.utils.tensorboard import SummaryWriter

from model import *
from torch.utils.data import DataLoader


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

train_size=len(train_data)
test_size=len(test_data)
#格式化字符串的写法
print("size of train,test is:{},{}".format(train_size,test_size))

#利用dataloader加载
train_dataloader=DataLoader(train_data,64)
test_dataloader=DataLoader(test_data,64)

# 创建网络模型
wxy = WXY()
# 损失函数
loss_f = nn.CrossEntropyLoss()
# 优化器
# 1e-2=0.01
learning_rate = 1e-2
opt = torch.optim.SGD(wxy.parameters(), lr=learning_rate, )
# 设置训练网络的参数
# 记录训练次数
train_step = 0
# 测试次数
test_step = 0
# 训练轮数
epoch = 10
# 添加tensoeboard
writer = SummaryWriter("train_log")

for i in range(epoch):
    print("第{}轮训练开始".format(i + 1))
    # 训练步骤开始,开始取数据
    # 有时不必要:test1.train()
    for data in train_dataloader:
        imgs, target = data
        output = wxy(imgs)
        loss = loss_f(output, target)
        # 优化器优化模型
        #清零梯度
        opt.zero_grad()
        #反向传播计算梯度
        loss.backward()
        #优化梯度
        opt.step()
        #增加训练步骤
        train_step = train_step + 1
        # loss.item更加规范(.item不会打印数据类型,例如tensor(5))
        #按照数量去打印,每训练100次打印一次
        if train_step % 100 == 0:
            # loss.item()  item把数值变成数字
            print("训练次数{},loss值为{}".format(train_step, loss.item()))
            writer.add_scalar("train_loss", loss.item(), train_step)
    loss_total = 0
    # 测试步骤开始
    # 有时不必要:test1.eval()
    total_correct = 0
    #with表示的是后面的代码没有梯度,主要测试训练的模型是不是可以
    with torch.no_grad():
        for data in test_dataloader:
            imgs, t = data
            output = wxy(imgs)
            loss = loss_f(output, t)
            #求出测试集中总的loss
            loss_total = loss_total + loss.item()
            test_step = test_step + 1
            # argmax参数:1为横向比较,2为纵向比较,output为64,10的矩阵
            # output.argmax(1)==t是为了得到[Ture,False,True....]这种形式
            # .sum:T为1,F为0
            corect = (output.argmax(1) == t).sum()
            total_correct = total_correct + corect
            #计算准确率
            accuracy = total_correct / test_size
    print("测试集总loss{}".format(loss_total))
    writer.add_scalar("test_loss", loss_total, test_step)
    writer.add_scalar("accuracy", accuracy, test_step)

    torch.save(wxy, "test1{}.pth".format(i))
    print("模型已保存")

使用GPU训练模型

第一种方法:


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

from model import *

#准备数据集
train_data = torchvision.datasets.CIFAR10('data', train=True, transform=torchvision.transforms.ToTensor(), download=True)
test_data = torchvision.datasets.CIFAR10('data', train=False, transform=torchvision.transforms.ToTensor(), download=True)

#数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集长度:{}".format(train_data_size))
print("测试数据集长度:{}".format(test_data_size))

#加载数据集(Dataloader)
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

#创建网络模型
tudui = WXY()
if torch.cuda.is_available():#1、网络模型
    tudui = tudui.cuda()

#损失函数
loss_fn = nn.CrossEntropyLoss()
if torch.cuda.is_available():#2、损失函数
    loss_fn = loss_fn.cuda()

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

#参数
total_train_step = 0
total_test_step = 0
epoh = 10

#添加tensorbooard
writer = SummaryWriter("logs/trainlogs")

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

    #训练开始
    tudui.train()#模型状态
    for data in train_dataloader:
        imgs, targets = data
        if torch.cuda.is_available():#3、数据
            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():#3、数据
                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))
    total_test_step = total_test_step + 1
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy / test_data_size, total_test_step)

    torch.save(tudui, "model/tudui_{}.pth".format(i))

writer.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch是一个用于深度学习的开源框架,它提供了一组工具和接口,使得我们可以轻松地进行模型训练、预测和部署。在PyTorch中,数据处理是深度学习应用的重要部分之一。 PyTorch中的数据处理主要涉及以下几个方面: 1.数据预处理:包括数据清洗、数据归一化、数据增强等操作,以提高模型的鲁棒性和泛化能力。 2.数据加载:PyTorch提供了多种数据加载方式,包括内置的数据集、自定义的数据集和数据加载器等,以便我们更好地管理和使用数据。 3.数据可视化:为了更好地理解数据和模型,PyTorch提供了多种数据可视化工具,如Matplotlib、TensorBoard等。 下面是一个简单的数据预处理示例,展示如何将图像进行归一化和数据增强: ```python import torch import torchvision.transforms as transforms from torchvision.datasets import CIFAR10 # 定义一个数据预处理管道 transform_train = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize(mean=[0.4914, 0.4822, 0.4465], std=[0.2023, 0.1994, 0.2010]) ]) # 加载CIFAR10数据集,进行预处理 trainset = CIFAR10(root='./data', train=True, download=True, transform=transform_train) trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) ``` 在上面的例子中,我们首先定义了一个数据预处理管道,其中包括了对图像进行随机裁剪、水平翻转、归一化等操作。然后,我们使用PyTorch内置的CIFAR10数据集,并将其预处理后,使用DataLoader进行批量加载。这个过程可以帮助我们更好地管理和使用数据,同时提高模型的训练效率和泛化能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值