pytorch常用函数积累

可以访问我的知乎:https://zhuanlan.zhihu.com/p/478576485

官方文档:https://pytorch.org/docs/master/torch.html

中文文档:https://pytorch-cn.readthedocs.io/zh/latest/

torch基础#

  1. torch.device():将使用GPU训练模型

    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    # 如果多个GPU
    model = Model()
    if torch.cuda.device_count() > 1:
    	model = nn.DataParallel(model,device_ids=[0,1,2])
    model.to(device)
    
  2. torch.permute():张量维度转换

    a = torch.randn(16, 16, 3) 
    b = a.permute(2,0,1)
    # b.shape=(3,16,16)
    
  3. torch.cat():拼接张量

    torch.cat((A,B),0)  # 第0维向下拼接,列数必须一致(其他维都必须一致)
    torch.cat((A,B),0)  # 第1维向右拼接,行数必须一致(其他维都必须一致)
    
  4. tensor.contiguous() :深拷贝

  5. torch.clamp(input, min, max) :输入input张量每个元素的值限制在区间 [min,max]内,返回一个新张量

  6. torch.save():保存模型(参数)

    import torch
    state ={''net':model.state_dict(),'optimizer':optimizer.state_dict(), 'epoch':epoch}
    torch.save(state, filename)  # state['net']也能是model ; filename:'*.pt(h)/*.pkl'(均二进制存储)
    -------------------------------------------------------------------
    checkpoint = torch.load(filename)
    model.load_state_dict(checkpoint['net'])
    optimizer.load_state_dict(checkpoint['optimizer'])
    start_epoch = checkpoint['epoch'] + 1    
    
  7. torch.squeeze() :去除取1的维度;torch.unsqueeze(i):增添第i维

  8. torch.gather(mytensor,i,index):对第i维按index索引并返回索引结果

  9. torch.sactter(mytensor,i,index,val):对第i维按index中索引值索引填val,返回填充后结果,可用于读独热编码,示例如下:

    def one_hot(labels,num_class):
        batch_size = len(labels)
        return torch.scatter(torch.zeros(batch_size,num_class),
                             1,labels.view(batch_size,1),1)
    

    [备注]:gather和sactter中index详见

    https://blog.csdn.net/Teeyohuang/article/details/82186666

torch.nn as nn#

详见:https://blog.csdn.net/qq_33952811/article/details/108430097

  1. torch.nn.Conv2d():二维卷积

    卷积尺寸变化如下:

    [备注]:保证输出高宽不变的\(p =[\displaystyle \frac{k-1}{2}]\)

    Conv2d(in_channels, out_channels, kernel_size, stride=1,padding=0, dilation=1, groups=1,bias=True, padding_mode=‘zeros’)
    # in_channels:输入的通道数目 【必选】
    # out_channels: 输出的通道数目 【必选】
    # kernel_size:卷积核的大小,类型为int 或者元组,当卷积是方形的时候,只需要一个整数边长即可,卷积不是方形,要输入一个元组表示 高和宽。【必选】
    # stride: 卷积每次滑动的步长为多少,默认是 1 【可选】
    # padding: 设置在所有边界增加 值为 0 的边距的大小(也就是在feature map 外围增加几圈 0 ),例如当 padding =1 的时候,如果原来大小为 3 × 3 ,那么之后的大小为 5 × 5 。即在外围加了一圈 0 。【可选】
    # dilation:控制卷积核之间的间距。 【可选】
    # groups:控制输入和输出之间的连接。【可选】
    # bias: 是否将一个 学习到的 bias 增加输出中,默认是 True 。【可选】
    # padding_mode : 字符串类型,可选择 “zeros” 和 “circular”。【可选】
    
  2. torch.nn.ConvTranspose2d():二维转置卷积

    • 卷积是将输入m×m的矩阵输出n×n的矩阵(shape减小)
    • 转置卷积≠反卷积是将输入n×n的矩阵输出m×m的矩阵(shape增大)

    \[Y_{n^2×1} = W_{n^2×m^2} · X_{m^2×1} \to Y'_{m^2×1} = W^T_{m^2×n^2} · X'_{n^2×1}\\ \]

    • 形状换算:
  1. torch.nn.Identity():占位

    不处理,输入即输出,相当于网络的一层空层,用于残差网络

  2. torch.nn.functional.interpolate():上下采样时插值

    # default:(input, size=None, scale_factor=None, mode='nearest',       align_corners=None)
    # input:输入张量
    # size:上/下采样目标大小
    # scale_factor:标量获元组,表示输出大小为输入的多少倍
    # mode:上采样算法,有'nearest', 'linear', 'bilinear', 'bicubic' ,    'trilinear'和'area'
    # align_corners:几何上,我们认为输入和输出的像素是正方形,而不是点。如果设置为True,则输入和输出张量由其角像素的中心点对齐,从而保留角像素处的值。如果设置为False,则输入和输出张量由它们的角像素的角点对齐,插值使用边界外值的边值填充;当scale_factor保持不变时,使该操作独立于输入大小。仅当使用的算法为'linear', 'bilinear', 'bilinear'or 'trilinear'时可以使用。默认设置为False
    

torchvision#

  1. torchvision.utils.make_grid():输出图片矩阵,用于算法性能效果比较

    make_grid()将若干图像以网格矩阵排列,save_image()用于保存图像,两函数参数类似

    # tensor:4D张量,形状为(B x C x H x W),分别表示样本数,通道数,图像高度,图像宽度。或者是一个图像列表
    # nrow:每行的图片数量,默认值为8
    # padding:相邻图像之间的间隔。默认值为2
    # normalize:如果为True,则把图像的像素值通过range指定的最大值和最小值归一化到0-1。默认为   False
    

    使用举例:

    def show(img):
        npimg = img.numpy()
        plt.imshow(
            np.transpose(npimg, (1,2,0)), interpolation='nearest')
    show(make_grid(images, nrow=5, padding=10))    
    
  2. torchvision.transforms():图像增强(image augmentation)

    参考:https://blog.csdn.net/u011995719/article/details/85107009

    注意图像数据格式:

    • ndarray->HWC
    • tensor->CHW
    • PIL->HW
    import torchvision.transforms as transforms
    trans = [
    # 数据转换
    transforms.ToPILImage(),
    transforms.ToTensor(),
    #-----------------------------------------------------
    # 随机长宽裁剪
    transforms.RandomResizedCrop(size,scale=(0.08, 1.0)), 
    # 按比例把图像最小边长放缩到256,另一边同比例放缩
    transforms.Resize(256),  
    # 像素值归一化
    transforms.Normalize(mean,std), 
    # 修改输入图像的4大参数值:brightness,contrast and saturation,hue,即亮度,对比度,饱和度和色度
    transforms.ColorJitter()  
    # 0.5几率水平翻转
    transforms.RandomHorizontalFlip(),  
    # 从一张输入图像中裁剪出5张指定大小的图像,包括图像九宫格的4个角的和一个中心
    transforms.FiveCrop(size)
    # 随机旋转
    transforms.RandomRotation()  
    # 仿射变换
    torchvision.transforms.RandomAffine(degrees, translate=None, scale=None,    shear=None, resample=False, fillcolor=0) 
    ]
    transformer = transforms.Compose(trans)  # 整合图像批量预处理的所有规则
    

数据集#

from torchvision.datasets import ImageFolder
dataset=ImageFolder(root, 
                    transform=None, 
    				target_transform=None, 
    				is_valid_file=None
                   )
'''参数说明'''
# root:图片存储的根目录,即各类别文件夹所在目录的上一级目录。
# transform:对图片进行预处理的操作(函数),原始图片作为输入,返回一个转换后的图片。
# target_transform:对图片类别进行预处理的操作,输入为 target,输出对其的转换。如果不传该参数,即对 target 不做任何转换,返回的顺序索引 0,1, 2…
# is_valid_file:获取图像文件的路径并检查该文件是否为有效文件的函数(用于检查损坏文件)
'''返回的dataset都有以下三种属性:'''
# self.classes:用一个 list 保存类别名称
# self.class_to_idx:类别对应的索引,与不做任何转换返回的 target 对应
# self.imgs:保存(img-path, class) tuple的 list

from torch.utils.data import DataLoader
DataLoader(dataset,batch_size, shuffle, num_workers)

迁移学习#

派生新网络,以全连接卷积神经网络举例:

from torchvision.models import resnet18
import torch.nn as nn

cnn = resnet18(pretrained=False)
FCN = nn.Sequential(*list(cnn.children())[:-2])  # 类似迁移学习,删掉最后的平均池化层和全连接层,保留前面提取特征的结构
FCN.add_module('final_conv',nn.Conv2d(in_channels=512,out_channels=21,kernel_size=1))  # 1*1卷积
FCN.add_module('transpose_conv',nn.ConvTranspose2d(in_channels=21,out_channels=21,kernel_size=64,stride=32,padding=16))

深度强化学习#

torch.distributions():深度学习中的概率分布

import torch
# 1.将pi列表的权重转化为概率构建离散分布
dist = torch.distributions.Categorical(logits=pi)
dist.sample()  # 按概率抽样下标
dist.log_prob(action_batch)  # 对action_batch中每个元素重构成仅1个索引值为1的独热编码序列,对每个序列计算交叉熵

# 2.构建(μ,σ)正态分布
dist = torch.distributions.Normal  # 构建3个标准正态分布
(loc=torch.Tensor([0,0,0]),scale=torch.Tensor([1,1,1]))
sample = dist.sample()   # 对每个正态分布直接抽样
rsample = dist.rsample() # 先在标准正态分布上抽样再μ+σx

以下内容强化学习策略梯度中使用:

当概率密度函数相对于其参数可微分时, 我们只需要sample()log_prob()来实现REINFORCE:从网络输出中采样一个动作, 将这个动作应用于一个环境中, 然后使用log_prob构造损失函数

from torch.distributions import Categorical
probs = policy_network(state)  # probs是特征
m = Categorical(probs=probs)  # 更推荐使用logits=probs,这个还可以传入未归一化的参数
action = m.sample()
next_state, reward = env.step(action)
loss = -m.log_prob(action) * reward  # max->min
loss.backward()

实现随机/策略梯度的另一种方法是使用来自rsample()方法的重新参数化技巧,其中参数化随机变量可以通过无参数随机变量的参数确定性函数构造. 因此, 重新参数化的样本变得可微分。

from torch.distributions import Normal
params = policy_network(state)
m = Normal(loc)
action = m.rsample()
next_state, reward = env.step(action)  
loss = -reward
loss.backward()
posted @   达拉崩吧班德贝迪卜多  阅读(222)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示
主题色彩