我已經(jīng)忘了秋天,最凄美的時(shí)節(jié),含著眼淚我與你分別
不想顧忌太多,冬天已經(jīng)來了,凜冬的湖面望不見春色
時(shí)間是星星的眼睛,忘穿我的困惑
11.4 入門神經(jīng)網(wǎng)絡(luò)
介紹了神經(jīng)網(wǎng)絡(luò)的四要素:輸入、權(quán)重、求和、激活函數(shù),用很簡單的神經(jīng)網(wǎng)絡(luò)(輸入層、隱藏層、輸出層各只有一個(gè)節(jié)點(diǎn))進(jìn)行了權(quán)值訓(xùn)練的數(shù)學(xué)推導(dǎo),介紹了反向傳播算法
部分內(nèi)容轉(zhuǎn)載自:零基礎(chǔ)入門深度學(xué)習(xí)(3) - 神經(jīng)網(wǎng)絡(luò)和反向傳播算法 - 作業(yè)部落 Cmd Markdown 編輯閱讀器 https://www.zybuluo.com/hanbingtao/note/476663



如上圖,輸入層有三個(gè)節(jié)點(diǎn),我們將其依次編號(hào)為1、2、3;隱藏層的4個(gè)節(jié)點(diǎn),編號(hào)依次為4、5、6、7;最后輸出層的兩個(gè)節(jié)點(diǎn)編號(hào)為8、9。因?yàn)槲覀冞@個(gè)神經(jīng)網(wǎng)絡(luò)是全連接網(wǎng)絡(luò),所以可以看到每個(gè)節(jié)點(diǎn)都和上一層的所有節(jié)點(diǎn)有連接。比如,我們可以看到隱藏層的節(jié)點(diǎn)4,它和輸入層的三個(gè)節(jié)點(diǎn)1、2、3之間都有連接,其連接上的權(quán)重分別為w41 w42 w43,那么我們?nèi)绾斡?jì)算a4呢?
為了計(jì)算節(jié)點(diǎn)a4的輸出值,我們必須先得到其所有上游節(jié)點(diǎn)(也就是節(jié)點(diǎn)1、2、3)的輸出值。節(jié)點(diǎn)1、2、3是輸入層的節(jié)點(diǎn),所以,他們的輸出值就是輸入向量本身。按照上圖畫出的對(duì)應(yīng)關(guān)系,可以看到節(jié)點(diǎn)1、2、3的輸出值分別是x1 x2 x3 我們要求輸入向量的維度和輸入層神經(jīng)元個(gè)數(shù)相同.

同樣,我們可以繼續(xù)計(jì)算出節(jié)點(diǎn)a5、a6、a7的輸出值。這樣,隱藏層的4個(gè)節(jié)點(diǎn)的輸出值就計(jì)算完成了,我們就可以接著計(jì)算輸出層的節(jié)點(diǎn)8的輸出值:

神經(jīng)網(wǎng)絡(luò)的每一層的權(quán)重這些參數(shù)是神經(jīng)網(wǎng)絡(luò)要學(xué)習(xí)的東西,而層數(shù)、層與層之間的連接方式,這些事先由人為給定的量,稱為超參數(shù)。
神經(jīng)網(wǎng)絡(luò)的計(jì)算方法:對(duì)于每一層而言,對(duì)輸入向量x(向量)左乘一個(gè)權(quán)重矩陣W,得到一個(gè)新的向量,再對(duì)這個(gè)向量逐元素應(yīng)用激活函數(shù),得到該層的輸出。
11.6
反向傳播算法
假設(shè)每個(gè)訓(xùn)練樣本為(x(向量), t(向量)) 其中x為樣本的特征,t為樣本的目標(biāo)值

沿著梯度方向是函數(shù)在該點(diǎn)增長最快的方向,反之沿著負(fù)梯度方向就是下降最快的方向,這也是神經(jīng)網(wǎng)絡(luò)反向傳播算法基于負(fù)梯度下降的依據(jù)。

為什么叫反向傳播算法?
要計(jì)算每個(gè)節(jié)點(diǎn)的誤差項(xiàng),就必須先計(jì)算與之相連的下一個(gè)結(jié)點(diǎn)的誤差項(xiàng),這一切不斷往下一個(gè)節(jié)點(diǎn)進(jìn)行追溯,直到輸出層。也就是必須要先計(jì)算輸出層的誤差項(xiàng),再逐個(gè)計(jì)算隱藏層,不斷更新。
推導(dǎo):https://www.zybuluo.com/hanbingtao/note/476663應(yīng)用鏈?zhǔn)椒▌t進(jìn)行推導(dǎo)
向量化編程
11.7
很開心,和小鐵憨煲了一個(gè)多小時(shí)的電話粥,互相嫌棄了五十分鐘哈哈
又在開會(huì)和回來的路上和班長聊了很多很多,又寫了學(xué)習(xí)心得體會(huì),今天還是很充實(shí)啊
11.8
為什么神經(jīng)網(wǎng)絡(luò)可以擬合任意的函數(shù)?
為什么模擬異或運(yùn)算就代表著能夠模擬任意的邏輯函數(shù)?
tip:新的surfacepro到了,但是鍵盤老是失靈,看幾分鐘代碼再敲就會(huì)失靈并伴隨顯示啟用自動(dòng)旋轉(zhuǎn)。哇原來是接觸不良切換到平板模式了

