PyTorch:动态计算图Dynamic Computation Graph;
TensorFlow:静态计算图Static Computation Graph。
PyTorch代码通俗易懂,非常接近Python原生代码。
类似于Numpy,但是它可以使用GPU;
可以用它定义深度学习模型,可以灵活地进行深度学习模型的训练和使用。
3.1构造一个未初始化的5×3矩阵
>>> import torch
>>> x=torch.empty(5,3)
>>> x
tensor([[9.1834e-41, 0.0000e+00, 0.0000e+00],
[0.0000e+00, 0.0000e+00, 0.0000e+00],
[0.0000e+00, 0.0000e+00, 0.0000e+00],
[0.0000e+00, 5.9415e-43, 0.0000e+00],
[0.0000e+00, 0.0000e+00, 0.0000e+00]])
3.2构造一个随机初始化的矩阵
>>> torch.rand(5,3)
tensor([[0.2936, 0.7109, 0.6839],
[0.9778, 0.2583, 0.6170],
[0.9016, 0.3895, 0.2596],
[0.0357, 0.9415, 0.0640],
[0.9949, 0.1010, 0.8019]])
3.3构建一个全部为0,类型为long的矩阵
>>> x=torch.zeros(5,3,dtype=torch.long)
>>> x
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
>>> x.dtype
torch.int64
3.4从数据直接构建tensor
>>> x=torch.tensor([5.5,3])
>>> x
tensor([5.5000, 3.0000])
3.5也可以从一个已有的tensor构件一个tensor,这些方法会重用原来tensor的特征,例如,数据类型,除非提供新的数据。
>>> x=x.new_ones(5,3)
>>> x
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
>>> x=x.new_ones(5,3,dtype=torch.double)
>>> x
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
>>> x=torch.randn_like(x,dtype=torch.float)
>>> x
tensor([[ 1.0381, 0.1043, 1.5760],
[-0.6895, 0.3802, 1.3165],
[ 0.5803, 0.8689, -0.7618],
[-0.9795, 0.5561, -0.3179],
[-0.7121, 1.0454, -0.6295]])
3.6得到tensor的形状
>>> x.shape
torch.Size([5, 3])
3.7运算
3.7.1加法
>>> y=torch.rand(5,3)
>>> y
tensor([[0.0149, 0.7933, 0.0335],
[0.7218, 0.8258, 0.4340],
[0.7336, 0.6049, 0.3085],
[0.1247, 0.2118, 0.9186],
[0.0502, 0.6861, 0.9377]])
>>> x
tensor([[ 1.0381, 0.1043, 1.5760],
[-0.6895, 0.3802, 1.3165],
[ 0.5803, 0.8689, -0.7618],
[-0.9795, 0.5561, -0.3179],
[-0.7121, 1.0454, -0.6295]])
>>> x+y
tensor([[ 1.0530, 0.8976, 1.6095],
[ 0.0323, 1.2060, 1.7505],
[ 1.3138, 1.4738, -0.4533],
[-0.8549, 0.7679, 0.6007],
[-0.6619, 1.7315, 0.3082]])
另一种加法的写法
>>> torch.add(x,y)
tensor([[ 1.0530, 0.8976, 1.6095],
[ 0.0323, 1.2060, 1.7505],
[ 1.3138, 1.4738, -0.4533],
[-0.8549, 0.7679, 0.6007],
[-0.6619, 1.7315, 0.3082]])
加法:把输出作为一个变量
>>> result=torch.empty(5,3)
>>> torch.add(x,y,out=result)
tensor([[ 1.0530, 0.8976, 1.6095],
[ 0.0323, 1.2060, 1.7505],
[ 1.3138, 1.4738, -0.4533],
[-0.8549, 0.7679, 0.6007],
[-0.6619, 1.7315, 0.3082]])
In-place加法
>>> y.add_(x)
tensor([[ 1.0530, 0.8976, 1.6095],
[ 0.0323, 1.2060, 1.7505],
[ 1.3138, 1.4738, -0.4533],
[-0.8549, 0.7679, 0.6007],
[-0.6619, 1.7315, 0.3082]])
3.8各种类似NumPy的indexing都可以在PyTorch tensor上面使用。
>>> x[1:,1:]
tensor([[ 0.3802, 1.3165],
[ 0.8689, -0.7618],
[ 0.5561, -0.3179],
[ 1.0454, -0.6295]])
3.9Resizing:如果希望resize/reshape一个tensor,可以使用torch.view
>>> x=torch.randn(4,4)
>>> x
tensor([[ 2.6453, -1.1685, -0.0857, 1.1225],
[ 0.1149, 0.2192, 0.9528, -0.2612],
[-0.8304, -0.5425, 0.3017, -1.3451],
[ 0.5863, 1.0294, 0.0201, 0.4943]])
>>> y=x.view(16)
>>> y
tensor([ 2.6453, -1.1685, -0.0857, 1.1225, 0.1149, 0.2192, 0.9528, -0.2612,
-0.8304, -0.5425, 0.3017, -1.3451, 0.5863, 1.0294, 0.0201, 0.4943])
>>> z=x.view(2,-1)
>>> z
tensor([[ 2.6453, -1.1685, -0.0857, 1.1225, 0.1149, 0.2192, 0.9528, -0.2612],
[-0.8304, -0.5425, 0.3017, -1.3451, 0.5863, 1.0294, 0.0201, 0.4943]])
如果只有一个元素的tensor,使用.item()方法可以把里面的value变成Python数值
>>> x=torch.randn(1)
>>> x
tensor([-1.5002])
>>> x.item()
-1.500231146812439
>>> z.transpose(1,0)
tensor([[ 2.6453, -0.8304],
[-1.1685, -0.5425],
[-0.0857, 0.3017],
[ 1.1225, -1.3451],
[ 0.1149, 0.5863],
[ 0.2192, 1.0294],
[ 0.9528, 0.0201],
[-0.2612, 0.4943]])
查看PyTorch文件网址:https://pytorch.org/docs/stable/torch.html
4.Numpy和Tensor之间的转化
在Torch Tensor和Numpy array之间相互转化非常容易。
Torch Tensor和Numpy array会共享内存,所以改变其中一项也会改变另一项。
把Torch Tensor转变成Numpy Array
>>> a=torch.ones(5)
>>> a
tensor([1., 1., 1., 1., 1.])
>>> b=a.numpy()
>>> b
array([1., 1., 1., 1., 1.], dtype=float32)
改变Numpy array里面的值。
>>> b[1]=2
>>> b
array([1., 2., 1., 1., 1.], dtype=float32)
>>> a
tensor([1., 2., 1., 1., 1.])
把NUmpy Array转变成Torch Tensor
>>> import numpy as np
>>> a=np.ones(5)
>>> b=torch.from_numpy(a)
>>> np.add(a,1,out=a)
array([2., 2., 2., 2., 2.])
>>> b
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
5.热身:用Numpy实现两层神经网络
一个全连接ReLU神经网络,一个隐藏层,没有bias。用来从x预测y,使用L2Loss。
·h=W1X+b1
·a=max(0,h)
·yhat=w2a+b2
这一实现完全使用Numpy来计算钱箱神经网络,loss,和反向传播。
·forward pass
·loss
·backward pass
Numpy ndarray是一个普通的n维array,他不知道任何关于深度学习或者梯度(gradient)的知识,也不知道计算图(computation graph),只是一种用来计算数学运算的数据结构。
import numpy as np
N,D_in,H,D_out=64,1000,100,10#N是数据集个数,D_in是输入数据维数,H是中间神经元的维数,D_out是输出神经元的维数
#随机创建一些训练数据
x=np.random.randn(N,D_in)
y=np.random.randn(N,D_out)
w1=np.random.randn(D_in,H)
w2=np.random.randn(H,D_out)
learning_rate=1e-6
for it in range(500):
#Forward pass
h=x.dot(w1)#N*H
h_relu=np.maximum(h,0)#N*H
y_pred=h_relu.dot(w2)#N*D_out
#compute loss
loss=np.square(y_pred-y).sum()
print(it,loss)
#backward pass
#compute the gradient
grad_y_pred=2.0*(y_pred-y)
grad_w2=h_relu.T.dot(grad_y_pred)
grad_h_relu=grad_y_pred.dot(w2.T)
grad_h=grad_h_relu.copy()
grad_h[h<0]=0
grad_w1=x.T.dot(grad_h)
#update weights of w1 and w2
w1=learning_rate*grad_w1
w2=learning_rate*grad_w2