Core ML框架詳細(xì)解析(十三) —— 使用Keras和Core ML開(kāi)始機(jī)器學(xué)習(xí)(一)

版本記錄

版本號(hào) 時(shí)間
V1.0 2018.10.16 星期二

前言

目前世界上科技界的所有大佬一致認(rèn)為人工智能是下一代科技革命,蘋(píng)果作為科技界的巨頭,當(dāng)然也會(huì)緊跟新的科技革命的步伐,其中ios API 就新出了一個(gè)框架Core ML。ML是Machine Learning的縮寫(xiě),也就是機(jī)器學(xué)習(xí),這正是現(xiàn)在很火的一個(gè)技術(shù),它也是人工智能最核心的內(nèi)容。感興趣的可以看我寫(xiě)的下面幾篇。
1. Core ML框架詳細(xì)解析(一) —— Core ML基本概覽
2. Core ML框架詳細(xì)解析(二) —— 獲取模型并集成到APP中
3. Core ML框架詳細(xì)解析(三) —— 利用Vision和Core ML對(duì)圖像進(jìn)行分類
4. Core ML框架詳細(xì)解析(四) —— 將訓(xùn)練模型轉(zhuǎn)化為Core ML
5. Core ML框架詳細(xì)解析(五) —— 一個(gè)Core ML簡(jiǎn)單示例(一)
6. Core ML框架詳細(xì)解析(六) —— 一個(gè)Core ML簡(jiǎn)單示例(二)
7. Core ML框架詳細(xì)解析(七) —— 減少Core ML應(yīng)用程序的大?。ㄒ唬?/a>
8. Core ML框架詳細(xì)解析(八) —— 在用戶設(shè)備上下載和編譯模型(一)
9. Core ML框架詳細(xì)解析(九) —— 用一系列輸入進(jìn)行預(yù)測(cè)(一)
10. Core ML框架詳細(xì)解析(十) —— 集成自定義圖層(一)
11. Core ML框架詳細(xì)解析(十一) —— 創(chuàng)建自定義圖層(一)
12. Core ML框架詳細(xì)解析(十二) —— 用scikit-learn開(kāi)始機(jī)器學(xué)習(xí)(一)

開(kāi)始

首先看一下本文的寫(xiě)作環(huán)境

Swift 4, iOS 11, Xcode 9

Apple的Core MLVision框架已經(jīng)讓開(kāi)發(fā)人員進(jìn)入了一個(gè)勇敢的機(jī)器學(xué)習(xí)新世界,并帶來(lái)了令人興奮的可能性。Vision允許您檢測(cè)和跟蹤面部,Apple的Machine Learning page提供檢測(cè)對(duì)象和場(chǎng)景的即用型模型,以及用于自然語(yǔ)言處理的NSLinguisticTagger。如果您想構(gòu)建自己的模型,請(qǐng)嘗試使用Apple的新Turi Create來(lái)擴(kuò)展其使用您的數(shù)據(jù)預(yù)先訓(xùn)練的模型之一。

但是,如果您想要做什么需要更加個(gè)性化的東西?然后,是時(shí)候進(jìn)入機(jī)器學(xué)習(xí)(ML),使用谷歌,微軟,亞馬遜或伯克利的眾多框架之一。而且,為了讓生活更加精彩,您需要選擇一種新的編程語(yǔ)言和一套新的開(kāi)發(fā)工具。

在這個(gè)Keras機(jī)器學(xué)習(xí)教程中,您將學(xué)習(xí)如何訓(xùn)練深度學(xué)習(xí)卷積神經(jīng)網(wǎng)絡(luò)模型,將其轉(zhuǎn)換為Core ML,并將其集成到iOS應(yīng)用程序中。您將學(xué)習(xí)一些ML術(shù)語(yǔ),使用一些新工具,并在此過(guò)程中學(xué)習(xí)一些Python。

示例項(xiàng)目使用ML的Hello-World示例 - 一種對(duì)手寫(xiě)數(shù)字進(jìn)行分類的模型,在MNIST dataset上進(jìn)行訓(xùn)練。


Why Use Keras? - 為什么使用Keras?

