target
implement LSTM update rule and use it for image captioning
LSTM
- 在vanilla RNN里面,可以根据vanilla来计算长的sequence,但是同样会因为不停的乘矩阵导致gradient爆炸的问题,LSTM主要就是用了一个其他的update rule解决了这个问题
- 和vanilla RNN差不多,现在这个step的x,前一个hidden state。LSTM保持着H-d的cell state,所以也会从前一个接收到前一个的cell state。
- LSTM会学一个input-to-hidden的矩阵 4HxD, hidden-to-hidden的矩阵 4HxH, bias 4H
- 在每一部都会先计算被激活之后的函数(4H),然后把这个结果a分成四个部分,每个部分的大小是H
- 根据这四个部分计算input gate,forget gate,output gate,block gate
- 前三个都用sigmoid激活,最后一个用tanh激活
- 然后用上面的四个参数计算下一个cell state和hidden state
step forward
- 输入的大小是D,hidden的大小是H,minibatch的大小是N
- input
- x (N,D)
- prev_h (N,H)
- prev_c (N,H)
- Wx input 2 hidden (D,4H)
- Wh hidden 2 hidden (H,4H)
- bias, (4H)
- output
- next_h (N,H)
- next_c (N,H)
- cache
- 按照之前给的公式直接计算就行了,其实就是把原来求出来的值分成了四个部分,分别求出来了四个新的值,用这四个新的值的公式可以得到下一个状态的c和h
step backward
- input
- dnext_h (N,H) 都是上面一个回来的
- dnext_c (N,H)
- cache
- output
- dx(N,D)
- dprev_h (N,H)
- dprev_c (N,H)
- dWx (D,4H)
- dWh (H,4H)
- db (4H)
- 按着正方向计算的顺序back回去就可以了,注意这里有个问题就是因为next_c被用来计算next h了,所以dnext_c需要再求一下关于next h的导数,并且把求出来的新的值加在以前的东西上面
- 后面的矩阵计算尺寸
1 | def lstm_step_forward(x, prev_h, prev_c, Wx, Wh, b): |
forward
- 输入了一大串data,假设输入的data包括了T个vector,每个的dim是D,用的hidden的大小是H,在N的minibatch上面进行,返回对于所有time step的hidden state
- 初始化的cell是0,不会return cell state,只是LSTM自己的变量
- 输入
- x (N,T,D)
- h0, (N,H)
- Wx (D,4H)
- Wh (H,4H)
- b (4H)
- out
- h (N,T,D)
- cache
- 注意h是需要初始化为0的,每次for里面拿出来的是h里面的一部分来赋值
backward
- 和之前的差不多,注意W和b都是要积累的,之前都是要初始化的
- 而且back的时候要用reversed的顺序
1 | def lstm_forward(x, h0, Wx, Wh, b): |