Make Your First GAN With PyTorch:1.PyTorch基础

本章主要是介绍 PyTorch,并通过构建简单的练习,来加深有关神经网络的理解。
本章是 Make Your First GAN With PyTorch 的第一章,其他介绍详见这篇文章

我们当然可以使用 Pythonnumpy 库来创建简单但有效的神经网络。但是构建更大的网络任务艰巨,特别是是通过做微积分来找到网络中后向传播误差(back­propagated error)和权重(weights)之间的关系。而且网络中一点点的改变,就需要完全重做上述工作。

而使用 PyTorch 等深度学习框架,可以避免很多低水平的重复工作,转而更关注于网络的设计问题。不管想要什么类型、什么尺寸的网络, PyTorch 可以做所有的微积分;而且,即使改变网络的设计,PyTorch 可以自动计算出新的微积分,不需要再次手工计算梯度。

特别是,PyTorch 的语法和用法很接近普通的 Python,这降低了入门的难度。

PyTorch 是一个开源的 Python 机器学习库,最初由 Facebook 的人工智能研究团队开发。
除了 PyTorch 外,还有诸如 TensorFlowCaffe 等其他开源框架。

1. Google Colab

Make Your First GAN With PyTorch 中主要是使用了 Google Colab 服务,通过在线的 Python notebook 在线运行我们的代码。Colab 完全通过浏览器接入,不需要在自己的电脑上安装任何软件。

这就是我说的蛋疼的地方,Make Your First GAN With PyTorch 为了简化再简化,直接使用了 Google Colab 来运行代码。而国内的同学基本不太可能使用这个服务.....
这里还是忠于原著,简单介绍 Google Colab 的使用方法。同时,后面的代码,亲测在自己电脑搭建的环境也可运行。

首先,登录 Google 账户后,通过下面的链接来激活 Google Colab 服务:

激活后可以在 File 目录,通过选择 New Python
3 notebook
来创建一个新的 notebook 文件,如下图所示:

可以看到一个空白的 Python notebook 文件:

在第一个 cell 里输入如下代码:

2 + 3

点击左侧的运行按钮,可以直接得到代码运行结果,也就是 5

2. PyTorch 张量

使用 PyTorch 前,需要导入 torch 模块。

由于 Google Colab 服务已经基本预装了常见的库,这里只需要简单地导 入即可。

还是那句话,如果在本机或者其他平台运行 PyTorch,需要安装这些常见的库.....

在第一个 cell 中输入下面的语句并运行:

import torch

普通的 Python 使用 变量(variables) 存储数据,而 PyTorch 则使用一种独特的变量类型来存储数据,称之为 PyTorch 张量(tensors),下面是一个例子:

# 定义 PyTorch 张量(tensor)并输出
x = torch.tensor(3.5)
print(x)

代码是指创建了称为 xPyTorch 张量,初始值为 3.5。运行结果为:

如图所示,输出显示数值为 3.5000,同时也表明这个值包含于一个 PyTorch 张量 (tensor) 中。

张量也可以进行一般的算术运算,运算结果也同样为张量。

3. PyTorch 的自动求导

下面的代码同样创建了一个称为 x 的张量,但是这次增加了一个附加选项 requires_grad = True

# PyTorch 张量
x = torch.tensor(3.5, requires_grad = True)
print(x)

输出结果为:

