改善我們的神經網路

2021-09-05 13:01:22 字數 3680 閱讀 7295

**可以在這裡找到。如果您要從上到下滾動指令碼,我會檢視改進,因為它應該很容易跟隨。我不會在這裡討論的一件事是通過numpy進行優化。這意味著我拿出了很多for迴圈並用numpy函式替換它們,比如numpy.dot()或直接在陣列上使用+ - *因為numpy會在內部處理迴圈。它有助於加快速度,最重要的是它可以更容易地將**移植到gnumpy以便使用gpu。

要記住的一件事是,大多數這些改進都具有保持低重量(接近0)的效果。出於正則化用於回歸的相同原因,在神經網路中具有低權重值可以幫助它更好地推廣。由於過度使用神經網路非常容易,我們會盡我們所能。

啟用功能

我做的第一件事是新增兩個我們可以使用的啟用(傳輸)函式。每乙個都比我們開始的邏輯sigmoid有一定的優勢。最大的改進來自於將隱藏層啟用函式從邏輯sigmoid更改為雙曲正切。兩者都被認為是sigmoid函式,但logistic是(0,1)的範圍,雙曲正切(tanh)的範圍是(-1,1)。這裡的想法是,由於tanh函式以0為中心,它產生的輸出平均將更接近0.邏輯sigmoid的輸出總是大於0所以輸出的平均值也會更大比0。

下乙個啟用功能稱為softmax。這個只在輸出層有用,並且僅在類互斥時才有用。它強制神經網路的輸出總和為1,這樣它們就可以表示各類的概率分布。這樣,網路「知道」它不能給出輸出中的類的相同概率。很簡約!

def softmax(w):

e = np.exp(w - np.amax(w))

dist = e / np.sum(e)

return dist

def tanh(x):

return np.tanh(x)

def dtanh(y):

return 1 - y*y

最好的部分是我們可以將這些啟用交換到我們的反向傳播演算法,只需很少的更改。為了在隱藏層中使用tanh函式,我們所要做的就是將它換成sigmoid。

sum = np.dot(self.wi.t, self.ai)

self.ah = tanh(sum)

當我們計算tanh隱藏單位的梯度時,我們將使用我們之前定義的新tanh導數代替logistic sigmoid導數。

error = np.dot(self.wo, output_deltas)

hidden_deltas = dtanh(self.ah) * error

要使用softmax輸出層,我們將進行最大幅度的更改。我們將從這裡走出來

output_deltas = dsigmoid(self.ao) * -(targets - self.ao)
對此

output_deltas = -(targets - self.ao)
再一次,我在這些帖子中跳過數學,只關注可讀的python**和更高層次的理解。但是,基本上這就是正在發生的事情:如果你要使用softmax函式的導數計算出梯度下降演算法,你將最終取消項並到達 - (t - yhat)進行誤差計算,其中t是真值和yhat是**值。真棒!

如果我沒記錯,只需切換出這些啟用功能,我就會有一些改進。

初始化權重

在我們之前的神經網路中,我們簡單地用一些隨機數初始化權重。哪個好,因為它打破了對稱性,但還有乙個更好的方法。我們想嘗試在它們的線性區域中啟用sigmoid函式,以便它們的導數為我們的學習提供足夠的梯度來繼續。換句話說,如果單位的輸出接近sigmoid函式的最小值或最大值,它的導數將是平坦的,我們的網路將學習得非常緩慢(沒有梯度下降)。那麼我們如何解決這個問題呢?

這部分需要在輸入資料和權重之間進行一些「協調」才能使其有效。對於輸入資料,我們只需要將它們縮放到平均值為0.那麼我們將再次隨機繪製權重,但這次我們將告訴numpy給它們乙個0的平均值和負平方根的標準偏差進入節點的層的大小。

input_range = 1.0 / self.input ** (1/2)

output_range = 1.0 / self.hidden ** (1/2)

self.wi = np.random.normal(loc = 0, scale = input_range, size = (self.input, self.hidden))

self.wo = np.random.normal(loc = 0, scale = output_range, size = (self.hidden, self.output))

洗牌訓練的例子

下乙個提示可能是**中最簡單有效的改進。在訓練期間的每次迭代中,我們現在將在將資料饋送到網路之前對資料的順序進行混洗。網路從最意想不到的樣本中學得最快。讓我們說我們所有的資料都很整潔有序。我們所有的』』』』,『twos』和』threes』都歸為一組。如果我們像這樣將資料輸入到網路中,那麼它將非常善於對「那些」進行分類,但是一旦它獲得它的第乙個「兩個」,它就無法接近對它進行分類。然後,網路必須開始學習』兩個』並忘記』那些』。如果我們在每次迭代時隨機化輸入,網路將更容易建立可在所有類之間進行推廣的權重。

將其新增到我們的**就像…一樣簡單

import random 

def fit(self, patterns):

for i in range(self.iterations):

error = 0.0

random.shuffle(patterns)

for p in patterns:

feed_forward(x)

backprop_function(y)

其中patterns是訓練資料集的x和y值列表。

正則與低重量值的整體主題保持一致另乙個方便的技巧是以重量衰減的形式新增正規化。這與線性模型中使用的l2正則化非常相似。對於這個神經網路,我初始化了隱藏權重的輸入和隱藏到輸出權重的正則化項。這樣就可以更靈活地進行微調。基本上,正則化引入了對大權重的懲罰,這反過來又將權重的值推向零。將其新增到網路非常簡單直接。

# update the weights connecting hidden to output, change == partial derivative change = output_deltas * np.reshape(self.ah,  (self.ah.shape[0],1)) regularization = self.l2_out * self.wo

self.wo -= self.learning_rate * (change + regularization) + self.co * self.momentum

self.co = change # update the weights connecting input to hidden, change == partial derivative change = hidden_deltas * np.reshape(self.ai, (self.ai.shape[0], 1)) regularization = self.l2_in * self.wi

self.wi -= self.learning_rate * (change + regularization) + self.ci * self.momentum

self.ci = change

翻譯自克里斯多福奧拉部落格

PyTorch學習(改善深度神經網路)

偏差,方差是我們調整神經網路的乙個重要指標,在搭建神經網路時需要權衡這兩個值,當高偏差時,演算法不能很好的擬合資料,稱之為欠擬合 當高方差時,演算法過於貼合資料集,稱之為過擬合。判斷偏差與方差的情況,可以根據訓練集與驗證集的正確率進行評估,訓練集的誤差高則偏差高,驗證集的誤差高則方差高,是可以出現方...

改善神經網路(吳恩達)2 1

4.正則化 5.正則化為什麼能防止過擬合 6.dropout正則化 7.理解dropout正則化 歸一化方差之後所有特徵的方差為1,均值為0 歸一化輸入步驟 1.歸一化輸入的好處 經過歸一化輸入之後,所有的特徵在相似的範圍之內,且方差都為1。使得cost函式影象從乙個狹長的碗變為較為規則的碗 如果某...

神經網路 卷積神經網路

這篇卷積神經網路是前面介紹的多層神經網路的進一步深入,它將深度學習的思想引入到了神經網路當中,通過卷積運算來由淺入深的提取影象的不同層次的特徵,而利用神經網路的訓練過程讓整個網路自動調節卷積核的引數,從而無監督的產生了最適合的分類特徵。這個概括可能有點抽象,我盡量在下面描述細緻一些,但如果要更深入了...