首页 > 其他分享 >pytorch

pytorch

时间:2024-04-22 18:11:06浏览次数:24  
标签:None nn self torch 张量 pytorch grad

pytorch

pytorch基础

Tensor(张量)

pytorch中最基本的操作对象,表示的是一个多维的矩阵

pytorch可以在GPU上运行,numpy的ndarry只能在CPU上运行

Tensor数据类型:

32位浮点型: torch.FloatTensor

64位浮点型:torch.DoubleTensor

16位整形:torch.ShoutTensor

32位整形:torch.IntTensor

64位整形:torch.LongTensor

定义一个三行两列矩阵:

a = torch.Tensor([2,3][4,5][6,7])

torch.Tensor默认为torch.FloatTensor

Variable(变量)

Variable Tensor 本质上没有区别,不过 Variable 会被放入个计算图中,然后进行前向传播,反向传播,自动求导

Variable 是在 torch.autograd.Variable 中

Variable有三个较重要的组成属性:
data 取出Variable中的tensor数值

grad 这个Variable传播梯度

grad_fn 表示得到这个Variable的操作,比如通过加减还是乘除来得到的

dataset(数据集)

定义数据类

from torch.utils.data import Dataset
import os
from PIL import Image
class my_dateset(Dataset):
    def __init__(self,root_dir,label_dir):
        self.root_dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(self.root_dir,self.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)

pytorch提供torch.utils.data.DataLoader 来定义一个新的迭代器

dataiter = DataLoader(my_dataset, batch_size=32, shuffle=True, collate_fn=default_collate)

collate_fn 是表示如何取样本的

torchvision中有一个关于计算机视觉的数据读取类ImageFolder主要功能是处理图片,且要求图片是下面这种存放形式

root/dog/xxx.png

root/dog/xxy.png

root/dog/xxz.png

root/cat/123.png

root/cat/asd.png

root/cat/zxc.png

之后这样来调用这个类:

dset = ImageFolder(root='root_path', transform=None, loader=default_loader) 

nn.Module (模组)

PyTorch 里面编写神经网络,所有的层结构和损失函数都来自于 torch.nn

class net_name(nn.Module):
	def __init__(self, other_argi ments):
		super(net_name, self) .__init__
		self.convl = nn .Conv2d(in channels, out channels, kernel size) 
		# other network layer 
	def forward(self, x) : 
		x = self. convl (x) 
		return x

相当于建立了一个计算图,并且这个结构可以复用多次,每次调用就相当于用该计算图定义的相同参数做一次前向传播

torch.optim (优化)

一阶优化算法

![](C:\Users\wyx\Pictures\Screenshots\屏幕截图 2024-04-18 155241.png)

最常用的一阶优化算法是梯度下降

二阶优化算法

二阶优化算法使用了二阶导数( 也叫做 Hessian 方法)来最小化或最大化损失函数

模型的保存与加载

PyTorch 里面使用 torch.save 来保存模型的结构和参数,有两种保存方式:

(1)保存整个模型的结构信息和参数信息,保存的对象是模型 model;

(2)保存模型的参数,保存的对象是模型的状态 model.state diet ()

可以这样保存, save 的第一个参数是保存对象,第二个参数是保存路径及名称:

torch.save(model ,’./model.pth ’) 

