PyTorch:动态计算图Dynamic Computation(像python)
Tensorflow:静态计算图Static Computation(像c++)
PyTorch代码通俗易懂,非常接近PyTorch原生代码,不会让人感觉是完全在学习一门新的语言。拥有Facebook支持,社区活跃。
PyTorch可以定义神经网络,主要干的是这个Model的部分,我们可以用PyTorch来定义这个Architecture,有了这个Architecture,调整Parameters(这些是真正模型的参数),这些参数如何进行优化呢?通过训练数据对这个模型进行优化。像下面这个图,你有一堆输入,这些输入经过这个模型后会产生一些输出,当你拿到模型的输出后,你要拿模型的输出和准确的输出做对比,计算一个loss function(预测的好坏),如果预测的好,说明你用的参数好。如果预测的不好,说明你模型的参数有问题,需要提升它。深度学习的一个标准优化方法是计算Gradient descent,用loss计算每一个Parameter的梯度,然后做梯度的下降。如果loss降低,就认为模型的效果有了提升。
#%%
import torch
#构造一个未初始化的5*3矩阵
x1=torch.empty(5,3)
#构造一个随机初始化矩阵 (0-1之间)
x2=torch.rand(5,3)
#构造一个全部为0的5*3矩阵
x3=torch.zeros(5,3)
x4=torch.zeros(5,3,dtype=torch.long)
x5=torch.zeros(5,3).long()
x5.dtype
# 从数据中直接构造tensor
x6=torch.tensor([5.5,3])
#%%
# 可以从一个已有的tensor构建一个tensor。这些方法会重用原来的tensor的特征,例如,数据类型,除非提供新的数据
x7=x6.new_ones(5,3,dtype=torch.double)
x7
#%%
#随机产生跟原来tensor相同形状的tensor
x8=torch.randn_like(x7,dtype=torch.float)
x8
#%%
x8.shape
#%%
x8.size()
#%%
#加法运算
y=torch.rand(5,3)
#方法一:
x8+y
# 方法二
torch.add(x8,y)
#方法三
result=torch.empty(5,3)
torch.add(x8,y,out=result)
#%%
#inplace加法,加上_会改变原来的值
y.add_(x8)
y
#%%
# 取出1到后面所有的列
y[:,1:]
#%%
# resizing:如果你希望resize/reshape一个tensor,可以使用torch.view
x=torch.rand(4,4)
y=x.view(16)
z=x.view(2,8)
y
z
#%%
x=torch.randn(1)
x
#%%
x.grad
x
#%%
#获取tensor中的数字
x.item()
#%%
#矩阵转置
z.transpose(1,0)
#%%
#Numpy和Tensor之间的转化
a=torch.ones(5)
a
#%%
b=a.numpy()
b
#%%
#把numpy ndarray转成Torch Tensor
import numpy as np
a=np.ones(5)
a
#%%
b=torch.from_numpy(a)
b
np.add(a,1,out=a)
#%%
# CUDA Tensors
# 使用.to方法,Tensor可以被移动到别的device上
# numpy的数据是在cpu上操作的
if torch.cuda.is_available():
device=torch.device("cuda")
y=torch.ones_like(x,device=device)
x=x.to(device)
z=x+y
print(z)
print(z.to("cpu",torch.double))
#%%
y.to("cpu").data.numpy()
y.cpu().data.numpy()
#%%
model=model.cuda()
import numpy as np
N,D_in,H,D_out=64,1000,100,10
#随机创建一些训练数据
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)
learing_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
用pytoch实现同一段代码
import torch
N,D_in,H,D_out=64,1000,100,10
#随机创建一些训练数据
x=torch.randn(N,D_in)
y=torch.randn(N,D_out)
w1=torch.randn(D_in,H)
w2=torch.randn(H,D_out)
learing_rate=1e-6
for it in range(500):
#forward pass
h=x.mm(w1)#N*H
h_relu=h.clamp(min=0)#N*H
y_pred=h_relu.mm(w2)#N*D_out
#compute loss
loss=np.square(y_pred-y).pow(2).sum().item()
print(it,loss)
#backward pass
#compute the gradient
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)
#update weights of w1 and w2