tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)
tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)
2024-11-22 12:31:53  作者:心疼的很  网址:https://m.xinb2b.cn/sport/vqs426915.html

选自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('_', ' ')

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

  • 毕业季最好的时光留下你的足迹(毕业季愿此去前程似锦)
  • 2024-11-22毕业季愿此去前程似锦盛夏降临毕业季也如约而至大学四年完美落幕老师的牵挂萦绕在心头你是否已准备好行囊出发长夏多暇青荫下听蝉之时长相忆起最忆莫过于师恩朝夕相处的老师殷殷嘱托既是赠语也是别离留给你们也留给自己四年来,我见证了同。
  • 南京酱板鸭二次做法(传统美食制作方法)
  • 2024-11-22传统美食制作方法主料:老湖南酱板鸭1只(酱板鸭的品质决定这道菜口味的好与坏),香干20克辅料:干锅油40克,红油20克,米酒10克,盐2克,味精3克,胡椒粉1克,芝麻2克,香油2克,姜20克,蒜瓣20克,干红椒20克。
  • 为什么经期又困又累(为什么经期特别困乏力)
  • 2024-11-22为什么经期特别困乏力为什么经期特别困乏力,以下几点你注意到了没?1、经期综合症女性在来月经的时候,由于身体的激素发生较大的改变,可能会出现烦躁、愁闷、不能很好工作或学习、疲乏、嗜睡、头痛、乳房及胸胁胀痛、不思饮食等症状,。
  • 札幌奥运(冬奥之季忆札幌)
  • 2024-11-22冬奥之季忆札幌万众瞩目的第24届北京冬奥会开幕了,首先祝愿北京冬奥会圆满举办,奥运健儿们收获满满说起往年冬季奥运会的举办地,不难让人们想到札幌这座城市1972年第11届冬奥会在北海道札幌举办,是有史以来第一次在欧美。
  • 大蒜怎么样吃有益身体(常吃大蒜的好处)
  • 2024-11-22常吃大蒜的好处大蒜含有30多种含硫化合物,因而也具有多种生物学作用,其生物学作用主要包括:抗微生物作用大蒜素对多种革兰阴性菌和阳性菌有抑制和杀灭作用,其作用与抗生素相当此外,大蒜还具有抗真菌、抗寄生虫和抗病毒等多种。
  • 西安未来五年的交通(西安的交通会是什么样)
  • 2024-11-22西安的交通会是什么样东北二环辛家庙立交(资料图片)未来五年,西安的交通会是什么样?9日,市政府常务会议审议通过的《西安市“十四五”综合交通运输发展规划》(以下简称《规划》)给出了答案:至2025年,西安将建成交通强国典范。
  • dota2莱恩玩法教程(dota2变体精灵大型攻略)
  • 2024-11-22dota2变体精灵大型攻略最近用水人上了一波分,感觉这个英雄是真的厉害用我朋友的说法就是:劣势能翻,优势无敌,还没什么天敌经常有小伙伴问我水人怎么玩,今天花点时间写篇完整的攻略这次的攻略想用一个新的形式来写,英雄属性和技能介绍。
  • 大丈夫演员表(大丈夫演员介绍)
  • 2024-11-22大丈夫演员介绍《大丈夫》是一部由彭浩翔自编自导,曾志伟、陈小春、杜汶泽、贾宗超、卢巧音、毛舜筠、原子鏸、李茏怡主演的喜剧片,于2003年09月11日在香港上映该片通过讲述四个男人背着女人“出来滚”(玩女人)的惊险故。
  • 地质罗盘使用方法(地质罗盘怎么使用)
  • 2024-11-22地质罗盘怎么使用工具/原料:罗盘一个即可一般情况下每个地区的磁偏角不一样,所以在使用之前我们需要给他调磁偏角当地球上某点磁北方向偏于正北方向的东边时,称东偏(记为+);偏于西边时,称西偏(记为-)磁偏角偏东时,转动罗。
  • 休杰克曼最新电影(休杰克曼将出演恩佐)
  • 2024-11-22休杰克曼将出演恩佐早上好!跟大家分享个搞笑视频,荷兰弟、唐尼、锤哥、星爵倾情出演的复联版《绿野仙踪》,完全没有违和感!哈哈哈哈哈哈哈哈嗝~轻松过后来看早毒吧↓【国内资讯】-《王牌特工》前传《王牌特工:源起》曝正式中字预。
  • 工业泵节能新技术(泵技术在环境保护中的应用)
  • 2024-11-22泵技术在环境保护中的应用泵技术  泵技能在环境保护中的运用:  跟着工业技能日新月异的展开,人类对资源的大规模开发运用使得环境问题日益突出,保护环境越来越遭到人们的关注,各个学科范畴各显其才,极力消除或减轻环境对人们生产和日。
  • 母亲节由来是什么(你知道母亲节的来历吗)
  • 2024-11-22你知道母亲节的来历吗传说母亲节最早是源于希腊每年一月八日,古希腊人会向希腊众神之母瑞亚致敬想必是母亲节最早的一个雏形意义是,记住我们的母亲和她的伟大再稍微近些,就是17世纪的英国了,封斋期的第四个星期天作为母亲节,这一天。