torch.save(model.state_dict(), './model_state . pth ’) 

加载模型有两种方式对应于保存模型的方式:

(1)加载完整的模型结构和参数信息,使用

load model = torch.load (’ model. pth ')

在网络较大的时候加载的时间比较长,同时存储空间也比较大;

(2)加载模型参数信息,需要先导人模型的结构,然后通过

model.load_state_die (torch.load( 'model_state pth '))来导人

pytorch核心模块

Tensor

张量表示的是一个多维数组,它是标量、向量、矩阵的拓展.标量是零维张量,向量是一维张量,矩阵是二维张量,一个RGB图像数组就是一个三维张量,第一维是图像高,第二维是图像的宽,第三维是图像颜色通道

张量相关函数

张量的创建

直接创建

torch.tensor(data, dtype=None, device=None, requires_grad=False, pin_memory=False)
  • data(array_like) - tensor的初始数据,可以是list, tuple, numpy array, scalar或其他类型。
  • dtype(torch.dtype, optional) - tensor的数据类型,如torch.uint8, torch.float, torch.long等
  • device (torch.device, optional) – 决定tensor位于cpu还是gpu。如果为None,将会采用默认值,默认值在torch.set_default_tensor_type()中设置,默认为 cpu。
  • requires_grad (bool, optional) – 决定是否需要计算梯度。
  • pin_memory (bool, optional) – 是否将tensor存于锁页内存。这与内存的存在方式有关,通常为False。
torch.from_numpy()

通过numpy创建tensor,改变array中的值,tensor的值也会改变

依据数值创建

torch.zeros(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

依给定的size创建一个全0的tensor,默认数据类型为torch.float32(也称为torch.float)

layout(torch.layout, optional) - 参数表明张量在内存中采用何种布局方式。常用的有torch.strided, torch.sparse_coo等。

out(tensor, optional) - 输出的tensor,即该函数返回的tensor可以通过out进行赋值

torch.zeros_like(input, dtype=None, layout=None, device=None, requires_grad=False)

依input的size创建全0的tensor。

input(Tensor) - 创建的tensor与intput具有相同的形状。

依据概率分布创建

torch.normal(mean, std, out=None)

为每一个元素以给定的mean和std用高斯分布生成随机数

mean (Tensor or Float) - 高斯分布的均值,

std (Tensor or Float) - 高斯分布的标准差

torch.rand(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

在区间[0, 1)上,生成均匀分布

size (int...) - 创建的张量的形状

张量的操作
cat 将多个张量拼接在一起,例如多个特征图的融合可用。
concat 同cat, 是cat()的别名。
conj 返回共轭复数。
chunk 将tensor在某个维度上分成n份。
dsplit 类似numpy.dsplit()., 将张量按索引或指定的份数进行切分。
column_stack 水平堆叠张量。即第二个维度上增加,等同于torch.hstack。
dstack 沿第三个轴进行逐像素(depthwise)拼接。
gather 高级索引方法,目标检测中常用于索引bbox。在指定的轴上,根据给定的index进行索引。强烈推荐看example。
hsplit 类似numpy.hsplit(),将张量按列进行切分。若传入整数,则按等分划分。若传入list,则按list中元素进行索引。例如:[2, 3] and dim=0 would result in the tensors input[:2], input[2:3], and input[3:].
hstack 水平堆叠张量。即第二个维度上增加,等同于torch.column_stack。
index_select 在指定的维度上,按索引进行选择数据,然后拼接成新张量。可知道,新张量的指定维度上长度是index的长度。
masked_select 根据mask(0/1, False/True 形式的mask)索引数据,返回1-D张量。
movedim 移动轴。如0,1轴交换:torch.movedim(t, 1, 0) .
moveaxis 同movedim。Alias for torch.movedim().(这里发现pytorch很多地方会将dim和axis混用,概念都是一样的。)
narrow 变窄的张量?从功能看还是索引。在指定轴上,设置起始和长度进行索引。例如:torch.narrow(x, 0, 0, 2), 从第0个轴上的第0元素开始,索引2个元素。x[0:0+2, ...]
nonzero 返回非零元素的index。torch.nonzero(torch.tensor([1, 1, 1, 0, 1])) 返回tensor([[ 0], [ 1], [ 2], [ 4]])。建议看example,一看就明白,尤其是对角线矩阵的那个例子,太清晰了。
permute 交换轴。
reshape 变换形状。
row_stack 按行堆叠张量。即第一个维度上增加,等同于torch.vstack。Alias of torch.vstack().
scatter scatter_(dim, index, src, reduce=None) → Tensor。将src中数据根据index中的索引按照dim的方向填进input中。这是一个十分难理解的函数,其中index是告诉你哪些位置需要变,src是告诉你要变的值是什么。这个就必须配合例子讲解,请跳转到本节底部进行学习。
scatter_add 同scatter一样,对input进行元素修改,这里是 +=, 而scatter是直接替换。
split 按给定的大小切分出多个张量。例如:torch.split(a, [1,4]); torch.split(a, 2)
squeeze 移除张量为1的轴。如t.shape=[1, 3, 224, 224]. t.squeeze().shape -> [3, 224, 224]
stack 在新的轴上拼接张量。与hstack\vstack不同,它是新增一个轴。默认从第0个轴插入新轴。
swapaxes Alias for torch.transpose().交换轴。
swapdims Alias for torch.transpose().交换轴。
t 转置。
take 取张量中的某些元素,返回的是1D张量。torch.take(src, torch.tensor([0, 2, 5]))表示取第0,2,5个元素。
take_along_dim 取张量中的某些元素,返回的张量与index维度保持一致。可搭配torch.argmax(t)和torch.argsort使用,用于对最大概率所在位置取值,或进行排序,详见官方文档的example。
tensor_split 切分张量,核心看indices_or_sections变量如何设置。
tile 将张量重复X遍,X遍表示可按多个维度进行重复。例如:torch.tile(y, (2, 2))
transpose 交换轴。
unbind 移除张量的某个轴,并返回一串张量。如[[1], [2], [3]] --> [1], [2], [3] 。把行这个轴拆了。
unsqueeze 增加一个轴,常用于匹配数据维度。
vsplit 垂直切分。
vstack 垂直堆叠。
where 根据一个是非条件,选择x的元素还是y的元素,拼接成新张量。看案例可瞬间明白。
张量的随机种子
seed 获取一个随机的随机种子。Returns a 64 bit number used to seed the RNG.
manual_seed 手动设置随机种子
initial_seed 返回初始种子。
get_rng_state 获取随机数生成器状态。Returns the random number generator state as a torch.ByteTensor.
set_rng_state 设定随机数生成器状态。这两怎么用暂时未知。Sets the random number generator state.

随机种子主要用于对实验的复现

张量的数学操作
  • Pointwise Ops: 逐元素的操作,如abs, cos, sin, floor, floor_divide, pow等
  • Reduction Ops: 减少元素的操作,如argmax, argmin, all, any, mean, norm, var等
  • Comparison Ops:对比操作, 如ge, gt, le, lt, eq, argsort, isnan, topk,
  • Spectral Ops: 谱操作,如短时傅里叶变换等各类信号处理的函数。
  • Other Operations:其它, clone, diag,flip等
  • BLAS and LAPACK Operations:BLAS(Basic Linear Algebra Subprograms)基础线性代数)操作。如, addmm, dot, inner, svd等。

计算图--自动求导核心

计算图由节点和边构成

节点表示数据,如标量,向量,矩阵,张量等;

表示运算,如加、减、乘、除、卷积、relu等;

![](C:\Users\wyx\Desktop\pytorch\屏幕截图 2024-04-19 161906.png)

叶子节点

叶子结点是最基础的结点,其数据不是由运算生成的,因此是整个计算图的基石,是不可轻易”修改“的

张量有一个属性是is_leaf, 就是用来指示一个张量是否为叶子结点的属性

import torch

w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)

a = torch.add(w, x)
b = torch.add(w, 1)     # retain_grad()
y = torch.mul(a, b)

y.backward()
print(w.grad)

# 查看叶子结点
print("is_leaf:\n", w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)
# 查看梯度
print("gradient:\n", w.grad, x.grad, a.grad, b.grad, y.grad)
# 查看 grad_fn
print("grad_fn:\n", w.grad_fn, x.grad_fn, a.grad_fn, b.grad_fn, y.grad_fn)
#

只有叶子节点的梯度得到保留,中间变量的梯度默认不保留;在pytorch中,非叶子结点的梯度在反向传播结束之后就会被释放掉,如果需要保留的话可以对该结点设置retain_grad()

grad_fn是用来记录创建张量时所用到的运算,在链式求导法则中会使用到。

自动微分--Autograd

  • 自动求导机制通过有向无环图(directed acyclic graph ,DAG)实现
  • 在DAG中,记录数据(对应tensor.data)以及操作(对应tensor.grad_fn
  • 操作在pytorch中统称为Function,如加法、减法、乘法、ReLU、conv、Pooling等,统统是Function

autograd的使用

torch.autograd.backward

使用频率最高的自动求导函数

torch.autograd.backward(tensors,grad_tensors=None,retain_graph=None,create_graph=False, 						grad_variables=None, inputs=None)
  • tensors (Sequence[Tensor] or Tensor) – 用于求导的张量。如上例的loss。
  • grad_tensors (Sequence[Tensor or None] or Tensor, optional) – 雅克比向量积中使用
  • retain_graph (bool, optional) – 是否需要保留计算图。pytorch的机制是在方向传播结束时,计算图释放以节省内存。连续使用loss.backward(),就会报错。如果需要多次求导,则在执行backward()时,retain_graph=True。
  • create_graph (bool, optional) – 是否创建计算图,用于高阶求导

使用时可直接调用.backward()函数

torch.autograd.grad
torch.autograd.grad(outputs, inputs, grad_outputs=None, retain_graph=None, create_graph=False, only_inputs=True, allow_unused=False)

功能:计算outputs对inputs的导数

主要参数:

  • outputs (sequence of Tensor) – 用于求导的张量,如loss
  • inputs (sequence of Tensor) – 所要计算导数的张量
  • grad_outputs (sequence of Tensor) – 雅克比向量积中使用。
  • retain_graph (bool, optional) – 是否需要保留计算图。
  • create_graph (bool, optional) – 是否创建计算图,用于高阶求导。
  • allow_unused (bool, optional) – 是否需要指示,计算梯度时未使用的张量是错误的。

例:

import torch
x = torch.tensor([3.], requires_grad=True)
y = torch.pow(x, 2)     # y = x**2

# 一阶导数
grad_1 = torch.autograd.grad(y, x, create_graph=True)   # grad_1 = dy/dx = 2x = 2 * 3 = 6
print(grad_1)
# 二阶导数
grad_2 = torch.autograd.grad(grad_1[0], x)              # grad_2 = d(dy/dx)/dx = d(2x)/dx = 2
print(grad_2)
torch.autograd.Function

想要实现自己的一些操作时,如特殊的数学函数、pytorch的module中没有的网络层,那就需要自己写一个Function

pytorch数据模块

Dataset

torch.utils.data.Dataset,供用户继承编写dataset

例:

from torch.utils.data import Dataset
import os
from PIL import Image
class my_dateset(Dataset):
    def __init__(self,root_dir,label_dir):
        self.root_dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(self.root_dir,self.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)
  • getitem:需要实现读取一个样本的功能。通常是传入索引(index,可以是序号或key),然后实现从磁盘中读取数据,并进行预处理(包括online的数据增强),然后返回一个样本的数据。数据可以是包括模型需要的输入、标签,也可以是其他元信息,例如图片的路径。getitem返回的数据会在dataloader中组装成一个batch。即,通常情况下是在dataloader中调用Dataset的getitem函数获取一个样本。
  • len:返回数据集的大小。如果这个函数返回的是0,dataloader会报错:"ValueError: num_samples should be a positive integer value, but got num_samples=0"

DataLoader

torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None, batch_sampler=None, num_workers=0, collate_fn=None, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None, multiprocessing_context=None, generator=None, *, prefetch_factor=2, persistent_workers=False)
  • dataset:一个Dataset实例,要能实现从索引(indices/keys)到样本的映射。(即getitem函数)
  • batch_size:每个batch的样本量
  • shuffle:是否对打乱样本顺序。训练集通常要打乱它!验证集和测试集无所谓。
  • sampler:设置采样策略。
  • batch_sampler:设置采样策略, batch_sampler与sampler二选一
  • num_workers: 设置多少个子进程进行数据加载(data loading)
  • collate_fn:组装数据的规则, 决定如何将一批数据组装起来。
  • pin_memory:是否使用锁页内存,具体行为是“the data loader will copy Tensors into CUDA pinned memory before returning them”
  • drop_last:每个epoch是否放弃最后一批不足batchsize大小的数据,即无法被batchsize整除时,最后会有一小批数据,是否进行训练,如果数据量足够多,通常设置为True。

Dataset及常用API

concat

在实际项目中,数据的来源往往是多源的,很难统一到一个数据格式.一种灵活的方式是每批数据编写一个Dataset,然后使用torch.utils.data.ConcatDataset类将他们拼接起来,这种方法可以灵活的处理多源数据,也可以很好的使用别人的数据及Dataset

Subset

subset可根据指定的索引获取子数据集,Subset也是Dataset类

    def __init__(self, dataset: Dataset[T_co], indices: Sequence[int]) -> None:
        self.dataset = dataset
        self.indices = indices

    def __getitem__(self, idx):
        if isinstance(idx, list):
            return self.dataset[[self.indices[i] for i in idx]]
        return self.dataset[self.indices[idx]]

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

random_aplit

该函数的功能是随机的将dataset划分为多个不重叠的子集,适合用来划分训练、验证集

torch.utils.data.random_split(dataset, lengths, generator=None)

只需要设置每个子集的数据量,传给lengths即可

sampler

sampler是在dataloader中起到挑选数据的功能,主要是设置挑选策略,如按顺序挑选、随机挑选、按类别分概率挑选等

sampler 与 batch_sampler

本质上两者都是采样器,当采用auto_collation时,采用batch_sampler

batch_sampler是一次返回一个batch的索引。通常我们用的都是batch_sampler,其对应的是BatchSampler类

BatchSampler
torch.utils.data.BatchSampler(sampler, batch_size, drop_last)

第一个参数传入的是一个sampler采样器,在这里会有两种情况,如果需要shuffle,则传入RandomSampler,不需要打乱,则传入SequentialSampler

BatchSampler是在其它两者之上封装了一个批抽取的功能,一次yield一个batch的index,而样本采样的顺序取决于RandomSampler和SequentialSample。

SequentialSampler

顺序迭代器,按顺序的迭代器

RandomSamoler

默认情况下会使用这行代码实现:yield from torch.randperm(n, generator=generator).tolist(), 利用torch的随机方法生成一个随机整数序列,对于generator默认采用的是随机一个随机种子进行设置

SubsetRandomSampler

通过索引定义一个自己的随机采样器

这个采样器返回的样本总数是传入的索引的长度

def __iter__(self) -> Iterator[int]:
	for i in torch.randperm(len(self.indices), generator=self.generator):
		yield self.indices[i]
WeightedRandomSampler
torch.utils.data.WeightedRandomSampler(weights, num_samples, replacement=True, generator=None)
  • weights (sequence) – 每个样本的采样权重,权重之和不必为1,只需要关心各样本之间的比例即可。
  • num_samples (int) – 采样数量,一般设为样本总量。
  • replacement (bool) –是否有放回采样。 True,表示有放回。
  • generator (Generator) – 自定义生成器,通常用默认的

transforms

pytorch的图像数据增强函数库

变换方法

Compose

用于包装一系列transforms方法

例:

dataset_transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
Resize

支持对PIL或Tensor对象的缩放

Resize(size, interpolation=, max_size=None, antialias=None)
Totensor

将PIL对象或nd.array对象转换成tensor,并且对数值缩放到[0, 1]之间,并且对通道进行右移

Normalize

对tensor对象进行逐通道的标准化,具体操作为减均值再除以标准差

Normalize(mean, std, inplace=False)
transforms.Pad

对图像进行填充

torchvision.transforms.Pad(padding, fill=0, padding_mode='constant')
transforms.Grayscale

将图片转为灰度图

torchvision.transforms.Grayscale(num_output_channels=1)
PILImage:transforms.ToPILImage
torchvision.transforms.ToPILImage(mode=None)

将 tensor 或者 ndarray 的数据转换为 PIL Image 类型数据

mode- 为None时为 1 通道, mode=3 通道默认转换为 RGB,4 通道默认转换为 RGBA

裁剪方法

随机裁剪:transforms.RandomCrop

依据给定的 size 随机裁剪

torchvision.transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0,
padding_mode='constant')

中心裁剪:transforms.CenterCrop

torchvision.transforms.CenterCrop(size)

依据给定的 size 从中心裁剪

随机长宽比裁剪:transforms.RandomResizedCrop

torchvision.transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.33333
33333333333), interpolation=2)

