Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >3个Tricks帮你提升你Debug Pytorch的效率

3个Tricks帮你提升你Debug Pytorch的效率

作者头像
石晓文
发布于 2020-11-09 03:26:51
发布于 2020-11-09 03:26:51
1.3K00
代码可运行
举报
文章被收录于专栏:小小挖掘机小小挖掘机
运行总次数:0
代码可运行

作者:Adrian Wälchli 编译:ronghuaiyang

导读

好的工具和工作习惯可以极大的提升工作效率。

每一个深度学习项目都是不同的。不管你有多少经验,你总会遇到新的挑战和意想不到的行为。你在项目中运用的技巧和思维方式将决定你多快发现并解决这些阻碍成功的障碍。

从实践的角度来看,深度学习项目从代码开始。一开始组织它很容易,但是随着项目的复杂性的增加,在调试和完整性检查上花费的时间会越来越多。令人惊讶的是,其中很多都可以自动完成。在这篇文章中,我将告诉你如何去做。

  • 找出为什么你的训练损失没有降低
  • 实现模型自动验证和异常检测
  • 使用PyTorch Lightning节省宝贵的调试时间

为了演示,我们将使用一个简单的MNIST分类器的例子,这里有几个bug:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import MNIST


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = nn.Dropout(0.25)
        self.dropout2 = nn.Dropout(0.5)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        output = F.log_softmax(x, dim=0)
        return output


def train(model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (x, y) in enumerate(train_loader):
        x, y = x.to(device), y.to(device)
        optimizer.zero_grad()
        output = model(x)
        loss = F.nll_loss(output, y)
        loss.backward()
        optimizer.step()
        if batch_idx % 10 == 0:
            print(f'Epoch: {epoch} [{100. * batch_idx / len(train_loader):.0f}%]\tLoss: {loss.item():.6f}')


def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for x, y in test_loader:
            x, y = x.to(device), y.to(device)
            output = model(x)
            test_loss += F.nll_loss(x, y, reduction='sum').item()  # sum up batch loss
            pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
            correct += pred.eq(y.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)
    print(
        f'\nTest set: Average loss: {test_loss:.4f},'
        f' Accuracy: {100. * correct / len(test_loader.dataset):.0f}%\n'
    )


def main():
    use_cuda = torch.cuda.is_available()
    device = torch.device("cuda" if use_cuda else "cpu")
    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize(128., 1.),
    ])
    train_dataset = MNIST('./data', train=True, download=True, transform=transform)
    test_dataset = MNIST('./data', train=False, transform=transform)
    train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=1)
    test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=1)

    model = Net().to(device)
    optimizer = optim.Adadelta(model.parameters(), lr=1.0)
    scheduler = StepLR(optimizer, step_size=1, gamma=0.7)

    epochs = 14
    for epoch in range(1, epochs + 1):
        train(model, device, train_loader, optimizer, epoch)
        test(model, device, test_loader)
        scheduler.step()


if __name__ == '__main__':
    main()

这是最原味的MNIST PyTorch代码,改编自github.com/pytorch/examples,如果你运行这段代码,你会发现损失不降,并且在第一个epoch之后,测试循环会崩溃。怎么回事?

Trick 0: 组织好你的PyTorch代码结构

在调试此代码之前,我们将把它组织成Lightning格式。PyTorch Lightning将所有的boilerplate/engineering代码自动放在一个Trainer对象中,并整齐地将所有的实际的研究代码放到了LightningModule中,这样我们就可以专注于最重要的部分:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import transforms, datasets
from torch.optim.lr_scheduler import StepLR
import pytorch_lightning as pl
from pytorch_lightning.metrics.functional.classification import accuracy


class LitClassifier(pl.LightningModule):

    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = nn.Dropout2d(0.25)
        self.dropout2 = nn.Dropout2d(0.5)
        self.fc1 = nn.Linear(9216, 128)
        self.fc2 = nn.Linear(128, 10)
        self.example_input_array = torch.rand(5, 1, 28, 28)

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = torch.flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        output = F.log_softmax(x, dim=0)
        return output

    def dataloader(self, train=False):
        transform = transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize(128, 1)
        ])
        dataset = datasets.MNIST('data', train=train, download=True, transform=transform)
        dataloader = torch.utils.data.DataLoader(dataset, batch_size=64, pin_memory=True, shuffle=True, num_workers=1)
        return dataloader

    def train_dataloader(self):
        return self.dataloader(train=True)

    def val_dataloader(self):
        return self.dataloader(train=False)

    def training_step(self, batch, batch_nb):
        x, y = batch
        output = self(x)
        loss = F.nll_loss(output, y)
        acc = accuracy(torch.max(output, dim=1)[1], y)
        self.log('train_loss', loss, on_step=True)
        self.log('train_acc', acc, on_step=True, prog_bar=True)
        return loss

    def validation_step(self, batch, batch_nb):
        x, y = batch
        output = self(x)
        loss = F.nll_loss(x, y)
        acc = accuracy(torch.max(output, dim=1)[1], y)
        self.log('val_loss', loss, on_epoch=True, reduce_fx=torch.mean)
        self.log('val_acc', acc, on_epoch=True, reduce_fx=torch.mean)

    def configure_optimizers(self):
        optimizer = torch.optim.Adadelta(model.parameters(), lr=1.0)
        scheduler = StepLR(optimizer, step_size=1, gamma=0.7)
        return [optimizer], [scheduler]


