RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

node.js在訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)模型識別圖像中物體的方法

zhKF_jqr_AI ? 2018-04-06 13:11 ? 次閱讀

編者按:opencv4nodejs及face-recognition.js維護者Vincent Mühler介紹了如何在Node.js環(huán)境下使用訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)模型識別圖像中的物體。

今天我們將看看Node.js的OpenCV深度神經(jīng)網(wǎng)絡(luò)模塊。

如果你希望釋放神經(jīng)網(wǎng)絡(luò)的魔力,來辨識和分類圖像中的物體,卻對深度學(xué)習(xí)是如何工作的毫無頭緒(像我一樣),更不知道如何創(chuàng)建和訓(xùn)練神經(jīng)網(wǎng)絡(luò),那么本文正適合你!

所以我們今天將創(chuàng)建什么?

在這一篇教程中,我們將了解如何通過OpenCV的DNN模塊,從Tensorflow和Caffe加載預(yù)訓(xùn)練的模型,然后我們將深入兩個基于Node.js和OpenCV進(jìn)行物體識別的例子。

首先我們將使用Tensorflow的Inception模型來辨識圖像中的物體,之后我們將使用COCO SSD模型檢測和辨識同一圖像中的多個不同物體。

你可以在我的github倉庫上找到樣例代碼:justadudewhohacks/opencv4nodejs

Tensorflow Inception

訓(xùn)練過的Tensorflow Inception模型可以辨別約1000個分類的物體。如果你將圖像傳入網(wǎng)絡(luò),它將給出圖像中的物體的每個分類的似然。

要在OpenCV下使用Inception模型,我們需要加載二進(jìn)制文件tensorflow_inception_graph.pb以及分類名稱列表imagenet_comp_graph_label_strings.txt。你可以下載inception5h.zip并解壓以獲得這些文件(下面的代碼內(nèi)有下載鏈接):

// 替換路徑為你解壓縮inception模型的路徑

const inceptionModelPath = '../data/dnn/tf-inception'

const modelFile = path.resolve(inceptionModelPath, 'tensorflow_inception_graph.pb');

const classNamesFile = path.resolve(inceptionModelPath, 'imagenet_comp_graph_label_strings.txt');

if (!fs.existsSync(modelFile) || !fs.existsSync(classNamesFile)) {

console.log('退出: 找不到inception模型');

console.log('從以下網(wǎng)址下載模型: https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip');

return;

}

// 讀取classNames(分類名稱),然后在數(shù)組中儲存它們

const classNames = fs.readFileSync(classNamesFile).toString().split(" ");

// 從modelFile初始化tensorflow inception模塊

const net = cv.readNetFromTensorflow(modelFile);

分類圖像中的物品

為了分類圖像中的物品,我們將編寫以下幫助函數(shù):

const classifyImg = (img) => {

// inception模型使用224 x 224 圖像,

// 因此我們調(diào)整輸入圖像的大小,

// 并使用白像素補齊圖像

const maxImgDim = 224;

const white = new cv.Vec(255, 255, 255);

const imgResized = img.resizeToMax(maxImgDim).padToSquare(white);

// 網(wǎng)絡(luò)接受blob作為輸入

const inputBlob = cv.blobFromImage(imgResized);

net.setInput(inputBlob);

// 前向傳播輸入至整個網(wǎng)絡(luò),

// 將返回包含每個分類的置信度的1xN矩陣分類結(jié)果

const outputBlob = net.forward();

// 找到大于最小置信度的所有標(biāo)簽

const minConfidence = 0.05;

const locations =

outputBlob

.threshold(minConfidence, 1, cv.THRESH_BINARY)

.convertTo(cv.CV_8U)

.findNonZero();

const result =

locations.map(pt => ({

confidence: parseInt(outputBlob.at(0, pt.x) * 100) / 100,

className: classNames[pt.x]

}))

// 根據(jù)置信度排序

.sort((r0, r1) => r1.confidence - r0.confidence)

.map(res => `${res.className} (${res.confidence})`);

return result;

}

這一函數(shù)做了這些事:

準(zhǔn)備輸入圖像

Tensorflow Inception網(wǎng)絡(luò)接受224x224大小的輸入圖像。因此我們調(diào)整圖像大小,使其最大邊的大小為224,然后用白像素補齊。

