梯度彌散和梯度爆炸
rnn在向w求梯度的過程中,有一項Whh的k次方。這一項會出現問題。Whh>1會趨向無窮,梯度非常非常大(梯度爆炸)。Whh<1會趨向0,梯度非常非常小(梯度彌散)。到一定的值時梯度劇烈變化。
梯度爆炸的解決辦法
設定閾值,當梯度大於某個數的時候,所取得梯度就不是梯度,取得是(梯度/它的模長)*k。這樣就可以把梯度限制在k大小的范圍內不至於無窮大且方向不變。
#只需要在backward生成了梯度信息之后 #循環所有參數p然后將p中的grad參數限制在10以內,方向不變 loss=criteon(output,y) model.zero_grad() loss.backward() for p in model.parameters(): print(p.grad.norm()) torch.nn.utils.clip_grad_norm_(p,10) optimizer.step()
解決梯度彌散的方法下一節的lstm
lstm
長短記憶神經網絡——通常稱作LSTM,是一種特殊的RNN,能夠學習長的依賴關系。
rnn的記憶長度非常的短,原始的rnn
lstm加入了三道門,hi記憶塊過來的時候要經過一道sigmoid,上一級輸出過來的時候也要經過一道sigmoid,他們兩個結合起來也要經過一道sigmoid。
記憶塊經過遺忘門后的信息
過濾后的新信息
以上兩者結合的到新的記憶塊
輸出時也加入sigmoid,輸出時也是用ct記憶塊
一層
import numpy as np import torch from torch import nn cell=nn.LSTMCell(input_size=40,hidden_size=20) inputx=torch.randn(2,3,40) #兩條曲線,3個時刻,每個時刻上的值用40維的向量表示 h=torch.zeros(3,20) #h和c的格式都是(時刻數,隱藏層數) c=torch.zeros(3,20) for i in inputx: #循環inputx,每次取出來(3,40) h,c=cell(i,[h,c]) #循環過程中會使用到h和c,弄出新的h和c print(h.shape,c.shape)
雙層
import numpy as np import torch from torch import nn cell1=nn.LSTMCell(input_size=40,hidden_size=20) cell2=nn.LSTMCell(input_size=20,hidden_size=10) inputx=torch.randn(2,3,40) #兩條曲線,3個時刻,每個時刻上的值用40維的向量表示 h1=torch.zeros(3,20) #h和c的格式都是(時刻數,隱藏層數) c1=torch.zeros(3,20) h2=torch.zeros(3,10) #h和c的格式都是(時刻數,隱藏層數) c2=torch.zeros(3,10) for i in inputx: #循環inputx,每次取出來(3,40) h1,c1=cell1(i,[h1,c1]) #循環過程中會使用到h和c,弄出新的h和c h2, c2 = cell2(h1, [h2, c2]) # 循環過程中會使用到h和c,弄出新的h和c print(h1.shape,c1.shape) print(h2.shape,c2.shape)
GAN
輸入數據,在生成器的作用下生成偽數據,訓練集里的是真實的數據。鑒別器可以鑒別出給出判斷偽數據和真實數據中哪一個是真實的。在不斷訓練的過程中,生成器的效能應該是不斷變好的,最終需要達到鑒別器很難鑒別出它與真實數據之間的差距。
判別模型的目標函數是:
其中D(x)是判別模型的輸出結果,是一個0-1范圍內的實數值,用來判斷圖片是真實圖片的概率,其中Pr和Pg分別代表真實圖像的分布與生成圖像的數據分布情況,目標函數是找到使得兩個式子之和最大
這一整個式子需要盡可能地大
是指使得真實數據放入到判別模型D(x)輸出的計算值和整個式子值盡可能大
是指使得造假數據放入到判別模型D(x)輸出的計算值盡可能小和整個式子值盡可能大,這樣整合下來就是使得目標函數盡可能大,因此在訓練時就可以根據目標函數進行梯度提升。
生成模型的目標是讓判別模型無法區分真實圖片和生成圖片,其目標函數是:
要使得目標函數盡量小
GAN訓練問題
Pr和Pg分別代表真實圖像的分布與生成圖像的數據分布情況,一開始如果Pr和Pg沒有重合部分,梯度為0梯度就無法更新
解決沒有重合部分的方法,引入em距離
通過把較遠的數據搬移到近的地方,要找出代價最小的方法,代價就是一次搬多少而且搬移的距離是多大
WGAN為了解決梯度為0的情況,將從Pr真實圖像的分布上的點x1和Pg生成圖像的數據分布上的點x2的中間進行線性抽樣出一定量的點(比如從28*28上的點x1(0.6)和28*28上的點x2(0.4)之間抽樣產生出一個新的點0.5),然后對這一定量的點求導數再累求和,加到loss當中去