ML模型涉及許多復(fù)雜的代碼,操縱數(shù)組和矩陣。但ML已經(jīng)存在了很長(zhǎng)時(shí)間,研究人員已經(jīng)創(chuàng)建了庫(kù),使像我們這樣的人更容易創(chuàng)建ML模型。其中許多是用Python編寫(xiě)的,盡管研究人員還使用R,SAS,MATLAB和其他軟件。但您可能會(huì)在基于Python的工具中找到所需的一切:

  • scikit-learn提供了一種運(yùn)行許多經(jīng)典ML算法的簡(jiǎn)便方法,例如線性回歸和支持向量機(jī)。
  • 另一方面是PyTorchGoogleTensorFlow,它可以讓您更好地控制深度學(xué)習(xí)模型的內(nèi)部工作。
  • 微軟的CNTKBerkeleyCaffe是類似的深度學(xué)習(xí)框架,它們使用Python API來(lái)訪問(wèn)他們的C ++引擎。

那么Keras在哪里適合?這是TensorFlowCNTK的包裝,亞馬遜的MXN??et即將推出。 (它也與Theano合作,但蒙特利爾大學(xué)于2017年9月停止了這項(xiàng)工作。)它提供了一個(gè)易于使用的API,用于構(gòu)建模型,您可以在一個(gè)后端訓(xùn)練,并在另一個(gè)后端部署。

使用Keras而不是直接使用TensorFlow的另一個(gè)原因是coremltools包括Keras轉(zhuǎn)換器,但不包括TensorFlow轉(zhuǎn)換器 - 盡管存在TensorFlow to CoreML converterMXNet to CoreML converter。雖然Keras支持CNTK作為后端,但coremltools僅適用于Keras + TensorFlow

注意:在使用這些工具之前,您是否需要學(xué)習(xí)Python?好吧,我沒(méi)有。當(dāng)你完成本教程時(shí),你會(huì)發(fā)現(xiàn)Python語(yǔ)法與Swift類似:更加簡(jiǎn)化,縮進(jìn)是語(yǔ)法的重要部分。如果您感到緊張,請(qǐng)?jiān)跒g覽器選項(xiàng)卡中保持打開(kāi)狀態(tài),以便快速參考:Crash Course in Python for Machine Learning Developers。

另一個(gè)注意事項(xiàng):研究人員同時(shí)使用Python 2Python 3,但coremltoolsPython 2.7中運(yùn)行得更好。


開(kāi)始進(jìn)入正題

打開(kāi)項(xiàng)目起始文件夾:它包含一個(gè)入門(mén)iOS應(yīng)用程序,您將在其中添加ML模型和代碼以使用它。 它還包含一個(gè)docker-keras文件夾,其中包含本教程的Jupyter筆記本。

1. Setting Up Docker - 設(shè)置Docker

Docker是一個(gè)容器平臺(tái),允許您在自定義環(huán)境中部署應(yīng)用程序 - 有點(diǎn)像虛擬機(jī),但different。 通過(guò)安裝Docker,您可以訪問(wèn)大量的ML資源,這些資源主要作為Docker鏡像中的交互式Jupyter notebooks分發(fā)。

注意:安裝Docker并構(gòu)建映像需要幾分鐘,因此請(qǐng)?jiān)诘却龝r(shí)閱讀ML in a Nutshell。

下載,安裝和啟動(dòng)Docker Community Edition for Mac。 在終端中,一次輸入以下命令:

cd <where you unzipped starter>/starter/docker-keras
docker build -t keras-mnist .
docker run --rm -it -p 8888:8888 -v $(pwd)/notebook:/workspace/notebook keras-mnist

最后一個(gè)命令將Docker容器的notebook文件夾映射到本地notebook文件夾,因此即使在您注銷(xiāo)Docker服務(wù)器之后,您也可以訪問(wèn)notebook所寫(xiě)的文件。

在命令輸出的最后是包含token的URL。 它看起來(lái)像這樣,但具有不同的標(biāo)記值:

http://0.0.0.0:8888/?token=7b189c8e200f49dcc33845d39101e8a0ab257db5f3b539a7

將此URL粘貼到瀏覽器中以登錄Docker容器的notebook服務(wù)器。

打開(kāi)notebook文件夾,然后打開(kāi)keras_mnist.ipynb。 點(diǎn)擊Not Trusted按鈕將其更改為Trusted:這樣您就可以在notebook文件夾中保存對(duì)notebook以及模型文件所做的更改。

