热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

快速入门torch.nn(一)

本文翻译自:https:pytorch.orgtutorialsbeginnernn_tutorial.html这是第一部分:如何用纯Python构造一个神经网络。Pytorch提

本文翻译自:https://pytorch.org/tutorials/beginner/nn_tutorial.html 这是第一部分:如何用纯Python构造一个神经网络。

Pytorch提供了几个设计得非常棒的模块和类,比如 torch.nn,torch.optim,Dataset 以及 DataLoader,来帮助你设计和训练神经网络。为了充分利用他们来解决你的问题,你需要明白他们具体是做什么的。为了帮助大家理解这些内容,我们首先基于MNIST数据集,不用以上提到的模块和类来训练一个基础的神经网络,只用到基本的PyTorch tensor 函数。然后我们会逐渐地使用来自torch.nn,torch.optim,Dataset 以及 DataLoader的功能。展示每个模块具体的功能,他的运作过程。这样来使得代码逐渐简洁和灵活。

MNIST数据集

我们使用经典的MNIST数据集。这个数据集由手写数字0~9的黑白照片组成。

我们使用pathlib包来解决文件路径问题(这是python3的一个标准包),我们使用requests函数来下载数据。我们只导入我们需要用到的模块,所以你可以清晰地看到每一步具体用了什么。

from pathlib import Path
import requests
DATA_PATH = Path("data")
PATH = DATA_PATH / "mnist"
PATH.mkdir(parents=True, exist_ok=True)
URL = "http://deeplearning.net/data/mnist/"
FILENAME = "mnist.pkl.gz"
if not (PATH / FILENAME).exists():
content = requests.get(URL + FILENAME).content
(PATH / FILENAME).open("wb").write(content)

数据现在是numpy array格式,用pickle存储起来了。这是Python特有的串行数据格式。

import pickle
import gzip
with gzip.open((PATH / FILENAME).as_posix(), "rb") as f:
((x_train, y_train), (x_valid, y_valid), _) = pickle.load(f, encoding="latin-1")

每一张照片都是 28*28大小的一个数组,但是被存成了一个长度为784(28*28)的一行。现在给大家展示其中一张图片,首先我们要把它重新组织成28*28的一个二维形状。

from matplotlib import pyplot
import numpy as np
pyplot.imshow(x_train[0].reshape((28, 28)), cmap="gray")
print(x_train.shape)

输出:

《快速入门torch.nn(一)》
《快速入门torch.nn(一)》

(50000, 784)

Pytorch使用 torch.tensor,而不是 numpy arrays。所以我们首先需要转换我们的数据。

import torch
x_train, y_train, x_valid, y_valid = map(
torch.tensor, (x_train, y_train, x_valid, y_valid)
)
n, c = x_train.shape
print(x_train, y_train)
print(x_train.shape)
print(y_train.min(), y_train.max())

输出:

tensor([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]]) tensor([5, 0, 4, ..., 8, 4, 8])
torch.Size([50000, 784])
tensor(0) tensor(9)

利用scratch(不是 torch.nn)构建神经网络

让我们首先只用PyTorch tensor的基本操作来构造我们的神经网络。首先假设你已经有一定的神经网络知识基础。如果没有,可以在 course.fast.ai 里面学习。(译者:或者可以通过《神经网络设计》这本书学习,这本书深入浅出,从基本的神经元讲起,很适合初学者)

PyTorch提供了一些创建随机或者零张量(tensor)的方法。我们可以利用他们去构建线性模型(linear model)所用到的权值(weights)和偏移(bias)。这些都是常规的张量,除了一个方面,他们需要一个梯度(gradient)。这样会使得PyTorch会记录所有对这个张量所进行的操作,所以这样可以自动计算关于这些权值和偏移的梯度。(关于pytorch gradient这个问题具体可以看https://www.jianshu.com/p/cbce2dd60120 我也会马上写一篇关于介绍这个的文章)

对于权值张量,我们在初始化它的时候设置 requires_grad

import math
weights = torch.randn(784, 10) / math.sqrt(784)
weights.requires_grad_()
bias = torch.zeros(10, requires_grad=True)

多亏了PyTorch自动计算梯度的这个功能,所以我们可以用任何标准的PyTorch函数。所以让我们来构建一个包含矩阵乘法和张量加法的简单线性模型。我们还需要一个激活函数(activation function)。所以我们写一个 log_softmax 函数。记住:虽然PyTorch提供了大量写好的损失函数(loss function)和激活函数(activation function)。但是你也可以用简单基本的Python语言实现。

def log_softmax(x):
return x - x.exp().sum(-1).log().unsqueeze(-1)
def model(xb):
return log_softmax(xb @ weights + bias)

以上代码中“@”表示点积(dot production)操作,我们将会使他作用于每一批量(batch)的数据(这个例子是64张图片的数据)。这是一次向前过程(forward pass)。注意我们这样的预测并不会比随机判断好多少,因为我们的权值刚开始是随机产生的。

bs = 64 # batch size
xb = x_train[0:bs] # a mini-batch from x
preds = model(xb) # predictions
preds[0], preds.shape
print(preds[0], preds.shape)

输出:

tensor([-1.5058, -2.1150, -2.4652, -2.4982, -2.4030, -3.0075, -2.2017, -2.8193,
-2.6561, -2.2075], grad_fn=) torch.Size([64, 10])

正如你所看到的一样,张量 preds 不仅包含了他的数值,也包含一个梯度函数。我们等下会用到它来做反向传播。

然我们来实现一个 negative log_likehood 函数作为他的损失函数。仍然用的是Python 标准函数,没有用PyTorch集成的函数。

def nll(input, target):
return -input[range(target.shape[0]), target].mean()
loss_func = nll

让我们来检测一下我们模型的损失值,这样我们在下一个回合就可以比较损失值的变化了。

yb = y_train[0:bs]
print(loss_func(preds, yb))

输出:

tensor(2.2584, grad_fn=)

让我们再来实现一个函数计算我们模型预测出来的结果的正确性。在每次预测中,输出向量最大值得下标索引如果和目标值(标签)相同,则认为预测结果是对的。

def accuracy(out, yb):
preds = torch.argmax(out, dim=1)
return (preds == yb).float().mean()

让我们来检测我们模型的正确率,这样我们就可以看到随着损失函数的提升,正确率也随之提升。

print(accuracy(preds, yb))

输出:

tensor(0.1094)

现在我们可以运行整个训练过程。在每次迭代中,我们将会:

  • 选择一个最小批量的数据(代码中表示为 bs,即每次进入神经网络的数据单元)
  • 用模型去得到预测结果
  • 计算损失函数值
  • loss.backward()更新模型的梯度,在这里是权值(weights)和偏移(bias)。

现在我们用梯度去更新权值和偏移。我们在更新时设置 torch.no_grad() ,因为我们不想把这个操作也记录到梯度中。

然后我们把梯度清零。这样我们就可以进行下一个循环过程。不然的话梯度会记录所有的操作。

from IPython.core.debugger import set_trace
lr = 0.5 # learning rate
epochs = 2 # how many epochs to train for
for epoch in range(epochs):
for i in range((n - 1) // bs + 1):
# set_trace()
start_i = i * bs
end_i = start_i + bs
xb = x_train[start_i:end_i]
yb = y_train[start_i:end_i]
pred = model(xb)
loss = loss_func(pred, yb)
loss.backward()
with torch.no_grad():
weights -= weights.grad * lr
bias -= bias.grad * lr
weights.grad.zero_()
bias.grad.zero_()

这就是我们用纯Python构建的神经网络。(这个例子中,这是一个逻辑回归,就两层,没有隐含层)。

让我们来检测这个模型的损失值和正确率。我们期望的是损失值能够降下来,正确率能够上升。

print(loss_func(model(xb), yb), accuracy(model(xb), yb))

输出:

tensor(0.0849, grad_fn=) tensor(1.)

正确率是1.


推荐阅读
  • 在腾讯云服务器上部署Nginx的详细指南中,首先需要确保安装必要的依赖包。如果这些依赖包已安装,可直接跳过此步骤。具体命令包括 `yum -y install gcc gcc-c++ wget net-tools pcre-devel zlib-devel`。接下来,本文将详细介绍如何下载、编译和配置Nginx,以确保其在腾讯云服务器上顺利运行。此外,还将提供一些优化建议,帮助用户提升Nginx的性能和安全性。 ... [详细]
  • 解决Only fullscreen opaque activities can request orientation错误的方法
    本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 微信公众号推送模板40036问题
    返回码错误码描述说明40001invalidcredential不合法的调用凭证40002invalidgrant_type不合法的grant_type40003invalidop ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 通过使用CIFAR-10数据集,本文详细介绍了如何快速掌握Mixup数据增强技术,并展示了该方法在图像分类任务中的显著效果。实验结果表明,Mixup能够有效提高模型的泛化能力和分类精度,为图像识别领域的研究提供了有价值的参考。 ... [详细]
  • 在Windows环境下离线安装PyTorch GPU版时,首先需确认系统配置,例如本文作者使用的是Win8、CUDA 8.0和Python 3.6.5。用户应根据自身Python和CUDA版本,在PyTorch官网查找并下载相应的.whl文件。此外,建议检查系统环境变量设置,确保CUDA路径正确配置,以避免安装过程中可能出现的兼容性问题。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • Egg.js 中间件详解与应用实例
    Egg.js 的中间件机制与 Koa 类似,均采用洋葱模型。每当开发一个中间件时,就像是在洋葱外增加了一层。本文将通过一个简单的中间件示例,详细介绍 Egg.js 中间件的编写方法及其应用场景,帮助读者更好地理解和使用这一功能。 ... [详细]
  • STAR: 转录组数据分析中的高效比对工具介绍
    欢迎关注“生信修炼手册”!STAR 是一款专为 RNA-seq 数据设计的高效比对工具,以其卓越的速度和高灵敏度著称。该软件在处理大规模转录组数据时表现出色,能够显著提高比对效率和准确性。此外,GATK 推荐使用 STAR 进行预处理步骤,以确保后续分析的可靠性。 ... [详细]
  • PyTorch 使用问题:解决导入 torch 后 torch.cuda.is_available() 返回 False 的方法
    在配置 PyTorch 时,遇到 `torch.cuda.is_available()` 返回 `False` 的问题。本文总结了多种解决方案,并分享了个人在 PyCharm、Python 和 Anaconda3 环境下成功配置 CUDA 的经验,以帮助读者避免常见错误并顺利使用 GPU 加速。 ... [详细]
author-avatar
嘤_嘤_嘤
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有