热门标签 | 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.


推荐阅读
  • 对于初学者而言,搭建一个高效稳定的 Python 开发环境是入门的关键一步。本文将详细介绍如何利用 Anaconda 和 Jupyter Notebook 来构建一个既易于管理又功能强大的开发环境。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 【图像分类实战】利用DenseNet在PyTorch中实现秃头识别
    本文详细介绍了如何使用DenseNet模型在PyTorch框架下实现秃头识别。首先,文章概述了项目所需的库和全局参数设置。接着,对图像进行预处理并读取数据集。随后,构建并配置DenseNet模型,设置训练和验证流程。最后,通过测试阶段验证模型性能,并提供了完整的代码实现。本文不仅涵盖了技术细节,还提供了实用的操作指南,适合初学者和有经验的研究人员参考。 ... [详细]
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解Tornado模板系统
    本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文探讨了如何在Python中处理长数据的完全显示问题,包括numpy数组、pandas DataFrame以及tensor类型的完整输出设置。 ... [详细]
  • 在Conda环境中高效配置并安装PyTorch和TensorFlow GPU版的方法如下:首先,创建一个新的Conda环境以避免与基础环境发生冲突,例如使用 `conda create -n pytorch_gpu python=3.7` 命令。接着,激活该环境,确保所有依赖项都正确安装。此外,建议在安装过程中指定CUDA版本,以确保与GPU兼容性。通过这些步骤,可以确保PyTorch和TensorFlow 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社区 版权所有