做者|Sakshi Butala
編譯|VK
來源|Towards Data Sciencepython
在本文中,我將向你展現如何使用卷積神經網絡(CNNs)構建字母識別系統,並使用anvil.works部署。在本文的最後,你將可以建立上面所示系統。git
卷積神經網絡github
CNN實施web
Anvil集成網絡
讓咱們從理解什麼是卷積神經網絡開始。卷積神經網絡(CNN)是一種普遍應用於圖像識別和分類的神經網絡。架構
cnn是多層感知器的正則化版本。多層感知器一般是指全鏈接網絡,即一層中的每一個神經元都與下一層的全部神經元相連。機器學習
CNN由如下層組成:函數
卷積層:一個大小爲3X3或5X5的「核」被傳遞到圖像上,並計算原始像素值與內核中定義的權重的點積。而後,該矩陣經過一個激活函數「ReLu」,該函數將矩陣中的每一個負值轉換爲零。工具
池化層:「池化矩陣」的大小有2X2或4X4,經過池化減少矩陣的大小,從而只突出圖像的重要特徵。性能
共有兩種類型的池操做:
注意:CNN架構中能夠有多個卷積層和池層的組合,以提升其性能。
全鏈接層:最後的矩陣被展平成一維向量。而後將該向量輸入神經網絡。最後,輸出層是附加到圖像上的不一樣標籤(例如字母a、b、c)的機率列表。最高几率的標籤是分類器的輸出。
讓咱們經過導入Jupyter Notebook中的庫開始實現,以下所示:
import numpy as np import matplotlib.pyplot as plt from keras.preprocessing.image import ImageDataGenerator from keras.preprocessing import image import keras from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Activation import os import pickle
而後,讓咱們從a到z導入包含圖像的2個數據集,以訓練和測試咱們的模型。你能夠從下面連接的GitHub存儲庫下載數據集。
連接:https://github.com/sakshibutala/CNN_AlphabetRecognition
train_datagen = ImageDataGenerator(rescale = 1./255, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True) test_datagen = ImageDataGenerator(rescale = 1./255) train_generator = train_datagen.flow_from_directory( directory = 'Training', target_size = (32,32), batch_size = 32, class_mode = 'categorical' ) test_generator = test_datagen.flow_from_directory( directory = 'Testing', target_size = (32,32), batch_size = 32, class_mode = 'categorical' )
ImageDataGenerator生成一批張量圖像數據,經過使用rescale進行縮放,將0-255範圍內的RGB係數轉換爲0到1之間的目標值。
shear_range用於隨機應用剪切變換。
zoom_range用於在圖片內部隨機縮放。
horizontal_flip用於水平隨機翻轉一半圖像。
而後咱們使用.flow_from_directory從目錄中逐個導入圖像,並對其應用ImageDataGenerator。
而後,咱們將圖像從原始大小轉換爲目標大小,並聲明batch大小,它是指在一次迭代中使用的訓練示例的數量。
而後咱們將class_mode設置爲category,這表示咱們有多個類(a到z)能夠預測。
接下來咱們構建咱們的CNN架構。
model = Sequential() model.add(Conv2D(32, (3, 3), input_shape = (32,32,3), activation = 'relu')) model.add(MaxPooling2D(pool_size = (2, 2))) model.add(Conv2D(32, (3, 3), activation = 'relu')) model.add(MaxPooling2D(pool_size = (2, 2))) model.add(Flatten()) model.add(Dense(units = 128, activation = 'relu')) model.add(Dense(units = 26, activation = 'softmax')) model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy']) model.summary()
咱們首先建立一個Sequential模型,它容許咱們使用.add函數逐層定義CNN架構。
咱們首先在輸入圖像上添加一個帶有32個3X3大小的濾波器(核)的卷積層,並將其經過「relu」激活函數。
而後咱們使用大小爲2X2的池執行MaxPooling操做。
而後再次重複這些層以提升模型的性能。
最後,咱們將獲得的矩陣展平並經過一個由128個節點組成的全鏈接層。而後將其鏈接到由26個節點組成的輸出層,每一個節點表明一個字母表。咱們使用softmax激活將分數轉換成一個正態化的機率分佈,並選擇機率最高的節點做爲輸出。
一旦咱們的CNN架構被定義,咱們就使用adam優化器編譯模型。
最後,咱們對模型進行訓練。
model.fit_generator(train_generator, steps_per_epoch = 16, epochs = 3, validation_data = test_generator, validation_steps = 16)
模型訓練後的準確率爲:93.42%
如今讓咱們來測試咱們的模型。可是在咱們這樣作以前,咱們須要定義一個函數,它給咱們與結果相關聯的字母表。
def get_result(result): if result[0][0] == 1: return('a') elif result[0][1] == 1: return ('b') elif result[0][2] == 1: return ('c') elif result[0][3] == 1: return ('d') elif result[0][4] == 1: return ('e') elif result[0][5] == 1: return ('f') elif result[0][6] == 1: return ('g') elif result[0][7] == 1: return ('h') elif result[0][8] == 1: return ('i') elif result[0][9] == 1: return ('j') elif result[0][10] == 1: return ('k') elif result[0][11] == 1: return ('l') elif result[0][12] == 1: return ('m') elif result[0][13] == 1: return ('n') elif result[0][14] == 1: return ('o') elif result[0][15] == 1: return ('p') elif result[0][16] == 1: return ('q') elif result[0][17] == 1: return ('r') elif result[0][18] == 1: return ('s') elif result[0][19] == 1: return ('t') elif result[0][20] == 1: return ('u') elif result[0][21] == 1: return ('v') elif result[0][22] == 1: return ('w') elif result[0][23] == 1: return ('x') elif result[0][24] == 1: return ('y') elif result[0][25] == 1: return ('z')
最後,讓咱們測試一下咱們的模型:
filename = r'Testing\e\25.png' test_image = image.load_img(filename, target_size = (32,32)) plt.imshow(test_image) test_image = image.img_to_array(test_image) test_image = np.expand_dims(test_image, axis = 0) result = model.predict(test_image) result = get_result(result) print ('Predicted Alphabet is: {}'.format(result))
該模型正確地預測了輸入圖像的字母,結果爲「e」。
Anvil是一個容許咱們使用python構建全棧web應用程序的平臺。它使咱們更容易將機器學習模型從Jupyter Notebook轉換成web應用程序。
讓咱們首先在anvil上建立一個賬戶。完成後,用material design建立一個新的空白應用程序。
查看此連接,瞭解如何使用anvil的逐步教程:https://anvil.works/learn
右邊的工具箱包含全部能夠拖到網站上的組件。
所需組件:
2個標籤(標題和子標題)
圖像(顯示輸入圖像)
FileLoader(上傳輸入圖像)
突出顯示按鈕(用於預測結果)
標籤(查看結果)
拖放這些組件並根據你的要求排列它們。
要添加標題和副標題,請在右側的「屬性」部分選擇標籤和,而後轉到名爲「文本」的選項,以下所示(以紅色突出顯示),而後鍵入標題/副標題。
完成用戶界面後,進入上面所示的代碼部分(以綠色突出顯示)並建立一個新函數,以下所示
def primary_color_1_click(self, **event_args): file = self.file_loader_1.file self.image_1.source = file result = anvil.server.call('model_run',file) self.label_3.text = result pass
當咱們按下「PREDICT」按鈕時,將執行此函數。它將獲取從文件加載程序上傳的輸入圖像並將其傳遞到Jupyter Notebook的「model_run」函數。此函數將返回預測字母。
如今要作的就是把咱們的anvil網站鏈接到Jupyter Notebook。
這須要執行如下兩個步驟:
在Jupyter Notebook內粘貼如下內容:
import anvil.server import anvil.media anvil.server.connect("paste your anvil uplink key here")
建立一個「model_run」函數來預測上傳到網站中的圖像。
@anvil.server.callable def model_run(path): with anvil.media.TempFile(path) as filename: test_image = image.load_img(filename, target_size = (32,32)) test_image = image.img_to_array(test_image) test_image = np.expand_dims(test_image, axis = 0) result = model.predict(test_image) result = get_result(result) return ('Predicted Alphabet is: {}'.format(result))
如今你能夠回到anvil,點擊run按鈕,字母識別系統就徹底完成了。
你能夠在個人GitHub存儲庫中找到源代碼和數據集:https://github.com/sakshibutala/CNN_AlphabetRecognition。
原文連接:https://towardsdatascience.com/building-and-deploying-an-alphabet-recognition-system-7ab59654c676
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方文檔:
http://sklearn123.com/
歡迎關注磐創博客資源彙總站:
http://docs.panchuang.net/