机大小,随机长宽比裁剪原始图片,最后将图片 resize 到设定好的 size

size- 输出的分辨率

scale- 随机 crop 的大小区间,如 scale=(0.08, 1.0),表示随机 crop 出来的图片会在的 0.08

倍至 1 倍之间。

ratio- 随机长宽比设置

interpolation- 插值的方法,默认为双线性插值(PIL.Image.BILINEAR)

上下左右中心裁剪transforms.FiveCrop

torchvision.transforms.FiveCrop(size)

功能:对图片进行上下左右以及中心裁剪,获得 5 张图片,返回一个 4D-tensor

上下左右中心裁剪后翻转: transforms.TenCrop

torchvision.transforms.TenCrop(size,vertical_flip=False)

功能:对图片进行上下左右以及中心裁剪,然后全部翻转(水平或者垂直),获得 10 张图

片,返回一个 4D-tensor。

vertical_flip (bool) - 是否垂直翻转,默认为 flase,即默认为水平翻转

翻转和旋转

依概率 p 水平翻转 transforms.RandomHorizontalFlip

torchvision.transforms.RandomHorizontalFlip(p=0.5)

功能:依据概率 p 对 PIL 图片进行水平翻转

p- 概率,默认值为 0.5

垂直翻转 transforms.RandomVerticalFlip

