- 讲解
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