Pytorch——循环神经网络层、损失函数、优化器

[TOC]
关于深度学习的一些理解的参考链接:
https://www.cnblogs.com/bamtercelboo/p/7469005.html

一、 基础知识

1)激活函数

这里写图片描述
sigmoid和tanh函数的导数都是原函数的函数。这样,我们一旦计算原函数的值,就可以用它来计算出导数的值。

二、循环神经网络层

1)LSTM

t.manual_seed(1000)

input=V(t.randn(2,3,4))
print('input:')

print(input)
lstm=nn.LSTM(4,3,1)
h0=V(t.randn(1,3,3))
c0=V(t.randn(1,3,3))
out,hn=lstm(input, (h0,c0))
print('out:')
print(out)

结果:

input:
tensor([[[-0.5306, -1.1300, -0.6734, -0.7669],
         [-0.7029,  0.9896, -0.4482,  0.8927],
         [-0.6043,  1.0726,  1.0481,  1.0527]],

        [[-0.6424, -1.2234, -1.0794, -0.6037],
         [-0.7926, -0.1414, -1.0225, -0.0482],
         [ 0.6610, -0.8908,  1.4793, -0.3934]]])
out:
tensor([[[-0.3610, -0.1643,  0.1631],
         [-0.0613, -0.4937, -0.1642],
         [ 0.5080, -0.4175,  0.2502]],

        [[-0.0703, -0.0393, -0.0429],
         [ 0.2085, -0.3005, -0.2686],
         [ 0.1482, -0.4728,  0.1425]]])

2)LSTMCell

t.manual_seed(1000)
input=V(t.randn(2,3,4))
print('input:')

print(input)
lstm=nn.LSTMCell(4,3)
hx=V(t.randn(3,3))
cx=V(t.randn(3,3))
out=[]
for i_ in input:
    hx,cx=lstm(i_, (hx,cx))
    out.append(hx)

print('out:')
print(out)

结果:

input:
tensor([[[-0.5306, -1.1300, -0.6734, -0.7669],
         [-0.7029,  0.9896, -0.4482,  0.8927],
         [-0.6043,  1.0726,  1.0481,  1.0527]],

        [[-0.6424, -1.2234, -1.0794, -0.6037],
         [-0.7926, -0.1414, -1.0225, -0.0482],
         [ 0.6610, -0.8908,  1.4793, -0.3934]]])
out:
[tensor([[-0.3610, -0.1643,  0.1631],
        [-0.0613, -0.4937, -0.1642],
        [ 0.5080, -0.4175,  0.2502]]), tensor([[-0.0703, -0.0393, -0.0429],
        [ 0.2085, -0.3005, -0.2686],
        [ 0.1482, -0.4728,  0.1425]])]

三、损失函数(Loss Function)

在深度学习中要用到各种各样的损失函数,这些损失函数可看做是一种特殊的layer, Pytorch也将这些损失函数专门提取出来,作为独立的一部分。
这里以交叉熵损失CrossEntripyliss为例:

#batchsize=3  计算对应每个类别的分数(只有两个类别0, 1)
score=V(t.randn(3,2))
#三个样本分别属于1,0,1类,label必须是LongTensor
label=V(t.Tensor([1,0,1])).long()

#loss与普通的layer无差异
criterion=nn.CrossEntropyLoss()
loss=criterion(score,label)
loss

结果:

tensor(0.8908)

四、优化器

Pytorch将深度学习中所有的优化方法都封装在torch.optim中,其设计十分灵活,能够很方便地扩展成自定义的优化方法。

所有的优化方法都是继承基类optim.Optimizer, 并实现了自己的优化步骤。
下面以最基本的 优化方法——随机梯度下降法(SGD)举例说明。
这里需要掌握:
1. 优化方法的基本使用方法;
2. 如何对模型的不同部分设置不同的学习率;
3. 如何调整学习率

from torch import optim
import torch as t
from torch import nn
from torch.autograd import Variable as V


#首先定义一个Lenet网络
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.features=nn.Sequential(
            nn.Conv2d(3,6,5),
            nn.ReLU(),
            nn.MaxPool2d(2,2),
            nn.Conv2d(6,16,5),
            nn.ReLU(),
            nn.MaxPool2d(2,2)

        )
        self.classifier=nn.Sequential(
            nn.Linear(16*5*5, 120),
            nn.ReLU(),
            nn.Linear(120, 84),
            nn.ReLU(),
            nn.Linear(84, 10),

        )
    def forward(self,x):
        x=self.features(x)
        x=x.view(-1,16*5*5)
        x=self.classifier(x)
        return x

net=Net()
optimizer=optim.SGD(params=net.parameters(), lr=1)
optimizer.zero_grad()   #梯度清零等价于net.zero_grad()

input=V(t.randn(1,3,32,32))
output=net(input)
output.backward(output)

optimizer.step()  #执行优化
#为不同的子网络设置不同的学习率,在finetune中经常用到
#如果对某个参数不指定学习率,就使用默认的学习率
optimizer=optim.SGD([
    {'params':net.features.parameters()},
    {'params':net.classifier.parameters()}
    ], lr=1e-5)
#只在全连接层设置较大的学习率,其余层设置较小的学习率
special_layers=nn.ModuleList([net.classifier[0], net.classifier[3]])
special_layers_params=list(map(id, special_layers.parameters())
base_params = filter(lambda p:id(p) not in special_layers_params, 
                     net.parameters())

optimizer=t.optim.SGD([
    {'params':base_params},
    {'params':special_layers.parameters(),'lr':0.01}
], lr=0.01)

调整学习率的方法主要有两种。
一种是修改optimizer.params_groups 中对应的学习率,另一种是新建优化器(更简单也是更推荐的做法)。由于optimizer十分轻量级,构建开销很小,故可以构建新的optimizer.
但是构建新的优化器会重新初始化动量等状态信息,这对使用动量的优化器来说(如带momentum的sgd),可能会造成损失函数在收敛过程中出现 震荡。

#调整学习率 新建一个optimizer
old_lr=0.1
optimizer=optim.SGD([
    {'params':net.features.parameters()},
    {'params':net.classifier.parameters(),'lr':old_lr*0.1}
],lr=1e-5)

猜你喜欢

转载自blog.csdn.net/zhenaoxi1077/article/details/80947073