torchvision.transforms.RandomVerticalFlip(p=0.5)

功能:依据概率 p 对 PIL 图片进行垂直翻转

p- 概率,默认值为 0.5

随机旋转transforms.RandomRotation

torchvision.transforms.RandomRotation(degrees,resample=False,expand=False,center=None)

功能:依 degrees 随机旋转一定角度

degress- (sequence or float or int) ,若为单个数,如 30,则表示在(-30,+30)之间随机旋

resample- 重采样方法选择,可选PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC,默认为False

expand-用于指定是否扩展图像以适应旋转后的图像。如果设置为 True,则会扩展图像的边界以容纳整个旋转后的图像;如果设置为 False,则会保留旋转后图像的原始尺寸,默认为 False

center- 可选为中心旋转还是左上角旋转

自动数据增强

AutoAugment
torchvision.transforms.AutoAugment(policy: torchvision.transforms.autoaugment.AutoAugmentPolicy = , interpolation: torchvision.transforms.functional.InterpolationMode = , fill: Optional[List[float]] = None)

功能:自动数据增强方法的封装,支持三种数据增强策略,分别是IMAGENET、CIFAR10 和SVHN

参数:

policy :需要是AutoAugmentPolicy类

interpolation:设置插值方法

fill :设置填充像素的像素值,默认为0,黑色。

RandAugment

RandAugment是进行N次(num_ops )变换,变换方法从策略池中随机挑选

num_ops :执行多少次变换

magnitude :每个变换的强度,

num_magnitude_bins:与变化强度的采样分布有关

pytorch模型模块

module

Module是所有神经网络的基类,所有的模型都必须继承于Module类,并且它可以嵌套

构建自己的网络只需要三步:

  1. 写一个类继承于Module
  2. init函数中把需要的网络层创建好
  3. forward函数中把模型如何搭建的规则写好

parameter--参数

parameter继承于Tensor,主要作用是用来区分可训练的参数与常规的tensor

Parameter指模型的参数,如卷积层的卷积核权重和偏置,Linear层的权重和偏置,BN层的α和β等等

  optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)

module的容器

Sequential

将一系列网络层按固定的先后顺序串起来,当成一个整体,调用时数据从第一个层按顺序执行到最后一个层

例:

model = nn.Sequential(
          nn.Conv2d(1,20,5),
          nn.ReLU(),
          nn.Conv2d(20,64,5),
          nn.ReLU()
        )
def forward(self, input):
    for module in self:
    	input = module(input)
    return input

ModuleList

将各个网络层放到一个“列表”中,便于迭代的形式调用

class MyModule(nn.Module):
	def __init__(self):
		super(MyModule, self).__init__()
		self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])

def forward(self, x):
	for sub_layer in self.linears:
		x = sub_layer(x)
	return x

ModuleDict

ModuleDict就是可以像python的Dict一样为每个层赋予名字,可以根据网络层的名字进行选择性的调用网络层

class MyModule2(nn.Module):
    def __init__(self):
        super(MyModule2, self).__init__()
        self.choices = nn.ModuleDict({
            'conv': nn.Conv2d(3, 16, 5),
            'pool': nn.MaxPool2d(3)
        })
        self.activations = nn.ModuleDict({
            'lrelu': nn.LeakyReLU(),
            'prelu': nn.PReLU()
        })
     def forward(self, x, choice, act):
        x = self.choices[choice](x)
        x = self.activations[act](x)
        return x

常用网络层

Convolutional Layers

卷积层

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')

对多个二维平面组成的信号进行二维卷积

  • in_channels (int) – 输入这个网络层的图像的通道数是多少。
  • out_channels (int) – 此网络层输出的特征图的通道数是多少,等价于卷积核数量是多少。
  • kernel_size (int or tuple) – 卷积核大小。
  • stride (int or tuple, optional) – 卷积核卷积过程的步长。
  • padding (int, tuple or str, optional) –对于输入图像的四周进行填充的数量进行控制,可指定填充像素数量,也可以指定填充模式,
  • padding_mode (string, optional) – 填充的像素值如何确定。默认填充0。
  • dilation (int or tuple, optional) – 孔洞卷积的孔洞大小。
  • groups (int, optional) – 分组卷积的分组。
  • bias (bool, optional) – 是否采用偏置。

![](C:\Users\wyx\Desktop\pytorch\屏幕截图 2024-04-20 161320.png)

![](C:\Users\wyx\Desktop\pytorch\屏幕截图 2024-04-20 161332.png)

Pooling Layers

池化层

将特征图分辨率变小,通常减小一半(提取特征量)

可对池化层进行划分为最大值池化、平均值池化、分数阶池化、基于范数的池化。分别对应torch.nn中的Maxpool, Avgpool, FractionalMaxPool, LPPool

Maxpool:

torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

2D最大池化

  • kernel_size – 池化窗口大小

  • stride – 滑窗步长

  • padding – 原图填充大小

  • dilation – 孔洞大小

  • return_indices – 是否返回最大值所在位置,主要在 torch.nn.MaxUnpool2d 中使用,是上采样的一种策略

  • ceil_mode – 当无法整除时,是向下取整还是向上取整,默认为向下。

    ![](C:\Users\wyx\Desktop\pytorch\屏幕截图 2024-04-20 161320-1713600998558-3.png)

    Padding Layers

    给特征图周围填充一定的像素,调整特征图分辨率的一种方法

    可将padding layer划分为三类,镜像填充、边界重复填充,指定值填充、零值填充,分别对应nn的三大类,nn.ReflectionPad2d, nn.ReplicationPad2d, nn.ZeroPad2d, nn.ConstantPad2d

Linear Layers

线性层

Linear Layers包含4个层分别是nn.Identity,nn.Linear, nn.Bilinear, nn.LazyLinear

nn.Identity 是恒等映射,不对输入做任何变换,它通常用于占位。

nn.Linear 全连接层(Fully Connection Layer),可实现 y= Wx + b

nn.Bilinear 是双线性层,它有两个输入,实现公式 y = x1Wx2 +b

nn.LazyLinear 是nn.Linear的lazy版本,也就是懒惰的Linear层,它在第一次推理时自动根据输入特征图的尺寸来设定in_features,免去了手动计算in_features的麻烦。

Dropout Layers

随机失活--防止模型过拟合

Dropout使用注意事项:

  • Dropout通常用于nn.Linear层之前;
  • Dropout执行后,神经元个数会减少,导致数据尺度发生变化.

Non - linear Layers

非线性激活函数函数

