在浏览器中用KerasTensorflow.js进行图片分类

来源:微信公众号:跨端与全栈

作者:噶牛

出处:https://mp.weixin.qq.com/s?__biz=MzU4OTAwOTE4Ng==&mid=2247483830&idx=1&sn=6b5d08c45ca83d352f99454599c8f0b6


本文翻译自:Classifying images using Keras MobileNet and TensorFlow.js in Google Chrome

在这篇文章中,我们将了解如何使用Keras的MobileNet模型进行图像分类,使用 TensorFlow.js 在Google Chrome浏览器中部署,并使用该模型在浏览器中进行实时的预测。

从长远来看,成为拥有Web开发知识的Python开发人员,对于您在人工智能领域肯定是有帮助的。因为我们现在有了具备强大能力的Keras以及在web浏览器中可以使用TensorFlow.js的TensorFlow机器学习框架。

文中放了一个可以在线演示的demo,因为无法嵌入过来,所以就不放过来了。具体的实现可以参见:https://github.com/Gogul09/mobile-net-projects

Python中的基础MobileNet神经网络模型

在Keras中,MobileNet存在applications模块中。如果要预测的类别在ImageNet类别中可用,Keras使用MobileNet提供现成的图像分类。如果ImageNet类别中不存在该类别,那么有一种称为微调的方法可以为您的数据集和类调优MobileNet,我们将在另一篇教程中讨论。

与其他最先进的卷积神经网络,如:VGG16、vg19、ResNet50、InceptionV3和exception等相比,MobileNet具有许多优势。

• MobileNets是最适合移动和嵌入式视觉应用的轻量级深层神经网络。 • mobilenet基于一种流线型架构,使用深度方向的可分离卷积。 • MobileNet使用两个简单的全局超参数,有效地在精确度和延迟之间进行权衡。 • MobileNet可用于 目标检测细粒度分类人脸识别大规模地理定位 等领域。

以下是使用MobileNet相对于其他最先进的深度学习模型的优势。

• 减少了网络大小—17MB。 • 减少了参数数量-420万。 • 性能更快,对移动应用非常有用。 • 小,低延迟卷积神经网络。

比较确定的是,除了MobileNet上述的优点外,它也有些缺点。尽管MobileNet具有更小的尺寸、更小的参数和更快的性能,但它比这篇文章中讨论的其他最先进的网络会更不精确。但别担心,与其他网络相比,准确度仅略有下降。

在本教程中,我们将按照图1中所示的步骤使用TensorFlow.js。

在浏览器中用KerasTensorflow.js进行图片分类

image.png

图1 在google chrome中使用TensorFlow.js接入Keras MobileNet模型

首先,我们将编写一个简单的python脚本,使用Keras MobileNet模型对测试图像进行预测。

在将图像传入到MobileNet之前,我们需要使用4个简单的步骤来处理图像。而要做到这一点,你并不需要OpenCV。Keras在eras.preprocessing模块,以及一些基本的numpy函数 提供了所有必要的功能。你可以直接开始了~

1. 使用load_img()函数加载图像并将其转换为MobileNet的输入大小:(224,224) 2. 使用 img_to_array() 函数将图片转化为一个numpy的数组 3. 使用 np.expand_dims() 函数展开numpy数组的维数 4. 通过使用 mobilenet.preprocess_input() 函数将所有值重新缩放到区间[-1,1]来预处理图像

python代码如下,位于basic-mobile-net.py文件:

<code># 组织引入模块

import

numpy as npfrom keras.models

import

Modelfrom keras.preprocessing

import

imagefrom keras.applications

import

imagenet_utils, mobilenetimport tensorflowjs as tfjs# process an image to be mobilenet friendly 将一个图片处理为对mobilenet友好def process_image(img_path): img = image.load_img(img_path, target_size=(

224

,

224

)) img_array = image.img_to_array(img) img_array = np.expand_dims(img_array, axis=

0

) pImg = mobilenet.preprocess_input(img_array)

