如何利用TensorFlow.js部署簡單的AI版「你畫我猜」圖像識別應用

2021-01-07 機器之心Pro

選自Medium,作者:Zaid Alyafeai,機器之心編譯,參與:Geek AI、路。

本文創建了一個簡單的工具來識別手繪圖像,並且輸出當前圖像的名稱。該應用無需安裝任何額外的插件,可直接在瀏覽器上運行。作者使用谷歌 Colab 來訓練模型,並使用 TensorFlow.js 將它部署到瀏覽器上。

代碼和 demo

demo 地址:https://zaidalyafeai.github.io/sketcher/代碼地址:https://github.com/zaidalyafeai/zaidalyafeai.github.io/tree/master/sketcher請通過以下連結在谷歌 Colab 上測試自己的 notebook:https://colab.research.google.com/github/zaidalyafeai/zaidalyafeai.github.io/blob/master/sketcher/Sketcher.ipynb

數據集

我們將使用卷積神經網絡(CNN)來識別不同類型的手繪圖像。這個卷積神經網絡將在 Quick Draw 數據集(https://github.com/googlecreativelab/quickdraw-dataset)上接受訓練。該數據集包含 345 個類別的大約 5 千萬張手繪圖像。

部分圖像類別

流程

我們將使用 Keras 框架在谷歌 Colab 免費提供的 GPU 上訓練模型,然後使用 TensorFlow.js 直接在瀏覽器上運行模型。我在 TensorFlow.js 上創建了一個教程(https://medium.com/tensorflow/a-gentle-introduction-to-tensorflow-js-dba2e5257702)。在繼續下面的工作之前,請務必先閱讀一下這個教程。下圖為該項目的處理流程:

流程

在 Colab 上進行訓練

谷歌 Colab 為我們提供了免費的 GPU 處理能力。你可以閱讀下面的教程(https://medium.com/deep-learning-turkey/google-colab-free-gpu-tutorial-e113627b9f5d)了解如何創建 notebook 和開始進行 GPU 編程。

導入

我們將使用以 TensorFlow 作為後端、Keras 作為前端的編程框架

import os

import glob

import numpy as np

from tensorflow.keras import layers

from tensorflow import keras

import tensorflow as tf

加載數據

由於內存容量有限,我們不會使用所有類別的圖像進行訓練。我們僅使用數據集中的 100 個類別(https://raw.githubusercontent.com/zaidalyafeai/zaidalyafeai.github.io/master/sketcher/mini_classes.txt)。每個類別的數據可以在谷歌 Colab(https://console.cloud.google.com/storage/browser/quickdrawdataset/full/numpybitmap?pli=1)上以 NumPy 數組的形式獲得,數組的大小為 [N, 784],其中 N 為某類圖像的數量。我們首先下載這個數據集:

import urllib.request

def download():

base = 'https://storage.googleapis.com/quickdraw_dataset/full/numpy_bitmap/'

for c in classes:

cls_url = c.replace('_', '%20')

path = base+cls_url+'.npy'

print(path)

urllib.request.urlretrieve(path, 'data/'+c+'.npy')

由於內存限制,我們在這裡將每類圖像僅僅加載 5000 張。我們還將留出其中的 20% 作為測試數據。

def load_data(root, vfold_ratio=0.2, max_items_per_class= 5000 ):

all_files = glob.glob(os.path.join(root, '*.npy'))

#initialize variables

x = np.empty([0, 784])

y = np.empty([0])

class_names = []

#load a subset of the data to memory

for idx, file in enumerate(all_files):

data = np.load(file)

data = data[0: max_items_per_class, :]

labels = np.full(data.shape[0], idx)

x = np.concatenate((x, data), axis=0)

y = np.append(y, labels)

class_name, ext = os.path.splitext(os.path.basename(file))

class_names.append(class_name)

data = None

labels = None

#separate into training and testing

permutation = np.random.permutation(y.shape[0])

x = x[permutation, :]

y = y[permutation]

vfold_size = int(x.shape[0]/100*(vfold_ratio*100))

x_test = x[0:vfold_size, :]

y_test = y[0:vfold_size]

x_train = x[vfold_size:x.shape[0], :]

y_train = y[vfold_size:y.shape[0]]

return x_train, y_train, x_test, y_test, class_names

數據預處理

我們對數據進行預處理操作,為訓練模型做準備。該模型將使用規模為 [N, 28, 28, 1] 的批處理,並且輸出規模為 [N, 100] 的概率。

# Reshape and normalize

x_train = x_train.reshape(x_train.shape[0], image_size, image_size, 1).astype('float32')

x_test = x_test.reshape(x_test.shape[0], image_size, image_size, 1).astype('float32')

x_train /= 255.0

x_test /= 255.0

# Convert class vectors to class matrices

y_train = keras.utils.to_categorical(y_train, num_classes)

y_test = keras.utils.to_categorical(y_test, num_classes)

創建模型

我們將創建一個簡單的卷積神經網絡。請注意,模型越簡單、參數越少越好。實際上,我們將把模型轉換到瀏覽器上然後再運行,並希望模型能在預測任務中快速運行。下面的模型包含 3 個卷積層和 2 個全連接層:

# Define model

model = keras.Sequential()

model.add(layers.Convolution2D(16, (3, 3),

padding='same',

input_shape=x_train.shape[1:], activation='relu'))

model.add(layers.MaxPooling2D(pool_size=(2, 2)))

model.add(layers.Convolution2D(32, (3, 3), padding='same', activation= 'relu'))

model.add(layers.MaxPooling2D(pool_size=(2, 2)))

model.add(layers.Convolution2D(64, (3, 3), padding='same', activation= 'relu'))

model.add(layers.MaxPooling2D(pool_size =(2,2)))

model.add(layers.Flatten())

model.add(layers.Dense(128, activation='relu'))

model.add(layers.Dense(100, activation='softmax'))

# Train model

adam = tf.train.AdamOptimizer()

model.compile(loss='categorical_crossentropy',

optimizer=adam,

metrics=['top_k_categorical_accuracy'])

print(model.summary())

擬合、驗證及測試

在這之後我們對模型進行了 5 輪訓練,將訓練數據分成了 256 批輸入模型,並且分離出 10% 作為驗證集。

#fit the model

model.fit(x = x_train, y = y_train, validation_split=0.1, batch_size = 256, verbose=2, epochs=5)

#evaluate on unseen data

score = model.evaluate(x_test, y_test, verbose=0)

print('Test accuarcy: {:0.2f}%'.format(score[1] * 100))

訓練結果如下圖所示:

測試準確率達到了 92.20% 的 top 5 準確率。

準備 WEB 格式的模型

在我們得到滿意的模型準確率後,我們將模型保存下來,以便進行下一步的轉換。

model.save('keras.h5')

為轉換安裝 tensorflow.js:

!pip install tensorflowjs

接著我們對模型進行轉換:

!mkdir model

!tensorflowjs_converter --input_format keras keras.h5 model/

這個步驟將創建一些權重文件和包含模型架構的 json 文件。

通過 zip 將模型進行壓縮,以便將其下載到本地機器上:

!zip -r model.zip model

最後下載模型:

from google.colab import files

files.download('model.zip')

在瀏覽器上進行推斷

本節中,我們將展示如何加載模型並且進行推斷。假設我們有一個尺寸為 300*300 的畫布。在這裡,我們不會詳細介紹函數接口,而是將重點放在 TensorFlow.js 的部分。

加載模型

為了使用 TensorFlow.js,我們首先使用下面的腳本:

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"> </script>

你的本地機器上需要有一臺運行中的伺服器來託管權重文件。你可以在 GitHub 上創建一個 apache 伺服器或者託管網頁,就像我在我的項目中所做的那樣(https://github.com/zaidalyafeai/zaidalyafeai.github.io/tree/master/sketcher)。

接著,通過下面的代碼將模型加載到瀏覽器:

model = await tf.loadModel('model/model.json')

關鍵字 await 的意思是等待模型被瀏覽器加載。

預處理

在進行預測前,我們需要對數據進行預處理。首先從畫布中獲取圖像數據:

//the minimum boudning box around the current drawing

const mbb = getMinBox()

//cacluate the dpi of the current window

const dpi = window.devicePixelRatio

//extract the image data

const imgData = canvas.contextContainer.getImageData(mbb.min.x * dpi, mbb.min.y * dpi,

(mbb.max.x - mbb.min.x) * dpi, (mbb.max.y - mbb.min.y) * dpi);

文章稍後將介紹 getMinBox()。dpi 變量被用於根據屏幕像素的密度對裁剪出的畫布進行拉伸。

我們將畫布當前的圖像數據轉化為一個張量,調整大小並進行歸一化處理:

function preprocess(imgData)

{

return tf.tidy(()=>{

//convert the image data to a tensor

let tensor = tf.fromPixels(imgData, numChannels= 1)

//resize to 28 x 28

const resized = tf.image.resizeBilinear(tensor, [28, 28]).toFloat()

// Normalize the image

const offset = tf.scalar(255.0);

const normalized = tf.scalar(1.0).sub(resized.div(offset));

//We add a dimension to get a batch shape

const batched = normalized.expandDims(0)

return batched

})

}

我們使用 model.predict 進行預測,這將返回一個規模為「N, 100」的概率。

const pred = model.predict(preprocess(imgData)).dataSync()

我們可以使用簡單的函數找到 top 5 概率。

提升準確率

請記住,我們的模型接受的輸入數據是規模為 [N, 28, 28, 1] 的張量。我們繪圖畫布的尺寸為 300*300,這可能是兩個手繪圖像的大小,或者用戶可以在上面繪製一個小圖像。最好只裁剪包含當前手繪圖像的方框。為了做到這一點,我們通過找到左上方和右下方的點來提取圍繞圖像的最小邊界框。

//record the current drawing coordinates

function recordCoor(event)

{

//get current mouse coordinate

var pointer = canvas.getPointer(event.e);

var posX = pointer.x;

var posY = pointer.y;

//record the point if withing the canvas and the mouse is pressed

if(posX >=0 && posY >= 0 && mousePressed)

{

coords.push(pointer)

}

}

//get the best bounding box by finding the top left and bottom right cornders

function getMinBox(){

var coorX = coords.map(function(p) {return p.x});

var coorY = coords.map(function(p) {return p.y});

//find top left corner

var min_coords = {

x : Math.min.apply(null, coorX),

y : Math.min.apply(null, coorY)

}

//find right bottom corner

var max_coords = {

x : Math.max.apply(null, coorX),

y : Math.max.apply(null, coorY)

}

return {

min : min_coords,

max : max_coords

}

}

用手繪圖像進行測試

下圖顯示了一些第一次繪製的圖像以及準確率最高的類別。所有的手繪圖像都是我用滑鼠畫的,用筆繪製的話應該會得到更高的準確率。

原文連結:https://medium.com/tensorflow/train-on-google-colab-and-run-on-the-browser-a-case-study-8a45f9b1474e

相關焦點

  • 教程 | 如何利用TensorFlow.js部署簡單的AI版「你畫我猜」圖像識別應用
    該應用無需安裝任何額外的插件,可直接在瀏覽器上運行。作者使用谷歌 Colab 來訓練模型,並使用 TensorFlow.js 將它部署到瀏覽器上。我在 TensorFlow.js 上創建了一個教程(https://medium.com/tensorflow/a-gentle-introduction-to-tensorflow-js-dba2e5257702)。在繼續下面的工作之前,請務必先閱讀一下這個教程。下圖為該項目的處理流程:
  • 關於TensorFlow,你應該了解的9件事
    我自己也是一個正在恢復正常的「學究」(很可能是外星人),但是自從它出現我就愛上了 TF 的 eager execution。強烈安利!#3:逐行構建神經網絡Keras + TensorFlow = 更容易的神經網絡構建!
  • 教程| 如何用TensorFlow在安卓設備上實現深度學習推斷
    以「Ok Google」這個功能為例:用一名用戶的聲音來訓練「Ok Google」,他的手機在接收到這個關鍵詞的時候就會被喚醒。這種小型關鍵詞檢測(small-footprint keyword-spotting,KWS)推斷通常在本地設備上運行,所以你不必擔心服務提供商隨時監聽你的聲音。而雲服務只在你發出指令後才啟動。
  • TensorFlow與PyTorch之爭,哪個框架最適合深度學習
    如果你在讀這篇文章,那麼你可能已經開始了自己的深度學習之旅。如果你對這一領域還不是很熟悉,那麼簡單來說,深度學習使用了「人工神經網絡」,這是一種類似大腦的特殊架構,這個領域的發展目標是開發出能解決真實世界問題的類人計算機。
  • 人機對戰又添新領域:這篇論文讓機器在「你畫我猜」中擊敗你
    機器之心報導SketchX 實驗室「你畫我猜」是一種廣泛流傳在不同文化中的人類通識遊戲,其形式簡單但高度體現人類的認知智慧。這種感知圖像的方式通常是孩子們快速發展認知理解能力的重要特徵之一。然而就像莫拉維克悖論 (Moravec's Paradox) 所總結的那樣,「對人類十分棘手的問題對計算機來說通常較為簡單,而對人類來說非常容易的事計算機則極難處理」。抽象感知,這種看似大多數兩歲孩童與生俱來的基本技能,對於機器智能來說則是一項巨大的挑戰。
  • TensorFlow 資源大全中文版
    使用TensorFlow來轉換莎士比亞作品和現代版本的英語 – 實現莎士比亞作品和現代版本的英語的單語轉換聊天機器人 – 一個基於深度學習的聊天機器人colornet – 使用神經網絡給灰度圖像著色圖像生成器 – Show and Tell算法實現Attention based的自動圖像生成器 – Show, Attend and
  • 玩轉TensorFlow?你需要知道這30功能
    在過去幾年,有關 TensorFlow 的知識系統佔據了我的大腦。與其它一些更新的框架相比,TensorFlow 的功能並不是很多。我對這個產品投入全心的思考並寫下了我的想法,下面是一條接一條不斷擴展的清單。對此,你準備好了嗎?
  • TensorFlow 2.0開源工具書,30天「無痛」上手
    作者 lyhue1991 表示,這本書對「人類用戶極其友善」,以「Don't let me think」為最高追求,「如果說通過學習 TensorFlow 官方文檔掌握 TensorFlow2.0 的難度大概是 9 的話,那麼通過學習本書掌握 TensorFlow2.0 的難度應該大概是 3。」
  • 如何在PyTorch和TensorFlow中訓練圖像分類模型
    介紹圖像分類是計算機視覺的最重要應用之一。它的應用範圍包括從自動駕駛汽車中的物體分類到醫療行業中的血細胞識別,從製造業中的缺陷物品識別到建立可以對戴口罩與否的人進行分類的系統。在所有這些行業中,圖像分類都以一種或另一種方式使用。他們是如何做到的呢?他們使用哪個框架?
  • TensorFlow 攜手 NVIDIA,使用 TensorRT 優化 TensorFlow Serving...
    而在本文中,我們要展示的是:以同樣的方法來運行經 TF-TRT 轉換的模型到底有多簡單。一如既往地,我們嘗試將 ResNet 模型部署到生產環境中。下文的所有案例都在配備 Titan-V GPU 的工作站上運行。
  • 人機對戰又添新領域:這篇SIGGRAPH AISA 2020論文讓機器在「你畫我...
    機器之心報導 SketchX 實驗室 「你畫我猜」是一種廣泛流傳在不同文化中的人類通識遊戲,其形式簡單但高度體現人類的認知智慧。
  • TFX 最新博文:如何使用 TensorFlow 生態系統實現快速高效的 BERT...
    這篇博客文章將向你概述如何使用 TensorFlow 生態系統來實現可伸縮、快速、高效的 BERT 部署。全文編譯如下。本文討論的方法將允許開發人員使用 TensorFlow Extended(TFX)v0.21 或更高版本來訓練 TensorFlow 模型。
  • 基於TensorFlow 、OpenCV 和 Docker 的實時視頻目標檢測
    Docker在數據科學中的應用我不在這裡描述 Tensorflow 目標檢測 API 的實現,因為相關的文檔很多。我將展示數據科學家在日常工作中如何使用 Docker。注意,我會使用 Tensorflow 的經典 ssd_mobilenet_v2_coco 模型來提高性能。
  • TensorFlow極簡教程:創建、保存和恢復機器學習模型
    繼續之前,也可以閱讀這個 Tensorflow 小入門:https://blog.metaflow.fr/tensorflow-a-primer-4b3fa0978be3#.wxlmweb8h你有必要了解這些信息,因為了解如何保存不同級別的代碼是非常重要的,這可以避免混亂無序。
  • TensorFlow極速入門
    一、前言目前,深度學習已經廣泛應用於各個領域,比如圖像識別,圖形定位與檢測,語音識別,機器翻譯等等,對於這個神奇的領域,很多童鞋想要一探究竟,這裡拋磚引玉的簡單介紹下最火的深度學習開源框架 tensorflow。
  • Tensorflow 全網最全學習資料匯總之Tensorflow 的入門與安裝【2】
    已經在圖像識別,大數據分析,語音識別和語義理解,機器翻譯等各個領域得到了廣泛應用,同時也得到了業內人士的普遍認可,成為了目前最受關注和使用率最高的開源框架之一。《TensorFlow學習筆記1:入門》連結:http://www.jeyzhang.com/tensorflow-learning-notes.html本文與上一篇的行文思路基本一致,首先概括了TensorFlow的特性,然後介紹了graph、session、variable 等基本概念的含義,以具體代碼的形式針對每個概念給出了進一步的解釋
  • TensorFlow 2.0 新鮮出爐!新版本,新架構,新特性
    這場發布會有幾大亮點:TensorFlow 2.0 Alpha版發布,用戶現在可以搶先體驗;2.0版本具有簡易性、更清晰、擴展性三大特徵,大大簡化API;提高了TensorFlow Lite和TensorFlow.js部署模型的能力;發布會還把TensorFlow目前的家底透露了一遍:目前TF在全球已經有超過4100萬的下載次數,社區有超過1800多個貢獻者
  • TensorFlow推出開發者技能證書
    產品開發人員可結合使用TensorFlow與Keras等工具構建各種應用產品。TensorFlow Hub提供大量預訓練模型。Google還推出端到端的AI雲平臺,從創意到發布,只需輕輕單擊滑鼠即可完成所有部署。此外,開發人員可以利用TensorFlow Lite等工具輕鬆將機器學習模型部署到各種設備上。
  • 分享TensorFlow Lite應用案例
    在 Kika 將 TF Mobile 部署到移動端的過程中,除了 CPU 佔用偏高,還有由於 TF Mobile 內存管理與內存保護設計的問題,導致:   內存保護機制不完善,在實際內存不是很充足的情況(尤其對於部分低端機型以及在內存消耗較大的應用,如大型手遊中彈起輸入法),容易引發內存非法操作。
  • 吳博:目標檢測集成框架在醫學圖像 AI 輔助分析中的應用 | AI 研習...
    分享主題:目標檢測集成框架在醫學圖像 AI 輔助分析中的應用分享提綱:1. 醫學圖像分析的任務類型和對象 2. 目標檢測已有框架用於醫學圖像分析的流程 3.醫學圖像分析任務類型和研究對象 醫學圖像分析的任務類型主要有:分類與識別:這是最簡單最直接的任務類型。左邊的圖是吳恩達教授之前做的一個 X 光模型,這個模型中主要做分類,判斷是否有肺炎等病症。