[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í)的基礎(chǔ)知識,再通過theano實現(xiàn)分類神經(jīng)網(wǎng)絡(luò),主要是學(xué)習(xí)"莫煩大神" 網(wǎng)易云視頻的在線筆記,后面隨著深入會講解具體的項目及應(yīng)用?;A(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
??
前文參考:
[Python人工智能] 一.神經(jīng)網(wǎng)絡(luò)入門及theano基礎(chǔ)代碼講解
[Python人工智能] 二.theano實現(xiàn)回歸神經(jīng)網(wǎng)絡(luò)分析
一.機器學(xué)習(xí)基礎(chǔ)
首先第一部分也是莫煩老師的在線學(xué)習(xí)筆記,個人感覺挺好的基礎(chǔ)知識,推薦給大家學(xué)習(xí)。對機器學(xué)習(xí)進行分類,包括:
? ? 1.監(jiān)督學(xué)習(xí):通過數(shù)據(jù)和標(biāo)簽進行學(xué)習(xí),比如從海量圖片中學(xué)習(xí)模型來判斷是狗還是貓,包括分類、回歸、神經(jīng)網(wǎng)絡(luò)等算法;
? ? 3.半監(jiān)督學(xué)習(xí):綜合了監(jiān)督學(xué)習(xí)和無監(jiān)督學(xué)習(xí),通過少量有標(biāo)簽樣本和大量沒有標(biāo)簽樣本進行訓(xùn)練和分類,有效提升了兩者效果;
? ? 4.強化學(xué)習(xí):常用于規(guī)劃機器人行為準(zhǔn)則,把計算機置于陌生環(huán)境去完成一項未知任務(wù),比如投籃,它會自己總結(jié)失敗經(jīng)驗和投籃命中的經(jīng)驗,進而懲罰或獎勵機器人從而提升命中率,比如阿爾法狗;
? ? 5.遺傳算法:和強化學(xué)習(xí)類似,通過淘汰機制去選擇最優(yōu)模型,比如自己玩超級馬里奧,淘汰前面幾代差的,基于強者的"遺傳和變異",適者生存,弱者淘汰的原理。
二.神經(jīng)網(wǎng)絡(luò)基礎(chǔ)
神經(jīng)網(wǎng)絡(luò)也稱為人工神經(jīng)網(wǎng)絡(luò)ANN(Artifical Neural Network),是80年代非常流行的機器學(xué)習(xí)算法,在90年代衰退,現(xiàn)在隨著"深度學(xué)習(xí)"和"人工智能"之勢重新歸來,成為最強大的機器學(xué)習(xí)算法之一。
神經(jīng)網(wǎng)絡(luò)是模擬生物神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)和功能的計算模型,由很多神經(jīng)層組成,每一層存在著很多神經(jīng)元,這些神經(jīng)元是識別事物的關(guān)鍵。神經(jīng)網(wǎng)絡(luò)通過這些神經(jīng)元進行計算學(xué)習(xí),每個神經(jīng)元有相關(guān)的激勵函數(shù)(sigmoid、Softmax、tanh等),包括輸入層、隱藏層(可多層或無)和輸出層,當(dāng)神經(jīng)元計算結(jié)果大于某個閾值時會產(chǎn)生積極作用(輸出1),相反產(chǎn)生抑制作用(輸出0),常見的類型包括回歸神經(jīng)網(wǎng)絡(luò)(畫線擬合一堆散點)和分類神經(jīng)網(wǎng)絡(luò)(圖像識別分類)。
例如下面的示例,通過海量圖片學(xué)習(xí)來判斷一張圖片是狗還是貓,通過提取圖片特征轉(zhuǎn)換為數(shù)學(xué)形式來判斷,如果判斷是狗則會反向傳遞這些錯誤信息(預(yù)測值與真實值差值)回神經(jīng)網(wǎng)絡(luò),并修改神經(jīng)元權(quán)重,通過反復(fù)學(xué)習(xí)來優(yōu)化識別。
下面簡單講解"莫煩大神"網(wǎng)易云課程的一個示例。假設(shè)存在千萬張圖片,現(xiàn)在需要通過神經(jīng)網(wǎng)絡(luò)識別出某一張圖片是狗還是貓,如下圖所示共包括輸入層、隱藏層(3層)和輸出層。
計算機通過訓(xùn)練或強化學(xué)習(xí)判斷貓,將獲取的特征轉(zhuǎn)換為數(shù)學(xué)的形式。首先得到一堆數(shù)字,通過判斷處理得到另一堆數(shù)據(jù),最終判斷其是狗還是貓。比如第一次正確識別的只有10%,下面那只貓被識別成了狗,它會將識別錯誤的信息(與真實答案的差別)反向傳遞回神經(jīng)網(wǎng)絡(luò),并修改神經(jīng)元權(quán)重,為下次更好地識別。
每一個神經(jīng)元都有一個激勵函數(shù),被激勵的神經(jīng)元傳遞的信息最有價值,它也決定最后的輸出結(jié)果,經(jīng)過海量數(shù)據(jù)的訓(xùn)練,最終神經(jīng)網(wǎng)絡(luò)將可以用于識別貓或狗。
三. theano實現(xiàn)分類神經(jīng)網(wǎng)絡(luò)
下面講解分類神經(jīng)網(wǎng)絡(luò)的實現(xiàn):
1.定義函數(shù)計算正確率
正確率為預(yù)測正確的數(shù)目占真實樣本數(shù)的百分比,代碼如下:
#coding:utf-8 #參考:http://study.163.com/course/courseLearn.htm?courseId=1003215006 import numpy as np import theano.tensor as T import theano from theano import function#正確率函數(shù):預(yù)測正確數(shù)占真實值數(shù)的百分比 def computer_accuracy(y_target, y_predict):correct_prediction = np.equal(y_predict, y_target)accuracy = np.sum(correct_prediction)/len(correct_prediction)return accuracy2.隨機生成數(shù)據(jù)
訓(xùn)練樣本為N,400個樣本;輸入特征數(shù)為feats,784個特征;隨機生成數(shù)據(jù),D = (input_values, target_class),包括輸入數(shù)據(jù)和類標(biāo),其中:
? (1) rng.randn(N, feats)生成400行,每行784個特征的標(biāo)注正態(tài)分布數(shù)據(jù);
? (2) rng.randint(size=N, low=0, high=2)隨機生成兩個類別比如0和1,0代表一個類,1代表另一個類,比如貓和狗。
然后進行訓(xùn)練,神經(jīng)網(wǎng)絡(luò)辨別哪些是狗哪些是對應(yīng)的貓。接下來編輯神經(jīng)網(wǎng)絡(luò),用D放到圖片中進行訓(xùn)練。
(array([[-1.03486767, 0.09141203, -2.14011897, ..., 0.24325359,-1.07465997, 0.74784503],[ 1.09143969, 1.5014381 , -0.12580536, ..., -1.63516987,0.51615268, 1.51542425],[ 1.26905541, -0.54147591, -0.23159387, ..., 0.22647348,-0.93035893, 1.19128709],...,[-0.53222844, 0.05877263, -1.05092742, ..., -1.07296129,1.11237909, 0.86891936],[-2.91024609, 0.09091794, -2.34392907, ..., -1.09686952,1.08838878, 0.79766499],[ 0.12949081, -0.0893665 , -0.43766707, ..., -0.66029383,0.03997112, 1.05149843]]), array([1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1,1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0,0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1,1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1,0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1,0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1,1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1,0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0,0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1,1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1,0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1,0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1,1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0,0, 1, 0, 1]))
3.定義變量和初始化權(quán)重
定義Theano變量,其中x為T.dmatrix類型,y因為輸出只是一個類型類型0或1,故使用dvector,也可以使用dmatrix。同時初始化權(quán)重和bias,這里不添加神經(jīng)網(wǎng)絡(luò)層,直接使用輸入層和輸出層,讀者可以結(jié)合上節(jié)課程自己定義。
4.定義計算誤差
p_1 = T.nnet.sigmoid(T.dot(x,W) + b)?
sigmoid激勵函數(shù)(activation function)用來求概率的,如果輸入的數(shù)越小,概率越接近0,輸入越大,概率越接近1。這里將x與W乘積加b(T.dot(x,W) + b)放到激勵函數(shù)中去。
prediction = p_1 > 0.5
定義預(yù)測值,當(dāng)值大于0.5時讓它等于True。
xent = -y*T.log(p_1)-(1-y)*T.log(1-p_1)
定義Cross-entropy loss function,它可以理解為cost誤差,前面cost使用是平方差和,這里使用的是上述公式。
cost = xent.mean()? + 0.01 * (W**2).sum()
由于xent是針對每一個樣本的cost,需要求平均值變成單獨的一個cost,對于整批數(shù)據(jù)的cost,故cost = xent.mean()求平均值。同時,為了克服Overfitted,在計算cost時增加 一個值(下節(jié)課補充),即0.01 * (W**2).sum()。
gW, gb = T.grad(cost, [W,b])
計算cost的梯度,這里理解為整個窗口的小控件。
p_1 => sigmoid.0
xent => Elemwise{sub,no_inplace}.0
cost => Elemwise{add,no_inplace}.0
gW,gb => Elemwise{add,no_inplace}.0 InplaceDimShuffle{}.0
5.編輯函數(shù)和編譯模型
調(diào)用theano.function函數(shù)編譯模型,兩個輸出即預(yù)測值和xent平均值,然后更新權(quán)重和bias,將學(xué)習(xí)的W-learning_rate*gW更新為W和b。同時,定義預(yù)測值。
#coding:utf-8 import numpy as np import theano.tensor as T import theano from theano import function#定義分類:預(yù)測正確數(shù)占真實值數(shù)的百分比 def computer_accuracy(y_target, y_predict):correct_prediction = np.equal(y_predict, y_target)accuracy = np.sum(correct_prediction)/len(correct_prediction)return accuracy#生成虛擬的data rng = np.random#訓(xùn)練數(shù)量:400個學(xué)習(xí)樣本 N = 400 #輸入特征數(shù) feats = 784 #generate a datasets: D = (input_values, target_class) #target_class: 隨機分成兩個類別,隨機生成0和1 D = (rng.randn(N, feats), rng.randint(size=N, low=0, high=2)) print(D)#Declare Theano symbolic variables x = T.dmatrix('x') y = T.dvector('y') print(x,y)#initialize the weights and bias #初始化權(quán)重和bias W = theano.shared(rng.randn(feats), name='w') #生成feats個的隨機權(quán)重W,并且給個名字w b = theano.shared(0.1, name='b') print(W) print(b)#Construct Theano expression graph #定義計算誤差,激勵函數(shù)sigmoid: 如果輸入的數(shù)越小,概率越接近0,輸入越大,概率越接近1 p_1 = T.nnet.sigmoid(T.dot(x,W) + b) print(p_1) #輸入的數(shù)是神經(jīng)網(wǎng)絡(luò)加工后的值T.dot(x,W) + b), 然后再將這個放到激勵函數(shù)中去#大于0.1的值讓它等于True prediction = p_1 > 0.5#梯度下降,可以理解為cost(誤差) #Cross-entropy loss function xent = -y*T.log(p_1)-(1-y)*T.log(1-p_1) print(xent)cost = xent.mean() #平均值 #The cost to minimize cost = xent.mean() + 0.01 * (W**2).sum() #l2:為了克服Overfitted,在計算cost時加上值 print(cost)#Compute the gradient of the cost gW, gb = T.grad(cost, [W,b]) print(gW,gb)#compile #編輯函數(shù) learning_rate = 0.1 #學(xué)習(xí)率 train = theano.function(inputs=[x,y],outputs=[prediction, xent.mean()],updates=((W, W-learning_rate*gW),(b, b-learning_rate*gb))) #兩個輸出,更新兩個數(shù)據(jù)#定義預(yù)測 預(yù)測值為x predict = theano.function(inputs=[x], outputs=prediction) 6.訓(xùn)練和預(yù)測
接下來通過for循環(huán)輸出結(jié)果,其中調(diào)用train(D[0],D[1])進行訓(xùn)練。
? D[0]:D = (input_values, target_class)的第一個值,即輸入變量;
? D[1]:D = (input_values, target_class)的第二個值,即類標(biāo);
然后每隔50步輸出結(jié)果,并查看預(yù)測正確率,函數(shù)如下:
computer_accuracy(D[1], predict(D[0]))
其中D[1]為真實的類標(biāo)值,predict(D[0])是對數(shù)據(jù)預(yù)測的類標(biāo)值,并計算正確率,最后輸出結(jié)果。
#coding:utf-8 import numpy as np import theano.tensor as T import theano from theano import function#定義分類:預(yù)測正確數(shù)占真實值數(shù)的百分比 def computer_accuracy(y_target, y_predict):correct_prediction = np.equal(y_predict, y_target)accuracy = np.sum(correct_prediction)/len(correct_prediction)return accuracy#生成虛擬的data rng = np.random#訓(xùn)練數(shù)量:400個學(xué)習(xí)樣本 N = 400 #輸入特征數(shù) feats = 784 #generate a datasets: D = (input_values, target_class) #target_class: 隨機分成兩個類別,隨機生成0和1 D = (rng.randn(N, feats), rng.randint(size=N, low=0, high=2)) print(D)#Declare Theano symbolic variables x = T.dmatrix('x') y = T.dvector('y') print(x,y)#initialize the weights and bias #初始化權(quán)重和bias W = theano.shared(rng.randn(feats), name='w') #生成feats個的隨機權(quán)重W,并且給個名字w b = theano.shared(0.1, name='b') print(W) print(b)#Construct Theano expression graph #定義計算誤差,激勵函數(shù)sigmoid: 如果輸入的數(shù)越小,概率越接近0,輸入越大,概率越接近1 p_1 = T.nnet.sigmoid(T.dot(x,W) + b) print(p_1) #輸入的數(shù)是神經(jīng)網(wǎng)絡(luò)加工后的值T.dot(x,W) + b), 然后再將這個放到激勵函數(shù)中去#大于0.1的值讓它等于True prediction = p_1 > 0.5#梯度下降,可以理解為cost(誤差) #Cross-entropy loss function xent = -y*T.log(p_1)-(1-y)*T.log(1-p_1) print(xent)cost = xent.mean() #平均值 #The cost to minimize cost = xent.mean() + 0.01 * (W**2).sum() #l2:為了克服Overfitted,在計算cost時加上值 print(cost)#Compute the gradient of the cost gW, gb = T.grad(cost, [W,b]) print(gW,gb)#compile #編輯函數(shù) learning_rate = 0.1 #學(xué)習(xí)率 train = theano.function(inputs=[x,y],outputs=[prediction, xent.mean()],updates=((W, W-learning_rate*gW),(b, b-learning_rate*gb))) #兩個輸出,更新兩個數(shù)據(jù)#定義預(yù)測 預(yù)測值為x predict = theano.function(inputs=[x], outputs=prediction)#Training for i in range(500):#輸入和輸入標(biāo)簽 D = (input_values, target_class)pred, err = train(D[0],D[1])if i % 50 == 0:#每50步輸出結(jié)果,查看多少預(yù)測正確print('cost:', err)#計算正確性 computer_accuracy(y_target, y_predict)print('accuracy:', computer_accuracy(D[1], predict(D[0])))#對比兩個結(jié)果,看預(yù)測是否正確 print("target values for D:") print(D[1]) print("prediction on D:") print(predict(D[0])) 輸出結(jié)果如下所示,可以看到誤差在不斷減小,其預(yù)測正確率也是不斷增加,最后到100%。
cost: 9.907479693928224 accuracy: 0.505 cost: 4.954027420378552 accuracy: 0.6525 cost: 2.1977148473835193 accuracy: 0.75 cost: 0.9396763739879143 accuracy: 0.875 cost: 0.40360223854133126 accuracy: 0.9575 cost: 0.17876663279172963 accuracy: 0.9825 cost: 0.0822797979378536 accuracy: 0.9925 cost: 0.048794195343816946 accuracy: 1.0 cost: 0.04187510776189411 accuracy: 1.0 cost: 0.03908366728475624 accuracy: 1.0
總結(jié):
1.theano構(gòu)建神經(jīng)網(wǎng)絡(luò)一般需要經(jīng)歷以下步驟:
? ? (1) 預(yù)處理數(shù)據(jù)
? ??generate a dataset: D = (input_values, target_class)
? ? (2) 定義變量
? ??Declare Theano symbolic variables
? ? (3) 構(gòu)建模型
? ? Construct Theano expression graph
? ? (4) 編譯模型
? ? theano.function()
? ??train = theano.function(inputs=[x,y],outputs=[],updates=((W, W-learning_rate*gW))?
? ? predict = theano.function(inputs=[x], outputs=prediction)
? ? (5) 訓(xùn)練模型
? ??train(D[0],D[1])
? ? (6) 預(yù)測新數(shù)據(jù)
? ??print(predict(D[0]))
? ??
2.分類神經(jīng)網(wǎng)絡(luò)不同于回歸神經(jīng)網(wǎng)絡(luò)(前一篇文章)之處:
? ? (1)?激勵函數(shù)為T.nnet.sigmoid(T.dot(x,W) + b),會用到求概率的激勵函數(shù);
? ? (2)?它計算cost規(guī)則不同于前面平方差誤差的方法,它用的是xent = -y*T.log(p_1)-(1-y)*T.log(1-p_1)。
推薦資料:
https://blog.csdn.net/zm714981790/article/details/51251759(鳶尾花分類——神經(jīng)網(wǎng)絡(luò)詳解)
基礎(chǔ)性文章,希望對您有所幫助,推薦大家閱讀莫煩大神的學(xué)習(xí)視頻,也建議大家一步步跟著學(xué)習(xí)。后面作者會結(jié)合神經(jīng)網(wǎng)絡(luò)分析實際的數(shù)據(jù)集,并增加隱藏層,希望您喜歡,同時文章中存在錯誤或不足之處,還請海涵~
(By:Eastmount 2018-05-24 晚上12點??http://blog.csdn.net/eastmount/?)
總結(jié)
以上是生活随笔為你收集整理的[Python人工智能] 三.theano实现分类神经网络及机器学习基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Python人工智能] 二.thean
- 下一篇: [Python人工智能] 五.thean