7 个有用的 PyTorch 技巧

原文:https://www.reddit.com/r/MachineLearning/comments/n9fti7/d_a_few_helpful_pytorch_tips_examples_included/

原文标题:a_few_helpful_pytorch_tips_examples_included

译文作者:kbsc13

联系方式:

Github:https://github.com/ccc013/AI_algorithm_notes

知乎专栏:机器学习与计算机视觉,AI 论文笔记

微信公众号:AI 算法笔记


前言

这是在国外的论坛 reddit 的机器学习版块,有人总结了大概 7 个有用的 PyTorch 技巧,并且还附带了 colab 的代码例子和视频,代码和视频链接分别如下:

代码:https://colab.research.google.com/drive/15vGzXs_ueoKL0jYpC4gr9BCTfWt935DC?usp=sharing

视频:https://youtu.be/BoC8SGaT3GE

视频也同步上传到我的 b 站上,链接如下:

https://www.bilibili.com/video/BV1YK4y1A7KM/

另外代码和视频可以在我的公众号后台回复"12"获取。


1. 直接在目标设备上创建 Tensors

第一个技巧就是使用 device 参数直接在目标设备上创建张量,这里分别演示了两种做法的运行时间,

第一种是先在 cpu 上创建 tensors,然后用.cuda() 移动到 GPU 上,代码如下所示:

start_time = time.time()for _ in range(100):# Creating on the CPU, then transfering to the GPUcpu_tensor = torch.ones((1000, 64, 64))gpu_tensor = cpu_tensor.cuda()print('Total time: {:.3f}s'.format(time.time() - start_time))

第二种则是直接在目标设备上创建张量,代码如下所示:

start_time = time.time()for _ in range(100):# Creating on GPU directlycpu_tensor = torch.ones((1000, 64, 64), device='cuda')print('Total time: {:.3f}s'.format(time.time() - start_time))

两种方法的运行时间如下所示:
在这里插入图片描述
可以看到直接在目标设备创建 Tensors 的速度是非常快速的;

2. 尽可能使用 Sequential

第二个技巧就是采用Sequential 层来让代码看起来更加简洁。

第一种搭建网络模型的代码如下:

class ExampleModel(nn.Module):def __init__(self):super().__init__()input_size = 2output_size = 3hidden_size = 16self.input_layer = nn.Linear(input_size, hidden_size)self.input_activation = nn.ReLU()self.mid_layer = nn.Linear(hidden_size, hidden_size)self.mid_activation = nn.ReLU()self.output_layer = nn.Linear(hidden_size, output_size)def forward(self, x):z = self.input_layer(x)z = self.input_activation(z)z = self.mid_layer(z)z = self.mid_activation(z)out = self.output_layer(z)return out

其运行效果如下:

在这里插入图片描述

而采用 Sequential 来搭建网络模型的写法如下所示:

class ExampleSequentialModel(nn.Module):def __init__(self):super().__init__()input_size = 2output_size = 3hidden_size = 16self.layers = nn.Sequential(nn.Linear(input_size, hidden_size),nn.ReLU(),nn.Linear(hidden_size, hidden_size),nn.ReLU(),nn.Linear(hidden_size, output_size))def forward(self, x):out = self.layers(x)return out

其运行效果如下:
在这里插入图片描述

可以看到用 nn.Sequential 来搭建网络模型的代码是更加的简洁。

3. 不要使用列表来存放网络层

第三个技巧是不建议使用列表来存放创建的网络层,因为 nn.Module 类不能成功注册他们。相反,应该把列表传入到nn.Sequential 中。

首先是展示一个错误的例子:

class BadListModel(nn.Module):def __init__(self):super().__init__()input_size = 2output_size = 3hidden_size = 16self.input_layer = nn.Linear(input_size, hidden_size)self.input_activation = nn.ReLU()# Fairly common when using residual layersself.mid_layers = []for _ in range(5):self.mid_layers.append(nn.Linear(hidden_size, hidden_size))self.mid_layers.append(nn.ReLU())self.output_layer = nn.Linear(hidden_size, output_size)def forward(self, x):z = self.input_layer(x)z = self.input_activation(z)for layer in self.mid_layers:z = layer(z)out = self.output_layer(z)return outbad_list_model = BadListModel()
print('Output shape:', bad_list_model(torch.ones([100, 2])).shape)
gpu_input = torch.ones([100, 2], device='cuda')
gpu_bad_list_model = bad_list_model.cuda()
print('Output shape:', bad_list_model(gpu_input).shape)

上述写法在打印第二句的时候,会报错:

在这里插入图片描述

正确的写法:

class CorrectListModel(nn.Module):def __init__(self):super().__init__()input_size = 2output_size = 3hidden_size = 16self.input_layer = nn.Linear(input_size, hidden_size)self.input_activation = nn.ReLU()# Fairly common when using residual layersself.mid_layers = []for _ in range(5):self.mid_layers.append(nn.Linear(hidden_size, hidden_size))self.mid_layers.append(nn.ReLU())self.mid_layers = nn.Sequential(*self.mid_layers)self.output_layer = nn.Linear(hidden_size, output_size)def forward(self, x):z = self.input_layer(x)z = self.input_activation(z)z = self.mid_layers(z)out = self.output_layer(z)return outcorrect_list_model = CorrectListModel()
gpu_input = torch.ones([100, 2], device='cuda')
gpu_correct_list_model = correct_list_model.cuda()
print('Output shape:', correct_list_model(gpu_input).shape)

其打印结果:

在这里插入图片描述

4. 好好使用 distributions

第四个技巧是PyTorch 的 torch.distributions 库中有一些很棒的对象和方法来实现分布式,但是并没有得到很好地使用,官方文档链接:

https://pytorch.org/docs/stable/distributions.html

下面是一个使用的例子:
在这里插入图片描述

在这里插入图片描述

5. 在长期指标上使用 detach

第 5 个技巧是在每个 epoch 之间如果需要存储张量指标,采用 .detach() 来防止内存泄露。

下面用一个代码例子来说说明,首先是初始配置:

# Setup
example_model = ExampleModel()
data_batches = [torch.rand((10, 2)) for _ in range(5)]
criterion = nn.MSELoss(reduce='mean')

错误的代码例子:

losses = []# Training loop
for batch in data_batches:output = example_model(batch)target = torch.rand((10, 3))loss = criterion(output, target)losses.append(loss)# Optimization happens hereprint(losses)

打印结果如下:

在这里插入图片描述

正确的写法

losses = []# Training loop
for batch in data_batches:output = example_model(batch)target = torch.rand((10, 3))loss = criterion(output, target)losses.append(loss.item()) # Or `loss.item()`# Optimization happens hereprint(losses)

打印结果如下:

在这里插入图片描述

这里应该调用 loss.item() 方法来保存每个 epoch 中的 loss 数值。

6. 删除 GPU上模型的技巧

第六个技巧是可以采用 torch.cuda.empty_cache() 来清理 GPU 缓存,这个方法在使用 notebook 的时候很有帮助,特别是你想要删除和重新创建一个很大的模型的时候。

使用例子如下所示:

import gcexample_model = ExampleModel().cuda()del example_modelgc.collect()
# The model will normally stay on the cache until something takes it's place
torch.cuda.empty_cache()

7. 测试前调用 eval()

最后一个是开始测试前别忘了调用 model.eval() ,这个很简单但很容易忘记。这个操作会让一些在训练和验证阶段设置不一样的网络层有必要的改变,会有影响的模块包括:

  • Dropout
  • Batch Normalization
  • RNNs
  • Lazy Variants

这个可以参考:https://stackoverflow.com/questions/66534762/which-pytorch-modules-are-affected-by-model-eval-and-model-train

使用例子如下:

example_model = ExampleModel()# Do trainingexample_model.eval()# Do testingexample_model.train()# Do training again

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/408294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5 CSS3的新交互特性

什么是HTML5和CSS3 HTML和CSS并不难理解。HTML为构成网页的主要语言。通过这种语言,我们可以向计算机说明网页格式、内容、显示效果等等。而CSS则是专 门用来控制网页显示效果的语言。这时候问题出来了,为什么我们要单独使用CSS呢,HTML不是一…

基于Colab Pro Google Drive的Kaggle实战

原文:https://hippocampus-garden.com/kaggle_colab/ 原文标题:How to Kaggle with Colab Pro & Google Drive 译文作者:kbsc13 联系方式: Github:https://github.com/ccc013/AI_algorithm_notes 微信公众号&…

Focal Loss 论文笔记

论文:《Focal Loss for Dense Object Detection》 论文地址:https://arxiv.org/abs/1708.02002 代码地址: 官方 github:https://github.com/facebookresearch/detectrontensorflow:https://github.com/tensorflow/m…

php 构造骚扰短信发送机(仅供学习与参考,请勿用于非法用途)

最近在某宝买东西得罪了某黑心商家。。然后他就疯狂的给我发骚扰短信,烦死了。。。 短信大概就是利用一些网站的手机验证码来实现的。。 所以再被他疯狂骚扰后决定自己动手反击。。 php主要用到了curl的函数库扩展,然后主要要做的还是去抓包分析网站注册…

A Quantization-Friendly Separable Convolution for MobileNets

论文:《A Quantization-Friendly Separable Convolution for MobileNets》 论文地址:https://arxiv.org/pdf/1803.08607.pdf 这篇是高通在 2018 年发表的一篇论文,主要是针对在量化方面效果很差的 MobileNetV1 网络进行研究,探索…

神经稀疏体素场论文笔记

论文地址:https://proceedings.neurips.cc/paper/2020/file/b4b758962f17808746e9bb832a6fa4b8-Paper.pdf Github:https://github.com/facebookresearch/NSVF 摘要 使用经典计算机图形技术对真实世界场景进行逼真的自由视角渲染具有挑战性&#xff0c…

3dmax 学习

^_^,今天早上起来,外面黢黑一片还以为是深夜了,一看表才知道上课快要迟到了,迅速起床作整理工作,一边整理一边看看外面的天,真是太吓人了。别人说天狗吃月是晚上可以看到的,但是在这个东北&…

Linux学习系列之Linux入门(一)linux安装与入门

第一篇:安装并配置Linux开发环境 一、安装linux: 主要安装Linux的发行版,到目前为之,主要的发行版有: 比较常用的是Ubuntu、redhat和centOS,主要的安装方法详细: Ubuntu安装1、Ubuntu安装2,Redhat安装1、Re…

神经网络中的 Dropout 以及变体方法

Dropout 的学习笔记,主要参考文章: 12种主要的Dropout方法:如何应用于DNNs,CNNs,RNNs中的数学和可视化解释 【科普】神经网络中的随机失活方法 1. 简介 深度学习训练模型的一个主要挑战是协同适应,这意…

【论文精读】Deep Rectangling for Image Stitching: A Learning Baseline

代码:https://github.com/nie-lang/DeepRectangling 链接:https://arxiv.org/abs/2203.03831 概览 目前图像拼接的一个问题是拼接后会产生不规则的边界,如下图1 b所示。目前解决这类问题主要是通过图像矩形化方法,并且通常是分…

[论文笔记]Depth-Aware Multi-Grid Deep Homography Estimation with Contextual Correlation

论文地址:https://arxiv.org/abs/2107.02524 代码:https://github.com/nie-lang/Multi-Grid-Deep-Homography 1. 概览 单应性估计是计算机视觉应用中的一项重要任务,例如图像拼接、视频稳定和相机校准。传统的单应性估计方法严重依赖特征对…