讓圖像穿過網(wǎng)絡(luò)

我們可以直接從圖像創(chuàng)建blob,然后調(diào)用net.forward()前向傳播輸入,然后獲取輸出blob.

從輸出blob提取結(jié)果

為了通用性,輸出blob的表達(dá)形式直接是矩陣(cv.Mat),而它的維度取決于模型。在Inception下這很簡單。blob不過是一個1xN矩陣(其中N等于分類數(shù)),描述了所有分類的概率分布。每個條目為一個浮點數(shù),表示相應(yīng)分類的置信度。所有條目相加,總和為1.0(100%)。

我們想仔細(xì)看看圖像可能性最大的分類,因此我們查看所有置信度大于minConfidence(這個例子中是5%)。最后,我們根據(jù)置信度排序結(jié)果,并返回className、confidence對。

測試

現(xiàn)在我們將讀取一些我們希望網(wǎng)絡(luò)辨識的樣本數(shù)據(jù):

const testData = [

{

image: '../data/banana.jpg',

label: 'banana'

},

{

image: '../data/husky.jpg',

label: 'husky'

},

{

image: '../data/car.jpeg',

label: 'car'

},

{

image: '../data/lenna.png',

label: 'lenna'

}

];

testData.forEach((data) => {

const img = cv.imread(data.image);

console.log('%s: ', data.label);

const predictions = classifyImg(img);

predictions.forEach(p => console.log(p));

console.log();

cv.imshowWait('img', img);

});

輸出為:(你可以參考本文開頭的圖片)

banana:

banana (0.95)

husky:

Siberian husky (0.78)

Eskimo dog (0.21)

car:

sports car (0.57)

racer (0.12)

lenna:

sombrero (0.34)

cowboy hat (0.3)

很有趣。我們得到了愛基斯摩犬和香蕉圖像非常準(zhǔn)確的描述。對于汽車圖像而言,汽車的具體類別不太準(zhǔn),但模型確實辨識出了圖像中的汽車。當(dāng)然,網(wǎng)絡(luò)不可能在無限的分類上進(jìn)行訓(xùn)練,因此它沒有為最后一張圖像返回“婦女”描述。然而,它確實辨識出了帽子。

COCO SSD

好,模型表現(xiàn)不錯。但是我們?nèi)绾翁幚戆鄠€物體的圖像呢?為了辨識單一圖像中的多個物體,我們將利用單圖多盒檢測器(Single Shot Multibox Detector, SSD)。在我們的第二個例子中,我們將查看一個在COCO(Common Object in Context)數(shù)據(jù)集上訓(xùn)練的SSD模型。我們使用的這一模型在84個不同分類上訓(xùn)練過。

這一模型來自Caffe,因此我們將加載二進(jìn)制文件VGG_coco_SSD_300x300_iter_400000.caffemodel,以及protoxt文件deploy.prototxt:

// 替換路徑為你解壓縮coco-SSD模型的路徑

const ssdcocoModelPath = '../data/dnn/coco-SSD_300x300'

const prototxt = path.resolve(ssdcocoModelPath, 'deploy.prototxt');

const modelFile = path.resolve(ssdcocoModelPath, 'VGG_coco_SSD_300x300_iter_400000.caffemodel');

if (!fs.existsSync(prototxt) || !fs.existsSync(modelFile)) {

console.log('退出: 找不到ssdcoco模型');

console.log('從以下網(wǎng)址下載模型 https://drive.google.com/file/d/0BzKzrI_SkD1_dUY1Ml9GRTFpUWc/view');

return;

}

// 從prototxt和modelFile初始化ssdcoco模型

const net = cv.readNetFromCaffe(prototxt, modelFile);

基于COCO分類

我們的分類函數(shù)和基于Inception的分類函數(shù)幾乎一樣,不過這次輸入將是300x300的圖像,而輸出將是1x1xNx7矩陣。

