有你想要的精彩
大家好,本期我們將開始一個新的專題的寫作,因為有一些小夥伴想了解一下深度學習框架Keras的知識,恰好本人也會一點這個知識,因此就開始嘗試著寫一寫吧。本著和大家一起學習的態度,有什麼寫的不是很好的地方還請大家多多指教。這裡我默認大家已經搭建好了深度學習的實踐環境了。
Keras介紹關於什麼是深度學習,我這裡就不多說明了,大家Google就能知道答案。關於深度學習的框架有很多:Tensorflow、Keras、PyTorch、 MXNet、PaddlePaddle等等,那麼為什麼我這裡就開講Keras呢,因為它簡潔好用啊。
它的簡潔在於:Keras是一個高級深度學習API,使用Python語言進行編寫的。Keras能夠在TensorFlow、Theano或CNTK上運行,這個意思就是Keras的後端引擎可以是這三者之一,用戶可以進行顯式的選擇。重要的是Keras提供了一個簡單和模塊化的API來構建和訓練我們需要的神經網絡,比如卷積神經網絡,循環神經網絡等等。還有一個優點就是使用Keras可以不用關心大部分函數實現的複雜細節,可真的太棒了。
Keras有四個特性:模塊性、易擴展、用戶友好和基於Python,以下的介紹來自Keras的中文文檔。
模塊化。模型被理解為由獨立的、完全可配置的模塊構成的序列或圖。這些模塊可以以儘可能少的限制組裝在一起。特別是神經網絡層、損失函數、優化器、初始化方法、激活函數、正則化方法,它們都是可以結合起來構建新模型的模塊。
易擴展性。新的模塊是很容易添加的(作為新的類和函數),現有的模塊已經提供了充足的示例。由於能夠輕鬆地創建可以提高表現力的新模塊,因此其更加適合高級研究。
用戶友好。Keras 是為人類而不是為機器設計的 API。它把用戶體驗放在首要和中心位置。Keras 遵循減少認知困難的最佳實踐:它提供一致且簡單的 API,將常見用例所需的用戶操作數量降至最低,並且在用戶錯誤時提供清晰和可操作的反饋。
基於 Python 實現。Keras 沒有特定格式的單獨配置文件。模型定義在 Python 代碼中,這些代碼緊湊,易於調試,並且易於擴展。
溫馨提示:如果大家對機器學習不清楚的話,可以先學習機器學習的相關知識,這對於本專題的學習是非常有利的。
迭深度學習的"Hello World"在跟學習其他語言一樣,學習Keras的時候,我們也要學習它的基礎知識。深度學習的「Hello World」知識就是使用深度學習來識別手寫字識別。在學習之前,我們來看一些其他儲備知識:
安裝依賴的庫和深度學習庫Numpy、scipy、scikit-learn、matplotlib、pandas、graphviz、pydot、h5py、Theano、Tensofflow、Keras。
安裝庫的方式比較簡單,打開cmd,輸入pip install packagename即可。
設置下載源大家下載庫的時候,如果速度很慢,可以修改下載源,本人電腦中文件的
修改路徑和修改方式如下,大家根據自己的電腦找到相應的路徑:
設置Kreas後端之前說過,我們可以更換Keras的後端引擎的。本人電腦文件和修改如下:
此時,「backend」:「tensorflow」,可修改tensorflow為Theano. 一般推薦 TensorFlow 後端,大家根據自己的電腦找到相應的路徑:
1、 加載數據
深度學習重要的就是數據,那麼手寫字體的數據是怎樣的呢?
我們先看一下這個手寫數字體的數據形式:
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print(X_train.shape)
print(y_train.shape)
上述使用mnist.load_data()加載文件的方式會在從連結:
https://s3.amazonaws.com/img-datasets/mnist.npz
上下載數據集,控制臺的部分輸出如下:
這個下載的過程是很漫長的,甚至下載不了這個數據集,因此我們將採用其他的方式進行數據下載:
方法一:先從網絡上下載好這個數據集,然後傳入文件路徑:
from keras.datasets import mnist
path = r'C:\Users\LEGION\Desktop\datasets\mnist.npz'
(X_train, y_train), (X_test, y_test) = mnist.load_data(path)
print(X_train.shape)
print(y_train.shape)
輸出(60000, 28, 28)和(60000,)
方法二:通過numpy來進行搭橋,當然了也要事先下載好數據集:
# 加載keras包含的mnist的數據集
import numpy as np
from keras.datasets import mnist
def load_data(path):
numpy_load= np.load(path)
X_train, y_train = numpy_load['x_train'], numpy_load['y_train']
X_test, y_test = numpy_load['x_test'], numpy_load['y_test']
numpy_load.close()
return (X_train, y_train), (X_test, y_test)
path = r'C:\Users\LEGION\Desktop\datasets\mnist.npz'
(X_train, y_train), (X_test, y_test) = load_data(path)
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
X_train.shape 的形狀為(60000, 28, 28)
y_train.shape的形狀為(60000,)
X_test.shape的形狀為(10000, 28, 28)
y_test.shape的形狀為(10000,)
可以看到每條樣本是一個28*28的矩陣(畢竟是圖片),共有訓練數據60000個,測試數據10000個,y_train和y_test是諸如這樣的列表[7 2 1 ... 4 5 6],其中數字代表每個數據樣本的真實值。
2、 數據樣本展示
我們可以通過代碼來查看一下樣本的真實樣貌:
from keras.datasets import mnist
import matplotlib.pyplot as plt
path = r'C:\Users\LEGION\Desktop\datasets\mnist.npz'
(X_train, y_train), (X_test, y_test) = mnist.load_data(path)
for each in range(4):
plt.subplot(2,2,each+1)
plt.imshow(X_train[each], cmap=plt.get_cmap('gray'), interpolation='none')
plt.title("Class {}".format(y_train[each]))
plt.show()
輸出顯示如下:可以看出每一個樣本的是gray形式的圖片,像素的灰度值在[0,255]
接下來我們的工作就是在訓練集(X_train和y_train)上訓練我們識別手寫字體的模型,在測試集上進行測試。
3、 重塑維度並歸一化
由於我們的任務是進行識別,實際上也就是進行分類,因此我們有必要對數據進行歸一化的操作。另外由於X_train.shape 的形狀為(60000, 28, 28),也就是說樣本是二維形狀的數據,在識別的時候是不好處理的,因此我們將數據轉換一維,並進行歸一化的處理。具體做法如下:
from keras.datasets import mnist
path = r'C:\Users\LEGION\Desktop\kerasdatasets\mnist.npz'
(X_train, y_train), (X_test, y_test) = mnist.load_data(path)
X_train = X_train.reshape(len(X_train), -1)
X_test = X_test.reshape(len(X_test), -1)
print(X_train.shape)
print(X_test.shape)
輸出: (60000, 784)和(10000, 784)
如果大家知道這個樣本(圖像的大小,如28*28),那麼餓哦們可以使用另外一個方法進行reshape操作:
X_train = X_train.reshape(len(X_train),784)
X_test = X_test.reshape(len(X_test), 784)
兩者效果是等效的,大家可以查看reshape函數的功能,就能明白這是為什麼了。
歸一化的操作很簡單,我們根據像素值的範圍進行歸一化,我們先看看數據的類型:
print(X_train.dtype) # uint8
print(X_test.dtype) # uint8
他們是uint8型的,由於要進行歸一化,歸一化的數據是float32類型的,因此我們將使用astype()進行轉換,轉換後進行歸一化:
X_train = X_train.astype('float32')/255
X_test = X_test.astype('float32')/255
之前我們說到標籤數據(也就是樣本的真實類別)y_train和y_test是諸如這樣的列表[7 2 1 ... 4 5 6],我們在此需要進行One-hot encoding的操作,不懂One-hot encoding編碼的同學可以查閱下資料:
from keras.utils import np_utils
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
至此我們的數據就處理結束了,接下來我們來搭建神經網絡模型並訓練。
4、 構建模型
關於這一步驟,我先給出構建模型的代碼,然後在進行解釋:
1from keras.models import Sequential
2from keras.layers import Dense,Activation
3model = Sequential()
4model.add(Dense(512, input_shape=(28*28,),activation='relu'))
5model.add(Dense(10,activation='softmax'))
6model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
7model.fit(X_train, y_train, epochs=10, batch_size=64, verbose=1, validation_split=0.05)
8Testloss, Testaccuracy = model.evaluate(X_test, y_test)
9print('Testloss ', Testloss)
10print(『Testaccuracy:', Testaccuracy)
上述代碼中:
第三行代碼表示使用Keras中的Sequential 順序模型。
第四行代碼表示增加一個全連接層(密集層),這層有512個神經元,輸入形狀是(28*28,)此處的輸入形狀也可以寫為:input_dim=28*28。Activation表示這層的激活函數使用是relu,不同的激活函數有不同的效果,大家可以自己學習。
第五行代碼增加一個全連接層,這層有10個神經元,這於我們的期望輸出個數一致(10個數字),激活函數使用softmax。
第六行代碼表示編譯我們之前構建的模型,優化器選擇adam,損失函數為categorical_crossentropy,指標度量選擇accuracy精度。
第七行代碼表示使用訓練集數據來訓練我們的模型,epochs表示模型的訓練的時期數,每個epoch是對x,y的整個迭代,這裡迭代10次。batch_size代表每個梯度更新的樣本數,默認值為32. verbose:日誌顯示verbose = 0為不在標準輸出流輸出日誌信息,verbose = 1為輸出進度條記錄,verbose=2為每個epoch輸出一行記錄,默認為1。validation_split按一定比例從訓練集中取出一部分作為驗證集。最後一行控制臺輸出:loss: 0.0109 - acc: 0.9964 - val_loss: 0.0862 - val_acc: 0.9823
第八行代碼表示對已經訓練好的模型在驗證集上進行評價,列印出驗證集上的損失和精度為:loss 0.0794 ,Accuracy: 0.9784。
可以看出在測試集上的精度要比訓練集上的精度高,這說明我們訓練的模型過擬合了,過擬合是指機器學習模型在新數據上的性能往往比在訓練數據上要差。
至此,我們就完成了使用Keras完成了深度學習的「Hello World」項目,後期我們將構建卷積神經網絡來進一步提升模型的精度。有興趣的小夥伴可以自己畫一個樣本,然後進行識別。
構建訓練模型的整個代碼如下:
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Activation
path = r'C:\Users\LEGION\Desktop\kerasdatasets\mnist.npz'
(X_train, y_train), (X_test, y_test) = mnist.load_data(path)
X_train = X_train.reshape(len(X_train),-1)
X_test = X_test.reshape(len(X_test), -1)
X_train = X_train.astype('float32')/255
X_test = X_test.astype('float32')/255
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
model = Sequential()
model.add(Dense(512, input_shape=(28*28,),activation='relu'))
model.add(Dense(10,activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=10, batch_size=64, verbose=1, validation_split=0.05)
loss, accuracy = model.evaluate(X_test, y_test)
Testloss, Testaccuracy = model.evaluate(X_test, y_test)
print('Testloss:', Testloss)
print('Testaccuracy:', Testaccuracy)
Keras實現一個深度學習的模型還是非常簡單的,對於Keras大家是不是有點了解了呢?學習Keras最重要的就是需要多寫,多看官方的API。當然了最重要的是大家要有機器學習或者深度學習的一些理論基礎。下次推文我們來介紹Keras中的模型的種類,即Sequential 順序模型和Model 模型。
往期精選(👇猛戳可查看)