當前位置:
首頁 > 知識 > Tensorflow_08A_Keras 助攻下的 Sequential 模型

Tensorflow_08A_Keras 助攻下的 Sequential 模型

Brief 概述

使用 keras 搭建模型時讓人們感受到的簡潔性與設計者的用心非常直觀的能夠在過程中留下深刻的印象,這個模塊幫可以讓呈現出來的代碼極為人性化且一目了然,使用 Tensorflow 模塊搭建神經網路模型通常需要百行的代碼,自定義模型和函數,唯一受到 tf 封裝的厲害功能只有梯度下降的自動取極值,如果是一個初出入門的人,沒有一定的基礎背景累積,更遑論使用 tf 搭建神經網路。

其大量封裝了一系列的複雜深度學習原理成為一個又一個簡潔的函數模塊,構建的時候即便基礎知識差一些也可以非常快的上手搭建工作,是一個對初學者非常友好的介面。不過其封裝的函數總量適用的對象遠遠不止初學者這麼簡單,其內部還有非常完整的高級功能,同時也滿足高級框架的搭建!

Tensorflow_08A_Keras 助攻下的 Sequential 模型

打開今日頭條,查看更多精彩圖片

keras 模塊原本並非是 Tensorflow 的高級 API,而是一個身在 Google 工作的工程師基於 Tensorflow 和 Theano 開發出來的第三方模塊,讓其他人也能夠快速的構建屬於自己的模型,到了後來此模塊逐漸受到大眾青睞後,Google 於是把它收邊進了 Tensorflow high level API 中,現在已經逐漸形成了使用者社群,並有許多巨頭以此模塊作為基礎開發基於他們熟悉的底層框架對應的 API 介面,相信不久的未來 Keras 將成為每種框架的統一介面,讓熟悉 Keras 的人們能夠在各種框架中根據性能的優劣自由切換。

p.s. 點擊此 進入 keras 官網,點擊此 進入 keras 的 GitHub 源代碼。

Import Data 導入數據

構建神經網路之前,最重要的還是數據本身,而這裡將繼續沿用前面面幾個章節中所使用的兩個模型 MNIST 與 CIFAR10,和與其對應的函數代碼,並簡單列印出引入數據集圖像對應標籤的結果。

import gzip

from Code_Session.TF_04 import mnist as M

import pickle

from Code_Session.TF_05 import cifar2cnn as cc

MNIST Dataset

path_mnist = "/Users/kcl/Documents/Python_Projects/01_AI_Tutorials/_2_Image_Datasets/MNIST_data"

mnist = M.MNIST(val_ratio=0.0, data_dir=path_mnist)

print(mnist.img_train.shape)

(60000, 784)

mnist_img_train = M.format_images(mnist.img_train)

mnist_lab_train = mnist.lab_train

mnist_cls_name = [i for i in range(10)]

cc.plot_images(mnist_img_train, mnist.lab_train, mnist_cls_name, size=[3, 4])

Tensorflow_08A_Keras 助攻下的 Sequential 模型

CIFAR10 Dataset

path_cifar = "/Users/kcl/Documents/Python_Projects/cifar-10-batches-py"

img_train = cc.merge_batches("data", file_dir=path_cifar)

print(img_train.shape)

(50000, 3072)

file_dir = path_cifar + "/" + "batches.meta"

def get_class_name(file_dir=file_dir):

with open(file_dir, "rb") as file:

dic = pickle.load(file, encoding="bytes")

return [w.decode("utf-8") for w in dic[b"label_names"]]

cifar_img_train = cc.format_images(img_train)

cifar_lab_train = cc.merge_batches("labels", file_dir=path_cifar)

cc.plot_images(cifar_img_train, cifar_lab_train,

get_class_name(), size=[3, 4])

Tensorflow_08A_Keras 助攻下的 Sequential 模型

p.s. 如果對其中的代碼有任何不熟悉,請詳見前面幾回合的內容。

接下來就可以從 Tensorflow 模塊中呼叫 keras 搭建一個非常迅捷且輕便的神經網路模型。類似 keras 的 API 模塊也有 PrettyTensor 與 layers,不過從 Tensorflow 官網的態度來看,它很可能將在未來被刪減,而主推 keras,同時很多更新的功能 keras 也持續同步著,是一個相對穩健的高級 API,故值得一探究竟。

