Странный результат с функцией градиента Julia Flux

После моего последнего вопроса о путанице при обучении повторяющейся нейронной сети с использованием Flux я углубился в процесс обучения Flux, и теперь я еще больше сбит с толку. Я думаю, что моя проблема связана с использованием суммы в функции, так что потеря учитывает множество точек в последовательности. См. Здесь, где убыток определяется как:

loss(x, y) = sum((Flux.stack(m.(x),1) .- y) .^ 2)

Если это последовательность с несколькими точками, и это соответствующий выход для каждой точки, эта функция оценивает потери для всей последовательности. Я пытаюсь понять, как Flux принимает градиент такой функции. Представьте, что упростите его до:

L(x, y) = sum((Flux.stack(rnn1.(xs), 1) .- y))

Мы также можем создать очень простую рекуррентную нейронную «сеть» в виде одного узла 1 -> 1 без функции активации:

m = Flux.RNN(1, 1, x -> x)

Это (вроде) эквивалент:

      h = [0.0]
function m(x)
    y = Wx .* x + Wh .* h .+ b
    global h = y
    return y
end

Какой градиент loss относительно Wx? Возьмем последовательность с двумя точками, x = [x1, x2] и y * = [y1 *, y2 *]. Поместите x1 через RNN, и вы получите:

y1 = h2 = Wx*x1 + Wh*h1 + b

Затем введите x2, и вы получите:

y2 = h3 = Wx * x2 + Wh* h2 + b = Wx * x2 + Wh* (Wx * x1 + Wh * h1 + b) + b.

Теперь посчитаем убыток:

L = y1 - y1 * + y2 - y2 * = Wx*x1 + Wh*h1 + b - y1 * + Wx * x2 + Wh* (Wx * x1 + Wh * h1 + b) + b - y2 *

Кажется очевидным, что dL / dWx должно быть x1 + x2 + Wh* x1. Итак, скажем x и y находятся:

      x = [[0.3], [2.5]]
y = [0.5, 1.0]

и параметры инициализируются следующим образом:

      Wxs = [0.5]
Whs = [0.001]
bs = [0.85]

Если вычислить dL / DWx = x1 + x2 + Wh* x1, получится 2,8003. Вы также можете попробовать конечную разницу:

      h = [0.0]
q = loss(x, y)
Wx .+= 0.01
h = [0.0]
r = loss(x, y)
abs(q - r)/0.01 # = 2.8003

и получаем 2.8003. Но если вы используете функцию Flux:

      Wx = [0.5]
h = [0.0]
gs = gradient(() -> loss(x, y), params(Wx, Wh, b))
gs[Wxs] # = 2.8025

вы получите 2,8025, что похоже на x1 + x2 + Wh* x2. Я не понимаю, почему результаты разные, особенно если учесть, что все согласуется при оценке самих двух разных функций потерь. Я что-то не замечаю? Что-то странное происходит в gradient?

0 ответов

Другие вопросы по тегам