2. ML in a Nutshell - Nutshell中的ML

Arthur Samuel將機(jī)器學(xué)習(xí)定義為“研究領(lǐng)域,讓計(jì)算機(jī)具有無(wú)需明確編程即可學(xué)習(xí)的能力”。 您有數(shù)據(jù),它具有一些可用于對(duì)數(shù)據(jù)進(jìn)行分類的功能,或者用它來(lái)進(jìn)行一些預(yù)測(cè),但是您沒(méi)有用于這種計(jì)算的明確的公式,因此您無(wú)法編寫(xiě)程序來(lái)執(zhí)行此操作。 如果您有“足夠”的數(shù)據(jù)樣本,則可以訓(xùn)練計(jì)算機(jī)模型以識(shí)別此數(shù)據(jù)中的模式,然后將其學(xué)習(xí)應(yīng)用于新數(shù)據(jù)。 當(dāng)您知道所有訓(xùn)練數(shù)據(jù)的正確結(jié)果時(shí),它被稱為監(jiān)督學(xué)習(xí):然后模型僅根據(jù)已知結(jié)果檢查其預(yù)測(cè),并調(diào)整自身以減少誤差并提高準(zhǔn)確性。 無(wú)監(jiān)督學(xué)習(xí)超出了本教程的范圍。

Weights & Threshold - 權(quán)重和閾值

假設(shè)您想和一群朋友一起選擇一家餐廳共進(jìn)晚餐。 有幾個(gè)因素會(huì)影響您的決定:飲食限制,公共交通,價(jià)格范圍,食物類型,兒童友好等。您為每個(gè)因素分配一個(gè)權(quán)重,以表明其對(duì)您決定的重要性。 然后,對(duì)于選項(xiàng)列表中的每個(gè)餐館,您可以根據(jù)餐廳滿足該因素的程度為每個(gè)因素分配一個(gè)值。 您將每個(gè)因子值乘以系數(shù)的權(quán)重,然后將它們相加以獲得加權(quán)和。 結(jié)果最高的餐廳是最佳選擇。 使用此模型的另一種方法是生成二進(jìn)制輸出:是或否。 您設(shè)置了一個(gè)閾值,并從列表中刪除任何加權(quán)總和低于此閾值的餐館。

Training an ML Model - 訓(xùn)練ML模型

提出權(quán)重并不是一件容易的事。 但幸運(yùn)的是,您有很多以前的晚餐數(shù)據(jù),包括選擇了哪家餐廳,因此您可以訓(xùn)練ML模型來(lái)計(jì)算產(chǎn)生相同結(jié)果的權(quán)重,盡可能接近。 然后將這些計(jì)算出的權(quán)重應(yīng)用于未來(lái)的決策。

要訓(xùn)練ML模型,首先要使用隨機(jī)權(quán)重,將它們應(yīng)用于訓(xùn)練數(shù)據(jù),然后將計(jì)算出的輸出與已知輸出進(jìn)行比較以計(jì)算誤差。 這是一個(gè)具有最小值的多維函數(shù),訓(xùn)練的目標(biāo)是確定非常接近此最小值的權(quán)重。 權(quán)重也需要處理新數(shù)據(jù):如果大量驗(yàn)證數(shù)據(jù)的誤差高于訓(xùn)練數(shù)據(jù)的誤差,那么模型就會(huì)過(guò)度擬合 - 權(quán)重對(duì)訓(xùn)練數(shù)據(jù)越適合,表明訓(xùn)練錯(cuò)誤檢測(cè)到一些不會(huì)推廣到新數(shù)據(jù)的功能。

Stochastic Gradient Descent - 隨機(jī)梯度下降

要計(jì)算減少誤差的權(quán)重,可以在當(dāng)前圖形位置計(jì)算誤差函數(shù)的梯度,然后調(diào)整權(quán)重以“降低”斜率。 這稱為梯度下降,在訓(xùn)練期間多次發(fā)生。 對(duì)于大型數(shù)據(jù)集,使用所有數(shù)據(jù)計(jì)算梯度需要很長(zhǎng)時(shí)間。 隨機(jī)梯度下降(Stochastic gradient descent - SGD)從隨機(jī)選擇的小批量訓(xùn)練數(shù)據(jù)中估計(jì)梯度 - 例如在選舉日之前對(duì)選民進(jìn)行調(diào)查:如果您的樣本代表整個(gè)數(shù)據(jù)集,則調(diào)查結(jié)果可準(zhǔn)確預(yù)測(cè)最終結(jié)果。

