1 pytorch60分钟入门教程
2017-05-22 13:16
766 查看
1 Tensors
from __future__ import print_function import torch x = torch.Tensor(5, 3) # 构造一个未初始化的5*3的矩阵 x = torch.rand(5, 3) # 构造一个随机初始化的矩阵
x
0.9643 0.2740 0.9700 0.2375 0.8547 0.1793 0.2462 0.8887 0.0271 0.8668 0.6014 0.9562 0.8588 0.3883 0.3741 [torch.FloatTensor of size 5x3]
x.size()
torch.Size([5, 3])
y = torch.rand(5,3)
y
0.3458 0.1517 0.1397 0.6764 0.6408 0.0139 0.6116 0.4172 0.8836 0.9197 0.6072 0.0751 0.7214 0.0613 0.4052 [torch.FloatTensor of size 5x3]
x+y
1.3101 0.4257 1.1097 0.9139 1.4955 0.1932 0.8578 1.3060 0.9108 1.7865 1.2086 1.0312 1.5802 0.4495 0.7793 [torch.FloatTensor of size 5x3]
torch.add(x,y)
1.3101 0.4257 1.1097 0.9139 1.4955 0.1932 0.8578 1.3060 0.9108 1.7865 1.2086 1.0312 1.5802 0.4495 0.7793 [torch.FloatTensor of size 5x3]
z = x+y
z
1.3101 0.4257 1.1097 0.9139 1.4955 0.1932 0.8578 1.3060 0.9108 1.7865 1.2086 1.0312 1.5802 0.4495 0.7793 [torch.FloatTensor of size 5x3]
result = torch.Tensor(5, 3) # 语法一 torch.add(x, y, out=result) # 语法二 result
1.3101 0.4257 1.1097 0.9139 1.4955 0.1932 0.8578 1.3060 0.9108 1.7865 1.2086 1.0312 1.5802 0.4495 0.7793 [torch.FloatTensor of size 5x3]
y.add_(x) # 将y与x相加 # 特别注明:任何可以改变tensor内容的操作都会在方法名后加一个下划线'_' # 例如:x.copy_(y), x.t_(), 这俩都会改变x的值。 y
1.3101 0.4257 1.1097 0.9139 1.4955 0.1932 0.8578 1.3060 0.9108 1.7865 1.2086 1.0312 1.5802 0.4495 0.7793 [torch.FloatTensor of size 5x3]
x[:1]
0.9643 0.2740 0.9700 [torch.FloatTensor of size 1x3]
2 Tensor与numpy的转换
注意Torch的Tensor和numpy的array会共享他们的存储空间,修改一个会导致另外的一个也被修改。a = torch.ones(5) b = a.numpy() a,b
( 1 1 1 1 1 [torch.FloatTensor of size 5], array([ 1., 1., 1., 1., 1.], dtype=float32))
import numpy as np a = np.ones(5) b = torch.from_numpy(a) a,b
(array([ 1., 1., 1., 1., 1.]), 1 1 1 1 1 [torch.DoubleTensor of size 5])
# 另外除了CharTensor之外,所有的tensor都可以在CPU运算和GPU预算之间相互转换 # 使用CUDA函数来将Tensor移动到GPU上 # 当CUDA可用时会进行GPU的运算 if torch.cuda.is_available(): x = x.cuda() y = y.cuda() x + y
3 PyTorch中的神经网络
PyTorch中所有的神经网络都来自于autograd包autograd自动梯度计算,这是一个运行时定义的框架,这意味着你的反向传播是根据你代码运行的方式来定义的,因此每一轮迭代都可以各不相同。
from torch.autograd import Variable x = Variable(torch.ones(2,2),requires_grad = True) y = x + 2 y.creator
<torch.autograd._functions.basic_ops.AddConstant at 0x3dad3f0>
z = y*y*3 out = z.mean() out
Variable containing: 27 [torch.FloatTensor of size 1]
out.backward()
x.grad
Variable containing: 4.5000 4.5000 4.5000 4.5000 [torch.FloatTensor of size 2x2]
这里有推倒,就是一个x函数,当x=1时这个函数的导数是多少。
https://zhuanlan.zhihu.com/p/25572330
x = torch.randn(3) # print(x) x = Variable(x, requires_grad = True) y = x * 2 while y.data.norm() < 1000: y = y * 2 # print (y) gradients = torch.FloatTensor([0.1, 1.0, 0.0001]) y.backward(gradients) x.grad
Variable containing: 204.8000 2048.0000 0.2048 [torch.FloatTensor of size 3]
这里y.backward(gradients)这句话有什么用呢???
y, y.data, y.data.norm()
(Variable containing: 1546.1327 -304.6176 642.7925 [torch.FloatTensor of size 3], 1546.1327 -304.6176 642.7925 [torch.FloatTensor of size 3], 1701.9108254060725)
4 神经网络
使用 torch.nn 包可以进行神经网络的构建。现在你对autograd有了初步的了解,而nn建立在autograd的基础上来进行模型的定义和微分。
nn.Module中包含着神经网络的层,同时forward(input)方法能够将output进行返回。
举个例子,来看一下这个数字图像分类的神经网络。
一个典型的神经网络的训练过程是这样的:
定义一个有着可学习的参数(或者权重)的神经网络
对着一个输入的数据集进行迭代:
用神经网络对输入进行处理
计算代价值 (对输出值的修正到底有多少)
将梯度传播回神经网络的参数中
更新网络中的权重
通常使用简单的更新规则: weight = weight + learning_rate * gradient
import torch.nn as nn import torch.nn.functional as F class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 6, 5) # 1 input image channel, 6 output channels, 5x5 square convolution kernel self.conv2 = nn.Conv2d(6, 16, 5) self.fc1 = nn.Linear(16*5*5, 120) # an affine operation: y = Wx + b self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) # Max pooling over a (2, 2) window x = F.max_pool2d(F.relu(self.conv2(x)), 2) # If the size is a square you can only specify a single number x = x.view(-1, self.num_flat_features(x)) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x def num_flat_features(self, x): size = x.size()[1:] # all dimensions except the batch dimension num_features = 1 for s in size: num_features *= s return num_features net = Net() net
Net ( (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1)) (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1)) (fc1): Linear (400 -> 120) (fc2): Linear (120 -> 84) (fc3): Linear (84 -> 10) )
x = x.view(-1, self.num_flat_features(x))应该是把x打平吧
仅仅需要定义一个forward函数就可以了,backward会自动地生成。
你可以在forward函数中使用所有的Tensor中的操作。
模型中可学习的参数会由net.parameters()返回。m
params = list(net.parameters()) print(len(params)) print(params[0].size()) # conv1's .weight input = Variable(torch.randn(1, 1, 32, 32)) out = net(input)
10 torch.Size([6, 1, 5, 5])
out
Variable containing: 0.0648 0.0148 0.0333 0.0013 0.0563 -0.0156 0.0543 0.1504 -0.0774 -0.0231 [torch.FloatTensor of size 1x10]
复习一下前面我们学到的:
torch.Tensor - 一个多维数组
autograd.Variable - 改变Tensor并且记录下来操作的历史记录。和Tensor拥有相同的API,以及backward()的一些API。同时包含着和张量相关的梯度。
nn.Module - 神经网络模块。便捷的数据封装,能够将运算移往GPU,还包括一些输入输出的东西。
nn.Parameter - 一种变量,当将任何值赋予Module时自动注册为一个参数。
autograd.Function - 实现了使用自动求导方法的前馈和后馈的定义。每个Variable的操作都会生成至少一个独立的Function节点,与生成了Variable的函数相连之后记录下操作历史。
到现在我们已经明白的部分:
定义了一个神经网络。
处理了输入以及实现了反馈。
仍然没整的:
计算代价。
更新网络中的权重。
5 计算每个参数的梯度
output = net(input) target = Variable(torch.range(1, 10)) # a dummy target, for example criterion = nn.MSELoss() loss = criterion(output, target) loss
Variable containing: 38.2952 [torch.FloatTensor of size 1]
input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d
-> view -> linear -> relu -> linear -> relu -> linear
-> MSELoss
-> loss
print(loss.creator) # MSELoss print(loss.creator.previous_functions[0][0]) # Linear print(loss.creator.previous_functions[0][0].previous_functions[0][0]) # ReLU
<torch.nn._functions.thnn.auto.MSELoss object at 0x31dd6878> <torch.nn._functions.linear.Linear object at 0x31dd6790> <torch.nn._functions.thnn.auto.Threshold object at 0x31dd66a8>
# 现在我们应当调用loss.backward(), 之后来看看 conv1's在进行反馈之后的偏置梯度如何 net.zero_grad() # 归零操作 print('conv1.bias.grad before backward') print(net.conv1.bias.grad) loss.backward() print('conv1.bias.grad after backward') print(net.conv1.bias.grad)
conv1.bias.grad before backward None conv1.bias.grad after backward Variable containing: 0.2046 0.0389 -0.0529 -0.0108 -0.0941 -0.0869 [torch.FloatTensor of size 6]
第一层的bias的个数刚好是6个,这里已经给出了每个参数的梯度,这样就可以以固定的学习率来更新了。感觉深度学习框架的牛逼之处就在于写好了自动求梯度的东西了么?
loss.backward就可以计算每一层的梯度了,更新还没解决。
6 更新参数
最简单的更新的规则是随机梯度下降法(SGD):weight = weight - learning_rate * gradient
我们可以用简单的python来表示:
learning_rate = 0.01
for f in net.parameters():
f.data.sub_(f.grad.data * learning_rate)
可以用torch.optim来实现
import torch.optim as optim # create your optimizer optimizer = optim.SGD(net.parameters(),lr = 0.01) # in your training loop: optimizer.zero_grad() # zero the gradient buffers output = net(input) loss = criterion(output,target) loss.backward() optimizer.step()# Does the update
总结一下
输入:input = Variable(torch.randn(1, 1, 32, 32))
输出:
out = net(input)
网络结构
class Net(nn.Module): def __init__(self): def forward(self, x): barkward自己会完成
更新
optimizer = optim.SGD(net.parameters(),lr = 0.01) optimizer.zero_grad() loss.backward() optimizer.step()# Does the update
参考:
https://zhuanlan.zhihu.com/p/25572330
相关文章推荐
- PyTorch快速入门教程二(线性回归以及logistic回归)
- PyTorch快速入门教程五(rnn)
- PyTorch快速入门教程五(rnn)
- PyTorch快速入门教程一(环境配置)
- PyTorch 深度学习:60分钟快速入门
- PyTorch快速入门教程七(pytorch下RNN如何做自然语言处理)
- PyTorch快速入门教程八(使用word embedding做自然语言处理的词语预测)
- PyTorch快速入门教程九(使用LSTM来做判别每个词的词性)
- PyTorch快速入门教程六(使用LSTM做图片分类)
- 60分钟入门深度学习库:pytorch,强烈推荐!!!
- PyTorch 深度学习:60分钟快速入门
- PyTorch快速入门教程三(神经网络)
- PyTorch快速入门教程九(使用LSTM来做判别每个词的词性)
- PyTorch快速入门教程四(cnn:卷积神经网络 )
- PyTorch深度学习:60分钟入门(Translation)
- PyTorch深度学习:60分钟入门(Translation) PyTorch深度学习:60分钟入门(Translation)
- pytorch入门教程(一):Tensor###tensor好好好####
- PyTorch 深度学习:60分钟快速入门
- PyTorch快速入门教程四(cnn:卷积神经网络 )
- pytorch教程[2] Tensor的使用