Реализация обратного распространения для LSTM RNN и градиентного спуска - PullRequest
0 голосов
/ 23 декабря 2018

Я пытаюсь реализовать рекуррентную нейронную сеть lstm на python с нуля, и у меня возникли проблемы с кодированием обратного распространения для получения правильных градиентов.Я запустил проверку градиента, и он показывает, что градиент неправильный, но я не вижу, где я ошибся в коде.Любая помощь будет принята с благодарностью,

def backward(cache,next,prob,target,params):
    wy,by,wf,bf,wu,bu,wo,bo = params
    c_temp,hf,hu,ho,c,a,X,c_old = cache
    a_next,c_next = next
    dy = np.copy(prob)
    dy[0,target] -= 1
    dwy = np.dot(a.T,dy)
    dby = dy
    dh = dy @ wy.T + a_next
    dho = tanh(c) * dh
    dho = sigmoidGradient(ho) * dho
    dc = ho * dh * tanhGradient(c)
    dc = dc + c_next
    dhf = c_old * dc
    dhf = sigmoidGradient(hf) * dhf
    dhu = c_temp * dc
    dhu = sigmoidGradient(hu) * dhu
    dc_temp = hu * dc
    dc_temp = tanhGradient(c_temp) * dc_temp
    dwf = np.dot(X.T,dhf)
    dbf = dhf
    dXf = np.dot(dhf,wf.T)
    dwu = np.dot(X.T,dhu)
    dbu = dhu
    dXu = np.dot(hu,wu.T)
    dwo = np.dot(X.T,dho)
    dbo = dho
    dXo = np.dot(dho,wo.T)
    dwc = np.dot(X.T,dc_temp)
    dbc = dc_temp
    dXc = np.dot(dc_temp,wc.T)
    dX = dXo + dXc + dXu + dXf
    a_next = dX[:,:hidden_size]
    c_next = hf * dc
    next = (a_next,c_next)
    grad = (dwy,dby,dwf,dbf,dwu,dbu,dwo,dbo)
    return next, grad

Также при обновлении параметров я использую обновление градиентного спуска после последовательности из 60 символов, используя это правило:

 for param,dparam in zip([wy,by,wf,bf,wu,bu,wo,bo],[wygrad,bygrad,wfgrad,bfgrad,wugrad,bugrad,wograd,bograd]):
            param += -alpha * dparam

Но градиенты иКажется, что параметры всегда становятся Нэн, и у меня тоже возникают проблемы с поиском причины.Спасибо за любую помощь.

...