Optimizers - 優(yōu)化器

錯(cuò)誤函數(shù)是塊狀的:你必須小心不要走得太遠(yuǎn),否則你可能會(huì)錯(cuò)過(guò)最低限度。 你的步數(shù)也需要有足夠的動(dòng)力來(lái)推動(dòng)你擺脫任何虛假的最低限度。 ML研究人員為設(shè)計(jì)優(yōu)化算法付出了很多努力。 目前最受歡迎的是AdamAdaptive Moment estimation - 自適應(yīng)力矩估計(jì)),它結(jié)合了以前最受歡迎的RMSpropRoot Mean Square propagation - 均方根傳播)和AdaGradAdaptive Gradient algorithm - 自適應(yīng)梯度算法)的特征。


Keras Code Time! - Keras代碼時(shí)間!

好的,Docker容器現(xiàn)在應(yīng)該準(zhǔn)備就緒:返回并按照說(shuō)明打開(kāi)notebook。 是時(shí)候?qū)懸恍?code>Keras代碼了!

在具有匹配標(biāo)題的keras_mnist.ipynb單元格中輸入以下代碼。 在每個(gè)單元格中輸入代碼后,按Control-Enter運(yùn)行它。 代碼運(yùn)行時(shí),In []:標(biāo)簽中會(huì)出現(xiàn)一個(gè)星號(hào),然后會(huì)出現(xiàn)一個(gè)數(shù)字,以顯示運(yùn)行單元格的順序。 當(dāng)您登錄notebook時(shí),所有內(nèi)容都會(huì)保留在內(nèi)存中。 每隔一段時(shí)間,點(diǎn)擊Save and Checkpoint按鈕。

注意:雙擊markdown單元格以添加自己的注釋;按Control-Enter以呈現(xiàn)markdown并運(yùn)行Python代碼。 您還可以使用其他筆記本按鈕添加或復(fù)制粘貼單元格,以及移動(dòng)單元格。


Import Utilities & Dependencies - 導(dǎo)入實(shí)用項(xiàng)和依賴項(xiàng)

輸入以下代碼,然后運(yùn)行它以檢查Keras版本。

from __future__ import print_function
from matplotlib import pyplot as plt

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
from keras.utils import np_utils
from keras import backend as K

import coremltools
# coremltools supports Keras version 2.0.6
print('keras version ', keras.__version__)

__future__Python 2Python 3之間的兼容層:Python 2有一個(gè)print命令(沒(méi)有括號(hào)),但Python 3需要print()函數(shù)。 導(dǎo)入print_function允許您在Python 2代碼中使用print()語(yǔ)句。

Keras使用NumPy數(shù)學(xué)庫(kù)來(lái)操作數(shù)組和矩陣。 MatplotlibNumPy的繪圖庫(kù):您將使用它來(lái)檢查訓(xùn)練數(shù)據(jù)項(xiàng)。

注意:由于due to NumPy 1.14,您可能會(huì)看到FutureWarning

導(dǎo)入keras后,打印其版本:coremltools支持2.0.6版,如果使用更高版本,將發(fā)出警告。 Keras已經(jīng)擁有MNIST數(shù)據(jù)集,因此您可以導(dǎo)入它。 然后接下來(lái)的三行導(dǎo)入模型組件。 您導(dǎo)入NumPy實(shí)用程序,并為后端提供帶有import backend as K的標(biāo)簽,您將使用它來(lái)檢查image_data_format。

最后,導(dǎo)入coremltools,您將在此notebook的末尾使用它。


Load & Pre-Process Data - 加載和預(yù)處理數(shù)據(jù)

1. Training & Validation Data Sets - 訓(xùn)練和驗(yàn)證數(shù)據(jù)集

首先,獲取您的數(shù)據(jù)! 輸入以下代碼并運(yùn)行它:下載數(shù)據(jù)需要一段時(shí)間。

(x_train, y_train), (x_val, y_val) = mnist.load_data()

