Pytorch Basic

Pytorch是一个深度学习框架,适合作为深度学习研究平台。

Pytorch的优点

  • 基于GPU的Tensor运算,堪称GPU上的numpy
  • 动态神经网络
  • 与Python的深度结合
  • 容易拓展

Pytorch系列大纲

  • Pytorch Basic [本篇文章]
  • Pytorch Visualization
  • Pytorch Cuda
  • Pytorch Training Utils
  • Pytorch NLP [CWS待完成]
  • Pytorch RL [DQN DRQN待完成]
  • Pytorch Recommendation[Dream, NCF]
  • Pytorch multi-process & multi-gpu

学习内容

  • 基础数据结构
    • Tensor
  • 计算流图和自动求导
    • Variable
    • 细粒度自动求导控制
  • 深度学习组件
    • nn.Module
    • 自定义Module
  • 网络优化与训练
  • 完整的网络

基础数据结构

Tensor

  • Tensor依据不同的数据类型可分为

    • LongTensor
    • FloatTensor
    • ...
  • 在创建相应类型的Tensor时注意numpy数据类型与torch的对应关系

    data = np.arange(12).reshape(3,4)
    data = data.astype('float')
    torch_data = torch.from_numpy(data)
    
    torch_data[0]
    >>> 0
    >>> 1
    >>> 2
    >>> 3
    >>> [torch.DoubleTensor of size 4]
    
    torch_data.size() # Tensor的形状
    >>> torch.Size([3,4])
    
    torch_data.numpy() # 转换为numpy数据
    >>> array([[  0.,   1.,   2.,   3.],
    >>>            [  4.,   5.,   6.,   7.],
    >>>            [  8.,   9.,  10.,  11.]])
    
    torch_data.cuda() # 使用GPU计算
    >>>  0   1   2   3
    >>> 4   5   6   7
    >>> 8   9  10  11
    >>> [torch.cuda.DoubleTensor of size 3x4 (GPU 0)
    
  • 查看Tensor的形状,size返回torch.Size类(继承了tuple,可以直接索引)

x.size()
  • 如何改变Tensor的形状?

    • 使用view返回具有相同数据但大小不同的新张量。 返回的张量必须有与原张量相同的数据和相同数量的元素,但可以有不同的大小。一个张量必须是连续contiguous()的才能被view。类似于Numpy的np.reshape()
    • resize将tensor的大小调整为指定大小,如果元素个数比当前的内存大小大,就将底层存储大小调整为与新元素数目一致的大小。如果元素个数比当前内存小,则底层存储不会被改变。原来tensor中被保存下来的元素将保持不变,但新内存将不会被初始化
    • permute维度互换
    • unsqueeze插入新维度
  • 如何组合多个Tensor?

    • 使用cat
  • 如何重复一个Tensor?向某个维度扩张

    • expand
x = torch.Tensor([[1, 2, 3]])
print(x.expand(3, -1))
 1  2  3
 1  2  3
 1  2  3
[torch.FloatTensor of size 3x3]
  • 运算符号类似numpy接口
    • _为后缀的操作为Inplace Operation
  torch.mean()
  • 区分矩阵运算与非矩阵运算
    • mm
    • matmul
  • Elment-wise Multiplication

batch_size = 2

a = torch.Tensor([1, 2, 3])
a = a.expand([batch_size, a.size()[0]])

w1 = torch.Tensor([1, 2, 3])

batch_size = 2
​
a = torch.Tensor([1, 2, 3])
a = a.expand([batch_size, a.size()[0]])
​
w1 = torch.Tensor([1, 2, 3])
​

a * w1

1  4  9
1  4  9
[torch.FloatTensor of size 2x3]

计算流图和自动求导

Variable

使用深度学习编程框架的一个好处是一旦我们搭建起计算流图(如何由输入得到输出),框架就可以帮我们进行误差反向传播求导运算。这是如何实现的呢?在Pytorch中,我们依靠可以记住历史的Variable

Variable类似Tensor但是它会记得自己是如何被创造的

  • 使用Variable包裹Tensor,这样就可以记得历史
x = autograd.Variable( torch.Tensor([1., 2., 3]), requires_grad=True )
  • data属性查看Variable包裹的具体数据
print x.data
  • Variable的运算类似Tensor
y = autograd.Variable( torch.Tensor([4., 5., 6]), requires_grad=True )
z = x + y
print z.data
  • 但是Variable还可以知道自己是如何被创造的(也是反向传播被求导的函数)
print z.grad_fn
  • 调用backward() 从当前变量开始进行反向传播;如果多次调用,则梯度会累加
s.backward() 
print x.grad # Tensor
  • !!! 如果中途从Variable取出Tensor再重新包裹,那么历史将会被遗忘,反向传播无法正确运行;反之,如果我们想要将计算流图中的某些结点遗忘,不进行反向传播,可以从Variable取出Tensor再重新包裹。

细粒度的自动求导控制

Variable有两个重要的属性, require_gradsvolatile,创建时,二者均默认为False(除了网络中的模型参数)

  • require_grads
    • 使用场景:pretrain时,要求某些层的参数固定不动,微调某些层;则可将固定层的参数Variable置为无需计算梯度
model = torchvision.models.resnet18(pretrained=True)
for param in model.parameters():
    param.requires_grad = False
# Replace the last fully-connected layer
# Parameters of newly constructed modules have requires_grad=True by default
model.fc = nn.Linear(512, 100)

# Optimize only the classifier
optimizer = optim.SGD(model.fc.parameters(), lr=1e-2, momentum=0.9)
  • volatile
    • 使用场景:当模型仅用于推理时,使用volatile效率高;仅需将模型的输入置为volatile=True即可

深度学习组件

对于大型的神经网络模型来说,自动求导机制是远远不够的——仅仅是底层的操作。我们需要一些深度学习组件——例如将底层计算包裹成layers。Pytorch的nn包定义了一系列相当于layersModules,一个Module通常包括

  • input Variable
  • output Variable
  • internal states, like learnable parameters
# -*- coding: utf-8 -*-
import torch
from torch.autograd import Variable

# N is batch size; D_in is input dimension;
# H is hidden dimension; D_out is output dimension.
N, D_in, H, D_out = 64, 1000, 100, 10

# Create random Tensors to hold inputs and outputs, and wrap them in Variables.
x = Variable(torch.randn(N, D_in))
y = Variable(torch.randn(N, D_out), requires_grad=False)

# Use the nn package to define our model as a sequence of layers. nn.Sequential
# is a Module which contains other Modules, and applies them in sequence to
# produce its output. Each Linear Module computes output from input using a
# linear function, and holds internal Variables for its weight and bias.
model = torch.nn.Sequential(
    torch.nn.Linear(D_in, H),
    torch.nn.ReLU(),
    torch.nn.Linear(H, D_out),
)

# The nn package also contains definitions of popular loss functions; in this
# case we will use Mean Squared Error (MSE) as our loss function.
loss_fn = torch.nn.MSELoss(size_average=False)

learning_rate = 1e-4
for t in range(500):
    # Forward pass: compute predicted y by passing x to the model. Module objects
    # override the __call__ operator so you can call them like functions. When
    # doing so you pass a Variable of input data to the Module and it produces
    # a Variable of output data.
    y_pred = model(x)

    # Compute and print loss. We pass Variables containing the predicted and true
    # values of y, and the loss function returns a Variable containing the
    # loss.
    loss = loss_fn(y_pred, y)
    print(t, loss.data[0])

    # Zero the gradients before running the backward pass.
    model.zero_grad()

    # Backward pass: compute gradient of the loss with respect to all the learnable
    # parameters of the model. Internally, the parameters of each Module are stored
    # in Variables with requires_grad=True, so this call will compute gradients for
    # all learnable parameters in the model.
    loss.backward()

    # Update the weights using gradient descent. Each parameter is a Variable, so
    # we can access its data and gradients like we did before.
    for param in model.parameters():
        param.data -= learning_rate * param.grad.data

nn包也提供了一些损失函数

  • 线性变换

    • 不同于传统的线性代数,深度学习框架一般采取行变换的形式,也就是说x中的每一行是一个样本,x的每一列是一个特征维度


  • 非线性变换

    • 梯度好求且提供了非线性
         torch.nn.functional.relu
         torch.nn.functional.softmax
         torch.nn.functional.log_softmax
    
  • 目标函数

    • 负对数似然 = 最大似然

自定义Module

继承nn.Module,定义forward

优化与训练

torch.optim

  • 最简单的方法:SGD
  • Adam和RMSProp可能会提供算法表现
  • 需要尝试不同优化算法和参数设置

Pytorch 完整的网络

网络组件应继承torch.nn.Module

class MyNN(torch.nn.module):
  def __init__(self, ):# 定义参数
  def forward(self): # 前向传播

输入和target应为Variable

def make_input()
def make_target()

训练

  loss_function = torch.nn.NLLLoss() 
  optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
  for epoch in xrange(100):
    for instance, label in data:
      model.zero_grad() # Pytorch会累积梯度,在使用新样本更新前需要先清空前面样本的梯度
      input = make_input() 
      target = make_target()
      output = model(input) # 前向传播
      loss = loss_function(output, target) # 损失函数
      optimizer.step()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容