Я имею дело со следующим сценарием:
Мой ввод имеет вид: [batch_size, input_sequence_length, input_features]
где:
input_sequence_length = 10
input_features = 3
Мой вывод имеет вид: [batch_size, output_sequence_length]
где:
output_sequence_length = 5
то есть: для каждого временного интервала из 10 единиц (каждый слот с 3 функциями) мне нужно предсказать значения следующих 5 слотов.
Я построил следующую модель:
import torch
import torch.nn as nn
import torchinfo
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.GRU = nn.GRU(input_size=3, hidden_size=32, num_layers=2, batch_first=True)
self.fc = nn.Linear(32, 5)
def forward(self, input_series):
output, h = self.GRU(input_series)
output = output[:, -1, :] # get last state
output = self.fc(output)
output = output.view(-1, 5, 1) # reorginize output
return output
torchinfo.summary(MyModel(), (512, 10, 3))
==========================================================================================
Layer (type:depth-idx) Output Shape Param #
==========================================================================================
MyModel [512, 5, 1] --
├─GRU: 1-1 [512, 10, 32] 9,888
├─Linear: 1-2 [512, 5] 165
==========================================================================================
Я получаю хорошие результаты (очень маленькие MSE
потери, и прогнозы выглядят хорошо),
но я не уверен, действительно ли выходные данные модели (5 значений последовательности) упорядочены моделью? то есть второй вывод на основе первого вывода и третий вывод на основе второго вывода...
Я знаю, что вывод GRU
основан на изученной истории последовательности.
Но я также использую линейный слой, поэтому вывод (после линейного слоя) все еще сортируется по времени?
Этот ответ не совсем правильный, см. этот дополнительный вопрос. Лучший способ — написать математику и показать, что 5 скалярных выходов не являются функциями друг друга.
Я не уверен, действительно ли выходные данные модели (5 значений последовательности) упорядочены моделью? то есть второй вывод на основе первого вывода и третий вывод на основе второго вывода
Нет, это не так. Вы можете проверить, что градиенты, скажем, последнего вывода относительно предыдущих выходов равны нулю, что в основном означает, что последний вывод не является функцией предыдущих выходов.
model = MyModel()
x = torch.rand([2, 10, 3])
y = model(x)
y.retain_grad() # allows accessing y.grad although y is a non-leaf Tensor
y[:, -1].sum().backward() # computes gradients of last output
assert torch.allclose(y.grad[:, :-1], torch.tensor(0.)) # gradients w.r.t previous outputs are zeroes
Популярной моделью для захвата зависимостей между выходными метками являются условные случайные поля. Но поскольку вы уже довольны прогнозами текущей модели, возможно, моделирование выходных зависимостей не так важно.
@user3668129 user3668129 Да, верно. Градиент выхода по отношению к входу говорит, насколько изменится выход, когда вход возмущен, верно? Итак, если градиент равен нулю, то ввод не имеет значения.
Кажется, что если бы я использовал модель только с одним слоем GRU (а вывод слоя GRU зависит от последовательности), я все равно получаю нулевые градиенты. Почему это ?
Я задал отдельный вопрос: stackoverflow.com/questions/74973860/…
@user3668129 user3668129 Я добавил обновление со ссылкой на ваш дополнительный вопрос, чтобы отвлечь людей от ответа.
Я не уверен, что понимаю, как градиенты говорят нам об этом. Если предыдущие градиенты не равны нулю, это означает, что результат является функцией предыдущего результата?