1. 程式人生 > >Keras學習筆記:Chapter1-Keras入門

Keras學習筆記:Chapter1-Keras入門

這裡寫圖片描述

Keras

Keras是一個高層神經網路庫。Keras是由Python編寫而成的,後端實現是基於Tensorflow,CNTK或Theano(Keras是一個庫,可以理解為一個基於多種不同機器學習庫提供相同api的庫)。

這裡寫圖片描述

Keras發展的要義是:將想法快速轉換實驗成果,(類似Python的理念:人生苦短,我用Python),正因為這樣,Keras很適合做研究使用。

如果你對深度學習庫有以下要求:

  • 能夠快速的、簡便的實現idea
  • 支援CNN和RNN
  • 在CPU和GPU上快速切換

那麼Keras會是一個非常好的選擇~

安裝Keras

Keras依賴

在安裝Keras之前,需要安裝一個Keras需要的任意一個後端引擎

(backend engines,後端是指Keras需要依賴的底層張量運算所需要的機器學習庫):

  • TensorFlow
  • CNTK
  • Theano

還有一些可選的依賴:

  • cuDNN (使用GPU加速Keras執行)
  • HDF5 and h5py (用於儲存Keras模型)
  • graphviz and pydot (繪製模型圖)

我個人覺得安裝Anaconda+TensorFlow+Keras這一套,省心省力~

安裝Keras庫本身

安裝Keras有兩種方法:

  • 使用PyPI安裝(推薦)

    sudo pip install keras
  • 也可以使用原始碼安裝

    • First: 從github上將Keras原始碼clone下來

      git clone https://github.com/fchollet/keras.git
    • Then: 進入Keras目錄,並執行安裝程式

      cd keras
      sudo python setup.py install

檢視是否安裝和Keras的後端設定

開啟終端

 >>>python               # 進入python環境
 >>>import keras         # 匯入keras
 Using TensorFlow backend.
 >>>keras.__version__    # 檢視當前Keras版本
'2.0.8'

這裡寫圖片描述

如何切換後端為CNTK或Theano

Keras預設使用TensorFlow作為後端實現張量計算,如果你想切換Keras的後端為CNTK或Theano,參考Keras backends

(現在Theano已經停止更新了,建議還是用TensorFlow吧)

一些基本概念

在學習Keras之前,需要有一些關於Keras、深度學習的基本概念。

張量

通常,在機器學習系統中使用張量(tensors)作為資料的基本結構,張量是這個領域的基礎概念,那麼tensor是啥?
張量是包含資料的容器,可以看做數字、向量、矩陣的擴充套件,它們都是張量的特殊表現。

  • 0維的張量就是數字,即標量(0D tensors: Scale)

     >>> import numpy as np
     >>> x = np.array(12)
     >>> x
     array(12)
     >>> x.ndim
     0

    只包含一個數字的張量稱之為標量,在numpy中可通過ndim屬性訪問張量的維度

  • 1維的張量就是一組資料,即向量(1D tensors:Vectors)

     >>> x = np.array([12, 3, 6, 14])
     >>> x
     array([12, 3, 6, 14])
     >>> x.ndim
     1
  • 2維的張量就是一組向量,即矩陣(2D tensors:Matrices)

     >>> x = np.array([[5, 78, 2, 34, 0],
                       [6, 79, 3, 35, 1],
                       [7, 80, 4, 36, 2]])
     >>> x.ndim
     2
  • 3維(例如一張彩色圖片)及更多維度的張量

     >>> x = np.array([[[5, 78, 2, 34, 0],
                        [6, 79, 3, 35, 1],
                        [7, 80, 4, 36, 2]],
                       [[5, 78, 2, 34, 0],
                        [6, 79, 3, 35, 1],
                        [7, 80, 4, 36, 2]],
                       [[5, 78, 2, 34, 0],
                        [6, 79, 3, 35, 1],
                        [7, 80, 4, 36, 2]]])
     >>> x.ndim
     3

在張量的表述上,一般把維度(dimension)稱為(axis)。在深度學習中,一般使用的是從0D到4D的張量,在處理video data時可能會用到5D的張量

下圖是4D張量的表示:

這裡寫圖片描述

多張圖片組成的4D張量,分別為長、寬、通道數、樣本數。一般的我們在訓練CNN模型時,定義的輸入張量就是這樣的形式。

張量的屬性

一個張量有3個關鍵屬性:

  • 張量的axes(階數)。
  • 張量的shape。shape描述的張量每個axis的維度。例如上面舉例的3D張量的shape為(3,3,5);2D的張量shape為(2,5);1D的張量shape為(4,);0D的張量shape為()。

  • 張量的資料型別(data type)。在numpy中dtype表示。

函式式模型

