В формуле минимизации эмпирического риска, которую я использую для своей нейронной сети, формула обновления весов выглядит следующим образом:
Delta = (-Gradient of weight) - (lambda * gradient of regularizer)
Weight = Weight + alpha * Delta
В источнике, на который я ссылаюсь, градиент регуляризатора l2 просто:
2 * weight
Поэтому я вставляю его в свой код: (фрагмент)
double regularizegrad(double weight)
{
return 2 * weight;
}
for (size_t I = 0; I < Inlayer.size(); I++)
{
double PD{};
for (size_t iw = 0; iw < Inlayer[I].weights.size(); iw++)
{
PD = (Inlayer[I].weightderivs[iw] * -1) - (Lambda * regularizegrad(Inlayer[I].weights[iw],"L1"));
Inlayer[I].weights[iw] = Inlayer[I].weights[iw] + (Alpha * PD);
}
}
как только я запустил это в своей сети, я получаю insta NAN (ind) независимо от того, какие значения лямбда и альфа я поставил.
Но если я использую градиент регуляризации L1 (который, согласно моему источнику, является знаком (Вес)):
double regularizegrad(double weight)
{
if (weight > 0) return 1;
else if (weight < 0) return -1;
else if (weight == 0) return 0;
else return 2; //error
}
У меня нет никаких проблем.
Итак, мой вопрос: это правильный способ рассчитать градиент регуляризатора для L2? В результате я сейчас сомневаюсь, правильно ли я сделал L1, но сеть определенно работает, если я использую L1. Но да, просто не уверен, правильный ли код для градиента L2.