201204-通过一个A4纸张扫描的例子通俗理解PyTorch中LSTM的参数定义

  • 讲解
import torch
from torch import nn
import torch.nn.functional as F

# 【第1步】 扫描仪参数设置   
batch = 10          # 一次同时扫描的纸张数
batchFirst = True   # 将bacth设置成input的第一个维度,与CNN等传统NN保持一致
a4_width = 21       # 扫描仪每一个时间步step扫描到的特征
a4_height = 29      # 扫描仪扫描完总共需要的时间步steps,即 seq_len
hidden_size = 210   # 输入特征:A4纸(21cm * 29 steps);输出特征:Jpeg照片(210 dpi * 29 steps); 深度特征提取的维度,任意数值
num_layers = 5     # 重复扫描的次数:将第一次扫描好的Jpeg文件打印出来(1dpi=1cm),继续扫描,重复之前的步骤 
bidirectL = False   # 是否同时双面扫描;并将两次扫描的结果在同一个Step上进行横向堆叠
bidirectN  = 2 if bidirectL == True else 1 # 记录扫描方式: 只是单面扫描:1; 同时双面扫描:2

# 【第2步】 待扫描纸张参数设置
# 每次扫描10张纸:batch = 10:
# 从上到下,扫描完一张纸总的时间步:seq_len = 29
# 从左到右:每秒一次扫描的宽度:input_size = 21
input = torch.randn(batch, a4_height, a4_width) # (batch, seq_len, input_size)

# 【第3步】 扫描仪结构性能设置,不需要考虑seq_len,针对同一个batch内不同seq_len要提前做好数据预处理
# input_size =21, hidden_size = 210, num_layers = 2, batch_first: 同CNN逻辑结构,bidirectional:同时扫描
rnn = nn.LSTM(a4_width, hidden_size, num_layers, batch_first = batchFirst, bidirectional=bidirectL)  

# 【第4步】 扫描仪扫描偏好设置,如果不设置,默认初始状态全部为零
h0 = torch.randn(num_layers*bidirectN, batch, hidden_size) # num_layers * num_directions, batch, hidden_siz
c0 = torch.randn(num_layers*bidirectN, batch, hidden_size) # num_layers * num_directions, batch, hidden_siz

# 【第5步】输出扫描结果
# - 如果bacth在第二维度:(seq_len, batch, num_directions * hidden_size)
# - 如果batch在第一维度:(batch, seq_len, num_directions * hidden_size)
output, (hn, cn) = rnn(input, (h0, c0)) 
print('output: {}; \nhn: {}; \ncn: {}.'.format(output.shape,hn.shape, cn.shape))

# output: torch.Size([10, 29, 210]); 
# hn: torch.Size([5, 10, 210]); 
# cn: torch.Size([5, 10, 210]).

# [第6步] 编辑并选择Jpeg图像的全部或局部
# - 如果需要全部扫描好的图像,则选择output[:, :,:], 随后reshape堆叠
# - 如果只需要扫面图像最下面,则选择output[:,-1,:], 通过index索引
edit = 'last' # or all
select =  output[:,-1,:] if edit == 'last' else output[:,:,:]
print('Select: {}'.format(select.shape))

# [第7步] 映射‘编辑选择好的Jpeg’作为逻辑值,输出归一化后的性能指标
map = nn.Linear(210,10)
logits  = map(select)
final = F.log_softmax(logits, dim=1)
print('Final: {}'.format(final.shape))

针对同一个batch内不同seq_len要提前做好数据预处理

  • 输出

output: torch.Size([10, 29, 210]);
hn: torch.Size([5, 10, 210]);
cn: torch.Size([5, 10, 210]).
Select: torch.Size([10, 210])
Final: torch.Size([10, 10])

  • 理解双向堆叠
    在这里插入图片描述

  • 理解如何利用所有时间步的全部隐藏特征
    在这里插入图片描述

  • 理解如何利用最后时间步的高层隐藏特征
    在这里插入图片描述
    在这里插入图片描述

  • 如何理解dropout
    在这里插入图片描述

  • 如何理解序列对齐
    在这里插入图片描述
    在这里插入图片描述

  • LSTM的多种应用模式
    在这里插入图片描述

  • Demo下面代码供参考,参数可调整

class LSTM(nn.Module):
    def __init__(self):
        super(LSTM,self).__init__()
        self.LSTM1 = nn.LSTM(21,210,batch_first=True,dropout=0.15,num_layers=2)
        self.LSTM2 = nn.LSTM(210,64,batch_first=True,dropout=0.15,num_layers=2)
        self.LSTM3 = nn.LSTM(64,32,batch_first=True)
        self.Logits = nn.Linear(32,10)
        
    def forward(self,x):
        x = x.view(-1,29,21) # input of shape (batch, seq_len, input_size):
        out,(h_n,c_n) = self.LSTM1(x)
        out,(h_n,c_n) = self.LSTM2(out)
        out,(h_n,c_n) = self.LSTM3(out)
        logits = self.Logits(out[:,-1,:]) # Only select the final feature
        output = F.log_softmax(logits, dim=1)
        return output
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页