這將從https://s3.amazonaws.com/img-datasets/mnist.npz下載數(shù)據(jù),對(duì)數(shù)據(jù)項(xiàng)進(jìn)行混洗,并在訓(xùn)練數(shù)據(jù)集和驗(yàn)證數(shù)據(jù)集之間進(jìn)行拆分。 驗(yàn)證數(shù)據(jù)有助于檢測(cè)模型過(guò)度擬合到訓(xùn)練數(shù)據(jù)的問(wèn)題。 訓(xùn)練步驟使用訓(xùn)練的參數(shù)來(lái)計(jì)算驗(yàn)證數(shù)據(jù)的輸出。 您將設(shè)置回調(diào)以監(jiān)控驗(yàn)證丟失和準(zhǔn)確性,以保存對(duì)驗(yàn)證數(shù)據(jù)執(zhí)行最佳的模型,并且如果驗(yàn)證丟失或準(zhǔn)確性未能在太多時(shí)期(重復(fù))中提高,則可能提前停止。

2. Inspect x & y Data - Inspect x&y數(shù)據(jù)

下載完成后,在下一個(gè)單元格中輸入以下代碼,然后運(yùn)行它以查看您獲得的內(nèi)容。

注意:您不必輸入以#開(kāi)頭的行。 這些是注釋,其中大部分都是為了向您展示運(yùn)行單元格時(shí)notebook應(yīng)顯示的內(nèi)容。

# Inspect x data
print('x_train shape: ', x_train.shape)
# Displays (60000, 28, 28)
print(x_train.shape[0], 'training samples')
# Displays 60000 train samples
print('x_val shape: ', x_val.shape)
# Displays (10000, 28, 28)
print(x_val.shape[0], 'validation samples')
# Displays 10000 validation samples

print('First x sample\n', x_train[0])
# Displays an array of 28 arrays, each containing 28 gray-scale values between 0 and 255
# Plot first x sample
plt.imshow(x_train[0])
plt.show()

# Inspect y data
print('y_train shape: ', y_train.shape)
# Displays (60000,)
print('First 10 y_train elements:', y_train[:10])
# Displays [5 0 4 1 9 2 1 3 1 4]

您有60,000個(gè)28×28像素的訓(xùn)練樣本和10,000個(gè)驗(yàn)證樣本。 第一個(gè)訓(xùn)練樣本是一個(gè)包含28個(gè)數(shù)組的數(shù)組,每個(gè)數(shù)組包含0到255之間的28個(gè)灰度值。查看非零值,您可以看到類似數(shù)字5的形狀。

果然,plt代碼顯示第一個(gè)訓(xùn)練樣本是手寫(xiě)的5:

y數(shù)據(jù)是一個(gè)60000元素的數(shù)組,包含訓(xùn)練樣本的正確分類:第一個(gè)訓(xùn)練樣本為5,下一個(gè)為0,依此類推。

3. Set Input & Output Dimensions - 設(shè)置輸入和輸出尺寸

輸入這兩行,然后運(yùn)行單元格以設(shè)置x輸入和y輸出的基本尺寸。

img_rows, img_cols = x_train.shape[1], x_train.shape[2]
num_classes = 10

MNIST數(shù)據(jù)項(xiàng)是28×28像素的圖像,您希望將每個(gè)數(shù)據(jù)分類為0到9之間的數(shù)字。

您可以使用x_train.shape值來(lái)設(shè)置圖像行和列的數(shù)量。 x_train.shape是一個(gè)包含3個(gè)元素的數(shù)組:

  • 0) 數(shù)據(jù)樣本數(shù):60000
  • 1) 每個(gè)數(shù)據(jù)樣本的行數(shù):28
  • 2) 每個(gè)數(shù)據(jù)樣本的列數(shù):28

4. Reshape x Data & Set Input Shape

該模型需要略有不同的“shape”的數(shù)據(jù)。 輸入以下代碼,然后運(yùn)行它。

