框架
- 看文档
- 看生态
- 看调试工具
最近许多网络结构都该用 pytorch 重新实现一遍,在很多领域都成为三足鼎立,在前端框架 react、angular 和 vue,他们相互学习共同进步。都有自己的特点,才能在众多前端项目中脱颖而出。
Tensorflow-VS-Pytorch.jpgimport torch
import numpy as np
初始化创建 tensor
在 torch 和 tensorflow 中都提供了一些类似 numpy 方法,虽然使用 tensorflow 和 torch 提供对 tensor 操作方法已经基本可以替换掉了 numpy 中对应的方法。但是大家还是习惯了使用 numpy,不知不觉还是想用 numpy。就像写 web 时,有时候还是想用 jquery。
x = torch.empty(3,2)
x
tensor([[ 0.0000e+00, -8.5899e+09],
[ 0.0000e+00, -8.5899e+09],
[ 1.1210e-44, 0.0000e+00]])
x = torch.rand(3,2)
x
tensor([[0.5045, 0.7438],
[0.5103, 0.1921],
[0.6033, 0.8493]])
创建一个全部为 0 的 tensor
torch.zeros(3,2)
x
tensor([[0.5045, 0.7438],
[0.5103, 0.1921],
[0.6033, 0.8493]])
# 查看类型
x.dtype
torch.float32
改变元素类型
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 = torch.zeros(5,3).long()
x.dtype
torch.int64
x = torch.tensor([1,2,3])
x
tensor([1, 2, 3])
重用信息,例如新建的 tensor 类型会 x 的类型相同
x = x.new_ones(2,3)
x
tensor([[1, 1, 1],
[1, 1, 1]])
x = torch.randn_like(x,dtype=torch.float)
x
tensor([[-0.3904, -0.7965, -0.2722],
[-0.2156, -0.0594, 0.6214]])
x.shape
torch.Size([2, 3])
tensor 运算操作符
y = torch.rand(2,3)
torch.add(x,y)
tensor([[ 0.2551, -0.3587, 0.0470],
[ 0.5914, 0.7677, 1.6127]])
# x + y 是 torch.add 的语法糖
x+y
tensor([[ 0.2551, -0.3587, 0.0470],
[ 0.5914, 0.7677, 1.6127]])
result = torch.empty(2,3)
torch.add(x,y,out=result)
result
tensor([[ 0.2551, -0.3587, 0.0470],
[ 0.5914, 0.7677, 1.6127]])
y.add_(x)
y
tensor([[ 0.2551, -0.3587, 0.0470],
[ 0.5914, 0.7677, 1.6127]])
x[:,1:]
tensor([[-0.7965, -0.2722],
[-0.0594, 0.6214]])
x
tensor([[-0.3904, -0.7965, -0.2722],
[-0.2156, -0.0594, 0.6214]])
x = torch.randn(5,5)
y = x.view(25)
y
tensor([ 0.8127, -1.0394, -0.4423, -0.2006, 0.0952, -2.0985, -0.6619, -1.3043,
1.4075, -0.4180, 2.3185, 0.8152, -0.6363, -1.7527, 0.3265, -0.6964,
-1.7822, 1.1541, -0.3272, 1.1663, 0.3566, -0.4818, 2.0843, -0.5080,
0.6954])
x = torch.randn(3,2)
z = x.view(2,-1)
z
tensor([[ 0.3892, -0.8355, 0.7208],
[ 1.4621, 1.3130, -1.1406]])
x = torch.randn(1)
x.data
tensor([1.5721])
# 提取 tensor 数值
x.item()
1.5720665454864502
z.transpose(1,0)
tensor([[ 0.3892, 1.4621],
[-0.8355, 1.3130],
[ 0.7208, -1.1406]])
z.shape
torch.Size([2, 3])
Numpy 和 Tensor 之间转换
有的时候我们需要将 torch 的 tensor 转换为 Numpy 的 ndarry,在 torch 提供方法可以让两者自由地切换,这个 tensorflow 2.0 中也提供了方法。
a = torch.ones(5)
a
tensor([1., 1., 1., 1., 1.])
调用 tensor 对象的 numpy() 方法就可以将 torch 的 tensor 转换为 ndarray 对象。这时如果我们改变由 torch tensor 得到的 ndarray 对象的值,torch 的 tensor 的值也会随之改变。
b = a.numpy()
b
array([1., 1., 1., 1., 1.], dtype=float32)
b[1] = 2
a
tensor([1., 2., 1., 1., 1.])
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a,1,out=a)
print(a)
[2. 2. 2. 2. 2.]
# 检测 cuda 是否可用
torch.cuda.is_available()
热身:用numpy 实现两层神经网络
ReLU
前向传播
反向传播
我们要求 $$$$
这部分内容虽然比较基础,但是只有很好理解这部
N, D_in, H, D_out= 64,1000,100,10
# N 表示样本数,x 表示数据而 y 表示标签,我们任务就找到 y 和 x 之间的映射关系
# D_in 输入样本维度
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 t in range(500):
# 前向传播
h = x.dot(w1)
h_relu = np.maximum(h,0)
y_pred = h_relu.dot(w2)
# 计算损失
loss = np.square(y_pred - y).sum()
print(t,loss)
# 反向传播,也就是分别计算 w1 和 w2 对 loss 函数的导数
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)
# 更新权重
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
h = x.dot(w1)
h_relu = np.maximum(h,0)
y_pred = h_relu.dot(w2)
(y_pred - y).mean()
5.423194979076235e-07
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)
learning_rate = 1e-6
for t in range(500):
h = x.mm(w1)
h_relu = h.clamp(min=0)
y_pred = h_relu.mm(w2)
# compute loss
loss = (y_pred - y).pow(2).sum().item()
print(t,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
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
x = torch.tensor(1.,requires_grad=True)
w = torch.tensor(2.,requires_grad=True)
b = torch.tensor(3.,requires_grad=True)
y = w*x + b
y.backward()
print(w.grad)
print(x.grad)
tensor(1.)
tensor(2.)
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)
learning_rate = 1e-6
for t in range(500):
y_pred = x.mm(w1).clamp(min=0).mm(w2)
# compute loss
loss = (y_pred - y).pow(2).sum().item()
print(t,loss)
loss.backward()
# update weights of w1 and w2
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
网友评论