在原本的Keras版本中,模型其實有兩種:

  • 一種叫Sequential,稱為序貫模型,也就是單輸入單輸出,一條路通到底,層與層之間只有相鄰關係,跨層連線統統沒有。這種模型編譯速度快,操作上也比較簡單。

  • 第二種模型稱為Graph,即圖模型(大部分機器學習庫都是基於這個模型),這個模型支援多輸入多輸出,層與層之間想怎麼連怎麼連,但是編譯速度慢。

可以看到,Sequential其實是Graph的一個特殊情況。新版Keras中,圖模型被移除,而增加了functional model API,這更加強調了Sequential是特殊情況。一般的模型就稱為Model,如果你要用簡單的Sequential,還有一個快捷方式Sequential。

functional model API將其譯為泛型模型,即只要是接收一個或一些張量作為輸入,然後輸出的也是一個或一些張量,統統都稱作“model”。

Pyhon和深度學習基礎

  • Keras使用的是Python語言,所以應該對Python有一定得了解。
  • Keras是一個深度學習庫,所以基本的深度學習基礎是要有的。
    • 模型:監督學習、無監督學習、分類、迴歸等
    • 損失函式、啟用函式、過擬合、欠擬合等
    • BP演算法、梯度下降法、SGD、batch、epoch等
    • 訓練集、校驗集、測試集等

開發環境

我的開發環境:

  • Ubuntu16.04(強烈建議在linux上開發)
  • TensorFlow 1.3-GPU(我的後端是tensorflow)
  • i7-7700k+GTX1080(沒有顯示卡也能搞,就是速度慢點)

在MNIST上構建一個簡單的神經網路

MNIST資料集

Keras內建操作MNIST資料集的函式MNIST資料集介紹。可通過下面格式載入:

>>>from keras.datasets import mnist

>>>(train_images, train_labels), (test_images, test_labels) = mnist.load_data()  # 下載完MNIST資料集並載入
# ... 下載

>>>train_images.shape # 看一下訓練集
(60000, 28, 28)
>>>len(train_labels)
60000
>>>test_images.shape # 看一下測試集
(10000, 28, 28)
>>>len(test_labels)
10000

在使用之前,我們對資料做reshape以便於後面直接塞給model,同時對資料做歸一化處理。原本我們的訓練圖片shape為(60000, 28, 28);dtype為uint8;值為[0, 255]之間。我們將其轉化為dtype為float32; shape為(60000, 28 * 28);值為[0, 1].

train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255

同樣的,我們也需要對labels做編碼,用如下程式碼:

from keras.utils import to_categorical

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

這樣我們算是準備好了資料集了~

構建網路模型

神經網路的核心組成模型是就是資料處理模組,也稱之為過濾器(filter)。一般的有輸入層、隱藏層、輸出層。

from keras import models
from keras import layers

network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))

這裡我們構建的模型由兩個Dense層組成,Dense層就是densely-connected (也稱之為”fully-connected”,即FC)層。(我就在琢磨17年的整出來了DenseNet,Keras該怎麼起名字)。第二層是softmax層,輸出是一個10維向量,對應的就是數字0-9的可能性。(總和為1)。

為了能夠訓練模型,我們還需要做以下三步:

  • 新增損失函式(loss function):評估模型在訓練集上訓練的好壞程度,為模型修正提供了正確方向。
  • 優化器(optimizer):模型優化自身引數的方法
  • 訓練和測試之間的度量標準。
 network.compile(optimizer='rmsprop',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

訓練模型並評估

在構建好的模型上,開始訓練:

>>>network.fit(train_images, train_labels, epochs=5, batch_size=128)

 Epoch 1/5
 60000/60000 [==============================] - 2s - loss: 0.2577 - acc: 0.9245     
 Epoch 2/5
 60000/60000 [==============================] - 1s - loss: 0.1042 - acc: 0.9690     
 Epoch 3/5
 60000/60000 [==============================] - 1s - loss: 0.0687 - acc: 0.9793     
 Epoch 4/5
 60000/60000 [==============================] - 1s - loss: 0.0508 - acc: 0.9848     
 Epoch 5/5
 60000/60000 [==============================] - 1s - loss: 0.0382 - acc: 0.9890 

可以看到,這裡列印的log裡主要有2個指標,’loss’表示network和訓練集之間的loss,’acc’即表示network和訓練集之間accuracy。可以看到,在訓練集上acc很快達到了98.9%, 下面看看模型在測試集上的表現:

 >>>test_loss, test_acc = network.evaluate(test_images, test_labels)
  9536/10000 [===========================>..] - ETA: 0s
 >>>print('test_acc:', test_acc)
 test_acc: 0.9777

可以看到在測試集上達到了97.7%,也還算不錯。到此為止,我們搭建了一個簡易的神經網路模型用於手寫數字的識別,後面還將詳細的講解本小節用到的函式。

參考資料

Keras中文文件 SCP-173
《Deep Learning with Python》 Francois Chollet