const classifyImg = (img) => {

const white = new cv.Vec(255, 255, 255);

// ssdcoco模型接受300 x 300圖像

const imgResized = img.resize(300, 300);

// 網(wǎng)絡(luò)接受blob作為輸入

const inputBlob = cv.blobFromImage(imgResized);

net.setInput(inputBlob);

// 前向傳播輸入至整個網(wǎng)絡(luò),

// 將返回1x1xNxM矩陣作為分類結(jié)果

let outputBlob = net.forward();

// 提取NxM矩陣

outputBlob = outputBlob.flattenFloat(outputBlob.sizes[2], outputBlob.sizes[3]);

const results = Array(outputBlob.rows).fill(0)

.map((res, i) => {

const className = classNames[outputBlob.at(i, 1)];

const confidence = outputBlob.at(i, 2);

const topLeft = new cv.Point(

outputBlob.at(i, 3) * img.cols,

outputBlob.at(i, 6) * img.rows

);

const bottomRight = new cv.Point(

outputBlob.at(i, 5) * img.cols,

outputBlob.at(i, 4) * img.rows

);

return ({

className,

confidence,

topLeft,

bottomRight

})

});

return results;

};

我不是很清楚為何輸出是1x1xNx7矩陣,不過我們實際上只關(guān)心Nx7部分。我們可以使用flattenFloat工具函數(shù)映射第三、第四維至2D矩陣。與Inception輸出矩陣相比,這次N不對應(yīng)每個分類,而是檢測到的每個物體。另外,每個物體對應(yīng)7個條目。

為什么是7個條目?

記住,這里我們遇到的問題和之前有點不一樣。我們想要檢測單張圖像中的多個物體,因此我們不可能僅僅給出每個分類的置信度。我們實際上想要得到的是一個指示每個物體在圖中的位置的矩形。7個條目分別為:

我其實毫無頭緒

物體的分類標(biāo)簽

分類的置信度

矩形左端的x

矩形底部的y

矩形右端的x

矩形頂部的y

輸出矩陣給了我們不少關(guān)于結(jié)果的信息,這看起來相當(dāng)整潔。我們同樣可以根據(jù)置信度再次過濾結(jié)果,并為每個辨識出的物體在圖像中繪制邊框。

看看它的效果!

出于行文的簡潔,我將跳過繪制矩形的代碼,以及其他可視化的代碼。如果你想知道具體是怎么做的,可以訪問前面提到的github倉庫。

讓我們傳入一張汽車圖像到網(wǎng)絡(luò),然后過濾結(jié)果,看看是否檢測到了car分類:

很棒!下面提高一下難度。讓我們試下……一張早餐桌?

很不錯!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴

原文標(biāo)題:當(dāng)Node.js遇上OpenCV深度神經(jīng)網(wǎng)絡(luò)