tensor(3.5000, requires_grad=True

可以看到 x 包括了值为 Truerequres_grad 的选项。使用 x 创建一个新变量 y,表达式如下所示:

# 定义 y 是 x 的一个函数
y = (x - 1) * (x - 2) * (x - 3)
print(y)

运行可得 y 的取值:

tensor(1.8750, grad_fn=<MulBackward0>)

正如预料,y 的值为 1.8750,这是因为 x3.5,所以 (3.5 − 1) ∗ (3.5 − 2) ∗ (3.5 − 3)1.8750

下图是刚刚计算的 y = (x − 1) ∗ (x − 2) ∗ (x − 3) 的曲线图:

上述例子看起来简单,但实际上 PyTorch 做了一些隐性的工作:除了计算了 1.8750 的值,并将其放入一个名为 y 的张量中,PyTorch 实际上还记住了数学定义。

PyTorch 记住数学定义,意味着在训练神经网络时,可以方便的使用微积分获得误差梯度,进而随着网络权重的改变,决定输出误差的改变率。

下面计算 x = 3.5y 的梯度(dy/dx),说明 PyTorch 是如何计算梯度的:

# 使用 PyTorch 直接计算梯度(导数)
y.backward()

这个简单的命令就完成了一切:明确了 y 是来自于 (x − 1) ∗ (x − 2) ∗ (x − 3),并且自动计算出梯度 dy/dx3x^2-12x +11。该命令也计算出了梯度的数值,由于x3.5,所以梯度值为 3*(3.5*3.5)-12*(3.5)+11=5.75,并将其放在了张量 x 中,可以使用 x.grad 查看张量 x 中的梯度值:

# x = 3.5 处的梯度值
x.grad

运算结果如下所示:

张量是 PyTorch 中数据的基本形式,几乎其他的所有特性都需要张量作为基础,比一般的 Python 变量或者 numpy 数组更加丰富,张量可以是多维数组、简单的二维阵列或一维列表,甚至单独一个值,而且:

  • 比简单的数值更多的附加信息,比如梯度值;
  • 这个张量依赖的其他张量的信息,和具体依赖的数学形式。

4. 计算图

4.1 计算图基本概念

观察下面非常简单的网络,它并不是神经网络,而只是一系列计算:

图中的输入是 x,输出为 z,中间变量为 yyz 的计算公式为:

y=x^2 \\ z=2y+3

使用 链式法则(chain rule of calculus) 计算 dz/dx

dz/dx=dz/dy \cdot dy/dx \\ dz/dx=2 \cdot 2x \\ dz/dx=4x

上图给出计算获得输出 z 随着 x 变化率是 4x ,所以,如果 x = 3.5,则 dz/dx4*3.5=14

PyTorch 中描述这些张量如何连接的图片称为计算图(computation graph)。这个例子中的计算图为:

上图可以看到 y 是如何使用 x 计算的,z 是如何使用 y 计算的。另外,PyTorch 还增加了反向箭头,显示出当 x 变化时 y 是如何变化,当 y 变化时 z 是如何变化,这是为了在训练时更新神经网络的梯度。

上图中,更简单的理解,我认为正向箭头是变量的计算公式,反向箭头代表了导数/变化率,也就是前一个向量变化时,后一个向量如何变化。

微积分由 PyTorch 完成,不需要我们计算。将计算图的正向箭头列入到 PyTorch 定义中:

# 使用 x, y, z 设置一个简单的计算图
x = torch.tensor(3.5, requires_grad = True)
y = x * x
z = 2 * y + 3

PyTorch 只构建正向的计算图。为了获取后向梯度,需要使用 backward() 函数进行计算:

# 计算梯度值
z.backward()

更前面一样,梯度 dz/dx 将会放入张量 x 中,作为 x.grad

# x = 3.5 处的梯度值
x.grad

运行结果如下图:

可以看到结果是 14,与手动计算结果一致!

需要注意的是,由于前面是 z.backward(),所以 x.graddz/dx,而不是 dy/dx

4.2 多节点的计算图示例

绝大多数神经网络中有多重链接,下面可以看一个稍微复杂的例子:

输入有两个,分别为 ab,输出为 z,这些节点的关系为:

x=2a+3b \\ y=5a^2+3b^2 \\ z=2x+3y

可以计算梯度:

dz/dx=2 \\ dx/da=2 \\ dz/dy=3 \\ dx/db=3

将这些信息添加到计算图上:

通过下面路径可以很简单的计算出从 za 的梯度 dz/da。实际上,dz/da 有两条路径,一条通过 x,另一条则通过 y,将这两条路径的表达式分别相加(下图用不同颜色标出),可以得到梯度值。

通过 x 的第一条路的结果是2∗2,通过 y 的第二条路是 3∗10a,所以 z 关于a 的梯度是 4 + 30a,当a2 时,dz/da4+30∗2 = 64

下面使用 PyTorch 计算,首先设定计算图中的关系:

# 设置 x, y, z 的关系
a = torch.tensor(2.0, requires_grad = True)
b = torch.tensor(1.0, requires_grad = True)

x = 2 * a + 3 * b
y = 5 * a * a + 3 * b * b * b
z = 2 * x + 3 * y

然后触发梯度计算,并将其值放入张量 a 中:

# 计算梯度值
z.backward()

# a = 2.0 处的梯度值
a.grad

PyTorch 计算的结果见下图:

计算结果正确。

4.3 计算图的有关讨论

上面并没有讲清楚如何将网络和更新内部的权重与 误差(error) 构建关系,下面就探讨这个。

如果和4.1 节中的简单网络类似,网络的输出为 z,且正确的输出应该是 t,此时误差 E(z − t),或者更一般的是 (z − t)^2。将误差 E 看做网络末端的另一个节点(而不是 z),所以 (z − t)^2 是从 zE 的计算。PyTorch 能够计算出新的输出 E 与网络输入相关的梯度。

对于网络的权重 w,假设权重也是节点,就如下图:

上图中,z 既依赖于变量 y ,也依赖于权重 w_2,也就是整个关系可以表示为 z = w_2 ∗ y,与神经网络类似。

可以看到 dz/dw_2 可以与 dz/dy 使用一样的方法计算。举例而言,就像前面一 样,可以通过遵循从 zw_1 的反向路径,来确定 dz/dw_1

5. 总结

本章主要围绕如何计算梯度开展,介绍了 PyTorch 中的张量和计算图。理论内容到此为止,下章开始就要实际构建网络。

PyTorch 的关键特性是能够对定义的函数自动计算 梯度(gradients)。计 算梯度是训练神经网络的基础,为了完成这项工作,PyTorch 构建了 计算图(computation graph) 来表示张量之间的关系。

可以代码中方便的定义张量之间的关系,也就是计算图的表示。

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

推荐阅读更多精彩内容