Я создаю модель ГРУ для прогнозирования цен на акции. Я хотел интегрировать в модель стохастический процесс, чтобы смоделировать волатильность цен.
Итак, это класс для создания стохастического пути.
class SDE(nn.Module):
def __init__(self,lam,sigma):
super().__init__()
self.lam = lam
self.sigma = sigma
def forward(self, T, steps, Npaths):
np.random.seed(4)
lam = self.lam.detach().numpy()
sigma= self.sigma.detach().numpy()
.....
return sigma * lam * xx
Теперь моя модель:
class MyModel(nn.Module):
def __init__(self, args):
super(MyModel, self).__init__()
self.lam = nn.Parameter(torch.tensor(1.0), requires_grad=True)
self.sigma = nn.Parameter(torch.tensor(0.2), requires_grad=True)
# GRU layers
self.gru = nn.GRU(
self.input_dim, self.hidden_dim, self.layer_dim, batch_first=True,
dropout=args.dropout, bidirectional=True)
# SDE
levy = SDE(self.lam, self.sigma)
# Fully connected layer
self.fc = nn.Linear(self.hidden_dim * 2, self.output_dim)
def forward(self, x):
lev = torch.from_numpy(levy(1.0, 16, 1))
.....
h0 = torch.zeros(self.args['num_layers']* 2, x.size(0), self.args['n_hidden_units'],
device=x.device).requires_grad_()
out, _ = self.gru(x, h0.detach())
out = out[:, -1, :]
out = self.fc(out)
out_m = torch.mul(out, lev)
return out
Поезд будет примерно такой:
# Makes predictions
yhat = self.model(x)
# Computes loss
loss = self.loss_fn(y, yhat)
# Computes gradients
#loss.requires_grad = True
loss.backward()
# Updates parameters and zeroes gradients
self.optimizer.step()
self.optimizer.zero_grad()
Обучая эту сеть, следует ли этому коду калибровать и определять оптимальные значения параметров сигмы и lam, используемых для генерации стохастического пути в SDE?
Из отладки я вижу, что их значения всегда одинаковы.
Какие-нибудь советы, пожалуйста, как сделать этот код полезным для моей цели, а именно калибровки сигмы и Лампа?
Если вы хотите, чтобы lam
и sigma
изучались, вам нужно реализовать их как pytorch Parameters
и вычислить результаты lam
и sigma
с помощью методов pytorch. Когда вы вызываете .detach().numpy()
для значений, вы удаляете их из вычислительного графа, а это означает, что pytorch не может обновлять их через обратное распространение.
В своем коде вы определяете lam
и sigma
как Parameters
в своем классе MyModel
, так что оставьте это как есть. Для элемента SDE
вы можете заменить класс функцией (класс SDE
просто содержит переменные, которые уже хранятся в MyModel
). Метод SDE
ward не показан, но вам необходимо реализовать его с помощью методов pytorch, а не numpy.
Вам также следует подумать, чего вы надеетесь достичь с помощью метода SDE
. Похоже, что SDE
создает последовательность значений на основе lam
и sigma
, которые используются для масштабирования выходных данных вашего GRU. Ваша модель может решить, что проще избежать параметров SDE
, установив для них значение lam=1, sigma=0
или другие неинформативные параметры.
Вы отделяете
lam
иsigma
от шага вычислительного графа (для преобразования их в numpy), чтобы они не получали никакой обратной связи по градиенту. Если вы хотите реализовать процесс SDE, реализуйте их в чистом Pytorch (по крайней мере, ту часть, которая взаимодействует сlam
иsigma
)