[https://zhuanlan.zhihu.com/p/29633019]知乎專欄神經(jīng)網(wǎng)絡(luò)詳解
[https://www.cnblogs.com/ms-uap/p/10031484.html]博客園神經(jīng)網(wǎng)絡(luò)詳解
[https://www.bilibili.com/video/av34151455?p=4]CMU深度學(xué)習(xí)導(dǎo)論
11.9-11 神經(jīng)網(wǎng)絡(luò)擬合

import random
import numpy as np
import matplotlib.pyplot as plt
import time
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def target(x):
y = 1 / np.sin(x) + 1 / np.cos(x)
return y
class Network():
def __init__(self, hidden_amount, iteration, learning_rate, max_error, x_min, x_max, x_amount):
self.hidden_amount = hidden_amount
self.iteration = iteration
self.learning_rate = learning_rate
self.max_error = max_error
self.W1 = np.random.random((self.hidden_amount, 1))
self.B1 = np.random.random((self.hidden_amount, 1))
self.W2 = np.random.random((1, self.hidden_amount))
self.B2 = np.random.random((1, 1))
self.X = np.linspace(x_min, x_max, x_amount)
self.T = target(self.X)
self.Y = np.zeros((x_amount, 1))
self.E = np.zeros((self.iteration, 1))
def hidden_layer(self):
error = 0
for i in range(len(self.X)):
x = self.X[i]
hidden_input = np.dot(x, self.W1) - self.B1
hidden_output = np.array([sigmoid(y) for y in hidden_input])
self.Y[i] = np.dot(self.W2, hidden_output) - self.B2
e = self.Y[i] - self.T[i]
error = error + 0.5 * e ** 2
dB2 = -1 * self.learning_rate * e
dW2 = self.learning_rate * e * np.transpose(hidden_output)
dB1 = np.transpose(self.W2) * hidden_output * (1 -hidden_output) * (-1) * e *
self.learning_rate
dW1 = np.transpose(self.W2) * hidden_output * (1 - hidden_output) * x * e * self.learning_rate
self.W1 -= dW1
self.W2 -= dW2
self.B1 -= dB1
self.B2 -= dB2
return error
def iterate(self):
start = time.time()
for i in range(self.iteration):
e = self.hidden_layer()
self.E[i] = e
if e <= self.max_error:
break
print("iteration:", i, "\nerror:", e, "\ntime:", time.time() - start)
plt.title('Blue:Training Red:Simulating')
plt.plot(self.X, self.T, color='blue')
plt.plot(self.X, self.Y, color='red')
plt.show()
xx = np.linspace(0, self.iteration, self.iteration)
plt.title('Error changing')
plt.plot(xx, self.E, color='pink')
plt.show()
a = Network(hidden_amount = 2, iteration = 10000, learning_rate = 0.005, max_error = 0.001, x_min= -1, x_max = 3, x_amount = 40)
a.iterate()
可以sigmoid更換其他的激活函數(shù),可以target更換其他的目標(biāo)函數(shù)




收獲
- 單隱層的神經(jīng)網(wǎng)絡(luò),在神經(jīng)元足夠多且參數(shù)合適的情況下,的確能夠在我們可接受的誤差范圍內(nèi)擬合連續(xù)函數(shù)
- 在其它參數(shù)不變的情況下,增加迭代次數(shù)能夠明顯地提升擬合的效果
- 增加神經(jīng)元數(shù)目時(shí),擬合效果的上限會(huì)提高,但一般需要增加迭代次數(shù)
- 對(duì)于overflow溢出問題,因?yàn)槎x的sigmoid函數(shù)為 1 / (1 + exp(-x))
當(dāng)x過小時(shí),e的-x次方會(huì)太大,當(dāng)x過大時(shí),e的-x次方會(huì)太趨于0
可以增加限制比如當(dāng)x < -30 時(shí),返回值為9e-15
當(dāng)x > 30 時(shí),返回值為 1 – 9e-15 - 對(duì)于周期函數(shù),可以在單周期內(nèi)進(jìn)行擬合,以減小網(wǎng)絡(luò)負(fù)載
- 對(duì)于運(yùn)算問題,若調(diào)用numpy進(jìn)行矩陣運(yùn)算,完成萬次迭代需要十秒級(jí),而若采用for循環(huán)進(jìn)行矩陣內(nèi)元素運(yùn)算,完成萬次迭代需要分鐘級(jí),矩陣運(yùn)算快3倍以上
- 若是目標(biāo)函數(shù)的峰值過大,單隱層神經(jīng)網(wǎng)絡(luò)會(huì)因?yàn)楦浇?xùn)練樣本過少而不能很好的擬合,若是想達(dá)到較好的效果至少需要十萬級(jí)的迭代次數(shù),可以采取擬合sinx和cosx,進(jìn)而計(jì)算出1/sinx + 1/cosx,以減少迭代次數(shù)