投稿日:2021年7月3日
この記事ではKerasに用意された訓練済のモデルEfficientNetをTensorflow.js用に出力し、それをNext.js + TypeScriptのアプリケーション上で読み込んで分類をする方法について詳しく解説しています。
この記事はPart1の続編で、Next.js + TypeScript + Tensorflow.jsで機械学習のWebアプリケーションを作成してみよう、のPart2です。
今回はKerasに用意された訓練済のモデルEfficientNetをTensorflow.js用に出力し、それをNext.js + TypeScriptのアプリケーション上で読み込んで分類をしてみましょう。
この記事の内容はNext.js、TypeScript、Tensorflow.jsになれることが目的であり、ベストプラクティスでは無いことに注意してください。
この記事では以下の環境を前提としています。
まずはtensorflow + Keras + JupyterNotebookの環境を用意します。今回はDocker、DockerComposeを使ってみることにします。
イメージはtensorflowのものを使用します。このイメージはJupyterNotebookをデフォルトでサポートしているので非常に便利です。
ではDockerCompose用の定義ファイルを作成しましょう!
version: "3"
services:
keras_app:
image: tensorflow/tensorflow:2.4.2-jupyter
volumes:
- ./keras_app/notebooks:/tf/notebooks
ports:
- 8888:8888
ここではホスト(ローカルPC)の./keras_app/notebooksというディレクトリをコンテナの/tf/notebooksというディレクトリにマウントしています。
コンテナの/tf/notebooksディレクトリはtensorflow/tensorflowのDockerイメージがJupyterNotebookのデフォルトのルートとして指定しているディレクトリです。つまり、そこにマウントすることでJupyterNotebook上で生成したファイルをホストの./keras_app/notebooksにそのまま同期できるというわけです。
では起動させてみましょう。
$ sudo docker-compose up -d
出力されるurlにアクセスすると以下の様にJupyter Notebookのページにアクセスできます。
では動作のテストをしてみます。
New > Python3
で新規ノートブックを開始できます。
ノートブックを開始できたら以下のコードをコピペして実行(Shift+ Enter)してみましょう。
import numpy as np
import tensorflow as tf
from tensorflow import keras
問題なく実行できていればKeras環境の構築は完了です!
機械学習ライブラリKerasには訓練済のニューラルネットワークモデルが用意されています。今回はこの中からEfficientNetを使ってみます。
from tensorflow.keras.applications import EfficientNetB0
# モデルをインスタンス化
model = EfficientNetB0(weights = "imagenet")
これだけでモデルの構築は完了です!
構造を見てみましょう。
構造を見るにはモデルインスタンスのsummary()メソッドを呼び出します。
model.summary()
Model: "efficientnetb0"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_5 (InputLayer) [(None, 224, 224, 3) 0
__________________________________________________________________________________________________
rescaling_3 (Rescaling) (None, 224, 224, 3) 0 input_5[0][0]
__________________________________________________________________________________________________
normalization_3 (Normalization) (None, 224, 224, 3) 7 rescaling_3[0][0]
[...]
top_dropout (Dropout) (None, 1280) 0 avg_pool[0][0]
__________________________________________________________________________________________________
predictions (Dense) (None, 1000) 1281000 top_dropout[0][0]
==================================================================================================
Total params: 5,330,571
Trainable params: 5,288,548
Non-trainable params: 42,023
これを見ると入力は(None, 224, 224, 3)、出力は(None, 1000)となっています。これは入力が224×224のRGB(3次元)画像、出力は1000次元のクラスタリングということを意味しています。
Noneは同時に読み込む入力が不定数であることを意味しています(同時に複数の枚数の画像を読み込める)。
pythonのKerasのモデルをそのままJavaScriptのTensorflowで読み込むことはできません。
modelをtensorflow.jsに読み込める形で生成しましょう。
tensorflow.js用のモデルの生成にはtensorflowjsというpythonパッケージが必要になります。
JupyterNotebookでは以下の様に!をつけることでNotebook上からシェルコマンドを実行できます。
今回はこれを使ってインストールしてみましょう。
!pip install tensorflowjs
ではこのパッケージを使ってモデルを生成してみましょう。
# pythonコードでjsモデルを出力
import tensorflowjs as tfjs
# tfjs_modelsディレクトリにモデルデータを出力
tfjs.converters.save_keras_model(model, "tfjs_models")
これでコンテナの/tf/notebooks/、そしてそこにマウントされているホストの./keras_app/notebooksにtfjs_modelsというディレクトリが作成され、そこにtensorflow.js用のモデルとパラメータ用データが生成されました。
ローカルPCのワーキングディレクトリを確認すると、以下のようなファイル群の生成が確認できると思います。
./keras_app/notebooks
└── tfjs_models
├── group1-shard10of25.bin
├── group1-shard11of25.bin
︙
├── group1-shard9of25.bin
└── model.json
ではいよいよWebアプリケーションの作成に入ります!
ここではNext.js+TypeScriptでアプリケーションを作成しましょう。
$ mkdir next_app
$ cd next_app
$ npm init
$ npx create-next-app --typescript app
次に、先程生成したtensorflow.js用に変換した訓練済EfficientNetモデルデータをブラウザ上で読み取らせる方法について考えましょう。方法はいくつかありますが、今回はサーバーから静的ファイルとして配信する方法でやってみましょう。
Next.jsで静的ファイルを配信するためにはpublicディレクトリに対象ファイルを配置します。
$ cp -r -f ./keras_app/notebooks/tfjs_models ./next_app/app/public
↑ここではコマンドで移動しましたが、普通に画面上からコピー&ペーストでOKです!
さあ、配信設定が問題なくできているか確認してみましょう。
$ npm run dev
この状態でブラウザからhttp://localhost:3000/tfjs_models/model.jsonにアクセスしてみてください。
以下のようにmodel.json内の内容が表示されましたか?
されていれば設定は完璧です!
次にブラウザ上でモデルを読み込みんでみます。
ブラウザ上でtensorflow.jsを実行するには@tensorflow/tfjsパッケージが必要になります。
まずはこれをインストールしましょう。
$ cd app
$ npm install --save @tensorflow/tfjs
では静的サーバーから訓練済EfficientNetのモデルを読み込んで見ましょう。
import * as tf from '@tensorflow/tfjs';
import { useState, useEffect, useRef} from "react";
export default function Home() {
// Modelをstateで定義
const [model, setModel] = useState<tf.LayersModel|null>(null);
// TODO:デバッグ情報は公開時には消去
// modelが読み込めたらコンソールに情報を出力
useEffect(()=>{
console.log(model);
},[model]);
// モデルは一度だけ読み込む
useEffect(()=>{
// モデルを静的サーバーから読み込む
tf.loadLayersModel('/tfjs_models/model.json').then(model => {
// stateにセット
setModel(model);
});
},[]);
return (
<div>
{model==null ? "読み込み中です…" : "準備完了しました…"}
</div>
)
}
このコンポーネントの中ではtensorflow.jsのモデルをmodelという名前でstateで定義しています。モデルの読み込みにはloadLayersModel()というメソッドを使います。このメソッドは非同期なので読み込みが終わったタイミングでthen()内のsetModel()が実行され、モデルがmodel変数にセットされます。
アプリケーションを実行してブラウザの開発者ツールなどで確認してみると下のようにモデルの内容が確認できると思います。
問題なくモデルの読み込みまで完了できました!
では最後にカメラの入力を受け取り、先程読み込んだ訓練済モデルでの推論を自動的に行うコンポーネントを作成してみましょう。
import * as tf from '@tensorflow/tfjs';
import { useState, useEffect, useRef } from "react";
export default function Home() {
// [ ref ] ビデオを参照するRef
const videoRef = useRef<HTMLVideoElement>(null);
// [ state ] 訓練済NNモデル
const [model, setModel] = useState<tf.LayersModel|null>();
// [ state ] 推論の結果
const [predictionResult, setPredictionResult] = useState<number>(0);
// モデルは初回一度だけ読み込む
useEffect(()=>{
// モデルを静的サーバーから読み込む
tf.loadLayersModel('/tfjs_models/model.json').then(model => {
// stateにセット
setModel(model);
});
},[]);
/**
* ビデオの読み込み、モデルの読み込みが完了したら推論スタート
*/
useEffect(()=>{
if(videoRef.current == null || model == null){
return;
}
// <video>の参照を取得
let video = videoRef.current;
// <video>にカメラのストリームを入力
getVideo(video).then(video => {
//<video>への入力が完了したら推論
video.onloadeddata = () => {
// 初回に1回だけ推論
execEstimate(video, model);
// 推論を1秒ごとにスケーリング
setInterval(() => {
execEstimate(video, model);
},1000);
}
});
},[model, videoRef]);
/**
* カメラの入力をvideoに流し込む
* 今回のNNモデルの入力は224 * 224 * 3なのでそれに合わせる
*/
const getVideo = (video: HTMLVideoElement):Promise<HTMLVideoElement> => {
console.log("getVideo");
return navigator.mediaDevices
.getUserMedia({ video: { width: 224, height: 224 } })
.then(stream => {
video.srcObject = stream;
video.play();
return video;
})
};
/**
* 推論の実行
* @returns
*/
const execEstimate = (video:HTMLVideoElement, model:tf.LayersModel): void => {
// <video>に出力されている画像をTensorとして取得
let input = tf.browser.fromPixels(video);
// Batch=1(1枚の画像のみ)の入力を生成
let inputReshaped = input.reshape([1,224,224,3]);
// モデルで推論
let prediction = model.predict(inputReshaped) as tf.Tensor<tf.Rank>;
// 出力は0~1の値なので、0~100の値に変更
let predictionHundredFold = prediction.dataSync<"float32">().map((value, index, array) => {
return value * 100;
});
let predictionArgMax = tf.argMax(predictionHundredFold).dataSync<"int32">();
setPredictionResult(predictionArgMax[0]);
}
return (
<div>
<video ref={videoRef}></video>
{model==null ? "読み込み中です…" : `推測ラベル:${predictionResult}`}
</div>
)
}
ここでは新しくvideoRefという<video>へのrefと、訓練済NNモデルで推論した結果を値として保持するpredictionResultというstateを定義しました。
<video>への参照をrefとして定義することで、この変数越しに好きなタイミングで<video>の値を読み取ることができます。
predictionResultはmodelの出力をそのまま保持するのではなく、modelの出力配列のうち最も値の大きなクラスのインデックス(0~999)を保持します。
<video>はもともと動画を埋め込むためのタグで、それ自身にカメラの入力を受け取る機能が実装されているわけではありません。そこでgetVideo()でカメラの入力を受け取り、それをそのまま<video>に流す処理が実装してあります。
execEstimate()がモデルから推論を行う関数です。ここについて、詳しく解説すると長くなるので、今回は
『へ〜。こう書くとなんか推論できるんだ〜。』
程度に考えてください。
開発用サーバーを起動して実行するとカメラが起動して推論がスタートします。
試しにバナナを見せてみました。
動いた!!
バナナは818あたりに分類されていそうですね!
※もちろん、実際にこのモデルの訓練データにバナナが含まれているかどうかはわかりません。訓練済モデルは一般的にそのまま使うことはなく、途中の層のパラメータや転移学習をしてからの分類が一般的です。
※今回のアプリケーションをそのままサーバーにデプロイして動かすと、訓練済モデルのダウンロードに毎回100MBくらいダウンロードしてしまいます。当然そのようなWebアプリは適切な設計ではありません。
Септик в подарок https://красивые-дома-приморья.рф/vypolnennye-proekty/photo/lenovo-2173
Спецпредложение https://красивые-дома-приморья.рф/vypolnennye-proekty/photo/img_20230412_161955_123
Этажность: 1 этаж Срок строительства: от 4 мес https://красивые-дома-приморья.рф/vypolnennye-proekty/photo/img_20200312_112055
Проект ГБД-178 https://красивые-дома-приморья.рф/vypolnennye-proekty/photo/img-20230723-wa0063
Строим из оцилиндрованного бревна и профилированного бруса https://красивые-дома-приморья.рф/demontazh-zdaniya
Стоимость строительства от 4 513 000 руб https://красивые-дома-приморья.рф/poleznaya-informaciya/post/stroitelstvo-doma-zimoj
Площадь 97 https://красивые-дома-приморья.рф/vypolnennye-proekty/photo/img_20200312_112056
3 м?
Обучалась в ППИЭ на курсе – Мастер маникюра и педикюра https://москва-курсы.рф/articles/kyrsu-nanoplastiki-volos/
https://москва-курсы.рф/главная/курсы-косметологов/
Здесь работают очень милые и отзывчивые люди https://москва-курсы.рф/финансово-хозяйственная-деятельност/
https://москва-курсы.рф/services/курс-вечерних-причесок/
Сотрудники и преподаватели профессионалы…
Курсы • Курсы маникюра •
Все необходимые инструменты и материалы включены в стоимость https://москва-курсы.рф/articles/kurcy-brobista-s-diplomom/
Все необходимые инструменты и материалы включены в стоимость http://москва-курсы.рф
Скидки на оборудование Скидка в магазинах профессиональной косметики https://москва-курсы.рф/articles/akkreditacia-medicinskih-rabotnikov/
hat_s Created with Sketch https://москва-курсы.рф/articles/individyalnue-kurcy-makiazha/
Почему стоит учиться в Академии красоты Эколь https://москва-курсы.рф/%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F/kursi-makeup/
Школа Интеримидж https://москва-курсы.рф/финансово-хозяйственная-деятельност/
Курсы • Маникюр и педикюр обучение •
Имитация камня Стили тату и акварель Уникальный френч Эффект хрустальных камней https://москва-курсы.рф/services/%D0%BA%D1%83%D1%80%D1%81%D1%8B-%D0%BC%D0%B0%D0%BD%D0%B8%D0%BA%D1%8E%D1%80%D0%B0-%D0%BF%D0%B5%D0%B4%D0%B8%D0%BA%D1%8E%D1%80%D0%B0-%D0%BD%D0%B0%D1%80%D0%B0%D1%89%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F/
маникюр классический, аппаратный, комбинированный, бразильский, горячий педикюр классический, аппаратный, комбинированный, бразильский, горячий спа уходы парафинотерапия техника массажа рук и ног наращивание ногтей по гелевой технологии на нижние формы и типсы наращивание ногтей полигель/акригель на нижние и верхние формы салонные дизайны (втирка, омбре, стемпинг, тонкие линии, геометрия, принты, фольга, все виды френч, блестки, стразы, глиттер, слайдеры) покрытие гель-лак под кутикулу, снятие вросший ноготь коррекция и снятие нарощенных ногтей ремонт ногтей https://москва-курсы.рф/%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F/kursy-parikmahera/
6 академических часов https://москва-курсы.рф/платные-образовательные-услуги/
250 академ https://москва-курсы.рф/articles/obychenie-permanentnomy-makiazhy-gyb-moskva/
ч https://москва-курсы.рф/articles/obychenie-na-estetista-bez-med-obrazovania/
Данные из анкеты отображаются на сайте https://москва-курсы.рф/services/маникюр-педикюр-наращивание/
“Рекомендую эти курсы всем, кто хочет освоить наращивание ногтей https://москва-курсы.рф/services/obychenie-na-barbera/
Здесь я смогла освоить различные техники и все закрепить на практике https://москва-курсы.рф/согласие-на-обработку-пд/
Планирую открыть собственный салон https://москва-курсы.рф/services/%D0%BA%D0%BE%D1%81%D0%BC%D0%B5%D1%82%D0%BE%D0%BB%D0%BE%D0%B3-%D0%B2%D0%B8%D0%B7%D0%B0%D0%B6%D0%B8%D1%81%D1%82/
”
На курсах обучения маникюру 6 часов отведено для практических занятий, в ходе которых обязательно обрабатываются все виды, а также проверяется усвоение полученных знаний:
Курсы • Курсы маникюра •
…маникюра, поскольку профессия достаточно востребованна https://москва-курсы.рф/services/маникюр-педикюр-наращивание/
Выбрала данные курсы и не пожалела грамотные педагоги https://москва-курсы.рф/services/kurs-koloristiki-s-nulia-moskva/
Екатерина спасибо за понятное…
16 академических часов https://москва-курсы.рф/services/курсы-массажа/
Ближайший старт: 05 Декабря https://москва-курсы.рф/платные-образовательные-услуги/
Студент проходит обучение https://москва-курсы.рф/services/повышение-квалификации-косметологов/
Беспроцентная рассрочка https://москва-курсы.рф/articles/obuchenie-keratinovomu-vypriamleniu-volos/
15740 чел уже прошли этот курс https://москва-курсы.рф/отзывы/
Отзывы о нашей работе https://москва-курсы.рф/articles/obychenie-permanentnomy-makiazhy-gyb-moskva/
Все необходимые инструменты и материалы включены в стоимость https://москва-курсы.рф/services/
Салонный мастер https://москва-курсы.рф/articles/devyshka-barber/
4 700 ?/в мес https://москва-курсы.рф/articles/lichnue-kachestva-parikmahera/
Подробности курса https://москва-курсы.рф/services/повышение-квалификации-косметологов/
Классический педикюр Аппаратный педикюр Дисковый педикюр Экспресс-педикюр и покрытие https://москва-курсы.рф/services/курсы-косметолога-vip-уровня/
У нас действует гибкое расписание, благодаря чему у студентов есть возможность совмещать занятия в Академии красоты с другой занятостью https://москва-курсы.рф/структура-и-органы-управления-образо/
Можно изучать теорию дистанционно, а в учебный центр приходить только для отработки практических навыков https://москва-курсы.рф/services/курсы-парикмахера-модельера-стилист/
любого предприятия независимо от его размеров включает в себя несколько сотен или даже тысяч приборов, которые выполняют различные технологические процессы https://пищевоеоборудование.рф/katalog/izdeliya-iz-nerzh.-stali-aisi304/blok-formy-dlya-zamorozki-800h250h60-mm/ottajshhik-blok-form-obf-1
Цветные металлы (латунь, титан, алюминий, бронза, медь) составляют основу отдельных деталей, емкостей, трубопроводов, некоторых видов упаковки (например, консервных банок) https://пищевоеоборудование.рф/katalog/izdeliya-iz-nerzh.-stali-aisi304/stellazh-dlya-razmorozki-aisi-304
Казино еще с прошлого века пользовалось бешеным успехом среди ценителей качественных развлечений и комфортного отдыха https://пищевоеоборудование.рф/moskva/katalog/oprokidyvateli-kontejnerov-i-telezhek/oprokidyvateli-bochek-ob-250
Когда реальные казино были запрещены законом и пришлось закрыть https://пищевоеоборудование.рф/katalog/oprokidyvateli-kontejnerov-i-telezhek/big-boksy
https://пищевоеоборудование.рф/katalog/bunkera-nakopitelnye-priemnye/
https://пищевоеоборудование.рф/katalog/izdeliya-iz-nerzh.-stali-aisi304/stol-dlya-razdelki-aisi-304
Реакторы термические применяются для термической обработки продукции во всех отраслях пищевой промышленности https://пищевоеоборудование.рф/katalog/sanpropuskniki-doz-200/dezbarery-dlya-avtotransporta-doz-m-5000
Изготавливаются различного объема, комплектации по техническому заданию или чертежам заказчика заданной производительности https://пищевоеоборудование.рф/katalog/glazirovshhiki-pogruzhnoj/
Торговое холодильное оборудование отличается меньшей мощностью (хотя и здесь используются мощные ) и применяется для кратковременного хранения охлажденных или замороженных продуктов в магазинах и предприятиях общепита https://пищевоеоборудование.рф/katalog/izdeliya-iz-nerzh.-stali-aisi304/rolgangi-rolikovye-aisi-304
Его отличительной особенностью является то, что это оборудование должно обеспечивать возможность демонстрации продуктов и удобство доступа к ним покупателей https://пищевоеоборудование.рф/katalog/oprokidyvateli-kontejnerov-i-telezhek/oprokidyvateli-cheburashka
ИСПЫТАНИЯ СЕЯЛКИ ДЛЯ ПОСЕВА СЕМЯН ГИДРАВЛИЧЕСКИМ СПОСОБОМ Виневский Е https://пищевоеоборудование.рф/katalog/centrifuga-reaktivnaya-ustanovka/
И https://пищевоеоборудование.рф/katalog/konvejera-z-obraznye/vibropitatel-s-bunkerom-v-200-l
*, д-р техн https://пищевоеоборудование.рф/soglashenie
наук, профессор Труфляк Е https://пищевоеоборудование.рф/katalog/oprokidyvateli-kontejnerov-i-telezhek/oprokidyvatel-cepnoj-orc-3000
В https://пищевоеоборудование.рф/soglashenie
**, д-р техн https://пищевоеоборудование.рф/katalog/oprokidyvateli-kontejnerov-i-telezhek/oprokidyvateli-cheburashek-och-250
наук Курченко Н https://пищевоеоборудование.рф/katalog/kamera-df/
Ю https://пищевоеоборудование.рф/katalog/izdeliya-iz-nerzh.-stali-aisi304/rolgangi-rolikovye-aisi-304
** Скоробогаченко И https://пищевоеоборудование.рф/katalog/mashina-mojki/
С https://пищевоеоборудование.рф/katalog/izdeliya-iz-nerzh.-stali-aisi304/protivni-dlya-kopcheniya-sushki-aisi-304
** * ФГБНУ «Всероссийский научно