[Python人工智能] 二.theano实现回归神经网络分析
從本篇文章開始,作者正式開始研究Python深度學(xué)習(xí)、神經(jīng)網(wǎng)絡(luò)及人工智能相關(guān)知識。前一篇文章主要講解神經(jīng)網(wǎng)絡(luò)基礎(chǔ)概念,同時講解Theano庫的安裝過程及基礎(chǔ)用法,這篇文章主要講解theano實現(xiàn)回歸神經(jīng)網(wǎng)絡(luò),主要是學(xué)習(xí)"莫煩大神" 網(wǎng)易云視頻的在線筆記,后面隨著深入會講解具體的項目及應(yīng)用。基礎(chǔ)性文章,希望對您有所幫助,也建議大家一步步跟著學(xué)習(xí),同時文章中存在錯誤或不足之處,還請海涵~
"莫煩大神" 網(wǎng)易云視頻地址:http://study.163.com/provider/1111519/course.html
從2014年開始,作者主要寫了三個Python系列文章,分別是基礎(chǔ)知識、網(wǎng)絡(luò)爬蟲和數(shù)據(jù)分析。
- Python基礎(chǔ)知識系列:Pythonj基礎(chǔ)知識學(xué)習(xí)與提升
- Python網(wǎng)絡(luò)爬蟲系列:Python爬蟲之Selenium+Phantomjs+CasperJS
- Python數(shù)據(jù)分析系列:知識圖譜、web數(shù)據(jù)挖掘及NLP
??
一. 定義神經(jīng)網(wǎng)絡(luò)Layer類
神經(jīng)網(wǎng)絡(luò)激勵函數(shù)參考:
http://deeplearning.net/software/theano/library/tensor/nnet/nnet.html
激勵函數(shù)相當(dāng)于一個過濾器或激勵器,它把特有的信息或特征激活,常見的激活函數(shù)包括softplus、sigmoid、relu、softmax、elu、tanh等。對于隱藏層,我們可以使用relu、tanh、softplus等非線性關(guān)系;對于分類問題,我們可以使用sigmoid(值越小越接近于0,值越大越接近于1)、softmax函數(shù),對每個類求概率,最后以最大的概率作為結(jié)果;對于回歸問題,可以使用線性函數(shù)(linear function)來實驗。
神經(jīng)網(wǎng)絡(luò)首先需要添加神經(jīng)層,將層(Layer)定義成類,通過類來添加神經(jīng)層。神經(jīng)層是相互鏈接,并且是全連接,從第一層輸入層傳入到隱藏層,最后傳輸至輸出層。假設(shè)接下來需要定義兩層內(nèi)容:
? ? L1 = Layer(inputs, in_size=1, out_size=10, activation_function)
? ??參數(shù)包括輸入值,輸入節(jié)點數(shù),輸出節(jié)點數(shù)和激勵函數(shù)
? ? L2 = Layer(L1.outputs, 10, 1, None)
? ? 參數(shù)中L1的輸出作為輸入值,L1的輸出10個節(jié)點作為輸入節(jié)點,輸出節(jié)點1個,激勵函數(shù)為None。
定義類的代碼如下,包括權(quán)重和bias,其中參數(shù)為隨機(jī)變量更有利于我們后面的更新,亂序更能促進(jìn)神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)。
class Layer(object):def __init__(self, inputs, in_size, out_size, activation_function=None):#權(quán)重: 平均值為0 方差為1 行數(shù)為in_size 列數(shù)為out_sizeself.W = theano.shared(np.random.normal(0,1,(in_size,out_size)))#biasself.b = theano.shared(np.zeros((out_size,) ) + 0.1)#乘法加biasself.Wx_plus_b = T.dot(inputs, self.W) + self.b #dot乘法#激勵函數(shù)self.activation_function = activation_function#默認(rèn)為None,否則進(jìn)行激活if activation_function is None: self.outputs = self.Wx_plus_belse: self.outputs = self.activation_function(self.Wx_plus_b)二. 回歸神經(jīng)網(wǎng)絡(luò)實現(xiàn)
接下來開始跟著莫煩大聲實現(xiàn)了第一個神經(jīng)網(wǎng)絡(luò)代碼,步驟如下:
1.制造虛擬數(shù)據(jù)
通過numpy.linspace生成300個隨機(jī)點進(jìn)行訓(xùn)練,形成y=x^2-0.5的虛擬數(shù)據(jù)。代碼如下:
#coding:utf-8 import numpy as np import theano.tensor as T import theano from theano import functionclass Layer(object):def __init__(self, inputs, in_size, out_size, activation_function=None):#權(quán)重: 平均值為0 方差為1 行數(shù)為in_size 列數(shù)為out_sizeself.W = theano.shared(np.random.normal(0,1,(in_size,out_size)))#biasself.b = theano.shared(np.zeros((out_size,) ) + 0.1)#乘法加biasself.Wx_plus_b = T.dot(inputs, self.W) + self.b #dot乘法#激勵函數(shù)self.activation_function = activation_function#默認(rèn)為None,否則進(jìn)行激活if activation_function is None: self.outputs = self.Wx_plus_belse: self.outputs = self.activation_function(self.Wx_plus_b)#回歸神經(jīng)網(wǎng)絡(luò) Regression#1.制造虛擬數(shù)據(jù) import matplotlib.pyplot as plt #Make up some fake data x_data = np.linspace(-1,1,300)[:, np.newaxis] #300個點進(jìn)行訓(xùn)練 noise = np.random.normal(0, 0.05, x_data.shape) y_data = np.square(x_data) - 0.5 + noise #y = x^2 - 0.5 #一元二次散點圖 plt.scatter(x_data, y_data) plt.show()生產(chǎn)的一元二次隨機(jī)散點圖如下圖所示:
圖1 散點圖結(jié)果
2.增加神經(jīng)層
定義輸入x和y,注意其dtype類型為64位浮點型,整個代碼前后類型需要保持一致。同時定義了L1層和L2層:
? ? L1 = Layer(x, 1, 10, T.nnet.relu)
? ? 輸入為x,1維的data,神經(jīng)元10個,relu非線性激勵函數(shù)
? ? L2 = Layer(L1.outputs, 10, 1, None)
? ? 輸入為L1輸出值,?L2的in_size為L1的神經(jīng)元10,假設(shè)L2輸出為最終output
3.計算誤差與梯度下降更新
定義cost變量計算誤差,即預(yù)測值與真實值的差別;再定義梯度下降變量,其誤差越大,降低趨勢越大,通過梯度下降讓預(yù)測值更接近真實值。代碼中通過theano.function()函數(shù)更新神經(jīng)網(wǎng)絡(luò)的四個參數(shù),計算公式如下啊:
L1.W, L1.W-learnging_rate*gW1:
(原始的權(quán)重-學(xué)習(xí)效率*下降幅度)并且更新為L1.W,通過該方法將L1.W、L1.b、L2.W、L2.b更新。
4.預(yù)測結(jié)果
最后是預(yù)測結(jié)果,訓(xùn)練時會給出x和y求cost,而預(yù)測時只給出輸入x,用來做預(yù)測。最后每隔50步輸出err,如果err不斷減小,說明神經(jīng)網(wǎng)絡(luò)在學(xué)到東西,因為預(yù)測值與真實值誤差在不斷減小。
#coding:utf-8 import numpy as np import theano.tensor as T import theano from theano import functionclass Layer(object):def __init__(self, inputs, in_size, out_size, activation_function=None):#權(quán)重: 平均值為0 方差為1 行數(shù)為in_size 列數(shù)為out_sizeself.W = theano.shared(np.random.normal(0,1,(in_size,out_size)))#biasself.b = theano.shared(np.zeros((out_size,) ) + 0.1)#乘法加biasself.Wx_plus_b = T.dot(inputs, self.W) + self.b #dot乘法#激勵函數(shù)self.activation_function = activation_function#默認(rèn)為None,否則進(jìn)行激活if activation_function is None: self.outputs = self.Wx_plus_belse: self.outputs = self.activation_function(self.Wx_plus_b)#回歸神經(jīng)網(wǎng)絡(luò) Regression#1.制造虛擬數(shù)據(jù) import matplotlib.pyplot as plt #Make up some fake data x_data = np.linspace(-1,1,300)[:, np.newaxis] #300個點進(jìn)行訓(xùn)練 noise = np.random.normal(0, 0.05, x_data.shape) y_data = np.square(x_data) - 0.5 + noise #y = x^2 - 0.5 #一元二次散點圖 plt.scatter(x_data, y_data) plt.show()#2.定義輸入和神經(jīng)元 #determine the inputs dytpe x = T.dmatrix('x') #d代表64位float類型 y = T.dmatrix('y') #add layers L1 = Layer(x, 1, 10, T.nnet.relu) L2 = Layer(L1.outputs, 10, 1, None)#3.計算誤差與梯度下降更新 #誤差為預(yù)測值與真實值差別 cost = T.mean(T.square(L2.outputs - y)) #mean()求平均誤差 #compute the gradients #梯度下降,讓預(yù)測值更接近真實值,誤差越大,降低趨勢越大 gW1, gb1, gW2, gb2 = T.grad(cost, [L1.W, L1.b, L2.W, L2.b]) #權(quán)重和bias #apply gradient descent #學(xué)習(xí)效率: 神經(jīng)網(wǎng)絡(luò)中l(wèi)earning_rate通常小于1的數(shù)字,0.05保證神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)比較精細(xì) learning_rate = 0.05#更新四個神經(jīng)網(wǎng)絡(luò)的參數(shù) train = theano.function(inputs = [x,y],outputs = cost,updates = [(L1.W, L1.W-learning_rate*gW1),(L1.b, L1.b-learning_rate*gb1),(L2.W, L2.W-learning_rate*gW2),(L2.b, L2.b-learning_rate*gb2)] ) #(L1.W, L1.W-learnging_rate*gW1) #(原始的權(quán)重-學(xué)習(xí)的效率*下降的幅度)更新為L1.W#4.預(yù)測結(jié)果 #訓(xùn)練時會給y求cost, 而預(yù)測輸入只給出x用來做預(yù)測 predict = theano.function(inputs=[x], outputs=L2.outputs)for i in range(1000):#training 把x_data和y_data放到函數(shù)x、y中err = train(x_data, y_data) #誤差#每隔50步輸出err, 如果err不斷減小說明神經(jīng)網(wǎng)絡(luò)在學(xué)到東西, 因為預(yù)測值與真實值誤差在不斷減小if i % 50 == 0: print(err)最后輸出誤差結(jié)果,可以看到在不斷減小,通過不斷更新權(quán)重和bias,神經(jīng)網(wǎng)絡(luò)在不斷學(xué)習(xí)。
2.079139917311914 0.019342171772016286 0.010080951605219858 0.007202397774306516 0.005702041299886045 0.004946926023254156 0.004565940080184372 0.0043433009094413985 0.00421325480276665 0.0041214880336559725 0.004046461715568916 0.003989685842213987 0.003934933552824453 0.003886586291155118 0.003843283475886867 0.0038068442317786316 0.0037721487639369986 0.0037432478192238835 0.003712756532212612 0.00368813308403329三. 回歸神經(jīng)網(wǎng)絡(luò)可視化
最后補(bǔ)充神經(jīng)網(wǎng)絡(luò)不斷學(xué)習(xí)的擬合圖形,從最早不合理的圖形到后面基本擬合,同時cost誤差也在不斷減小,說明神經(jīng)網(wǎng)絡(luò)的真實值和預(yù)測值在不斷更新接近,神經(jīng)網(wǎng)絡(luò)正常運行。結(jié)果如下:
圖2 第一次擬合結(jié)果
圖3 第二次擬合結(jié)果
圖4 最后一次擬合結(jié)果
完整代碼及注釋如下所示:
#coding:utf-8 import numpy as np import theano.tensor as T import theano from theano import functionclass Layer(object):def __init__(self, inputs, in_size, out_size, activation_function=None):#權(quán)重: 平均值為0 方差為1 行數(shù)為in_size 列數(shù)為out_sizeself.W = theano.shared(np.random.normal(0,1,(in_size,out_size)))#biasself.b = theano.shared(np.zeros((out_size,) ) + 0.1)#乘法加biasself.Wx_plus_b = T.dot(inputs, self.W) + self.b #dot乘法#激勵函數(shù)self.activation_function = activation_function#默認(rèn)為None,否則進(jìn)行激活if activation_function is None: self.outputs = self.Wx_plus_belse: self.outputs = self.activation_function(self.Wx_plus_b)#回歸神經(jīng)網(wǎng)絡(luò) Regression#1.制造虛擬數(shù)據(jù) import matplotlib.pyplot as plt #Make up some fake data x_data = np.linspace(-1,1,300)[:, np.newaxis] #300個點進(jìn)行訓(xùn)練 noise = np.random.normal(0, 0.05, x_data.shape) y_data = np.square(x_data) - 0.5 + noise #y = x^2 - 0.5 #一元二次散點圖 plt.scatter(x_data, y_data) plt.show()#2.定義輸入和神經(jīng)元 #determine the inputs dytpe x = T.dmatrix('x') #d代表64位float類型 y = T.dmatrix('y') #add layers L1 = Layer(x, 1, 10, T.nnet.relu) L2 = Layer(L1.outputs, 10, 1, None)#3.計算誤差與梯度下降更新 #誤差為預(yù)測值與真實值差別 cost = T.mean(T.square(L2.outputs - y)) #mean()求平均誤差 #compute the gradients #梯度下降,讓預(yù)測值更接近真實值,誤差越大,降低趨勢越大 gW1, gb1, gW2, gb2 = T.grad(cost, [L1.W, L1.b, L2.W, L2.b]) #權(quán)重和bias #apply gradient descent #學(xué)習(xí)效率: 神經(jīng)網(wǎng)絡(luò)中l(wèi)earning_rate通常小于1的數(shù)字,0.05保證神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)比較精細(xì) learning_rate = 0.05#更新四個神經(jīng)網(wǎng)絡(luò)的參數(shù) train = theano.function(inputs = [x,y],outputs = cost,updates = [(L1.W, L1.W-learning_rate*gW1),(L1.b, L1.b-learning_rate*gb1),(L2.W, L2.W-learning_rate*gW2),(L2.b, L2.b-learning_rate*gb2)] ) #(L1.W, L1.W-learnging_rate*gW1) #(原始的權(quán)重-學(xué)習(xí)的效率*下降的幅度)更新為L1.W#4.預(yù)測結(jié)果 #訓(xùn)練時會給y求cost, 而預(yù)測輸入只給出x用來做預(yù)測 predict = theano.function(inputs=[x], outputs=L2.outputs)#可視化分析#plot the fake data fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.scatter(x_data,y_data) #散點圖效果 #輸入紅線并且連續(xù)不斷更新 plt.ion() plt.show() #參數(shù)block=True: 只顯示這張圖,關(guān)掉圖后才運行后面程序#每隔50步輸出err并繪制擬合曲線 #cost值不斷減小說明預(yù)測值與真實值誤差在不斷減小,擬合直線越來越接近 for i in range(1000):#誤差: training 把x_data和y_data放到函數(shù)x、y中err = train(x_data, y_data)pre = predict(x_data)#to visualize the result and improvement#查看神經(jīng)網(wǎng)絡(luò)結(jié)果和擬合提升過程if i % 50 == 0: #消除紅線, 否則每次的紅線繪制在一起#因為第一步?jīng)]有紅線, 故使用try忽略第一步try:ax.lines.remove(lines[0])except Exception:passpredicted_value = predict(x_data)#plot the predictionlines = ax.plot(x_data, predicted_value, 'r-', lw=5) #x和預(yù)測y lw線寬度plt.pause(1) #暫定1秒#輸出誤差print(err)#print(pre)基礎(chǔ)性文章,希望對您有所幫助,推薦大家閱讀莫煩大神的學(xué)習(xí)視頻,也建議大家一步步跟著學(xué)習(xí),同時文章中存在錯誤或不足之處,還請海涵~
(By:Eastmount 2018-05-21 下午4點 ? ? http://blog.csdn.net/eastmount/ ? )
總結(jié)
以上是生活随笔為你收集整理的[Python人工智能] 二.theano实现回归神经网络分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【python数据挖掘课程】二十三.时间
- 下一篇: [Python人工智能] 三.thean