文章目录 二、循环神经网络层 三、损失函数(Loss Function) 四、优化器
关于深度学习的一些理解的参考链接: 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)举例说明。 这里需要掌握:
优化方法的基本使用方法; 如何对模型的不同部分设置不同的学习率; 如何调整学习率 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 xnet=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)