本篇介紹如何在 CentOS Linux 中安裝與使用 Keras 這套深度學習工具。

談到深度學習(Deep Learning)的工具,大家都會想到 TensorFlow 這類的底層 framework,這類的基礎的 framework 由於保留了非常多的彈性空間,導致使用上比較不方便,如果想要快速進行依些簡單的問題測試,就可以使用 Keras 這類的高階工具。


Keras 是一套高階的 Python 深度學習工具,底層可以介接 Tensorflow、CNTK 或 Theano 來執行,使用它的好處就是可以快速建立基本的類神經網路,不用寫太多的程式碼,就可以快速做一些基本的測試。

目前 Google 已將 Keras 正式納入 TensorFlow 核心模組中,所以在 TensorFlow 的環境下可以直接使用 Keras,不需要另外安裝,這部分請參考 TensorFlow 內建 Keras 的範例

以下是在 CentOS Linux 中安裝與使用 Keras 的流程。

安裝 Keras

使用 yum 安裝 pip,而 Python 有 2 與 3 兩種版本,我是比較喜歡直接用 Python 3 來寫新的程式,所以這裡我以 Python 3 作為示範(註解掉的部分是 Python 2):

# yum install python2-pip
yum install python34-pip

Keras 底層可以連接 Tensorflow、CNTK 或 Theano,任選一種來安裝就可以了,而我習慣用的是 TensorFlow,所以就安裝一下 GPU 版的 TensorFlow。

#pip install tensorflow-gpu
pip3 install tensorflow-gpu

GPU 版本的 TensorFlow 會需要 NVIDIA cuDNN,請從 NVIDIA 網站直接下載安裝。

接著安裝 Keras:

#pip install keras
pip3 install keras

安裝好之後,進入 Python 環境測試一下:

python3

測試引入 keras 這個 Python 模組:

import keras

若沒有出現錯誤的話,就代表安裝好了。

引入 Keras 模組

MNIST 手寫數字辨識

我們拿 MNIST 手寫數字辨識這個最簡單的範例來示範如何在 Keras 中建立 CNN 模型。首先引入一些在這個範例中會使用到的 Python 模組,並定義幾個常數。

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D

# 影像的類別數目
num_classes = 10

# 輸入的手寫影像解析度
img_rows, img_cols = 28, 28

接著將手寫數字的資料讀進程式中,並且整理成 Keras 可以用的資料形式:

# 載入資料(將資料打散,放入 train 與 test 資料集)
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 將原始資料轉為 2D 的影像排列方式
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)

# 輸入資料的維度
input_shape = (img_rows, img_cols, 1)

# 標準化輸入資料
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255

print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# 將數字轉為 One-hot 向量
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

整理資料的重點在於把每個像素的數值從 0255 的整數轉換為 01 的浮點數,而 label 則是從 010 的整數轉換為長度為 10 的 one-hot 向量。

準備好資料之後,接著即可開始使用 Keras 建立 CNN 模型。在 Keras 中的建立模型的方式可分為兩種,比較簡單的模型可以用 Sequential 來建立,若要建立比較複雜的模型,則可改用 functional API

這裡我們示範用 Sequential 建立一個 CNN 模型,首先呼叫 Sequential 建立一個基礎模型。

# 建立模型
model = Sequential()

接著就可以開始把每一層 layer 依序加上去,首先加上一層 2D 的 convolution layer,然後接著一層 ReLU 的 activation 函數:

# 加入 2D 的 Convolution Layer,接著一層 ReLU 的 Activation 函數
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))

接著再加入第二層 convolution layer:

# 第二層 2D 的 Convolution Layer,接著一層 ReLU 的 Activation 函數
model.add(Conv2D(64, (3, 3), activation='relu'))

由於 Keras 的設計很直覺,如果你對於 CNN 的理論很熟悉的話,這些程式碼應該是一看就懂了,就看自己的類神經網路要如何設計,依序加上去就可以把整個網路建立出來。

# 2D 的 Max-Pooling Layer
model.add(MaxPooling2D(pool_size=(2, 2)))

# Dropout Layer
model.add(Dropout(0.25))

# 將 2D 影像轉為 1D 向量
model.add(Flatten())

# 連接 Fully Connected Layer,接著一層 ReLU 的 Activation 函數
model.add(Dense(128, activation='relu'))

# Dropout Layer
model.add(Dropout(0.5))

# 連接 Fully Connected Layer,接著一層 Softmax 的 Activation 函數
model.add(Dense(num_classes, activation='softmax'))

把所有的 layers 加上去之後,模型就定義完成了,接著要設定模型的 loss 函數、optimizer 以及用來判斷模型好壞的依據(metrics),通常判斷模型好壞的依據就是看準確度,所以 metrics 在大多數的狀況下都會設為 'accuracy'

# 設定模型的 Loss 函數、Optimizer 以及用來判斷模型好壞的依據(metrics)
model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

接下來進行模型的訓練,這裡要決定 batch size 的大小、epochs 的數目:

# 訓練模型
model.fit(x_train, y_train,
          batch_size=128,
          epochs=12,
          verbose=1,
          validation_data=(x_test, y_test))

模型訓練完之後,驗證模型並輸出結果。

# 驗證模型
score = model.evaluate(x_test, y_test, verbose=0)

# 輸出結果
print('Test loss:', score[0])
print('Test accuracy:', score[1])

Keras 在訓練模型時,會有互動式的輸出,可以即時看到模型訓練的進度、loss 函數值以及準確度。

執行 Keras 程式

程式執行完之後,我們就可以看到 testing set 的 loss 與準確度。

Keras 程式執行結果

由於這個範例是經過特別設計過的,準確率特別高,而在處理一般的深度學習問題時,不太可能程式一寫出來就有很好的表現,通常都要經過一些模型與參數的調整,才能獲得理想的結果,在 Keras 的架構下,不管是變更類神經網路的結構或是調整參數都非常方便,對於初期的模型測試很有幫助。