# Set input_shape for channels_first or channels_last
if K.image_data_format() == 'channels_first':  
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_val = x_val.reshape(x_val.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:  
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_val = x_val.reshape(x_val.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

卷積神經(jīng)網(wǎng)絡(luò)認(rèn)為圖像具有寬度,高度和深度。 深度維度稱為通道,并包含顏色信息。 灰度圖像有1個(gè)通道;RGB圖像有3個(gè)通道。

TensorFlowCNTK這樣的Keras后端,期望圖像數(shù)據(jù)采用channels-last format (rows, columns, channels)channels-first format (channels, rows, columns)。 reshape函數(shù)將通道插入正確的位置。

您還可以在正確的末尾設(shè)置初始input_shape和通道。

5. Inspect Reshaped x Data

輸入下面的代碼,然后運(yùn)行它以查看形狀的變化情況。

print('x_train shape:', x_train.shape)
# x_train shape: (60000, 28, 28, 1)
print('x_val shape:', x_val.shape)
# x_val shape: (10000, 28, 28, 1)
print('input_shape:', input_shape)
# input_shape: (28, 28, 1)

TensorFlow圖像數(shù)據(jù)格式是最后一個(gè)通道,因此x_train.shapex_val.shape現(xiàn)在最后有一個(gè)新元素1。

6. Convert Data Type & Normalize Values - 轉(zhuǎn)換數(shù)據(jù)類型和規(guī)范化值

模型需要特定格式的數(shù)據(jù)值。 輸入以下代碼,然后運(yùn)行它。

x_train = x_train.astype('float32')
x_val = x_val.astype('float32')
x_train /= 255
x_val /= 255

MNIST圖像數(shù)據(jù)值的類型為uint8,范圍為[0,255],但Keras需要float32類型的值,范圍為[0,1]。

7. Inspect Normalized x Data

輸入以下代碼,然后運(yùn)行它以查看對(duì)x數(shù)據(jù)的更改。

print('First x sample, normalized\n', x_train[0])
# An array of 28 arrays, each containing 28 arrays, each with one value between 0 and 1

現(xiàn)在每個(gè)值都是一個(gè)數(shù)組,值是浮點(diǎn)數(shù),非零值介于0和1之間。

8. Reformat y Data

y數(shù)據(jù)是一個(gè)60000個(gè)元素的數(shù)組,包含訓(xùn)練樣本的正確分類,但是只有10個(gè)類別并不明顯。 輸入以下代碼,僅運(yùn)行一次以重新格式化y數(shù)據(jù)。

print('y_train shape: ', y_train.shape)
# (60000,)
print('First 10 y_train elements:', y_train[:10])
# [5 0 4 1 9 2 1 3 1 4]
# Convert 1-dimensional class arrays to 10-dimensional class matrices
y_train = np_utils.to_categorical(y_train, num_classes)
y_val = np_utils.to_categorical(y_val, num_classes)
print('New y_train shape: ', y_train.shape)
# (60000, 10)

y_train是一維數(shù)組,但該模型需要一個(gè)60000 x 10矩陣來(lái)表示10個(gè)類別。 您還必須為10000元素的y_val數(shù)組進(jìn)行相同的轉(zhuǎn)換。

9. Inspect Reformatted y Data - 檢查重新格式化的y數(shù)據(jù)

輸入以下代碼,然后運(yùn)行它以查看y數(shù)據(jù)的更改方式。

print('New y_train shape: ', y_train.shape)
# (60000, 10)
print('First 10 y_train elements, reshaped:\n', y_train[:10])
# An array of 10 arrays, each with 10 elements, 
# all zeros except at index 5, 0, 4, 1, 9 etc.

y_train現(xiàn)在是一個(gè)包含10個(gè)元素?cái)?shù)組的數(shù)組,每個(gè)數(shù)組都包含除了圖像匹配的索引之外的所有零。


Define Model Architecture - 定義模型架構(gòu)

模型架構(gòu)是煉金術(shù)的一種形式,如完美燒烤醬或garam masala的秘密家庭食譜。 您可以從通用架構(gòu)開(kāi)始,然后調(diào)整它以利用輸入數(shù)據(jù)中的對(duì)稱性,或者生成具有特定特征的模型。

以下是來(lái)自兩位研究人員的模型:Sri Raghu Malireddi和Keras作者的Fran?ois CholletChollet是通用的,Malireddi's旨在生產(chǎn)適合移動(dòng)應(yīng)用的小模型。

輸入以下代碼,然后運(yùn)行它以查看模型摘要。

