Это 11-й день моего участия в августовском испытании обновлений. Ознакомьтесь с подробностями мероприятия: Испытание августовского обновления
Слой RNN показан на следующем рисунке.
Предположим, что форма x[10, 3, 100]
, перевод есть, 10 слов, 3 предложения за тренировку, каждое слово выражается 100-мерным тензором
затем для вводаСказать,Форма[3 100]
Затем посмотрите на приведенный выше рабочий процесс, которыйhidden len
Это размер памяти, скажем, 20. следовательно:
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, как показано на рисунке ниже.
в параметренет, то есть непосредственнопринести
Если не написано, по умолчанию 0, если написано,Размерность
посмотри на код
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]
Форма каждого локального параметра связана, вы должны понять, что я написал выше, чтобы понять.
иЛегко запутаться, давайте сначала рассмотрим двухслойную модель RNN.
объяснениеиПрежде чем нам нужно понять концепцию - отметка времени. Отметка времени слева и справа, а не вверх и вниз. Что это значит? На приведенном выше рисунке изображен двухслойный RNN. Предположим, правая сторона двух слоев RNN подключен к другому слою, то левая и правая структура - это метка времени, основанная на этом, учитываяиОпределение:
- : Все состояния памяти выше последней метки времени
- : последнее состояние памяти на всех временных метках
Первые несколько ячеек памяти предназначены для слоев.Например, память первого слоя — это первая память, а память последнего слоя — последняя память.
посмотри на код
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]
Если вы понимаете вышеизложенноеиформу, выход тут придумать не сложно
вышеnn.RNN()
определяется прямым помещением всейEnter, цикл автоматически завершается. Далее мы представим еще один способ определения 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 второго слоя