RNN Layer

алгоритм

Это 11-й день моего участия в августовском испытании обновлений. Ознакомьтесь с подробностями мероприятия: Испытание августовского обновления

Слой RNN показан на следующем рисунке.

Предположим, что форма x[10, 3, 100], перевод есть, 10 слов, 3 предложения за тренировку, каждое слово выражается 100-мерным тензором

затем для вводаxtx_tСказать,xtx_tФорма[3 100]

Затем посмотрите на приведенный выше рабочий процесс, которыйhidden lenЭто размер памяти, скажем, 20. следовательно:

ht+1=xt@wxh+ht@whh=[3,100]@[20,100]T+[3,20]@[20,20]T=[3,20]\begin{aligned} h_{t+1} &= x_t @ w_{xh} + h_t @ w_{hh}\\ &= [3, 100] @ [20, 100]^T + [3, 20] @ [20, 20]^T \\ &= [3, 20] \end{aligned}

nn.RNN

Определите слой RNN с помощью кода, а затем просмотрите информацию о его параметрах.

import torch
import torch.nn as nn

rnn = nn.RNN(100, 20)
print(rnn._parameters.keys())
print(rnn.weight_ih_l0.shape) # w_{xh} [20, 100]
print(rnn.weight_hh_l0.shape) # w_{hh} [20, 20]
print(rnn.bias_ih_l0.shape) # b_{xh} [20]
print(rnn.bias_hh_l0.shape) # b_{hh} [20]

Прежде чем объяснять приведенный выше код, взгляните на параметры класса RNN в PyTorch (см. официальный сайт PyTorch).RNN API)

  • Обязательный параметрinput_size, указывает размер одной выборки во входной последовательности, например, вектор длиной 1000 может использоваться для представления слова, тогдаinput_size=1000
  • Обязательный параметрhidden_size, который относится к размеру выходных объектов в скрытом слое.
  • Обязательный параметрnum_layers, относится к количеству скрытых слоев по вертикали, обычно устанавливается от 1 до 10, по умолчанию = 1.

Теперь приведенный выше код легко понять,nn.RNN(100, 20)100 относится к представлению слова с вектором длины 100, а 20 относится к hidden_size.

Прямая функция RNN немного отличается от способа определения CNN, как показано на рисунке ниже.

в параметреxxнетxtx_t, то есть непосредственноx=[seq_len,batch,feature_len]x=[\text{seq\_len}, \text{batch}, \text{feature\_len}]принести

h0h_0Если не написано, по умолчанию 0, если написано,h0h_0Размерность[layers,batch,hidden_len][\text{layers},\text{batch}, \text{hidden\_len}]

посмотри на код

import torch
import torch.nn as nn

rnn = nn.RNN(input_size=100, hidden_size=20, num_layers=1)
x = torch.randn(10, 3, 100)
out, h_t = rnn(x, torch.zeros(1, 3, 20))
print(out.shape) # [10, 3, 20]
print(h_t.shape) # [1, 3, 20]

Форма каждого локального параметра связана, вы должны понять, что я написал выше, чтобы понять.

hth_tиoutoutЛегко запутаться, давайте сначала рассмотрим двухслойную модель RNN.

объяснениеhth_tиoutoutПрежде чем нам нужно понять концепцию - отметка времени. Отметка времени слева и справа, а не вверх и вниз. Что это значит? На приведенном выше рисунке изображен двухслойный RNN. Предположим, правая сторона двух слоев RNN подключен к другому слою, то левая и правая структура - это метка времени, основанная на этом, учитываяhth_tиoutoutОпределение:

  • hth_t: Все состояния памяти выше последней метки времени
  • outout: последнее состояние памяти на всех временных метках

Первые несколько ячеек памяти предназначены для слоев.Например, память первого слоя — это первая память, а память последнего слоя — последняя память.

посмотри на код

import torch
import torch.nn as nn

rnn = nn.RNN(input_size=100, hidden_size=20, num_layers=4)
x = torch.randn(10, 3, 100)
out, h_t = rnn(x)
print(out.shape) # [10, 3, 20]
print(h_t.shape) # [4, 3, 20]

Если вы понимаете вышеизложенноеoutoutиhth_tформу, выход тут придумать не сложно

вышеnn.RNN()определяется прямым помещением всейxxEnter, цикл автоматически завершается. Далее мы представим еще один способ определения RNN, который требует ручного завершения цикла.

nn.RNNCell

Давайте посмотрим на официальный PyTorchAPI

параметры иnn.RNNВ целом похоже, но обратите внимание, что форма input_size (batch, input_size) и форма hidden_size также (batch, hidden_size), что приводит к разным форвардам.

посмотри на код

import torch
import torch.nn as nn

cell1 = nn.RNNCell(100, 20)
x = torch.randn(10, 3, 100)
h1 = torch.zeros(3, 20)
for xt in x:
    h1 = cell1(xt, h1)
print(h1.shape) # [3, 20]

Вышеупомянутый уровень RNN, который обучается в ручном цикле по пути RNNCell.

Давайте посмотрим на двухслойную RNN, как это сделать по пути RNNCell.

import torch
import torch.nn as nn

cell1 = nn.RNNCell(100, 30) # 100 -> 30
cell2 = nn.RNNCell(30, 20)
x = torch.randn(10, 3, 100)
h1 = torch.zeros(3, 30)
h2 = torch.zeros(3, 20)
for xt in x:
    h1 = cell1(xt, h1)
    h2 = cell2(h1, h2)
print(h2.shape) # [3, 20]

Функция первого уровня состоит в том, чтобы преобразовать 100-мерный ввод в 30-мерный вывод памяти, а затем вывести вывод во второй уровень, а вывод второго слоя представляет собой 20-мерную память. Самый важный код — это два предложения в for, вход первого слоя — xt и память h1, вход второго слоя — память h1 первого слоя и память h2 второго слоя