Keras Insight

此 API 主要有兩種模式可以讓我們建構神經網路:

Sequential Model

Functional Model

他們彼此之間在背後代碼上的運算過程是一樣的,差別主要在於我們使用者書寫上的差異,Sequential 的代碼看起來和一般的代碼沒什麼區別,基本山看到代碼就能了解其含義,而 Functional 方法寫起來是讓參數帶入函數裡面的函數,等下面內容提及到代碼就會知曉。

既然是搭建神經網路專用的 API,那麼整個框架主要的功能也就只圍繞著相關的機制操作,主要的機制如下陳列:

.add: 添加一層新的神經網路

.compile: 把上面呢所有添加好的神經網路全部打包

.fit: 訓練設定好的神經網路

.evaluate: 計算神經網路的損失值和驗證集正確率

.predict: 計算新的數據在此模型的正確率

.save: 把更新到一定階段的神經網路參數儲存起來,如同 checkpoint

.load_model: 重新載入儲存好的神經網路參數文檔

不論是哪一個神經網路搭建方式,都同樣遵循上面一到七的步驟,基本上一個人熟練的情況下,每一個神經網路的搭建都可以在 5 分鐘內完成,比起其他的快速搭建方式,keras 同時也是最為完整的一個 API,每個上述列舉的方法內還有與之方法對應的細分方法可以調用,可以自行查找官方文檔了解。

1-1. Sequential Linear Model

keras 可以從 tensorflow 中被呼叫,也可以直接使用 keras 本身的模塊,本系列由於跟 tensorflow 相關,因此主要從 tf 中使用 keras,不過模塊中的函數名稱和代碼使用方式基本上是完全相同的。

首先呼叫出 sequential 方法本身,如下代碼:

import numpy as np

import tensorflow as tf

import tensorflow.keras as K

接著使用 Sequential 創建一個對象,基於這個對象開始逐層添加神經網路結構至對象中,其中 Dense 方法表示全聯接的意思,Dense 裡面的數字項表示的是該全聯接層有幾個輸出神經元。

等搭建到了最後一層神經網路結構時,如果是分類問題的話,則激勵函數調整成 softmax 相關的方式即可。

model = K.models.Sequential()

model.add(K.layers.Flatten())

model.add(K.layers.Dense(units=128, activation=tf.nn.relu))

model.add(K.layers.Dense(units=128, activation=tf.nn.relu))

model.add(K.layers.Dense(units=10, activation=tf.nn.softmax))

建構的方式還有另一種代碼寫法,可以參考 官網的示範,不過為了不讓自己的記憶混淆,建議從一而終。

完成神經網路的構建之後,接下來把整個框架使用 compile 打包起來,在參數部分設定需要使用的梯度下降函數和損失函數的使用演算法。如果對於梯度下降演算法有更細節調整的需要,可以進一步引入下面模塊,使用對象的方式設定好之後再傳入 .compile 方法中。

opt = K.optimizers.Adam(lr=1e-3)

model.compile(optimizer=opt, # option no.1

# optimizer="adam" # option no.2

loss="categorical_crossentropy",

metrics=["accuracy"])

最後輸入我們期望訓練的數據開始訓練模型,並試圖讓損失函數降到最低。輸入數據標籤如果是分類問題,那就必須是 one hot 形式,否則會報錯。在參數像中調整好 epochs 的次數後就可以開始訓練。

1-1-1. Train MNIST Dataset

首先使用上面搭建好的神經網路模型運行 MNIST 數據集,以 "圖像" 與 "one hot" 形式作為輸入尤為重要:

model.fit(M.format_images(mnist.img_train),

cc.one_hot(mnist_lab_train, class_num=10),

epochs=5)

Epoch 1/5

60000/60000 [==============================] - 5s 86us/step - loss: 0.2346 - acc: 0.9306

Epoch 2/5

60000/60000 [==============================] - 5s 79us/step - loss: 0.0981 - acc: 0.9696

Epoch 3/5

60000/60000 [==============================] - 5s 78us/step - loss: 0.0683 - acc: 0.9778

Epoch 4/5

60000/60000 [==============================] - 5s 79us/step - loss: 0.0514 - acc: 0.9833

Epoch 5/5

60000/60000 [==============================] - 5s 79us/step - loss: 0.0424 - acc: 0.9862

完成訓練後接下來使用驗證集測試訓練模型的結果,同樣的輸入參數需要使用圖像數據格式(不能是拉直狀態),並且標籤使用 one hot 格式。

mnist_loss, mnist_acc = model.evaluate(M.format_images(mnist.img_test),

cc.one_hot(mnist.lab_test))

print("The loss value: {}".format(mnist_loss))

print("The accuracy: {}".format(mnist_acc))

10000/10000 [==============================] - 0s 32us/step

The loss value: 0.08600640584569191

The accuracy: 0.9754

1-1-2. Train CIFAR10 Dataset

接下來是完全一摸一樣的操作,重複一遍套用在 CIFAR10 數據集上,唯一的差別是數據本身多了一個顏色通道,同樣多的圖片張數卻要多出三倍的運算量。

完整的代碼如下:

model.fit(cc.format_images(img_train),

cc.one_hot(cifar_lab_train, class_num=10),

epochs=5, batch_size=128)

Epoch 1/5

50000/50000 [==============================] - 8s 170us/step - loss: 1.8626 - acc: 0.3288

Epoch 2/5

50000/50000 [==============================] - 8s 156us/step - loss: 1.6912 - acc: 0.3922

Epoch 3/5

50000/50000 [==============================] - 8s 159us/step - loss: 1.6262 - acc: 0.4178

Epoch 4/5

50000/50000 [==============================] - 8s 159us/step - loss: 1.5786 - acc: 0.4355

Epoch 5/5

50000/50000 [==============================] - 8s 160us/step - loss: 1.5457 - acc: 0.4477

接著同樣步驟使用驗證集的數據檢測訓練完成的模型的準確率,切記同樣需要使用非拉直狀態的圖像數據和 one hot 形式的標籤數據作為參數輸入。

cifar_img_test = cc.format_images(cc.load_binary_data(

"test_batch", "data", file_dir=path_cifar) / 255.0)

cifar_lab_test = cc.one_hot(cc.load_binary_data(

"test_batch", "labels", file_dir=path_cifar).astype(np.int))

cifar_loss, cifar_acc = model.evaluate(cifar_img_test, cifar_lab_test)

print("The loss value: {}".format(cifar_loss))

print("The accuracy: {}".format(cifar_acc))

10000/10000 [==============================] - 1s 57us/step

The loss value: 1.5932202987670898

The accuracy: 0.4278

1-2. Sequential CNN Model

線性模型構建的方式使用了全聯接層的方法,而論及卷積神經網路則需要使用到卷積核掃描之,建構神經網路的方法從核心概念來看是類似的,不過多了一個卷積層構建的函數調用,首先同樣導入需要用到的模塊:

import numpy as np

import tensorflow as tf

import tensorflow.keras as K

接著同樣使用模塊的功能開始創建神經網路,如果一開始設定神經層的格式需要修改,可以參考下面方法,分作兩種輸入數據的格式。

1-2-1. MNIST input

mnist_img_size = 28

cnn_model = K.models.Sequential()

# To define the format of input data. Dimension scale and size.

cnn_model.add(K.layers.InputLayer(input_shape=(mnist_img_size**2,)))

cnn_model.add(K.layers.Reshape((mnist_img_size, mnist_img_size, 1)))

1-2-2. CIFAR10 input

cifar_img_size = 32

cnn_model = K.models.Sequential()

# To define the format of input data. Dimension scale and size.

cnn_model.add(K.layers.InputLayer(input_shape=(cifar_img_size, cifar_img_size, 3)))

上面兩種輸入模式根據執行需求自行選擇一個執行。

接著開始 CNN 卷積神經網路的搭建過程,都是使用 .layers 模塊裡面的方法,為了達到加深印象的目的,每一次呼叫指令的時候都還是把其來源輸入一遍,如下代碼:

# 1st convolutional layer with ReLU-activation and max-pooling.

cnn_model.add(K.layers.Conv2D(kernel_size=3, strides=1, filters=16,

padding="same", activation="relu", name="layer_conv1"))

cnn_model.add(K.layers.MaxPooling2D(pool_size=2, strides=2))

cnn_model.add(K.layers.BatchNormalization())

# 2nd convolutional layer with ReLU-activation and max-pooling.

cnn_model.add(K.layers.Conv2D(kernel_size=3, strides=1, filters=36,

padding="same", activation="relu", name="layer_conv2"))

cnn_model.add(K.layers.MaxPooling2D(pool_size=2, strides=2))

cnn_model.add(K.layers.BatchNormalization())

# Flatten the 4D tensor into 2D tensor for next fully connected step

cnn_model.add(K.layers.Flatten())

# 1st FC layer with 128 output units

cnn_model.add(K.layers.Dense(units=128, activation="relu"))

cnn_model.add(K.layers.BatchNormalization())

# 2nd FC layer connecting to classification answers

cnn_model.add(K.layers.Dense(units=10, activation="softmax"))

1-2-1. Train MNIST Dataset

框架構建好後,接著開始訓練模型,方法與上麵線性模型相同,不過輸入數據的時候需要特別注意自己先前在模型搭建的時候設定的數據規格,如果有任何一點不一樣的話將報錯。

opt = K.optimizers.Adam(lr=1e-3)

cnn_model.compile(optimizer=opt,

loss="categorical_crossentropy",

metrics=["accuracy"])

cnn_model.fit(x=mnist.img_train,

y=cc.one_hot(mnist.lab_train),

epochs=2, batch_size=128)

Epoch 1/2

60000/60000 [==============================] - 43s 724us/step - loss: 0.1180 - acc: 0.9643

Epoch 2/2

60000/60000 [==============================] - 43s 715us/step - loss: 0.0366 - acc: 0.9887

如同在線性模型訓練完後所使用驗證集準確率測試操作,也使用 evaluate 函數檢測准模型準確率。

mnist_loss, mnist_acc = cnn_model.evaluate(mnist.img_test,

cc.one_hot(mnist.lab_test))

print("The loss value: {}".format(mnist_loss))

print("The accuracy: {}".format(mnist_acc))

10000/10000 [==============================] - 3s 297us/step

The loss value: 0.04114889272502623

The accuracy: 0.9879

1-2-2. Train CIFAR10 Dataset

同樣步驟訓練 CIFAR10 數據集,代碼如下:

opt = K.optimizers.Adam(lr=1e-3)

cnn_model.compile(optimizer=opt,

loss="categorical_crossentropy",

metrics=["accuracy"])

cnn_model.fit(x=cifar_img_train, y=cc.one_hot(cifar_lab_train),

epochs=3, batch_size=128)

Epoch 1/3

50000/50000 [==============================] - 59s 1ms/step - loss: 1.2917 - acc: 0.5494

Epoch 2/3

50000/50000 [==============================] - 57s 1ms/step - loss: 0.9213 - acc: 0.6799

Epoch 3/3

50000/50000 [==============================] - 52s 1ms/step - loss: 0.7637 - acc: 0.7344

如同在線性模型訓練完後所使用驗證集準確率測試操作,也使用 evaluate 函數檢測准模型準確率。

cifar_img_test = cc.format_images(cc.load_binary_data(

"test_batch", "data", file_dir=path_cifar) / 255.0)

cifar_lab_test = cc.one_hot(cc.load_binary_data(

"test_batch", "labels", file_dir=path_cifar).astype(np.int))

cifar_loss, cifar_acc = cnn_model.evaluate(cifar_img_test, cifar_lab_test)

print("The loss value: {}".format(cifar_loss))

print("The accuracy: {}".format(cifar_acc))

10000/10000 [==============================] - 4s 410us/step

The loss value: 0.994779656124115

The accuracy: 0.6507

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

String str = "ab" +"cd";共創建幾個對象
Spring事務用法示例與實現原理

TAG:程序員小新人學習 |