pytorch中RNN函數

'''
參考https://www.cnblogs.com/lindaxin/p/8052043.html
以及pytorch中文文檔https://pytorch-cn.readthedocs.io/zh/latest/package_references/torch-nn/#class-torchnnrnn-args-kwargssource
熟悉pytorch的RNN網絡流程,現在還有疑惑
'''
import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.nn import utils as nn_utils

batch_size = 2
max_length = 3
hidden_size = 2
n_layers =1

tensor_in = torch.FloatTensor([[1,2,3],[4,5,6]]).resize_(2,3,1)  # 爲什麼要resize,是因爲要區分每個時間步和每個時間步的特徵吧
torch_in = Variable(tensor_in)  # 輸入Tensor的shape是[batch_size, time_step, feature],這是肯定的
print('tensor_in')
print(tensor_in)
'''
tensor([[[1.],
         [2.],
         [3.]],

        [[4.],
         [5.],
         [6.]]])
'''

# list of integers holding information about the batch size at each sequence step?
# 可以理解爲3個時間步,每個時間步一個特徵吧
seq_lengths = [3,1]

# pack(壓縮?統一長度,作用是不是類似Keras中的Embedding()?) it
pack = nn_utils.rnn.pack_padded_sequence(tensor_in, seq_lengths, batch_first=True)
'''
輸入的形狀可以是(T×B×* )。T是最長序列長度,B是batch size,*代表任意維度(可以是0)。
參數說明:
input (Variable) – 變長序列 被填充後的 batch
lengths (list[int]) – Variable 中 每個序列的長度。應該按序列長度的長短排序 ?
batch_first (bool, optional) – 如果是True,input的形狀應該是B*T*size。

返回值:
一個PackedSequence 對象。
'''

# initialize
rnn = nn.RNN(1,hidden_size,n_layers,batch_first=True)
'''
RNN參數說明:
input_size – 輸入x的特徵數量。
hidden_size – 隱層的特徵數量。
num_layers – RNN的層數。
nonlinearity – 指定非線性函數使用tanh還是relu。默認是tanh。
bias – 如果是False,那麼RNN層就不會使用偏置權重 $b_ih$和$b_hh$,默認是True
batch_first – 如果True的話,那麼輸入Tensor的shape應該是[batch_size, time_step, feature],輸出也是這樣。
dropout – 如果值非零,那麼除了最後一層外,其它層的輸出都會套上一個dropout層。
bidirectional – 如果True,將會變成一個雙向RNN,默認爲False。
'''
h0 = Variable(torch.randn(n_layers, batch_size, hidden_size))

out,_ = rnn(pack,h0)
'''
RNN的輸入: 
(input, h_0) - input (seq_len, batch, input_size): 保存輸入序列特徵的tensor。input可以是被填充的變長的序列。
h_0 (num_layers * num_directions, batch, hidden_size): 保存着初始隱狀態的tensor

RNN的輸出: (output, h_n)
output (seq_len, batch, hidden_size * num_directions): 保存着RNN最後一層的輸出特徵。如果輸入是被填充過的序列,那麼輸出也是被填充的序列。
h_n (num_layers * num_directions, batch, hidden_size): 保存着最後一個時刻隱狀態。
'''

unpacked = nn_utils.rnn.pad_packed_sequence(out,batch_first=True)
'''
 這個操作和pack_padded_sequence()是相反的。把壓緊的序列再填充回來。
 參數說明:
sequence (PackedSequence) – 將要被填充的 batch
batch_first (bool, optional) – 如果爲True,返回的數據的格式爲 B×T×*。
返回值: 一個tuple,包含被填充後的序列,和batch中序列的長度列表。
'''
print('unpacked')
print(unpacked)
'''
(tensor([[[-0.0543,  0.1340],
         [ 0.2547,  0.6385],
         [ 0.3781,  0.9012]],

        [[ 0.5487,  0.9719],
         [ 0.0000,  0.0000],
         [ 0.0000,  0.0000]]], grad_fn=<TransposeBackward0>), tensor([3, 1]))
         
爲什麼變成兩列了? 即上面提到的*
'''

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章