Pytorch中torch常用函数

torch.scatter(dim, index, src)

  • scatter_: 直接修改原来的 Tensor

    • PyTorch 中,一般函数加下划线代表直接在原来的 Tensor 上修改
  • 参数

    • dim:沿着哪个维度进行索引
    • index:用来 scatter 的元素索引
    • src:用来 scatter 的源元素,可以是一个标量或一个张量
  • 计算方式

    • self[index[i][j]][j]=src[i][j]
  • 用途

    • 一般可以用来对标签进行 one-hot 编码
  • 资料

    • https://www.cnblogs.com/dogecheng/p/11938009.html

torch.backends.cudnn.benchmark() = true

  • 让内置的 cuDNN 的 auto-tuner 自动寻找最适合当前配置的高效算法,来达到优化运行效率的问题。

  • 一般来讲,应该遵循以下准则

    • 如果网络的输入数据维度或类型上变化不大,设置 torch.backends.cudnn.benchmark = true 可以增加运行效率;
    • 如果网络的输入数据在每次 iteration 都变化的话,会导致 cnDNN 每次都会去寻找一遍最优配置,这样反而会降低运行效率。
  • 资料:

    • https://blog.csdn.net/zxyhhjs2017/article/details/91348108

nn.init 参数初始化方法

import torch
import torch.nn as nn

w = torch.empty(2, 3)

# 1. 均匀分布 - u(a,b)
# torch.nn.init.uniform_(tensor, a=0, b=1)
nn.init.uniform_(w)
# tensor([[ 0.0578,  0.3402,  0.5034],
#         [ 0.7865,  0.7280,  0.6269]])

# 2. 正态分布 - N(mean, std)
# torch.nn.init.normal_(tensor, mean=0, std=1)
nn.init.normal_(w)
# tensor([[ 0.3326,  0.0171, -0.6745],
#        [ 0.1669,  0.1747,  0.0472]])

# 3. 常数 - 固定值 val
# torch.nn.init.constant_(tensor, val)
nn.init.constant_(w, 0.3)
# tensor([[ 0.3000,  0.3000,  0.3000],
#         [ 0.3000,  0.3000,  0.3000]])

# 4. 对角线为 1,其它为 0
# torch.nn.init.eye_(tensor)
nn.init.eye_(w)
# tensor([[ 1.,  0.,  0.],
#         [ 0.,  1.,  0.]])

# 5. Dirac delta 函数初始化,仅适用于 {3, 4, 5}-维的 torch.Tensor
# torch.nn.init.dirac_(tensor)
w1 = torch.empty(3, 16, 5, 5)
nn.init.dirac_(w1)

# 6. xavier_uniform 初始化
# torch.nn.init.xavier_uniform_(tensor, gain=1)
# From - Understanding the difficulty of training deep feedforward neural networks - Bengio 2010
nn.init.xavier_uniform_(w, gain=nn.init.calculate_gain('relu'))
# tensor([[ 1.3374,  0.7932, -0.0891],
#         [-1.3363, -0.0206, -0.9346]])

# 7. xavier_normal 初始化
# torch.nn.init.xavier_normal_(tensor, gain=1)
nn.init.xavier_normal_(w)
# tensor([[-0.1777,  0.6740,  0.1139],
#         [ 0.3018, -0.2443,  0.6824]])

# 8. kaiming_uniform 初始化
# From - Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification - HeKaiming 2015
# torch.nn.init.kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
nn.init.kaiming_uniform_(w, mode='fan_in', nonlinearity='relu')
# tensor([[ 0.6426, -0.9582, -1.1783],
#         [-0.0515, -0.4975,  1.3237]])

# 9. kaiming_normal 初始化
# torch.nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
nn.init.kaiming_normal_(w, mode='fan_out', nonlinearity='relu')
# tensor([[ 0.2530, -0.4382,  1.5995],
#         [ 0.0544,  1.6392, -2.0752]])

# 10. 正交矩阵 - (semi)orthogonal matrix
# From - Exact solutions to the nonlinear dynamics of learning in deep linear neural networks - Saxe 2013
# torch.nn.init.orthogonal_(tensor, gain=1)
nn.init.orthogonal_(w)
# tensor([[ 0.5786, -0.5642, -0.5890],
#         [-0.7517, -0.0886, -0.6536]])

# 11. 稀疏矩阵 - sparse matrix 
# 非零元素采用正态分布 N(0, 0.01) 初始化.
# From - Deep learning via Hessian-free optimization - Martens 2010
# torch.nn.init.sparse_(tensor, sparsity, std=0.01)
nn.init.sparse_(w, sparsity=0.1)
# tensor(1.00000e-03 *
#        [[-0.3382,  1.9501, -1.7761],
#         [ 0.0000,  0.0000,  0.0000]])
  • 资料:
    • https://blog.csdn.net/qq_21980099/article/details/105564367
    • https://www.aiuai.cn/aifarm613.html

Warning

DistributedDataParallel

  • 有的时候会发现另外几个进程会在0卡上占一部分显存,导致0卡显存出现瓶颈,可能会导致cuda-out-of-memory 错误。
    checkpoint = torch.load("checkpoint.pth")  # 默认把load进来的数据放到0卡上
    model.load_state_dict(checkpoint["state_dict"])
    
    • 解决的方法: 把load进来的数据map到cpu上
    checkpoint = torch.load("checkpoint.pth", map_location=torch.device('cpu'))
    model.load_state_dict(checkpoint["state_dict"])
    

dropout

  • 使用F.dropout ( nn.functional.dropout )的时候需要设置它的training这个状态参数与模型整体的一致。比如:
Class DropoutFC(nn.Module):
    def __init__(self):
        super(DropoutFC, self).__init__()
        self.fc = nn.Linear(100,20)

    def forward(self, input):
        out = self.fc(input)
        out = F.dropout(out, p=0.5)
        return out

Net = DropoutFC()
Net.train()

这段代码中的F.dropout实际上是没有任何用的, 因为它的training状态一直是默认值False。由于F.dropout只是相当于引用的一个外部函数, 模型整体的training状态变化也不会引起F.dropout这个函数的training状态发生变化。 所以, 此处的out = F.dropout(out) 就是 out = out。

  • 正确的使用方法如下, 将模型整体的training状态参数传入dropout函数
Class DropoutFC(nn.Module):
	   def __init__(self):
	       super(DropoutFC, self).__init__()
	       self.fc = nn.Linear(100,20)
	
	   def forward(self, input):
	       out = self.fc(input)
	       out = F.dropout(out, p=0.5, training=self.training)
	       return out
	
	Net = DropoutFC()
	Net.train()

或者直接使用nn.Dropout() (nn.Dropout()实际上是对F.dropout的一个包装, 也将self.training传入。

Trick

  • torch.backends.cudnn.benchmark = True 在程序刚开始加这条语句可以提升一点训练速度,没什么额外开销。
  • 有时候可能是因为每次迭代都会引入点临时变量,会导致训练速度越来越慢,基本呈线性增长。开发人员还不清楚原因,但如果周期性的使用torch.cuda.empty_cache()的话就可以解决这个问题。这个命令是清除没用的临时变量的。
  • 在test代码里,最好使用 volatile=True; 每个batch计算完之后,手动del output。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值