Я разместил этот вопрос на сайте Data Science StackExchange, поскольку StackOverflow не поддерживает LaTeX.Ссылка здесь, потому что этот сайт, вероятно, более уместен.
Вопрос с правильно отрендеренным LaTeX здесь: https://datascience.stackexchange.com/questions/48062/pytorch-does-not-seem-to-be-optimizing-correctly
Идея состоит в том, что я рассматриваю суммы синусоидальных волн с разными фазами.Волны дискретизируются с некоторой частотой дискретизации s
в интервале [0, 2pi].Мне нужно выбирать фазы таким образом, чтобы сумма волн в любой точке выборки была минимальной.
Ниже приведен код Python.Оптимизация, похоже, не рассчитана правильно.
import numpy as np
import torch
def phaseOptimize(n, s = 48000, nsteps = 1000):
learning_rate = 1e-3
theta = torch.zeros([n, 1], requires_grad=True)
l = torch.linspace(0, 2 * np.pi, s)
t = torch.stack([l] * n)
T = t + theta
for jj in range(nsteps):
loss = T.sin().sum(0).pow(2).sum() / s
loss.backward()
theta.data -= learning_rate * theta.grad.data
print('Optimal theta: \n\n', theta.data)
print('\n\nMaximum value:', T.sin().sum(0).abs().max().item())
Ниже приведен пример вывода.
phaseOptimize(5, nsteps=100)
Optimal theta:
tensor([[1.2812e-07],
[1.2812e-07],
[1.2812e-07],
[1.2812e-07],
[1.2812e-07]], requires_grad=True)
Maximum value: 5.0
Я предполагаю, что это как-то связано с вещанием в
T = t + theta
и / или способом, которым явычисляю функцию потерь.
Один из способов проверить, что оптимизация неверна, - просто оценить функцию потерь при случайных значениях для массива $ \ theta_1, \ dots, \ theta_n $, скажем, равномерно распределенного в $ [0, 2 \ pi] $.Максимальное значение в этом случае почти всегда намного ниже максимального значения, указанного в phaseOptimize()
.Гораздо проще на самом деле рассмотреть случай с $ n = 2 $ и просто оценить при $ \ theta_1 = 0 $ и $ \ theta_2 = \ pi $.В этом случае мы получаем:
phaseOptimize(2, nsteps=100)
Optimal theta:
tensor([[2.8599e-08],
[2.8599e-08]])
Maximum value: 2.0
С другой стороны,
theta = torch.FloatTensor([[0], [np.pi]])
l = torch.linspace(0, 2 * np.pi, 48000)
t = torch.stack([l] * 2)
T = t + theta
T.sin().sum(0).abs().max().item()
производит
3.2782554626464844e-07