Module常用函数

  • 设置模型训练、评估模式

    eval:设置模型为评估模式,与BN,Dropout息息相关,即评估模式下模型的某些层执行的操作与训练状态下是不同的。

    train:设置模型为训练模式,如BN层需要统计runing_var这些统计数据,Dropout层需要执行随机失活等

  • 设置模型存放在cpu/gpu/xpu

    1. cpu,将Module放到cpu上
    2. cuda,把需要运算的数据放到gpu即可。方法就是 xxx.cuda()
    3. to,可将对象放到指定的设备中去,如to.("cpu") 、 to.("cuda)、to("cuda:0") 等
  • 获取模型参数、加载权重参数

    1. load_state_dict,将参数字典中的参数复制到当前模型中。要求key要一一对应
    2. state_dict,返回参数字典。key是告诉你这个权重参数是放到哪个网络层
  • 管理模型的modules, parameters, sub_module

    parameters:返回一个迭代器,迭代器可抛出Module的所有parameter对象

    named_parameters:作用同上,不仅可得到parameter对象,还会给出它的名称

    modules:返回一个迭代器,迭代器可以抛出Module的所有Module对象,注意:模型本身也是module,所以也会获得自己。

    named_modules:作用同上,不仅可得到Module对象,还会给出它的名称

    children:作用同modules,但不会返回Module自己。

    named_children:作用同named_modules,但不会返回Module自己

  • 设置模型的参数精度,可选半精度、单精度、双精度等

    1. bfloat16
    2. half
    3. float
    4. double
  • 对子模块执行特定功能

    1. apply
    2. zero_grad

pytorch优化模块

损失函数--Loss Function

损失函数(loss function)是用来衡量模型输出与真实标签之间的差异,当模型输出越接近标签,认为模型越好,反之亦然

在pytorch中提供了二十一个损失函数,如下所示

nn.L1Loss
nn.MSELoss
nn.CrossEntropyLoss
nn.CTCLoss
nn.NLLLoss
nn.PoissonNLLLoss
nn.GaussianNLLLoss
nn.KLDivLoss
nn.BCELoss
nn.BCEWithLogitsLoss
nn.MarginRankingLoss
nn.HingeEmbeddingLoss
nn.MultiLabelMarginLoss
nn.HuberLoss
nn.SmoothL1Loss
nn.SoftMarginLoss
nn.MultiLabelSoftMarginLoss
nn.CosineEmbeddingLoss
nn.MultiMarginLoss
nn.TripletMarginLoss
nn.TripletMarginWithDistanceLoss

L1loss

torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean')

计算output和target之差的绝对值,可选返回同维度的tensor(reduction=none)或一个标量(reduction=mean/sum)

CrossEntropyLoss -- 交叉熵损失函数

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

将输入经过softmax激活函数之后,计算交叉熵损失

eight (Tensor, optional) – 类别权重,用于调整各类别的损失重要程度,常用于类别不均衡的情况
ignore_index (int, optional) – 忽略某些类别不进行loss计算。
size_average (bool, optional) – 已舍弃使用的变量,功能已经由reduction代替实现,仍旧保留是为了旧版本代码可以正常运行。
reduce (bool, optional) – 已舍弃使用的变量,功能已经由reduction代替实现,仍旧保留是为了旧版本代码可以正常运行。
reduction (string, optional) – 是否需要对loss进行“降维”,这里的reduction指是否将loss值进行取平均(mean)、求和(sum)或是保持原尺寸(none)

优化器--Optimizer

对模型进行优化使loss不断降低

优化器的实现在torch.optim中

优化器基类

参数组(param_groups):参数组是用于管理需要进行优化的那些参数,例如权值weight,偏置bias,BN的alpha/beta等

这里是参数组不是参数,表明可以将所有参数进行分组,例如在finetune过程中,通常让前面层的网络采用较小的学习率,后面几层全连接层采用较大的学习率,这时我们就要把网络的参数划分为两组,每一组有它对应的学习率

参数组是一个list,其元素是一个dict,dict中包含,所管理的参数,对应的超参,例如学习率,momentum,weight_decay等等。

state:用于存储优化策略中需要保存的一些缓存值,例如在用momentum时,需要保存之前的梯度,这些数据保存在state中。

defaults:优化方法默认的超参数

方法:

zero_grad()

功能:清零所管理参数的梯度。由于pytorch不会自动清零梯度,因此需要再optimizer中手动清零,然后再执行反向传播,得出当前iteration的loss对权值的梯度。

step()

功能:执行一步更新,依据当前的梯度进行更新参数

add_param_group(param_group)

功能:给optimizer管理的参数组中增加一组参数,可为该组参数定制lr,momentum,weight_decay等,在finetune中常用。

例如:

optimizer_1.add_param_group({'params': w3, 'lr': 0.001, 'momentum': 0.8})

state_dict()

功能:获取当前state属性。

通常在保存模型时同时保存优化器状态,用于断点保存,下次继续从当前状态训练;

load_state_dict(state_dict)

功能:加载所保存的state属性,恢复训练状态。

SGD--随机梯度下降

深度学习中最基础的一个

SGD核心理论知识是梯度下降( gradient descent),即沿着梯度的负方向,是变化最快的方向。

SGD的使用
optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)#实例化
optimizer.zero_grad()#loss.backward()之前进行梯度清零
loss.backward()
optimizer.step()#loss.backward()之后执行一步更新

pytorch 可视化

TensorBoard

from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
writer.add_image("test",img_array,2,dataformats="HWC")
writer.close()

终端输入

tensorboard --logdir=your path dir

add_scalar

add_scalar(tag, scalar_value, global_step=None, walltime=None, new_style=False, double_precision=False)

添加标量;tag的设置可以有个技巧是在同一栏下绘制多个图,如'Loss/train', 'Loss/Valid', 这就类似于matplotlib的subplot(121), subplot(122)

  • tag (string) – Data identifier
  • scalar_value (float or string/blobname) – Value to save
  • global_step (int) – Global step value to record

add_scalars