return

pImg# main functionif __name__ ==

'__main__'

: # path to test image test_img_path =

"G:\\git-repos\\mobile-net-projects\\dataset\\test\\test_image_1.jpg"

# process the test image pImg = process_image(test_img_path) # define the mobilenet model mobilenet = mobilenet.MobileNet() #

make

predictions on test image using mobilenet prediction = mobilenet.predict(pImg) # obtain the top

-5

predictions results = imagenet_utils.decode_predictions(prediction)

print

(results) # convert the mobilenet model into tf.js model save_path =

"output\\mobilenet"

tfjs.converters.save_keras_model(mobilenet, save_path)

print

(

"[INFO] saved tf.js mobilenet model to disk.."

)/<code>

输出为:

<code>[[('n01806143', 'peacock', 

0.9998889

), ('n01806567', 'quail',

3.463593e-05

), ('n02018795', 'bustard',

2.7573227e-05

), ('n01847000', 'drake',

1.1352683e-05

), ('n01795545', 'black_grouse',

1.0532762e-05

)]]/<code>

代码释义:

• 2-5行导入所有要使用到的函数 • 8-13行是我们用来处理图像的特殊定义,以便它变得对MobileNet友好 • 19行定义了测试图片的路径 • 22行对测试图片进行预处理 • 25行初始化MobileNet模型 • 28行使用MobileNet模型对测试图像进行预测 • 31行给出对测试图像的匹配度最高的前5个预测 • 32行打印出对测试图像的匹配最高的前5个预测 • 36-38行将Keras模型转换为Tf.js层的格式,并保存在了save_path变量指代的路径中

请确保你更改了第19行中的test_img_path的变量值以测试你自己磁盘中的映像。图2(如下所示)是我选择的测试图像,MobileNet模型以99.99%的概率准确地预测了它。很酷!:heart_eyes:

在浏览器中用KerasTensorflow.js进行图片分类

image.png

图2 输入给MobileNet模型的测试图片

酷!在我们的Python环境中,一切都能完美地工作!现在,我们将在web浏览器中使用这个经过预训练的移动网络模型。

将Keras模型转化Tf.js层的格式

在web中部署keras模型之前,我们需要将keras mobilenet python模型转换为tf.js layers的格式(我们已经在上面代码的第36-38行中做过了)。

为了在web中部署一个Keras模型,我们需要一个叫做 tensorflowjs. 的包。可以通过运行下面的命令行来安装它:

安装tensorflowjs

<code>$ pip install tensorflowjs/<code>

安装后,您可以单独运行该命令,也可以将其集成到python脚本中,如下所示(我更推荐这种)。

1、keras 模型转化为 tf.js 层的格式:

<code>$ tensorflowjs_converter /<code>

2、集成到python脚本中

<code>

import

tensorflowjs

as

tfjsdef train(...): model = keras.models.Sequential() /<code>

我们例子中的 tfjs_target_path 或 save_path ,是一个包含model.json以及一组切分权重的二进制文件 的文件夹。如果我们去观察下model.json,你将看到模型结构或图(层及其连接的描述)以及权重文件的清单。

Keras模型转为TensorFlow JS

