torch.nn.rnn,實現的是jeffrey elman在2023年提出的****** recurrent neural network (srnn),它還有乙個更為廣泛的稱呼:elman network。
torch.nn.lstm,實現的是2023年的lstm
torch.nn.gru,實現的是2023年的gru
rnn、lstm、gru,都繼承了相同的基類rnnbase,並且三者只在構造方法(init)有細微差別:
rnnbase(module)的核心**:
class
rnnbase
(module):.
....
.def
__init__
(self, mode, input_size, hidden_size,
num_layers=
1, bias=
true
, batch_first=
false
, dropout=0.
, bidirectional=
false):
super
(rnnbase, self)
.__init__(
) self.mode = mode
self.input_size = input_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.bias = bias
self.batch_first = batch_first
self.dropout = dropout
self.bidirectional = bidirectional
num_directions =
2if bidirectional else1.
....
.if mode ==
'lstm'
: gate_size =
4* hidden_size
elif mode ==
'gru'
: gate_size =
3* hidden_size
elif mode ==
'rnn_tanh'
: gate_size = hidden_size
elif mode ==
'rnn_relu'
: gate_size = hidden_size
else
:raise valueerror(
"unrecognized rnn mode: "
+ mode)
self._all_weights =
for layer in
range
(num_layers)
:for direction in
range
(num_directions)
: layer_input_size = input_size if layer ==
0else hidden_size * num_directions
w_ih = parameter(torch.tensor(gate_size, layer_input_size)
) w_hh = parameter(torch.tensor(gate_size, hidden_size)
) b_ih = parameter(torch.tensor(gate_size)
)# second bias vector included for cudnn compatibility. only one
# bias vector is needed in standard definition.
b_hh = parameter(torch.tensor(gate_size)
) layer_params =
(w_ih, w_hh, b_ih, b_hh)
suffix =
'_reverse'
if direction ==
1else
'' param_names =
['weight_ih_l{}{}'
,'weight_hh_l{}{}'
]if bias:
param_names +=
['bias_ih_l{}{}'
,'bias_hh_l{}{}'
] param_names =
[x.format
(layer, suffix)
for x in param_names]
for name, param in
zip(param_names, layer_params)
:setattr
(self, name, param)
self.flatten_parameters(
) self.reset_parameters(
)
主要工作:
為rnn每一層,每個方向,都建立一組引數w_ih,w_hh,b_ih,b_hh ,並且把所有引數設定為模型的屬性,這一步通過setattr()函式實現。
因為rnn每一層的計算公式如下所示:
由此可以看到,單層單方向的rnn網路,只包含w_ih,w_hh,b_ih,b_hh 這四個引數。另外,pytorch中rnn僅支援兩種啟用函式:tanh和relu,上圖公式中的tanh也可以換作relu。
self.reset_parameters()方法對rnn中的所有引數都使用均勻分布進行隨機初始化。
因為:pytorch核心開發人員soumith chintala建議:「 for most practical purposes, i found the torch defaults to work well.」
def
reset_parameters
(self)
: stdv =
1.0/ math.sqrt(self.hidden_size)
for weight in self.parameters():
init.uniform_(weight,
-stdv, stdv)
rnn(rnnbase)的核心**class
rnn(rnnbase)
:def
__init__
(self,
*args,
**kwargs):if
'nonlinearity'
in kwargs:
if kwargs[
'nonlinearity']==
'tanh'
: mode =
'rnn_tanh'
elif kwargs[
'nonlinearity']==
'relu'
: mode =
'rnn_relu'
else
:raise valueerror(
"unknown nonlinearity '{}'"
.format
( kwargs[
'nonlinearity'])
)del kwargs[
'nonlinearity'
]else
: mode =
'rnn_tanh'
super
(rnn, self)
.__init__(mode,
*args,
**kwargs)
主要工作:
繼承rnnbase,判斷使用哪一種非線性函式。
gru(rnnbase)的核心**
class
gru(rnnbase)
:def
__init__
(self,
*args,
**kwargs)
:super
(gru, self)
.__init__(
'gru'
,*args,
**kwargs)
主要工作:
繼承rnnbase。
on going…
參考:source code for torch.nn.modules.rnn
讀pytorch原始碼學習rnn
pytorch 學習(8):recurrent layers (迴圈層)實現(gru)
pytorch 學習(8):recurrent layers (迴圈層)實現之grucell)
Pytorch原始碼注釋
field類為可以由張量表示的常見文字處理資料型別建模。它包含乙個vocab物件,用於定義字段元素的可能值集及其對應的數字表示。field物件還包含與資料型別應如何數位化有關的其他引數,例如標記化方法和應生成的tensor型別。如果在資料集中的兩列之間共享字段 例如,qa資料集中的問題和答案 則它們...
讀HashSet原始碼
先看建構函式 public hashset public hashset int initialcapacity public hashset int initialcapacity,float loadfactor 這個構造方法不是public的,僅用於linkedhashset.hashset ...
讀LockSupport原始碼
locksupport類是其他類實現鎖和同步的基礎 basic thread blocking primitives for creating locks and other synchronization classes.讀了原始碼就會知道,這個類主要利用了unsafe類中提供的part和unpa...