pytorch使用教程及应用-GANS编程(1)-基础使用
Pytorch使用教程及应用-GANS(构建生成对抗神经网络)
本博文基于书籍–<<Pytorch 生成对抗网络编程>>,欢迎大家购买书籍支持原创
1.基础使用
建立张量:
x=torch.tensor(3.5,requires_grad=True)#建立一个值为3.5且需要计算其梯度的张量
求解函数y对于x的梯度:
import torch
x=torch.tensor(3.5,requires_grad=True)
y=(x-1)*(X-2)
y.backward() #必要步骤,进行反向传播(包含很多底层步骤)
print(x.grad)
这几个看似简单的步骤,实际上pytorch做了很多工作,例如定义y=(x-1)*(x-2),pytorch会计算出x=3.5时y的值并将其加入张量中,而且,pytorch还记录了y在数学上是由x来定义的,学过基本神经网络的都知道,训练神经网络的计算需要使用微积分计算出误差梯度,既输出误差改变的速率随着网络链接权重的改变而改变。所以,其记录y在数学上由x定义对于后面梯度的计算是十分有作用的,y.backward()这一行代码会计算出x对于y的梯度值并加入到张量x中.
实际上,张量的数学含义就是计算图(compute graph)
所以,总结一下,一个pytorch张量可以包含以下内容:
- 除原始数值之外的附加信息,比如梯度值
- 关于它所依赖的其他张量的信息,以及这种依赖的数学表达式
实际上,这种关联张量和自动微分的能力是pytorch最重要的特性,是其他功能的基础.
张量的来源:计算图
这种自动梯度计算其实来源于我们人为创造的一个逻辑-计算图(compute graph)
举个例子:
一个最简单的网络 每层只有一个神经元
x->y->z
设定:
y
=
x
2
y=x^2
y=x2
z
=
2
y
+
3
z=2y+3
z=2y+3
我们都知道,神经网络中,我们需要计算梯度dy/dx.
计算的基本法则是链式法则,这个大家自己学习bp的时候都会讲到,我就不多赘述了.
总之,我们在标记参数requires_grad=True的时候再执行反向传播pytorch就会帮我们计算好梯度保存在张量x中.
所以,对于这个例子的代码就是下面这样
import torch
x=torch.tensor(3.5,requires_grad=True)
y=x*x
z=2*y+3
z.backward() #x标记好梯度后,用z进行反向传播传入张量x的梯度就是dz/dx,用y进行反向传播就是dy/dx
print(x.grad)
注意,如果直接同时写两个backward函数会报错,当然实际使用过程中我们也没有这样的需求.
报错:RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.
其含义是第一次反向传播的时候我们并没有标记参数
retain_graph为true,导致缓冲区在第一次反向传播后就释放了,从而导致第二次反向传播无法进行,所以,我们在第一次反向传播标记此参数后就可以同时写两个反向传播,这样**保存至张量x的梯度值就是计算出的两个梯度值的和,当然一般我们不需要这个和(只需要依据链式法则进行一层层的反向 传播,不需要叠加),所以也没必要这样做.**
(但是在实际使用过程中dz/dy是需要的,所以一般除了输出层,中间的神经层参数( n [ l ] , n [ l − 1 ] n^[l],n^[l-1] n[l],n[l−1])(神经元)都必须被定义为张量来方便后面计算出梯度进行参数更新.)
稍复杂一点的神经网络
定义结点间关系:
x = 2 a + 3 b , y = 5 a 2 + 3 b 3 , z = 2 x + 3 y x=2a+3b ,y=5a^2+3b^3,z=2x+3y x=2a+3b,y=5a2+3b3,z=2x+3y
神经网络关系
a x
z
b y
梯度计算代码(这里我们就不能仅仅定义一个张量了):
#创建包含x、y和z的计算图
import torch
a=torch.tensor(2.0,requires_grad=True)
b=torch.tensor(1.0,requires_grad=True)
x=2*a+3*b #x由张量定义,所以本身也是一个张量
y=5*a*a+3*b*b*b
z=2*x+3*y
z.backward()
print(a.grad,b.grad) #即使经过反向传播后,也无法打印出x的grad,因为没有标记参数,目前还没有找到一个更好的办法去得到x的grad结果,因为是经过计算图的缓存了的
感兴趣的同学也可以自己画一下计算图来复盘一下pytorch的计算.