pytorch的tricks

本文介绍了PyTorch中提高性能的技巧,如torch.backends.cudnn.benchmark=True加速卷积运算,并探讨了不同tensor创建方法的区别。在功能部分,讲解了nn.ModuleList、tensor.detach()与tensor.data的区别、tensor在不同设备间转换以及模型的保存与加载策略,包括跨设备保存和加载的细节。
摘要由CSDN通过智能技术生成

性能part

1. torch.from_numpy() vs. torch.tensor() vs. torch.as_tensor()

torch.from_numpy() vs. torch.tensor()

from_numpy() automatically inherits input array dtype. On the other hand, torch.Tensor is an alias for torch.FloatTensor.
Therefore, if you pass int64 array to torch.Tensor, output tensor is float tensor and they wouldn’t share the storage. torch.from_numpy gives you torch.LongTensor as expected.

torch.tensor() vs. torch.as_tensor()

torch.tensor always copies the data. For example, torch.tensor(x) is equivalent to x.clone().detach().
torch.as_tensor always tries to avoid copies of the data. One of the cases where as_tensor avoids copying the data is if the original data is a numpy array.

2. torch.backends.cudnn.benchmark=True

在网络结构固定(不是动态变化的),网络的输入形状(包括 batch size,图片大小,输入的通道)不变的场景下,在 PyTorch 程序开头设置torch.backends.cudnn.benchmark=True,就可以大大提升卷积神经网络的运行速度。原理是:在每一个卷积层中测试 cuDNN 提供的所有卷积实现算法,然后选择最快的那个。
一般加在开头,如:
if args.use_gpu and torch.cuda.is_available():
device = torch.device(‘cuda’)
torch.backends.cudnn.benchmark = True
else:
device = torch.device(‘cpu’)

功能part

1.nn.ModuleList

首先说说 nn.ModuleList 这个类,你可以把任意 nn.Module 的子类 (比如 nn.Conv2d, nn.Linear 之类的) 加到这个 list 里面,方法和 Python 自带的 list 一样,无非是 extend,append 等操作。但不同于一般的 list,加入到 nn.ModuleList 里面的 module 是会自动注册到整个网络上的,同时 module 的 parameters 也会自动添加到整个网络中:

class net1(nn.Module):
	def __init__(self):
		super(net1, self).__init__()
		self.linears = nn.ModuleList([nn.Linear(10,10) for i in range(2)])
	def forward(self, x):
		for m in self.linears:
			x = m(x)
		return x

net = net1()
print(net)
# net1(
#   (modules): ModuleList(
#		(0): Linear(in_features=10, out_features=10, bias=True)
#		(1): Linear(in_features=10, out_features=10, bias=True)
#	)
# )

for param in net.parameters():
	print(type(param.data), param.size())
# <class 'torch.Tensor'> torch.Size([10, 10])
# <class 'torch.Tensor'> torch.Size([10])
# <class 'torch.Tensor'> torch.Size([10, 10])
# <class 'torch.Tensor'> torch.Size([10])

2.PyTorch中 tensor.detach() 和 tensor.data 的区别

PyTorch0.4中,.data 仍保留,但建议使用 .detach(), 区别在于 .data 返回和 x 的相同数据 tensor, 但不会加入到x的计算历史里,且require s_grad = False, 这样有些时候是不安全的, 因为 x.data 不能被 autograd 追踪求微分 。 .detach() 返回相同数据的 tensor ,且 requires_grad=False ,但能通过 in-place 操作报告给 autograd 在进行反向传播的时候.

与一个Variable(Tensor)的梯度有关的参数有两个:

  • grad_fn:把一个tensor的grad_fn设置为None,则该节点前面的节点将不会再接收来自该节点后面的节点的梯度的反向传播。
  • requires_grad:把一个tensor的requires_grad设置为False,则对该节点后面的节点进行反向传播时不会对该节点求梯度。

举例:变量之间的关系是x -> m -> y,这里的叶子variable是x,但是这个时候对m进行了.detach_()操作,其实就是进行了两个操作:

  • 将m的grad_fn的值设置为None,这样m就不会再与前一个节点x关联,这里的关系就会变成x, m -> y,此时的m就变成了叶子结点
  • 然后会将m的requires_grad设置为False,这样对y进行backward()时就不会求m的梯度

detach()detach_()很像,两个的区别就是detach_()是对本身的更改,detach()则是生成了一个新的variable

tensor复制可以使用clone()函数和detach()函数即可实现各种需求。

clone
clone()函数可以返回一个完全相同的tensor,新的tensor开辟新的内存,但是仍然留在计算图中。

detach
detach()函数可以返回一个完全相同的tensor,新的tensor开辟与旧的tensor共享内存,新的tensor会脱离计算图,不会牵扯梯度计算。此外,一些原地操作(in-place, such as resize_ / resize_as_ / set_ / transpose_) 在两者任意一个执行都会引发错误。

Operation New/Shared memory Still in computation graph
tensor.clone() New Yes
tensor.detach() Shared No
tensor.clone().detach() New No

3.cpu tensor, gpu tensor, ndarray之间的转换

  1. CPU tensor转GPU tensor:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值