if __name__ == "__main__":
    model = LitClassifier()
    trainer = pl.Trainer(gpus=1)
    trainer.fit(model)

你能找出这段代码中的所有bug吗?

Lightning负责处理许多经常导致错误的工程模式:训练、验证和测试循环逻辑、将模型从训练模式切换到eval模式或反之、将数据移动到正确的设备、检查点、日志记录等等。

Trick 1: 检查验证循环的完整性

如果我们运行上面的代码,我们会立即得到一条错误消息,说在验证步骤的第65行中大小不匹配。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
...
---> 65         loss = F.nll_loss(x, y)
     66         acc = accuracy(torch.max(output, dim=1)[1], y)
     67         self.log('val_loss', loss, on_epoch=True, 
                reduce_fx=torch.mean)
...RuntimeError: 1only batches of spatial targets supported (3D tensors) but got targets of size: : [64]

如果你注意到了,Lightning在训练开始前运行了两个验证步骤。这不是一个bug,而是一个[特性](https://pytoring-lightning.readthedocs.io/en/stable/debugging.html #设置验证健全步骤的数量)!这实际上为我们节省了大量的时间,否则,如果错误发生在长时间的训练之后,我们就会浪费很多时间。Lightning在开始时检查验证循环,这让我们可以快速修复错误,因为很明显,现在应该读取第65行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
loss = F.nll_loss(output, y)

就像在训练步骤中一样。

这是一个很容易解决的问题,因为堆栈跟踪告诉我们哪里出了问题,而且这是一个明显的错误。修正后的代码现在运行没有错误,但如果我们查看进度条中的损失值,我们会发现它停留在2.3。这可能有很多原因:错误的优化器,糟糕的学习率或学习率策略,错误的损失函数,数据的问题等等。

PyTorch Lightning内置了TensorBoard ,在这个例子中,训练损失和验证损失都没有减少。

Trick 2: 记录训练数据的直方图

经常检查输入数据的范围是很重要的。如果模型权重和数据是非常不同的量级,它可能导致没有或非常低的学习进展,并在极端情况下导致数值不稳定。例如,当以错误的顺序应用数据扩充或忘记了归一化时,就会发生这种情况。我们的例子中是这样的吗?我们应该可以通过打印最小值和最大值来找出答案。但是等等!这不是一个好的解决方案,因为它会不必要地污染代码,并且在需要的时候需要花费太多的时间来重复它。更好的方法:写一个回调类来为我们完成它!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class InputMonitor(pl.Callback):

    def on_train_batch_start(self, trainer, pl_module, batch, batch_idx, dataloader_idx):
        if (batch_idx + 1) % trainer.log_every_n_steps == 0:
            x, y = batch
            logger = trainer.logger
            logger.experiment.add_histogram("input", x, global_step=trainer.global_step)
            logger.experiment.add_histogram("target", y, global_step=trainer.global_step)

            
# use the callback like this:
model = LitClassifier()
trainer = pl.Trainer(gpus=1, callbacks=[InputMonitor()])
trainer.fit(model)

一个简单的回调,它将训练数据的直方图记录到TensorBoard中。

PyTorch Lightning中的回调可以保存可以注入训练器的任意代码。这个在进入训练步骤之前计算输入数据的直方图。将此功能封装到回调类中有以下优点:

  1. 它与你的研究代码是分开的,没有必要修改你的LightningModule!
  2. 它是可移植的,因此可以在未来的项目中重用,并且只需要更改两行代码:导入回调,然后将其传递给Trainer。
  3. 可以通过子类化或与其他回调组合来扩展。

现在有了新的回调功能,我们可以打开TensorBoard并切换到“直方图”选项卡来检查训练数据的分布情况:

目标在范围[0,9]中,这是正确的,因为MNIST有10位的类,但是图像的值在-130到-127之间,这是错误的!我们很快发现在第41行归一化中有一个问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
transforms.Normalize(128, 1)  # wrong normalization

这两个数字应该是输入数据的平均值和标准差(在我们的例子中,是图像中的像素)。为了解决这个问题,我们添加了真实的平均值和标准差,也命名了参数,以使其更清楚:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
transforms.Normalize(mean=0.1307, std=0.3081)

我们可以查一下这些数字,因为它们是已知的。对于你自己的数据集,你必须自己计算。

经过归一化处理后,像素点的均值为0,标准差为1,就像分类器的权重一样。我们可以通过看TensorBoard的直方图来确认这一点。

Trick 3: 在前向传播中检测异常

在修复了归一化问题之后,我们现在也可以在TensorBoard中得到预期的直方图。但不幸的是,损失仍然没有降低。还是有问题。我知道数据是正确的,开始查找错误的一个好地方是网络的前向路径。一个常见的错误来源是操纵张量形状的操作,如permute、reshape、view、flatten等,或应用于一维的操作,如softmax。当这些函数被应用在错误的尺寸或错误的顺序上时,我们通常会得到一个形状不匹配的错误,但情况并不总是如此!这些bug很难追踪。

让我们来看看一种技术,它可以让我们快速地检测出这些错误。

快速检查模型是否在批处理中混合数据。

想法很简单:如果我们改变第n个输入样本,它应该只对第n个输出有影响。如果其他输出i≠n也发生变化,则模型会混合数据,这就不好了!一个可靠的方法来实现这个测试是计算关于所有输入的第n个输出的梯度。对于所有i≠n(上面动画中为红色),梯度必须为零,对于i = n(上面动画中为绿色),梯度必须为非零。如果满足这些条件,则模型通过了测试。下面是n = 3时的实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# examine the gradient of the n-th minibatch sample w.r.t. all inputs
n = 3  

# 1. require gradient on input batch
example_input = torch.rand(5, 1, 28, 28, requires_grad=True)

# 2. run batch through model
output = model(example_input)

# 3. compute a dummy loss on n-th output sample and back-propagate
output[n].abs().sum().backward()

# 4. check that gradient on samples i != n are zero!
# sanity check: if this does not return 0, you have a bug!
i = 0
example_input.grad[i].abs().sum().item()

这里是同样的Lightning Callback:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class CheckBatchGradient(pl.Callback):
    
    def on_train_start(self, trainer, model):
        n = 0

        example_input = model.example_input_array.to(model.device)
        example_input.requires_grad = True

        model.zero_grad()
        output = model(example_input)
        output[n].abs().sum().backward()
        
        zero_grad_inds = list(range(example_input.size(0)))
        zero_grad_inds.pop(n)
        
        if example_input.grad[zero_grad_inds].abs().sum().item() > 0
            raise RuntimeError("Your model mixes data across the batch dimension!")
            
            
# use the callback like this:
model = LitClassifier()
trainer = pl.Trainer(gpus=1, callbacks=[CheckBatchGradient()])
trainer.fit(model)

将这个测试应用到LitClassifer上,可以立即发现它混合了数据。现在知道了我们要找的是什么,我们很快就发现了正向传播中的一个错误。第35行中的softmax被应用到了错误的维度上:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
output = F.log_softmax(x, dim=0)

应该是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
output = F.log_softmax(x, dim=1)

好了,分类器开始工作了!训练和验证损失迅速降低。

![](3 Simple Tricks That Will Change the Way You Debug Pytorch.assets/1_1_HWZbn7RkHwKnLutk5kfg.jpeg)

总结

编写好的代码从组织开始。PyTorch Lightning通过删除围绕训练循环工程、检查点保存、日志记录等的样板代码来处理这一部分。剩下的是实际的研究代码:模型、优化和数据加载。如果某些东西没有按照我们期望的方式工作,很可能是代码的这三部分中的某一部分有错误。在这篇博文中,我们实现了两个回调,帮助我们1)监控进入模型的数据,2)验证我们网络中的各层不会在批处理维度上混合数据。回调的概念是向现有算法添加任意逻辑的一种非常优雅的方式。一旦实现,就可以通过更改两行代码轻松地将其集成到新项目中。

