第二讲Pytorch使用
Posted bolunwei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二讲Pytorch使用相关的知识,希望对你有一定的参考价值。
PyTorch入门
首先要安装好Anaconda(以前就已经安装好,所以在这里不多加赘述)
有序的管理环境
在很多项目中,需要使用不用版本的环境,比如这个项目需要使用pytorch0.4,另一个项目需要用到pytorch1.0,如果卸载了0.4版本,转而安装了1.0版本。那么下一次再需要用到0.4版本,就还得卸载1.0版本。而Anaconda集成的conda包就能够解决这个问题,它可以创造出两个屋子,相互隔离,一个屋子放0.4版本,另一个屋子放1.0版本,需要使用哪个屋子,就进哪个屋子工作。
首先使用conda指令创建一个屋子,叫做pytorch,指令如下:
conda create -n pytorch python=3.9
conda是指使用conda包,create是创建的意思,-n是指后面的名字是屋子的名字,pytorch是屋子的名字(可以更改成自己喜欢的),python=3.9是指创建的屋子是python3.9版本的。
01.安装PyTorch
(1)进入官网https://pytorch.org/并在首页向下找到如下页面进行选择
- 第一行推荐选择稳定版本
- 第二行根据系统性进行选择
- 第三行windows系统选择conda并且要有anaconda,linux系统选择pip
- 第四行根据自己情况选择,我使用的是python3.9版本
- 第五行要先知道自己是GPU还是集显或者没有显卡,我这里是3060所以选择第一个,如果是集显或者没有显卡,要选择cpu
- 前面五行选择的结果给出第六行的安装指令,将其复制
(2)打开anaconda的命令提示行前面已经创建了pytorch的环境,在此处输入conda activate pytorch再把上面的第六行的命令粘贴进来,这里11.6版本安装失败,我又改成了11.7版本
(3)检验版本是否安装成功,先输入python之后再输入import torch,如果没有报错则证明,已经安装成功
(4)下载好pytorch之后,在pycharm官网下载ppycharm编译器并导入pytorch环境,在python console中输入import torch若什么都不显示再输入torch.cuda.is_available()若显示True则环境配置成功
(5)在pytorch环境中安装jupyter
先在anaconda的小黑框里面输入conda activate pytorch,之后再安装一个包输入conda install nb_conda,python3.9版本的使用conda install nb_conda_kernels命令符。安装完成之后输入jupyter notebook,后打开网页版的jupyter
再输入import torch,按住shift+enter则跳转到下一个代码块,运行了代码块前面会有数字,再输入torch.cuda.is_available()
在运行jupyter的时候不要关闭anaconda的小黑框,否则会断开链接
02.python学习中的两大法宝函数
dir( ):打开看见内部有什么
help( ):说明书
比如要打开pytorch工具箱里面有什么就是:
-
dir(pytorch)==>会输出函数1、函数2、函数3、函数4
-
继续探索函数里面有什么就是dir(pytorch.函数3)==>会输出a、b、c
-
之后想要查看道具如何使用则可以使用help(pytorch.函数3.a)==>会输出想要查看的内容的使用方法
03.pytorch加载数据
pytorch里面涉及到如何读取数据一般涉及到两个类Dataset和Dataloader
假设数据是一堆垃圾,我们需要在其中提取到有用的数据,也就是加入我们需要的都是可回收垃圾这一类,我们就需要把可回收垃圾这一大类别全都提取出来。其中在对数据处理的过程中:
Dataset是提供一种方式去获取数据及其label
- 如何获取每一个数据及其label
- 告诉我们总共有多少数据
Dataloader是为后面的网络提供不同的数据格式
03.Transforms的用法
tensor的数据类型
通过transforms.ToTensor去看两个问题
- transforms该如何使用(python)
- Tensor数据类型相较于普通的数据类型有什么区别,为什么需要使用Tensor的数据类型
官方给出的Transforms的源代码中,关于ToTensor的函数解释是,将一个PIL或者numpy类型的图片转化成Tensor类型的函数
transforms该如何使用(python)
可以简单理解为,transforms是一个工具箱,我们根据这个工具箱打造一个属于自己的工具(类的实例化),再用这个自己的工具来把输入的图片进行加工,之后再得出我们想要的结果
常见的Transforms
import cv2
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("../logs")
img_path = "../data/images/ali.jpg"
img = Image.open(img_path)
print(img)
# ToTensor的使用
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("ToTensor",img_tensor)
# Normalize的使用
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([1,1.5,2],[5,5,3])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalsize",img_norm,1)
# Resize的使用
print(img.size)
trans_resize = transforms.Resize((512,512))
img_resize = trans_resize(img)
print(img_resize )
img_resize_totensor = trans_totensor(img_resize)
writer.add_image("ReSize",img_resize_totensor,0)
# Compose--resize的用法
# 不改变长和宽的大小关系,进行等比缩放
trans_resize_2 = transforms.Resize(512)
# transforms.Compose的两个参数,第一个是改变图片的大小,第二个是转换图片类型为tensor类型
# 如果调换位置,也就是先转换成tensor类型之后再传入resize会发现参数类型不匹配,resize需要传入img类型,所以前一个函数的和第二个函数数之间的参数传递需要对应
trans_compose = transforms.Compose([trans_resize_2,trans_totensor])
img_resize_2 = trans_compose(img)
writer.add_image("ReSize",img_resize_2,1)
# RandomCrop
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()
04.torchvision中数据集的使用
在pytorch的官网上https://pytorch.org/的Docs有torchvision的介绍,介绍了关于pytorch提供的数据集的API文档,新版的pytorch在左上角的Search Docs选择0.9.0版本即可
我们选择CIFAR的数据集进行试验,其中有50000张训练图片和10000张测试图片,常见的dataset的使用如下
import torchvision
train_set = torchvision.datasets.CIFAR10(root="./dataset",train=True,download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,download=True)
print(test_set[0])
print(test_set.classes)
img,target = test_set[0]
print(img)
print(target)
print(test_set.classes[target])
img.show()
如果要进行pytorch进行使用,则应该用transforms进行转化成tensor数据类型
import torchvision
from torch.utils.tensorboard import SummaryWriter
dataset_transform = torchvision.transforms.Compose([
# 先进行数据类型的转化
torchvision.transforms.ToTensor()
# 再对图片进行一下裁剪,但是原始数据集中图片较小,这里就放弃进行裁剪
])
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])
# 之后可以再用tensorboard进行一下显示
writer = SummaryWriter("p10")
for i in range(10):
img,target = test_set[i]
writer.add_image("dataset",img,i)
writer.close()
之后再打开下方的Ter\'minal输入tensorboard --logdir="p10(此文件夹的相对路径)"
05.DataLoader的使用
前面用到的dataset可以理解为作用是告诉程序,我们所用到的数据集是在什么位置,dataloader可以理解为一个加载器,可以把数据加载到神经网络当中,dataloader每次是从dataset之中取数据,每次取多少数据和每次怎么取数据决定权再dataloader的参数之中——
在官网中找到关于dataloader的使用方法,其中参数,batch_size表示的是要抓取的数据大小。shuffle表示两次抓取过程中数据的顺序是否有被打乱,如果是true就是两次顺序不一样,如果是false就是两次没被打乱。num_workers 表示加载数据时使用的是单进程还是多进程进行加载,默认情况是0,0表示采用主进程进行加载(num_worker再windows上使用大于0时总是会出错,要注意!!)。drop_last表示当取数据取不尽时,剩下的数据是舍去还是继续取走
import torchvision
from torch.utils.data import DataLoader
# 准备测试数据集
from torch.utils.tensorboard import SummaryWriter
test_data = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor())
test_loader = DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0,drop_last=False)
# 测试数据集中的第一张图片级target
img,target = test_data[0]
print(img.shape)
print(target)
writer = SummaryWriter("dataloader")
step = 0
for data in test_loader:
imgs,targets = data
# print(imgs.shape)
# print(targets)
# 由于是多个图片,所以使用的是add_images而不是image
writer.add_images("dataloader_data",imgs,step)
step += 1
writer.close()
生成文件用tensorboard打开时可能会出错
此时问题可能是端口被占用导致的,将默认的6006端口改成8008或者其他端口即可
tensorboard --logdir=learn/dataloader --host=127.0.0.1 --port=8008
06.神经网络的基本骨架-nn.Module的使用
在pytorch的官网给出的Docs找到torch.nn的文档,其中containers直译是容器,在这里是给神经网络定义了一些骨架和结构,只需要往这些结构之中添加一些不同的内容,就可以组成神经网络。后面的一些就是往这个骨架中填充的一些东西,convolution layers(卷积层),pooling layers(池化层),Non-linear Activations (weighted sum, nonlinearity)(非线性激活),Normalization Layers(智能化层)等等,这些共同组成神经网络中的核心操作部分
在containers中一共有六个模块,其中Module模块是我们最常用的模块,它用来给所有的神经网络提供一个基本的骨架。我们搭建的神经网络,都必须从这个类之中进行继承
import torch
from torch import nn
class Nn_module(nn.module):
def __int__(self):
super().__init__()
def forward(self,input):
output = input + 1
return output
nn_module = Nn_module()
x = torch.tensor(1.0)
output = nn_module(x)
print(output)
07.卷积操作
在pytorch官网的Docs中,torch.nn的convolution layers(卷积层)中一些很重要的内容,其中最重要的是nn.Conv1d和nn.Conv2d,分别表示一维和二维。对于卷积的原理,参考另一篇笔记https://www.cnblogs.com/bolunwei/p/17119617.html
神经网络需要设置的参数介绍。其中需要输入的函数input需要四个参数,普通的矩阵的shape只有两个参数,此时就需要pytorch给提供的一个尺寸变换函数,reshape
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]])
# 尺寸只有矩阵的高和宽,但是输入到神经网络中的要求是尺寸需要有四个参数
# 采用reshape函数进行改变尺寸
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)
output1 = F.conv2d(input,kernel,stride=2)
print(output1)
output2 = F.conv2d(input,kernel,stride=1,padding=1)
print(output2)
当参数中stride是1的时候移动的时候就会移动一个步径,所以输出的是3*3的矩阵,如果stride是2的时候,那么输出的矩阵就会是一个2*2的矩阵
还有一个重要的参数是padding,它可以决定是否可以在矩阵的周边进行填充,填充的内容可以进行设置
08.神经网络-卷积层
conv2d参数介绍
- in_channels:输入图片的通道数,一般彩色图片的通道数是3个
- out_channels:通过卷积之后产生的输出通道数是多少
- kernel_size:可以是个数,也可以是元组,表示卷积核的一个大小
- stride:表示卷积核在卷积过程中横向和纵向的步幅的大小
- padding:表示在卷积过程中,是否需要在卷积图像的边缘进行填充
- padding_mode:控制padding以一个什么样的方式进行填充,一般是zeros,把填充的内容都设为0
- dilation:定义在卷积过程中核之间的距离
- groups:一般设置成1
- bias:一般设置为true,设置一个偏置
https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md为不同参数设置的图像演示
out_channels是2的时候,可能会有两个不同的卷积核对一个in_channels是1的图像进行卷积,能得到两个输出,这样out_channels的值就是2
对图像进行卷积并显示在tensorboard上面
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
dataset = torchvision.datasets.CIFAR10(root="./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset,batch_size=64)
class Nnmodule(nn.Module):
def __init__(self):
super(Nnmodule, self).__init__()
self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)
def forward(self,x):
x = self.conv1(x)
return x
nnmodule = Nnmodule()
print(nnmodule)
writer = SummaryWriter("conv2d")
step = 0
for data in dataloader:
imgs,targets = data
output = nnmodule(imgs)
print(imgs.shape)
print(output.shape)
# 输入大小 torch.Size([64, 3, 32, 32])
writer.add_images("input",imgs,step)
# 输出大小 torch.Size([64, 6, 30, 30])
# add_images不能显示6个out_channels的图片,所以可以用reshape改变一下
# 第一个参数不知道是多少的时候,先写-1,这样会根据后面参数再进行计算
output = torch.reshape(output,(-1,3,30,30))
writer.add_images("output",output,step)
step += 1
writer.close()
经典模型vgg16
以上是关于第二讲Pytorch使用的主要内容,如果未能解决你的问题,请参考以下文章