李宏毅机器学习:RNN(下)

RNN的Learning

RNN在Learning时如何定义loss function呢?以slot filling 为例,对每个输入xi, 其输出的yi与相应的reference vector计算cross entropy, cross entropy之和就是loss function. 训练时word sequence不能打散,要先用x1 得到y1, 再用x2得到y2
定义好loss function之后,用gradient descent做training。gradient descent的算法从BP进阶为BPTT(Backpropagation through time). 

但是,很遗憾的,RNN的训练是比较困难的,其error surface要么很平缓要么很陡峭。这样在做gradient descent时,参数可能跳到悬崖上,造成loss暴增,或者跳到悬崖边上(gradient很大),造成参数飞出去(NAN)。解决办法是clipping: 当gradient>某个阈值时,另gradient = 阈值。 

李宏毅机器学习:RNN(下)_第1张图片

为何RNN会有rough的error surface? 
并不是因为来自sigmoid的gradient vanish,因为换成ReLU也存在相同问题。(RNN中把sigmoid换成ReLU效果往往更差) 

其实是因为RNN处理的是time sequence, 同样的weight在不同时刻被多次使用。 

李宏毅机器学习:RNN(下)_第2张图片

(gradient在w=1处很大,在w=0.99处很小)

如何解决这一问题呢?使用最广泛的技巧是LSTM. 
为什么要把一般的RNN换成LSTM?因为LSTM可以处理gradient vanishing的问题:LSTM可以让error surface不那么崎岖,把平坦的部分拿掉,这样解决了gradient vanishing的问题,但没有解决gradient explosion的问题。 
那么,为什么LSTM可以处理gradient vanishing的问题呢? 
在一般的RNN中,每个时刻neuron的output都会被放到memory中去,所以在每个时刻memory中的值都会被洗掉。但在LSTM中,是把memory中原来的值乘上一个数再加上一个数,即memory和input是想加的关系。所以LSTM中如果weight影响了memory中的值,那么这个影响会永远都存在(除非forget gate决定洗掉memory,有说法认为要给forget gate很大的bias以使其多数情况下开启),而不像SimpleRNN中memory的值在每个时刻都会被洗掉。 
若使用LSTM出现了过拟合,可考虑改用GRU。GRU的精神是“旧的不去,新的不来”,它将input gate与forget gate联动起来:若input gate 开,则forget gate 关。

其它处理gradient descent的技巧还有clockwise RNN, SCRN…… 

如果random初始化一般RNN的weight,那么用ReLU的效果要比用sigmoid的效果差。但[Quoc V. Le, arXiv’15]提出,如果用单位矩阵初始化一般RNN的weight,那么用ReLU的效果要比用LSTM的效果好。 



你可能感兴趣的:(深度学习)