add_scalars`(main_tag, tag_scalar_dict, global_step=None,walltime=None)

功能:在一个坐标轴中绘制多条曲线。常用于曲线对比。

  • main_tag (string) – The parent name for the tags
  • tag_scalar_dict (dict) – Key-value pair storing the tag and corresponding values
  • global_step (int) – Global step value to record

add_image

add_image(tag, img_tensor, global_step=None, walltime=None, dataformats='CHW')

功能:绘制图像。

  • tag (string) – Data identifier
  • img_tensor (torch.Tensor, numpy.array, or string/blobname) – Image data
  • global_step (int) – Global step value to record dataformats- 数据通道顺序物理意义。默认为 CHW

标签:None,nn,self,torch,张量,pytorch,grad
From: https://www.cnblogs.com/wangyixiang2023004464/p/18151166

相关文章

  • AI+X 经典共读-《动手学深度学习(Pytorch版)》Task打卡
    0.笔记仓库AI入门路线Task01:初识深度学习深度学习介绍和环境安装配置1.深度学习介绍1.1AI地图x轴:模式y轴:想做的东西感知:所见(人能够快速反应)推理:基于所见的想象知识:根据所见形成自己的知识规划:根据知识进行长远的规划自然语言处理:感知,用的最多的是机器翻译计算机视......
  • 【pytorch学习】之数据操作
    1数据操作为了能够完成各种数据操作,我们需要某种方法来存储和操作数据。通常,我们需要做两件重要的事:(1)获取数据;(2)将数据读入计算机后对其进行处理。如果没有某种方法来存储数据,那么获取数据是没有意义的。首先,我们介绍n维数组,也称为张量(tensor)。使用过Python中NumPy计算包的读者......
  • Python pytorch 坐标系变换与维度转换
    前言深度学习中经常要用到张量坐标系变换与维度转换,因此记录一下,避免混淆坐标系变换坐标系变换(矩阵转置),主要是调换tensor/array的维度pytorchimporttorchdefinfo(tensor):print(f"tensor:{tensor}")print(f"tensorsize:{tensor.size()}")print(f"tenso......
  • Pytorch 如何使用 storage 实现参数 offload?
    在深入探讨PyTorch中的Storage类以及其在参数offload场景中的应用之前,让我们首先了解一下PyTorch和它的基础组件。PyTorch是一个广泛使用的开源机器学习库,它不仅提供了强大的计算图功能和自动梯度计算,还允许开发者直接操作底层数据结构,这其中就包括Storage。1.什么是......
  • pytorch学习
    数据集PyTorch中,torch.utils.data.DataLoader和torch.utils.data.Dataset可以让我们方便使用预加载的数据集或者自己的数据集。Dataset存储数据样本及其对应的标签,而DataLoader将Dataset包裹起来,生成一个可迭代对象,以便轻松访问数据样本。1.加载数据集importtorchfromtorc......
  • 解决加载GPT2(Tensorflow预训练模型)的Linear权重到PyTorch的Linear权重 形状不匹配(互为
    解决报错内容:RuntimeError:Error(s)inloadingstate_dictforPyTorchBasedGPT2:sizemismatchfortransformer.h.0.attn.c_attn.weight:copyingaparamwithshapetorch.Size([768,2304])fromcheckpoint,theshapeincurrentmodelistorch.Size([2304,768]).........
  • Pytorch Dataset入门
    ​Dataset入门PytorchDatasetcode:torch/utils/data/dataset.py#L17PytorchDatasettutorial:tutorials/beginner/basics/data_tutorial.html 理论:PyTorch中的Dataset是一个抽象类,用来表示数据集的接口,所有其他数据集都需要继承这个类,并且覆写以下三个方法:__init__:......
  • Pytorch计算机视觉实战(更新中)
    第一章人工神经网络基础1.1人工智能与传统机器学习学习心得:传统机器学习(ML):需要专业的主题专家人工提取特征,并通过一个编写良好的算法来破译给定的特征,从而判断这幅图像中的内容。输入-->人工提取特征-->特征-->具有浅层结构的分类器-->输出当存在欺骗性的图片出现时可能会......
  • Pytorch DistributedDataParallel(DDP)教程二:快速入门实践篇
    一、简要回顾DDP在上一篇文章中,简单介绍了Pytorch分布式训练的一些基础原理和基本概念。简要回顾如下:1,DDP采用Ring-All-Reduce架构,其核心思想为:所有的GPU设备安排在一个逻辑环中,每个GPU应该有一个左邻和一个右邻,设备从它的左邻居接收数据,并将数据汇总后发送给右邻。通过N轮迭代......
  • Pytorch分类模型的训练框架
    Pytorch分类模型的训练框架PhotoDataset数据集是自己定义的数据集,数据集存放方式为:----image文件夹--------0文件夹--------------img1.jpg--------------img2.jpg--------1文件夹--------------img1.jpg--------------img2.jpg....如果是cpu训练的话,就把代码中的.cu......