從環境搭建到回歸神經網絡案例,帶你掌握Keras


摘要: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()

 

點擊關注,第一時間了解華為雲新鮮技術~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM