摘要:Keras作為神經網路的高階包,能夠快速搭建神經網路,它的相容性非常廣,相容了TensorFlow和Theano。
本文分享自華為雲社群《[Python人工智慧] 十六.Keras環境搭建、入門基礎及迴歸神經網路案例》,作者:eastmount。
一.為什麼要使用Keras
Keras是一個由Python編寫的開源人工神經網路庫,可以作為Tensorflow、Microsoft-CNTK和Theano的高階應用程式介面,進行深度學習模型的設計、除錯、評估、應用和視覺化 。其主要開發者是谷歌工程師François Chollet。
Keras在程式碼結構上由物件導向方法編寫,完全模組化並具有可擴充套件性,其執行機制和說明文件有將使用者體驗和使用難度納入考慮,並試圖簡化複雜演算法的實現難度 。Keras支援現代人工智慧領域的主流演算法,包括前饋結構和遞迴結構的神經網路,也可以通過封裝參與構建統計學習模型。在硬體和開發環境方面,Keras支援多作業系統下的多GPU平行計算,可以根據後臺設定轉化為Tensorflow、Microsoft-CNTK等系統下的元件。
Keras作為神經網路的高階包,能夠快速搭建神經網路,它的相容性非常廣,相容了TensorFlow和Theano。
二.安裝Keras和相容Backend
1.如何安裝Keras
首先需要確保已經安裝了以下兩個包:
- Numpy
- Scipy
呼叫“pip3 list”命令可以看到相關包已經安裝成功。
接著通過“pip3 install keras”安裝,作者是使用Anaconda下的Python3.6版本。
activate tensorflow
pip3 install keras
pip install keras
搭建過程詳見這篇文章:
安裝如下圖所示:
安裝成功之後,我們嘗試一個簡單的程式碼。開啟Anaconda,然後選擇已經搭建好的“tensorflow”環境,執行Spyder。
測試程式碼如下:
# -*- coding: utf-8 -*- """ Created on Fri Feb 14 16:43:21 2020 @author: Eastmount CSDN """ import numpy as np from keras.preprocessing.sequence import TimeseriesGenerator # 時間序列 y = np.array(range(5)) tg = TimeseriesGenerator(y, y, length=3, sampling_rate=1) for i in zip(*tg[0]): print(*i)
執行結果如下圖所示,究竟“Using TensorFlow backend.”表示什麼意思呢?
2.相容Backend
Backend是指Keras基於某個框架來做運算,包括基於TensorFlow或Theano,上面的那段程式碼就是使用TensorFlow來運算的。後面要講解的神經網路也是基於TensorFlow或Theano來搭建的。
如何檢視Backend呢?當我們匯入Keras擴充套件包時,它就會有相應的提示,比如下圖使用的就是Theano來搭建底層的神經網路。
如果想要改成TensorFlow,怎麼辦呢?
- 第一種方法,找到“keras/keras.json”這個檔案,然後開啟它。所有的backend資訊就儲存在這裡,每次匯入Keras包就會檢測這個“keras.json”檔案的backend。接著我們嘗試修改。
- 第二種方法是在命令列中輸入下面這句命令,每次執行指令碼時它會直接幫你修改成臨時的TensorFlow。
import os os.environ['KERAS_BACKEND']='tensorflow' import keras
三.白話神經網路
該部分還是有必要再給大家普及一遍,參考"莫煩大神"網易雲課程對神經網路的介紹,講得清晰透徹,推薦大家閱讀。開始吧!讓我們一起進入神經網路和TensorFlow的世界。
首先,什麼是神經網路(Neural Networks)?
計算機神經網路是一種模仿生物神經網路或動物神經中樞,特別是大腦的結構和功能,它是一種數學模型或計算機模型。神經網路由大量的神經元連線並進行計算,大多數情況下人工神經網路能在外界資訊的基礎上改變內部結構,是一種自適應的過程。
現代神經網路是一種基於傳統統計學建模的工具,常用來對輸入和輸出間複雜的關係進行建模,或探索資料間的模式,神經網路是一種運算模型,有大量的節點或神經元及其聯絡構成。和人類的神經元一樣,它們負責傳遞資訊和加工資訊,神經元也能被訓練或強化,形成固定的神經形態,對特殊的資訊有更強烈的反應。
神經網路是如何工作的呢?
如上圖所示,不管這是一隻跳躍飛奔的貓,或是一隻靜靜思考的貓,你都知道它是一隻貓,因為你的大腦已經被告知過圓眼睛、毛茸茸、尖耳朵的就是貓,你通過成熟的視覺神經系統判斷它是貓。計算機也是一樣,通過不斷的訓練,告訴哪些是貓、哪些是狗、哪些是豬,它們會通過數學模型來概括這些學習的判斷,最終以數學的形式(0或1)來分類。目前,谷歌、百度圖片搜尋都能清晰識別事物,這些都歸功於計算機神經系統的飛速發展。
神經網路系統由多層神經層構成,為了區分不同的神經層,我們分為:
- 輸入層:直接接收資訊的神經層,比如接收一張貓的圖片
- 輸出層:資訊在神經元中傳遞中轉和分析權衡,形成輸出結果,通過該層輸出的結果可以看出計算機對事物的認知
- 隱藏層:在輸入和輸出層之間的眾多神經元連線組成的各個層面,可以有多層,負責對傳入資訊的加工處理,經過多層加工才能衍生出對認知的理解
神經網路舉例說明
如下圖所示,通常來說,計算機處理的東西和人類有所不同,無論是聲音、圖片還是文字,它們都只能以數字0或1出現在計算機神經網路裡。神經網路看到的圖片其實都是一堆數字,對數字的加工處理最終生成另一堆數字,並且具有一定認知上的意義,通過一點點的處理能夠得知計算機到底判斷這張圖片是貓還是狗。
計算機是怎麼訓練的呢?
首先,需要很多的資料,比如需要計算機判斷是貓還是狗,就需要準備上千萬張有標記的圖片,然後再進行上千萬次的訓練。計算機通過訓練或強化學習判斷貓,將獲取的特徵轉換為數學的形式。
我們需要做的就是隻給計算機看圖片,然後讓它給我們一個不成熟也不準確的答案,有可能100次答案中有10%是正確的。如果給計算機看圖片是一張飛奔的貓(如下圖),但計算機可能識別成一條狗,儘管它識別錯誤,但這個錯誤對計算機是非常有價值的,可以用這次錯誤的經驗作為一名好老師,不斷學習經驗。
那麼計算機是如何學習經驗的呢?
它是通過對比預測答案和真實答案的差別,然後把這種差別再反向傳遞回去,修改神經元的權重,讓每個神經元向正確的方向改動一點點,這樣到下次識別時,通過所有改進的神經網路,計算機識別的正確率會有所提高。最終每一次的一點點,累加上千萬次的訓練,就會朝正確的方向上邁出一大步。
最後到驗收結果的時候,給計算機再次顯示貓的圖片時,它就能正確預測這是一隻貓。
激勵函式是什麼東東?
接著再進一步看看神經網路是怎麼訓練的。原來在計算機裡每一個神經元都有屬於它的激勵函式(Active Function),我們可以利用這些激勵函式給計算機一個刺激行為。當我們第一次給計算機看一隻飛奔的貓時,神經網路中只有部分神經元被啟用或激勵,被啟用傳遞下去的資訊是計算機最為重視的資訊,也是對輸出結果最有價值的資訊。
如果預測的結果是一隻狗,所有神經元的引數就會被調整,這時有一些容易被啟用的神經元就會變得遲鈍,而另一些會變得敏感起來,這就說明了所有神經元引數正在被修改,變得對圖片真正重要的資訊敏感,從而被改動的引數就能漸漸預測出正確的答案,它就是一隻貓。這就是神經網路的加工過程。
四.Keras搭建迴歸神經網路
推薦前文:[Python人工智慧] 二.TensorFlow基礎及一元直線預測案例,最終輸出的結果如下圖所示:
1.匯入擴充套件包
Sequential(序貫模型)表示按順序建立模型,它是最簡單的線性、從頭到尾的結構順序,不分叉,是多個網路層的線性堆疊。Dense是layers中的屬性,表示全連線層。Keras還可以實現各種層,包括core核心層、Convolution卷積層、Pooling池化層等非常豐富有趣的網路結構。
import numpy as np from keras.models import Sequential from keras.layers import Dense import matplotlib.pyplot as plt
2.建立散點圖資料
通過numpy.linspace隨機生成200個散點,並構建y=0.5*x+2的虛擬資料,並呼叫 np.random.normal(0, 0.05, (200,)) 增加噪聲。
import numpy as np from keras.models import Sequential from keras.layers import Dense import matplotlib.pyplot as plt #---------------------------建立散點資料--------------------------- # 輸入 X = np.linspace(-1, 1, 200) # 隨機化資料 np.random.shuffle(X) # 輸出 y = 0.5*X + 2 + np.random.normal(0, 0.05, (200,)) #噪聲平均值0 方差0.05 # 繪製散點圖 plt.scatter(X, y) plt.show() # 資料集劃分(訓練集-測試集) X_train, y_train = X[:160], y[:160] # 前160個散點 X_test, y_test = X[160:], y[160:] # 後40個散點
這裡通過matplotlib簡單繪製散點圖,輸出結果如下圖所示,基本滿足:y = 0.5*x + 2 + noise。
3.新增神經網路層
- 建立Sequential模型。
- 新增神經網路層。在Keras中,增加層的操作非常簡單,呼叫model.add(Dense(output_dim=1, input_dim=1))函式新增即可。注意,如果再新增一個神經層,預設上一層的輸出為下一層的輸入資料,此時不需要定義input_dim,比如model.add(Dense(output_dim=1, ))。
- 搭建模型並選擇損失函式(loss function)和優化方法(optimizing method)。
#----------------------------新增神經層------------------------------ # 建立模型 model = Sequential() # 增加全連線層 輸出個數和輸入個數(均為1個) model.add(Dense(output_dim=1, input_dim=1)) # 搭建模型 選擇損失函式(loss function)和優化方法(optimizing method) # mse表示二次方誤差 sgd表示亂序梯度下降優化器 model.compile(loss='mse', optimizer='sgd')
PS:是不是感覺Keras程式碼比TensorFlow和Theano都簡潔很多,但還是建議大家先學習前者,再深入Keras。
4.訓練並輸出誤差
print("訓練") # 學習300次 for step in range(301): # 分批訓練資料 返回值為誤差 cost = model.train_on_batch(X_train, y_train) # 每隔100步輸出誤差 if step % 100 == 0: print('train cost:', cost)
5.測試神經網路並輸出誤差\權重和偏置
print("測試") # 執行模型測試 一次傳入40個測試散點 cost = model.evaluate(X_test, y_test, batch_size=40) # 輸出誤差 print("test cost:", cost) # 獲取權重和誤差 layers[0]表示第一個神經層(即Dense) W, b = model.layers[0].get_weights() # 輸出權重和偏置 print("weights:", W) print("biases:", b)
6.繪製預測圖形
y_pred = model.predict(X_test)
plt.scatter(X_test, y_test)
plt.plot(X_test, y_pred)
plt.show()
輸出結果如下所示:
誤差從4.002261下降到0.0030148015,說明學習到知識。同時,誤差為0.47052705接近我們的初始值0.5,偏置為1.9944116也接近2。
訓練 train cost: 4.002261 train cost: 0.07719966 train cost: 0.005076804 train cost: 0.0030148015 測試 40/40 [==============================] - 0s 1ms/step test cost: 0.0028453178238123655 weights: [[0.47052705]] biases: [1.9944116]
完整程式碼如下:
# -*- coding: utf-8 -*- """ Created on Fri Feb 14 16:43:21 2020 @author: Eastmount CSDN YXZ O(∩_∩)O Wuhan Fighting!!! """ import numpy as np from keras.models import Sequential from keras.layers import Dense import matplotlib.pyplot as plt #---------------------------建立散點資料--------------------------- # 輸入 X = np.linspace(-1, 1, 200) # 隨機化資料 np.random.shuffle(X) # 輸出 y = 0.5*X + 2 + np.random.normal(0, 0.05, (200,)) #噪聲平均值0 方差0.05 # 繪製散點圖 # plt.scatter(X, y) # plt.show() # 資料集劃分(訓練集-測試集) X_train, y_train = X[:160], y[:160] # 前160個散點 X_test, y_test = X[160:], y[160:] # 後40個散點 #----------------------------新增神經層------------------------------ # 建立模型 model = Sequential() # 增加全連線層 輸出個數和輸入個數(均為1個) model.add(Dense(output_dim=1, input_dim=1)) # 搭建模型 選擇損失函式(loss function)和優化方法(optimizing method) # mse表示二次方誤差 sgd表示亂序梯度下降優化器 model.compile(loss='mse', optimizer='sgd') #--------------------------------Traning---------------------------- print("訓練") # 學習300次 for step in range(301): # 分批訓練資料 返回值為誤差 cost = model.train_on_batch(X_train, y_train) # 每隔100步輸出誤差 if step % 100 == 0: print('train cost:', cost) #--------------------------------Test------------------------------- print("測試") # 執行模型測試 一次傳入40個測試散點 cost = model.evaluate(X_test, y_test, batch_size=40) # 輸出誤差 print("test cost:", cost) # 獲取權重和誤差 layers[0]表示第一個神經層(即Dense) W, b = model.layers[0].get_weights() # 輸出權重和偏置 print("weights:", W) print("biases:", b) #------------------------------繪製預測圖形----------------------------- y_pred = model.predict(X_test) plt.scatter(X_test, y_test) plt.plot(X_test, y_pred, "red") plt.show()
下面補充程式碼對比各訓練階段擬合的直線,可以看到隨著訓練次數增加,誤差逐漸降低並且擬合的直線越來越好。
# -*- coding: utf-8 -*- """ Created on Fri Feb 14 16:43:21 2020 @author: Eastmount CSDN YXZ """ import numpy as np from keras.models import Sequential from keras.layers import Dense import matplotlib.pyplot as plt #---------------------------建立散點資料--------------------------- # 輸入 X = np.linspace(-1, 1, 200) # 隨機化資料 np.random.shuffle(X) # 輸出 y = 0.5*X + 2 + np.random.normal(0, 0.05, (200,)) #噪聲平均值0 方差0.05 # 繪製散點圖 # plt.scatter(X, y) # plt.show() # 資料集劃分(訓練集-測試集) X_train, y_train = X[:160], y[:160] # 前160個散點 X_test, y_test = X[160:], y[160:] # 後40個散點 #----------------------------新增神經層------------------------------ # 建立模型 model = Sequential() # 增加全連線層 輸出個數和輸入個數(均為1個) model.add(Dense(output_dim=1, input_dim=1)) # 搭建模型 選擇損失函式(loss function)和優化方法(optimizing method) # mse表示二次方誤差 sgd表示亂序梯度下降優化器 model.compile(loss='mse', optimizer='sgd') #--------------------------------Traning---------------------------- print("訓練") k = 0 # 學習1000次 for step in range(1000): # 分批訓練資料 返回值為誤差 cost = model.train_on_batch(X_train, y_train) # 每隔100步輸出誤差 if step % 100 == 0: print('train cost:', cost) #----------------------------------------------------------- # 執行模型測試 一次傳入40個測試散點 cost = model.evaluate(X_test, y_test, batch_size=40) # 輸出誤差 print("test cost:", cost) # 獲取權重和誤差 layers[0]表示第一個神經層(即Dense) W, b = model.layers[0].get_weights() # 輸出權重和偏置 print("weights:", W) print("biases:", b) #----------------------------------------------------------- # 視覺化繪圖 k = k + 1 plt.subplot(5, 2, k) y_pred = model.predict(X_test) plt.scatter(X_test, y_test) plt.plot(X_test, y_pred, "red", label='cost=%.4f k=%d' %(cost,k)) plt.legend() plt.show()