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

选自Medium,作者:Zaid Alyafeai,机器之心编译,参与:Geek AI、路。

本文创建了一个简单的工具来识别手绘图像,并且输出当前图像的名称。该应用无需安装任何额外的插件,可直接在浏览器上运行。作者使用谷歌 Colab 来训练模型,并使用 TensorFlow.js 将它部署到浏览器上。

tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)(1)

代码和 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 千万张手绘图像。

tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)(2)

部分图像类别

流程

我们将使用 Keras 框架在谷歌 Colab 免费提供的 GPU 上训练模型,然后使用 TensorFlow.js 直接在浏览器上运行模型。我在 TensorFlow.js 上创建了一个教程(https://medium.com/tensorflow/a-gentle-introduction-to-tensorflow-js-dba2e5257702)。在继续下面的工作之前,请务必先阅读一下这个教程。下图为该项目的处理流程:

tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)(3)

流程

在 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))

训练结果如下图所示:

tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)(4)

测试准确率达到了 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

}

}

用手绘图像进行测试

下图显示了一些第一次绘制的图像以及准确率最高的类别。所有的手绘图像都是我用鼠标画的,用笔绘制的话应该会得到更高的准确率。

tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)(5)

tensorflow图像分类构建过程(如何利用TensorFlow.js部署简单的AI版)(6)

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

  • 我好方是什么梗(我好方解释)
  • 2024-07-03我好方解释“我好方”是“我好慌”谐音的说法,调侃f、h分的不太清楚的一种说法,意思为当遇到某些烦恼和懵逼的境况的时候的一种比较调侃的说法,类似于“宝宝心里苦”的含义除此之外,“我好方”一词也被用作“我有点方”的。
  • 公鸡怎么吃(公鸡的功效)
  • 2024-07-03公鸡的功效小仔鸡750克一1000克、蘑菇75克调料:葱、姜、干红辣椒、大料、酱油、料酒、盐、糖、食用油做法:将小仔鸡洗净,剁成小块;将蘑菇用温水泡30分钟,洗净待用;坐锅烧热,放入少量油,待油热后放入鸡块翻炒。
  • 腾讯历年财报一览表(腾讯影业公布12部片单)
  • 2024-07-03腾讯影业公布12部片单蓝鲸娱乐9月17日文:今日,腾讯影业举行“新探索·共生长”成立一周年发布会,并公布腾讯影业2017年重点项目片单去年今日,腾讯互娱宣布成立全资子公司——腾讯影业至此,腾讯影业、腾讯游戏、腾讯动漫、阅文。
  • 吉林工商学院筑牢安全防线(吉林工商学院筑牢安全防线)
  • 2024-07-03吉林工商学院筑牢安全防线秋日的校园晴空万里,秋风习习,按照“错区域、错层次、错时、错峰”开学返校要求,8月27日、28日、29日,吉林工商学院学生分批次顺利安全返校为确保师生安全平稳返校,学校积极贯彻落实吉林省关于疫情防控的。
  • 互通式立交和高架桥的区别(什么是立交桥)
  • 2024-07-03什么是立交桥立交桥全称是立体交叉桥,主要是在城市重要交通交汇点建立的上下分层、多方向行驶、互不相扰的陆地桥高架桥是指具有高支撑的塔或支柱,跨过山谷、河流、道路或其他低处障碍物的桥梁高架桥与立交桥本无本质区别,只是。
  • 圣诞节送女孩什么花比较好(圣诞节要表白的看过来)
  • 2024-07-03圣诞节要表白的看过来每年的圣诞节都会有开不了口的男生借由向女神表白,在这个节日送礼寓意着平安和新的开始,被拒绝也不尴尬,反正这不是情人节非黑即白的抉择时刻本期推荐7种小众又时髦的圣诞花材,带你快速了解今年的圣诞趋势1.玫。
  • 高度近视如何选合适的眼镜(近视患者的苦恼)
  • 2024-07-03近视患者的苦恼随着我们每天接触越来越长时间的电子产品,长时间近距离的盯着手机电脑眼睛终于不堪重负,产生了不可逆的结果——近视此时我们后悔莫及没有好好珍惜眼睛这一至宝,使它蒙尘亡羊补牢,为时未晚我们通常会去眼镜店去配。
  • 安卓平板电脑和ipad哪个好(最强大屏手游机)
  • 2024-07-03最强大屏手游机本月拯救者陆续预热了多款待发布新品:拯救者手机系列拯救者Y90、拯救者平板系列拯救者Y700游戏8英寸平板、拯救者PC系列拯救者Y9000P等,今天拯救者Y700平板有更多消息据官方预热,拯救者Y70。
  • 低压断路器安装要注意什么(低压断路器安装要注意哪些方面)
  • 2024-07-03低压断路器安装要注意哪些方面首先安装前,应检查低压断路器铭牌上所列的技术参数是否符合使用要求低压断路器应垂直安装,板前接线的低压断路器允许安装在金属支架上或金属底板上,但板后接线的低压断路器必须安装在绝缘底板上固定低压断路器的支。
  • 洗手液可以用来洗碗吗(洗手液是否可以用来洗碗)
  • 2024-07-03洗手液是否可以用来洗碗洗手液不可用来洗碗,因为洗手液和洗洁精的配方不一样,而洗手液里有许多化工的强碱性和杀菌等原料成分,而这种原料成分不适应洗碗,虽然能够洗干净碗,但是它的残留物,吸附在碗上不一定能彻底清除任何东西还是对症。
  • 陈晓嫌赵丽颖太要强(不管是前男友还是前同事)
  • 2024-07-03不管是前男友还是前同事死丫头于正又作妖了5号这天他发微博称正构思一个时装剧单元,本来谁也不care他的脑洞小作文,但「取材于真实故事」几个大字成功引起了吃瓜群众的注意单看故事剧情没什么新意,但于妈既然说了取材真实故事,男女。
  • 普通马桶与墙排马桶哪个好(入墙式马桶好还是地排式马桶好)
  • 2024-07-03入墙式马桶好还是地排式马桶好小编知道装修确实有很多需要想,需要去琢磨,考虑的地方毕竟装修不是小事,而且涉及到几十年家居使用的大事所以我们一般在做一个小决定都要思考半天才会去做对于卫浴方面大家也是会经常去想和设计的,今天小编就为大。