—END—

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小小挖掘机 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
国家信息中心数据恢复中心官网_stn源源
写在前面:目前在学习pytorch官方文档的内容,以此来记录自己的学习过程,本次学习的是STN网络。 传送门:官方文档 中文翻译 STN论文链接(Spatial Transformer Networks ) 为什么要用到STN网络呢: 卷积神经网络定义了一个异常强大的模型类,但在计算和参数有效的方式下仍然受限于对输入数据的空间不变性。在此引入了一个新的可学模块,空间变换网络,它显式地允许在网络中对数据进行空间变换操作。这个可微的模块可以插入到现有的卷积架构中,使神经网络能够主动地在空间上转换特征映射,在特征映射本身上有条件,而不需要对优化过程进行额外的训练监督或修改。我们展示了空间变形的使用结果,在模型中学习了平移、缩放、旋转和更一般的扭曲,结果在几个基准上得到了很好的效果。
全栈程序员站长
2022/11/10
7650
国家信息中心数据恢复中心官网_stn源源
Pytorch基础 | eval()的用法比较
model.train()的作用是启用 Batch Normalization 和 Dropout。
公众号机器学习与AI生成创作
2021/04/30
10.1K0
Pytorch基础 | eval()的用法比较
PyTorch中神经网络的对抗性攻击和防御
深度学习和神经网络的兴起为现代社会带来了各种机会和应用,例如对象检测和文本转语音。然而,尽管看似准确性很高,但神经网络(以及几乎所有机器学习模型)实际上都可能受到数据(即对抗性示例)的困扰,而这些数据是从原始训练样本中进行的非常轻微的操纵。实际上,过去的研究表明,只要您知道更改数据的“正确”方法,就可以迫使您的网络在数据上表现不佳,而这些数据在肉眼看来似乎并没有什么不同!这些对数据进行有意操纵以降低模型精度的方法称为对抗性攻击,而攻击与防御之战是机器学习领域中持续流行的研究主题。
代码医生工作室
2020/09/14
2.1K0
【深度学习入门篇 ④ 】Pytorch实现手写数字识别
通过前面的学习,我们已经掌握了PyTorch API的基本使用,今天我们使用PyTorch实现手写数字识别案例!
@小森
2024/07/25
2860
【深度学习入门篇 ④ 】Pytorch实现手写数字识别
听,是梯度的声音!用听觉监控神经网络训练,边听音乐边炼丹
训练神经网络是个极为枯燥的工作。与其盯着Learning Curves发呆,或许可以调动一下其他感官,一起做点更有意思的事情。
大数据文摘
2019/08/08
5470
听,是梯度的声音!用听觉监控神经网络训练,边听音乐边炼丹
手撕CNN的MNIST手写数字识别
废话不多说直接上代码,这次研究了一下pytorch中的二维卷积的函数,所以人为的改了一下代码,毕竟一直模仿是行不通的,就和修车一样,你得拆了之后再组装起来才能说明你good at修车。
Tom2Code
2023/02/14
4890
手撕CNN的MNIST手写数字识别
STN:空间变换网络(Spatial Transformer Network)「建议收藏」
卷积神经网络定义了一个异常强大的模型类,但在计算和参数有效的方式下仍然受限于对输入数据的空间不变性。在此引入了一个新的可学模块,空间变换网络,它显式地允许在网络中对数据进行空间变换操作。这个可微的模块可以插入到现有的卷积架构中,使神经网络能够主动地在空间上转换特征映射,在特征映射本身上有条件,而不需要对优化过程进行额外的训练监督或修改。我们展示了空间变形的使用结果,在模型中学习了平移、缩放、旋转和更一般的扭曲,结果在几个基准上得到了很好的效果。
全栈程序员站长
2022/11/19
1.6K0
STN:空间变换网络(Spatial Transformer Network)「建议收藏」
用PyTorch实现MNIST手写数字识别(非常详细)
MNIST可以说是机器学习入门的hello word了!导师一般第一个就让你研究MNIST,研究透了,也算基本入门了。好的,今天就来扯一扯学一学。
小锋学长生活大爆炸
2020/08/13
2K0
用PyTorch实现MNIST手写数字识别(非常详细)
是选择Keras还是PyTorch开始你的深度学习之旅呢?
原文:https://medium.com/@karan_jakhar/keras-vs-pytorch-dilemma-dc434e5b5ae0
kbsc13
2020/05/22
5670
libtorch系列教程3:优雅地训练MNIST分类模型
在这篇文章中,我们对如何使用Libtorch进行MNIST分类模型的训练和测试进行详细描述。首先会浏览官方MNIST示例,然后对其进行模块化重构,为后续别的模型的训练提供 codebase。
王云峰
2023/10/23
5590
从原始图片数据开始构建卷积神经网络(Pytorch)
说在前面入门机器学习的时候,我们往往使用的是框架自带的数据集来进行学习的,这样其实跳过了机器学习最重要的步骤,数据预处理,本文通过从原始数据(图片格式)到卷积神经网络的设计,逐步实现 MNIST 的分类本文使用的是 Facebook 的深度学习框架 PytorchMNIST 数据集是机器学习界的 HelloWorld ,主要是手写字符(0-9)数据下载:后台回复 MNIST 获取下载链接# 导入所需要的包 import torch # 1.1.0 版本 from torchvision import dat
机器视觉CV
2019/07/17
8760
Pytorch打怪路(二)pytorch进行mnist训练和测试
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Teeyohuang/article/details/79242946
TeeyoHuang
2019/05/25
1.9K0
Pytorch实现STN
import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import torchvision from torchvision import datasets, transforms import matplotlib.pyplot as plt import numpy as np class TPSNet(nn.Module): def __init__(self): super(TPSNet, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.conv2_drop = nn.Dropout2d() self.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) # Spatial transformer localization-network self.localization = nn.Sequential( nn.Conv2d(in_channels=1, out_channels=8, kernel_size=7), nn.MaxPool2d(kernel_size=2, stride=2), nn.ReLU(True), nn.Conv2d(in_channels=8, out_channels=10, kernel_size=5), nn.MaxPool2d(kernel_size=2, stride=2), nn.ReLU(True) ) # Regressor for the 3 * 2 affine matrix self.fc_loc = nn.Sequential( nn.Linear(10 * 3 * 3, 32), nn.ReLU(True), nn.Linear(32, 3 * 2) ) # Initialize the weights/bias with identity transformation self.fc_loc[2].weight.data.fill_(0) self.fc_loc[2].bias.data = torch.FloatTensor([1, 0, 0, 0, 1, 0]) # Spatial transformer network forward function def stn(self, x): #x是[b,1,28,28] xs = self.localization(x) #xs是[b,10,3,3] xs = xs.view(-1, 10 * 3 * 3) #xs是[b,90] theta = self.fc_loc(xs) #theta是[b,6] theta = theta.view(-1, 2, 3) grid = F.affine_grid(theta, x.size()) x = F.grid_sample(x, grid) #x是[b,1,28,28] return x def forward(self, x): # transform the input #x是[b,1,28,28] x = self.stn(x) #x是[b,1,28,28] # Perform the usual forward pass x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) x = self.fc2(x) return F.log_softmax(x, dim=1) def train(epoch): model.train() for batch_idx, (data, target) in enumerate(train_loader): if use_cuda: data, target = data.cuda(), target.cuda() optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target) #和TPSNet中的log_softmax搭配,就是CE loss loss.backward() optimizer.step() if batch_idx
全栈程序员站长
2022/11/02
4400
Pytorch实现STN
PyTorch 系列教程之空间变换器网络
在本教程中,您将学习如何使用称为空间变换器网络的视觉注意机制来扩充您的网络。你可以在DeepMind paper 阅读更多有关空间变换器网络的内容。
磐创AI
2019/09/24
7060
PyTorch 系列教程之空间变换器网络
教程 | PyTorch经验指南:技巧与陷阱
项目地址:https://github.com/Kaixhin/grokking-pytorch
机器之心
2018/08/07
1.5K0
教程 | PyTorch经验指南:技巧与陷阱
【colab pytorch】使用tensorboard可视化
import datetime import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.utils.data import Dataset, DataLoader from torchvision import transforms, utils, datasets from tensorflow import summary %load_ext t
西西嘛呦
2020/08/26
1K0
【colab pytorch】使用tensorboard可视化
PyTorch深度学习(2)
Deep Learning = Learning Hierarchical Representations 深度学习即学习层次的表征。
何武凡
2023/03/09
3700
PyTorch深度学习(2)
PyTorch Lightning工具学习
【GiantPandaCV导语】Pytorch Lightning是在Pytorch基础上进行封装的库(可以理解为keras之于tensorflow),为了让用户能够脱离PyTorch一些繁琐的细节,专注于核心代码的构建,提供了许多实用工具,可以让实验更加高效。本文将介绍安装方法、设计逻辑、转化的例子等内容。
BBuf
2020/12/09
1.6K0
PyTorch Lightning工具学习
stn  pytorch[通俗易懂]
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/02
2660
从原始图片数据开始构建卷积神经网络(Pytorch)
入门机器学习的时候,我们往往使用的是框架自带的数据集来进行学习的,这样其实跳过了机器学习最重要的步骤,数据预处理,本文通过从原始数据(图片格式)到卷积神经网络的设计,逐步实现 MNIST 的分类
机器视觉CV
2019/07/12
8270
推荐阅读
相关推荐
国家信息中心数据恢复中心官网_stn源源
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文