在本教程中,我使用GitHub pages repo保存keras mobilenet模型文件。我复制了save_path(https://gogul.dev/models/mobilenet/model.json)下的整个文件夹。

这对于我们的应用程序的工作是至关重要的,因为如果您将这些模型文件托管在不同的服务器上,您的web应用程序可能会面临CORS问题(https://enable-cors.org/)。将模型文件存储在与web应用程序相同的域中是更安全和首选的方法。

让我们开始怡人的Tensorflow.js的部分吧~

您需要在网站中加载这三个javascript库。

1. IMAGENET_CLASSES变量,该变量索引了所有IMAGENET类别,可以轻松地从这里(https://github.com/tensorflow/tfjs-examples/blob/master/mobilenet/imagenet_classes.js)加载。 2. TensorFlow.js最新的资源。 3. 让js变得简单的jQuery。

index.html

<code>

<

script

type

=

"text/javascript"

src

=

"/js/imagenet_classes.js"

>

script

>

<

script

src

=

"https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"

>

script

>

<

script

type

=

"text/javascript"

src

=

"https://code.jquery.com/jquery-2.1.1.min.js"

>

script

>

/<code>

一旦加载了以上三个脚本,就可以打开一个名为mobile-net.js 的文件,他将具备使得Keras MobileNet模型在web浏览器中工作所需的所有功能。

我在教程开始时制作的用户界面结合了HTML、CSS和JavaScript代码。我们将只研究模型的部分,而不是查看每一行代码。

1、加载Keras模型到tf.js

首先,需要加载存储在你的web服务器中的Keras预训练过的模型json。为此,可以使用下面的代码片段。

下面的代码片段是一个async函数,它使用 tf.loadModel() 来加载一个keras模型json。在第17行,await意味着在不干扰UI的情况下,要求JavaScript在后台加载模型。为了查看模型加载的状态,我们还使用了一个进度条以及console.log()。

mobile-net.js

<code>let model;async function loadModel() {  

console

.log(

"model loading.."

);

//

display model loading progress box loader =

document

.getElementById(

"progress-box"

); load_button =

document

.getElementById(

"load-button"

); loader.style.display =

"block"

;

//

model name

is

"mobilenet"

modelName =

"mobilenet"

;

//

clear the model variable model =

undefined

;

//

load the model using a HTTPS request (where you have stored your model files) model =

await

tf.loadLayersModel(

'https://gogul09.github.io/models/mobilenet/model.json'

);

//

hide model loading progress box loader.style.display =

"none"

; load_button.disabled =

true

; load_button.innerHTML =

"Loaded Model"

;

console

.log(

"model loaded.."

);}/<code>

2、从磁盘上传图片

要从磁盘上载图像,可以使用下面的代码片段,该代码片段使用HTML5文件API。我使用了一个按钮来上传图像,它有一个与之相关联的change处理器。

index.html

<code>

<

input

id

=

"select-file-image"

type

=

"file"

>

/<code>

mobile-net.js

<code>// 

if

there is a change to

"Upload Image"

button, //

load

and

render the image$(

"#select-file-image"

).change(

function

()

{ renderImage(this.files[

0

]);}// renders the image which is

loaded

from disk to the img tag

function

renderImage

(file)

{ var reader = new FileReader(); reader.onload =

function

(event)

{ img_url = event.target.result; document.getElementById(

"test-image"

).src = img_url; } reader.readAsDataURL(file);}/<code>

3、使用MobileNet模型进行预测

为了使用现在已经加载进Tf.js环境的mobilenet模型进行预测,我们需要执行两个操作步骤,

1. 对输入图像进行预处理,使其对mobilenet友好。 2. 对输入图像进行预测。

3.1 对输入图像进行预处理

正如我已经提到的,输入到mobilenet的图像大小是[224, 224],并且特征在[-1,1]之间缩放。在使用模型进行预测之前,您需要执行这两个步骤(将输入图像的大小转化为[224, 224],并且将特征大小转为[-1, 1]之间)。为此,我们使用preprocessImage()函数,该函数接受image和modelName两个参数。

使用 tf.fromPixels() 可以很方便的将输入图片加载进来,使用 resizeNearestNeighbor() 调整大小,并使用toFloat()将图片中的所有值转化为浮点类型。

然后,我们使用127.5的标量值来缩放图像张量中的值,127.5是图像像素范围[0, 255]的中间值。对于图像中的每个像素值,我们减去该偏移值并除以该偏移值以达到在[-1,1]之间缩放的效果。然后使用expandDims()来扩展维度。

mobile-net.js

<code>// 对图像做预处理,以使得其对mobilenet模型友好function preprocessImage(image, modelName) {  // resize the input image to mobilenet's target size of (224, 224)  let tensor = tf.browser.fromPixels(image)    .resizeNearestNeighbor([224, 224])    .toFloat();  // if model is not available, send the tensor with expanded dimensions  if (modelName === undefined) {    return tensor.expandDims();  }   // if model is mobilenet, feature scale tensor image to range [-1, 1]  

else

if (modelName ===

"mobilenet"

) { let offset = tf.scalar(127.5); return tensor.sub(offset) .div(offset) .expandDims(); } //

else

throw an error

else

{ alert(

"Unknown model name.."

) }}/<code>

3.2 使用Tf.js模型进行预测

在对图像进行预处理后,我为Predict按钮做了一个处理程序。同样,这也是一个async函数,它使用await关键字,直到模型进行成功的预测。

使用Tf.js的模型(使用model.predict(tensor)方法)进行预测与Keras一样简单明了。为了得到预测结果,我们对model.predict(tensor)执行了data()方法。

预测的结果被映射到了一个名为results的数组中,这个数组使用了我们在本教程开始时加载的IMAGENET_CLASSES。我们还使用sort()根据概率从高到低对数组进行排序,并使用slice()只获取前5个概率。

mobile-net.js

<code>// If 

"Predict Button"

is clicked, preprocess the image and// make predictions using mobilenet$(

"#predict-button"

).click(async function () { // check if model loaded if (model == undefined) { alert(

"Please load the model first.."

) } // check if image loaded if (document.getElementById(

"predict-box"

).style.display ==

"none"

) { alert(

"Please load an image using 'Demo Image' or 'Upload Image' button.."

) } // html-image element can be given to tf.fromPixels let image = document.getElementById(