文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    當(dāng)訓(xùn)練好神經(jīng)網(wǎng)絡(luò)用于應(yīng)用的時候,權(quán)值是不是不能變了?

    當(dāng)訓(xùn)練好神經(jīng)網(wǎng)絡(luò)用于應(yīng)用的時候,權(quán)值是不是不能變了????就是已經(jīng)訓(xùn)練好神經(jīng)網(wǎng)絡(luò)是不是相當(dāng)于得到一個公式了,權(quán)值不能變了
    發(fā)表于 10-24 21:55

    請問Labveiw如何調(diào)用matlab訓(xùn)練好神經(jīng)網(wǎng)絡(luò)模型呢?

    matlab訓(xùn)練好了一個神經(jīng)網(wǎng)絡(luò)模型,想在labview調(diào)用,請問應(yīng)該怎么做呢?或者la
    發(fā)表于 07-05 17:32

    MATLAB訓(xùn)練好神經(jīng)網(wǎng)絡(luò)移植到STM32F407上

    MATLAB中進(jìn)行了神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練,然后將訓(xùn)練好模型的閾值和權(quán)值導(dǎo)出來,移植到STM32
    發(fā)表于 06-16 11:14

    基于深度神經(jīng)網(wǎng)絡(luò)的激光雷達(dá)物體識別系統(tǒng)

    的激光雷達(dá)物體識別技術(shù)一直難以嵌入式平臺上實時運行。經(jīng)緯恒潤經(jīng)過潛心研發(fā),攻克了深度神經(jīng)網(wǎng)絡(luò)嵌入式平臺部署所面臨的算子定制與加速、量化策
    發(fā)表于 12-21 07:59

    圖像預(yù)處理和改進(jìn)神經(jīng)網(wǎng)絡(luò)推理的簡要介紹

    為提升識別準(zhǔn)確率,采用改進(jìn)神經(jīng)網(wǎng)絡(luò),通過Mnist數(shù)據(jù)集進(jìn)行訓(xùn)練。整體處理過程分為兩步:圖像預(yù)處理和改進(jìn)神經(jīng)網(wǎng)絡(luò)推理。
    發(fā)表于 12-23 08:07

    卷積神經(jīng)網(wǎng)絡(luò)模型發(fā)展及應(yīng)用

    network,DBN)[24], 從此拉開了深度學(xué)習(xí)大幕。隨著深度學(xué)習(xí)理論的研究和發(fā)展,研究人員提 出了一系列卷積神經(jīng)網(wǎng)絡(luò)模型。為了比較不同模型 的質(zhì)量,收集并整理了文獻(xiàn)
    發(fā)表于 08-02 10:39

    卷積神經(jīng)網(wǎng)絡(luò)簡介:什么是機器學(xué)習(xí)?

    ,用于描述網(wǎng)絡(luò)的方程也有 32 個偏差和 32 個權(quán)重。CIFAR神經(jīng)網(wǎng)絡(luò)是一種廣泛用于圖像識別任務(wù)的CNN。它由兩種主要類型的層組成:卷積層和池化層,它們
    發(fā)表于 02-23 20:11

    node.jsjs要點總結(jié)

    (Non-blocking)或異步I/O 由于Node.js一個服務(wù)器端框架,所以它主要工作之一是處理瀏覽器請求。傳統(tǒng)的I/O系統(tǒng),每個請求的發(fā)出都是在上一請求到達(dá)之后才發(fā)出的。所以這被稱為阻塞
    發(fā)表于 10-13 10:39 ?0次下載

    介紹Node.js應(yīng)用全鏈路信息獲取的方法

    這種技術(shù),就是Node.js應(yīng)用全鏈路追蹤。它是 Node.js 涉及到復(fù)雜服務(wù)端業(yè)務(wù)場景,必不可少的技術(shù)保障。
    的頭像 發(fā)表于 02-10 11:21 ?631次閱讀

    node.js實戰(zhàn)源碼

    node.js實戰(zhàn)源碼
    發(fā)表于 05-16 18:06 ?1次下載

    卷積神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練步驟

    卷積神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練步驟? 卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network, CNN)是一種常用的深度學(xué)習(xí)算法,廣泛應(yīng)用于
    的頭像 發(fā)表于 08-21 16:42 ?1705次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)如何識別圖像

    多層卷積層、池化層和全連接層。CNN模型通過訓(xùn)練識別并學(xué)習(xí)高度復(fù)雜的圖像模式,對于識別物體和進(jìn)行
    的頭像 發(fā)表于 08-21 16:49 ?1924次閱讀

    神經(jīng)網(wǎng)絡(luò)圖像識別的應(yīng)用

    隨著人工智能技術(shù)的飛速發(fā)展,神經(jīng)網(wǎng)絡(luò)圖像識別領(lǐng)域的應(yīng)用日益廣泛。神經(jīng)網(wǎng)絡(luò)以其強大的特征提取和分類能力,為圖像識別帶來了革命性的進(jìn)步。本文將
    的頭像 發(fā)表于 07-01 14:19 ?669次閱讀

    MATLAB如何使用訓(xùn)練好網(wǎng)絡(luò)

    引言 本文中,我們將探討如何在MATLAB中使用訓(xùn)練好神經(jīng)網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)是一種強大的機器學(xué)習(xí)技術(shù),廣泛應(yīng)用于圖像識別、自然語言處理、預(yù)測
    的頭像 發(fā)表于 07-03 10:06 ?1108次閱讀

    怎么對神經(jīng)網(wǎng)絡(luò)重新訓(xùn)練

    重新訓(xùn)練神經(jīng)網(wǎng)絡(luò)是一個復(fù)雜的過程,涉及到多個步驟和考慮因素。 引言 神經(jīng)網(wǎng)絡(luò)是一種強大的機器學(xué)習(xí)模型,廣泛應(yīng)用于圖像識別、自然語言處理、語音
    的頭像 發(fā)表于 07-11 10:25 ?449次閱讀
    RM新时代网站-首页