1. Malireddi’s Architecture

model_m = Sequential()
model_m.add(Conv2D(32, (5, 5), input_shape=input_shape, activation='relu'))
model_m.add(MaxPooling2D(pool_size=(2, 2)))
model_m.add(Dropout(0.5))
model_m.add(Conv2D(64, (3, 3), activation='relu'))
model_m.add(MaxPooling2D(pool_size=(2, 2)))
model_m.add(Dropout(0.2))
model_m.add(Conv2D(128, (1, 1), activation='relu'))
model_m.add(MaxPooling2D(pool_size=(2, 2)))
model_m.add(Dropout(0.2))
model_m.add(Flatten())
model_m.add(Dense(128, activation='relu'))
model_m.add(Dense(num_classes, activation='softmax'))
# Inspect model's layers, output shapes, number of trainable parameters
print(model_m.summary())

2. Chollet’s Architecture

model_c = Sequential()
model_c.add(Conv2D(32, (3, 3), input_shape=input_shape, activation='relu'))
# Note: hwchong, elitedatascience use 32 for second Conv2D
model_c.add(Conv2D(64, (3, 3), activation='relu'))
model_c.add(MaxPooling2D(pool_size=(2, 2)))
model_c.add(Dropout(0.25))
model_c.add(Flatten())
model_c.add(Dense(128, activation='relu'))
model_c.add(Dropout(0.5))
model_c.add(Dense(num_classes, activation='softmax'))
# Inspect model's layers, output shapes, number of trainable parameters
print(model_c.summary())

雖然Malireddi的架構(gòu)比Chollet有更多的卷積層(Conv2D),但它的運(yùn)行速度要快得多,而且結(jié)果模型要小得多。

3. Model Summaries - 模型摘要

快速瀏覽這兩個(gè)模型的模型摘要:

model_m

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_6 (Conv2D)            (None, 24, 24, 32)        832       
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 12, 12, 32)        0         
_________________________________________________________________
dropout_6 (Dropout)          (None, 12, 12, 32)        0         
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 10, 10, 64)        18496     
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
dropout_7 (Dropout)          (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 5, 5, 128)         8320      
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 2, 2, 128)         0         
_________________________________________________________________
dropout_8 (Dropout)          (None, 2, 2, 128)         0         
_________________________________________________________________
flatten_3 (Flatten)          (None, 512)               0         
_________________________________________________________________
dense_5 (Dense)              (None, 128)               65664     
_________________________________________________________________
dense_6 (Dense)              (None, 10)                1290      
=================================================================
Total params: 94,602
Trainable params: 94,602
Non-trainable params: 0

model_c

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 26, 26, 32)        320       
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 24, 24, 64)        18496     
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 12, 12, 64)        0         
_________________________________________________________________
dropout_4 (Dropout)          (None, 12, 12, 64)        0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 9216)              0         
_________________________________________________________________
dense_3 (Dense)              (None, 128)               1179776   
_________________________________________________________________
dropout_5 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_4 (Dense)              (None, 10)                1290      
=================================================================
Total params: 1,199,882
Trainable params: 1,199,882
Non-trainable params: 0

底線Total params是尺寸差異的主要原因:Chollet的1,199,882比Malireddi的94,602多12.5倍。 而這正是模型尺寸的差異:4.8MB對(duì)380KB。

Malireddi的模型有三個(gè)Conv2D圖層,每個(gè)圖層后跟一個(gè)MaxPooling2D圖層,它將圖層的寬度和高度減半。 這使得第一個(gè)密集層的參數(shù)數(shù)量遠(yuǎn)遠(yuǎn)小于Chollet,并解釋了為什么Malireddi的模型要小得多并且訓(xùn)練速度要快得多。 卷積層的實(shí)現(xiàn)是高度優(yōu)化的,因此額外的卷積層提高了準(zhǔn)確性,而不會(huì)增加訓(xùn)練時(shí)間。 但較小的致密層比Chollet的運(yùn)行速度快得多。

在等待下一步完成運(yùn)行時(shí),我將在Explanations部分告訴您有關(guān)圖層,輸出形狀和參數(shù)編號(hào)的信息。

后記

本篇主要講述了使用Keras和Core ML開(kāi)始機(jī)器學(xué)習(xí),感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容