"test-image"

); let tensor = preprocessImage(image, modelName); // make predictions on the preprocessed image tensor let predictions = await model.predict(tensor).data(); // get the model's prediction results let results = Array.from(predictions) .map(function (p, i) { return { probability: p, className: IMAGENET_CLASSES[i] }; }).sort(function (a, b) { return b.probability - a.probability; }).slice(0, 5); // display the top-1 prediction of the model document.getElementById(

"results-box"

).style.display =

"block"

; document.getElementById(

"prediction"

).innerHTML =

"MobileNet prediction - "

+ results[0].className +

""

; // display top-5 predictions of the model var ul = document.getElementById(

"predict-list"

); ul.innerHTML =

""

; results.forEach(function (p) { console.log(p.className +

" "

+ p.probability.toFixed(6)); var li = document.createElement(

"LI"

); li.innerHTML = p.className +

" "

+ p.probability.toFixed(6); ul.appendChild(li); });});/<code>

至此,整个演示就结束了,你可以根据自己的情况操作起来了。我们现在在客户端浏览器中拥有了最先进的Keras预训练模型MobileNet的能力,它能够对属于ImageNet类别的图像进行预测。

请注意,mobilenet模型在浏览器中的加载速度非常快,预测速度也非常快。

参考文档

1. TensorFlow.js - Official Documentation

2. Keras - Official Documentation

3. Importing a Keras model into TensorFlow.js

4. Introduction to TensorFlow.js - Intelligence and Learning

5. TensorFlow.js: Tensors - Intelligence and Learning

6. TensorFlow.js Quick Start 7. Session 6 - TensorFlow.js - Intelligence and Learning 8. Session

7 - TensorFlow.js Color Classifier - Intelligence and Learning

9. Tensorflow.js Explained

10. Webcam Tracking with Tensorflow.js

11. Try TensorFlow.js in your browser


来源:微信公众号:跨端与全栈

作者:噶牛

出处:https://mp.weixin.qq.com/s?__biz=MzU4OTAwOTE4Ng==&mid=2247483830&idx=1&sn=6b5d08c45ca83d352f99454599c8f0b6


分享到:


相關文章: