【机器学习】PyTorch 基本网络实现

地点:鉴主
时间:2017-1130
本文主要记录学习 Pytorch Tutorials 过程中的笔记及相关问题。

PyTorch 的相关背景就不做介绍了,网上很多。
在实际的使用过程中来看,对比之前用过的 TensorFlow 和 Keras 而言,使用 PyTorch 就像是在写一个普通的 Python 程序,而不是像 TF 和 Keras 一样限制颇多,因此在使用的过程中,相比于其他框架能够很清楚自己做的是什么,非常的新手友好。

PyTorch 基本概念

机器学习方面的几个重要概念在 PyTorch 主要通过 Tensors, Autograd, nn module 进行体现。

Tensors

Numpy 是一个很好的计算工具,但是它无法使用 GPUs 加速数值计算,因此性能不能满足要求。
首先引入最基本的 PyTorch 概念: Tensor. Tensor 是一个 n 维数组,同时 PyTorch 提供了多种函数对它进行操作。与 Numpy.array 相同的是, PyTorch 的 Tensors 不包含任何 深度学习,计算图或者梯度 这些科学计算的工具。
然而不同于 numpy 的是,PyTorch 的 Tensors 能够利用 GPUs 来进行加速数值计算。在 GPU 上运行 PyTorch 的 Tensor, 我们需要将它简单转换一下数据格式。

# -*- coding: utf-8 -*-

import torch

dtype = torch.FloatTensor
# dtype = torch.cuda.FloatTensor # 在 GPU 上运行调用的函数

# N is 批数目; D_in is 输入维数;
# H is 隐藏层维数; D_out is 输出层维数.
N, D_in, H, D_out = 64, 1000, 100, 10

# 创建随机输入输出数据
x = torch.randn(N, D_in).type(dtype)
y = torch.randn(N, D_out).type(dtype)

# 随机初始化权重文件
w1 = torch.randn(D_in, H).type(dtype)
w2 = torch.randn(H, D_out).type(dtype)

# 设置学习率
learning_rate = 1e-6

for t in range(500):
    # 前向传播,计算预测的 y 值 
    h = x.mm(w1)
    h_relu = h.clamp(min=0)
    y_pred = h_relu.mm(w2)

    # 计算并且输出 loss 值
    loss = (y_pred - y).pow(2).sum()
    print(t, loss)

    # 基于 loss 值 反向传播计算 w1 和 w2 的梯度
    grad_y_pred = 2.0 * (y_pred - y)
    grad_w2 = h_relu.t().mm(grad_y_pred)
    grad_h_relu = grad_y_pred.mm(w2.t())
    grad_h = grad_h_relu.clone()
    grad_h[h < 0] = 0
    grad_w1 = x.t().mm(grad_h)

    # 使用梯度下降更新权值
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

可以看出,在实际的操作上面,其使用方法和 numpy 非常相似。

Autograd

上面的例子实现了前向传播和反向传播,这是神经网络的基础。在实际的过程中,我们可以使用 Automatic Differentiation 来自动计算神经网络的反向传播值。PyTorch 中的 autograd 包就是用于提供这个功能。

When using autograd, the forward pass of your network will define a computational graph; nodes in the graph will be Tensors, and edges will be functions that produce output Tensors from input Tensors. Backpropagating through this graph then allows you to easily compute gradients.
当使用 autograd 时,你网络中的前向传播将会定义一个计算图,在这个图中的每个节点都是张量,边可以提供从输入张量到输出张量的处理功能。随后图中的反向传播过程能够让你简单计算梯度。

在实际的使用中非常简单。我们将 PyTorch 的 Tensors 包装进 Variable ; 一个 Varible 展示了计算图中的一个节点。如果 x 是一个 Variable ,x.data 既是张量,x.grad 是另一个 Variable,其中包含了通过变换值求出的 x 梯度。

PyTorch Variable 的操作基本和 PyTorch Tensors 一样。区别在于使用 Variable 定义的是一个计算图,允许网络自动求梯度。

随后使用 Variables 和 autograd 来实现上文的神经网络, 现在我们不需要再实现上文的 backward pass 过程。

import torch
from torch.autograd import Variable

dtype = torch.FloatTensor
# dtype = torch.cuda.FloatTensor  # gpu 运行时的代码

# N is 批数目; D_in is 输入维数;
# H is 隐藏层维数; D_out is 输出层维数.
N, D_in, H, D_out = 64, 1000, 100, 10

# 创建随机 Tensors 来保存  输入和输出, 随后将它们包进 Variables 
# 设置 requires_grad = False 来表示我们无需计算梯度
# with respect to these Variables during the backward pass.
x = Variable(torch.randn(N, D_in).type(dtype), requires_grad=False)
y = Variable(torch.randn(N, D_out).type(dtype), requires_grad=False)

# 为权值创建随机 Tensor, 并且将它们包进 Variables 
# 设置 requires_grad = True 表示我们需要计算梯度 
# respect to these Variables during the backward pass.
w1 = Variable(torch.randn(D_in, H).type(dtype), requires_grad=True)
w2 = Variable(torch.randn(H, D_out).type(dtype), requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    # Forward pass: 使用 Variables 中的值计算 y;这个操作和我们使用 Tensors 计算
    # 时一样, 但是我们不需要保持对中间值的引用,因为我们无需动手实现 backward pass .
    y_pred = x.mm(w1).clamp(min=0).mm(w2)

    # 使用 Variable 中的函数计算并且输出 loss 值 
    # 此时 loss 值是一个 shape (1, ) 的 Variable,并且 loss.data 是一个形状为 (1, ) 的 Tensor。
    # loss.data[0] 是一个保存 loss 值的标量
    loss = (y_pred - y).pow(2).sum()
    print(t, loss.data[0])

    # 使用 autograd 计算 backward pass. 这个调用将会计算 loss 值的梯度,依据的是
    # 所有 requires_grad = True 的 Variable。
    # After this call w1.grad and w2.grad will be Variables holding the gradient
    # of the loss with respect to w1 and w2 respectively.
    loss.backward()

    # 使用 梯度下降更新权值;w1.data 和 w2.data 是 Tensors。
    # w1.grad 和 w2.grad 是 Variable; w1.grad.data 和 w2.grad.data 是 Tensors
    w1.data -= learning_rate * w1.grad.data
    w2.data -= learning_rate * w2.grad.data

    # 更新权值之后将梯度归 0
    w1.grad.data.zero_()
    w2.grad.data.zero_()

PyTorch : Variables and autograd

nn module

PyTorch CNN

为了进行实际操作,用 PyTorch 构建一个 CNN 是很常见的方法。
首先需要导入基本的包。

参考

http://pytorch.org/tutorials/beginner/pytorch_with_examples.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容