はじめに
この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2022 (1枚目) の 2日目として投稿しています。
2017年版: https://qiita.com/advent-calendar/2017/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco
2019年版: https://qiita.com/advent-calendar/2019/cisco
2020年版①: https://qiita.com/advent-calendar/2020/cisco
2020年版②: https://qiita.com/advent-calendar/2020/cisco2
2021年版①: https://qiita.com/advent-calendar/2021/cisco
2021年版②: https://qiita.com/advent-calendar/2021/cisco2
2022年版①②: https://qiita.com/advent-calendar/2022/cisco (これ)
Meraki MV Cameraについて書くに至った経緯
11/16, 17, 18に幕張メッセで開催された放送事業者関連の展示会であるInter BEE 2022にシスコとして出展をしていたのですが、その展示の1つに今回記事にさせていただいたMeraki MV Cameraがあり、説明員として参加していたこともあり何か書いてみようと考えました。
(シスコが放送事業者向けに展示できるものって何かあるの!?という話については本Advent Calenderの6日目に@hanakamuさんが報告してくれるようなので詳しくはそちらをご覧ください。)
Cisco Merakiはクラウド管理型のネットワーク製品群になります。スイッチやルータ、アクセスポイントといった製品も当然その中に含まれますが、今回この記事にまとめたカメラもスマートカメラという位置づけで製品群の一部となっています。
Meraki MV Cameraはデフォルトのインテリジェンスな機能として、下の画像にもある通り人や車両の認識を行うことができるようになっています。
1時間の間にカメラで撮影している場所を何人が通過したのか、どういった動線で移動しているのかといったデータをアナリティクスデータとして表示できるため、小売店などのマーケティングデータとしての利用もユースケースとして想定されています。
今回は人や車両以外も自分で作ったカスタムモデルを利用すれば認識できるという機能追加があったということで試してみようと思います。
TensorFlowを使ってみよう!
TensorFlowはGoogleが開発した機械学習用のソフトウェアライブラリです。
私はそもそも機械学習ってなんなの?どうやってやるの?というレベルの知識しかないため、まずはお試しで感覚をつかもうと思います。
今回は機械学習のモデルデータの作成に当たり、TensorFlow Lite Model Makerというものを利用しました。
TensorFlowによる画像分類は、基本的には自身で環境を準備しコードを実行することでモデルを作成しますが、下のリンク内にある「Run in Google Colab」を選択すると、Google Colabを用いてブラウザベースでコードを実行できてしまいます。
利用するリソース等により無償版の制限はあるようなので(それでもここまで使えるのはすごすぎる!)、詳しくはこちらで確認ください。
TensorFlow Lite Model Maker による画像分類
デフォルトのシナリオは数種類の花を分類するモデルを作成するシナリオのようです。
<b>flower_photos</b>
|__ <b>daisy</b>
|______ 100080576_f52e8ee070_n.jpg
|______ 14167534527_781ceb1b7a_n.jpg
|______ ...
|__ <b>dandelion</b>
|______ 10043234166_e6dd915111_n.jpg
|______ 1426682852_e62169221f_m.jpg
|______ ...
|__ <b>roses</b>
|______ 102501987_3cdb8e5394_n.jpg
|______ 14982802401_a3dfb22afb.jpg
|______ ...
|__ <b>sunflowers</b>
|______ 12471791574_bb1be83df4.jpg
|______ 15122112402_cafa41934f.jpg
|______ ...
|__ <b>tulips</b>
|______ 13976522214_ccec508fe7.jpg
|______ 14487943607_651e8062a1_m.jpg
|______ ...
少しオリジナリティを出すため、ポケモンで一番好きな「メタモン」を画像分類することにしました。
Google画像検索でメタモンを検索すると、このようにたくさんのメタモンの画像が表示されます。
様々な種類のメタモンの画像をダウンロードします。メタモン以外の画像も用意し学習用データとします。
TensorFlow Lite Model Makerのガイドには数百枚の画像があればOKと書いてありますが、そもそも数百枚のメタモンを集めるのが大変です、、。
当然この枚数が多ければ多いほど学習の精度は向上します。
1. 必要なパッケージのインポート
!pip install -q tflite-model-maker
import os
import numpy as np
import tensorflow as tf
assert tf.__version__.startswith('2')
from tflite_model_maker import model_spec
from tflite_model_maker import image_classifier
from tflite_model_maker.config import ExportFormat
from tflite_model_maker.config import QuantizationConfig
from tflite_model_maker.image_classifier import DataLoader
import matplotlib.pyplot as plt
2. 利用する学習データとテストデータのアップロード
学習データはコンテナ実行環境にアップロードするか、インターネット上からコマンドでダウンロードさせるか、Google Driveをマウントするとか色々とやり方はあるようです。
Macでtarコマンドを利用し.tgzファイルを作成、アップロードし解凍しようとしましたがエラーが出てしまいました。
私の作業環境はMacなのですが、Macはデフォルトのtarとしてbsdtarを利用しており、LinuxはGNU tarを使用しているためエラーが出るようです。
Mac側にbrewコマンドでGNU tarをインストールします。
<参考>
Mac で GNU の tar コマンドを利用する: https://hacknote.jp/archives/8951/
tar から Ignoring unknown extended header keyword と怒られた件: https://atuweb.info/201812_tar-unknown-extended-header/#gsc.tab=0
・PC側での作業
$ brew install gnu-tar
$ gtar -cf Metamon.tgz Metamon
・Google Colabでの作業
!tar -xvf Metamon.tgz
これでエラーは出なくなり、解凍ができました。
次にimage_pathの指定をします。
dir = "./Metamon"
image_path = os.path.join(os.path.dirname(dir), 'Metamon')
この後のステップでTensorFlowモデルのカスタマイズを行うのですが、このようなエラーが出てしまいました。
InvalidArgumentError: Unknown image file format. One of JPEG, PNG, GIF, BMP required.
Mac上ではJPEGファイルと表示されていますが、偽JPEGが紛れ込んでいるようです。
JPEGのファイルヘッダにはJFIFという文字列が含まれているので、含まれていないファイルを自動で消去するコードを実行します。
<参考>
Filter out corrupted images: https://keras.io/examples/vision/image_classification_from_scratch/#filter-out-corrupted-images
num_skipped = 0
for folder_name in ("Metamon", "Not_Metamon"):
folder_path = os.path.join("Metamon", folder_name)
for fname in os.listdir(folder_path):
fpath = os.path.join(folder_path, fname)
try:
fobj = open(fpath, "rb")
is_jfif = tf.compat.as_bytes("JFIF") in fobj.peek(10)
finally:
fobj.close()
if not is_jfif:
num_skipped += 1
# Delete corrupted image
os.remove(fpath)
print("Deleted %d images" % num_skipped)
#結果
Deleted 2 images
3. トレーニングデータとテストデータの分割
data = DataLoader.from_folder(image_path)
train_data, test_data = data.split(0.9)
このdata.split(0.9)で90%のデータをtest_dataに、10%のデータをtrain_dataに分割しています。
4. TensorFlow Liteモデルのカスタマイズ
model = image_classifier.create(train_data)
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
hub_keras_layer_v1v2 (HubKe (None, 1280) 3413024
rasLayerV1V2)
dropout (Dropout) (None, 1280) 0
dense (Dense) (None, 2) 2562
=================================================================
Total params: 3,415,586
Trainable params: 2,562
Non-trainable params: 3,413,024
_________________________________________________________________
None
Epoch 1/5
11/11 [==============================] - 10s 51ms/step - loss: 0.5685 - accuracy: 0.7415
Epoch 2/5
11/11 [==============================] - 1s 65ms/step - loss: 0.2825 - accuracy: 0.9773
Epoch 3/5
11/11 [==============================] - 1s 70ms/step - loss: 0.2728 - accuracy: 0.9886
Epoch 4/5
11/11 [==============================] - 1s 71ms/step - loss: 0.2664 - accuracy: 0.9830
Epoch 5/5
11/11 [==============================] - 1s 70ms/step - loss: 0.2500 - accuracy: 0.9915
5. テストデータを使用したモデルの評価
loss, accuracy = model.evaluate(test_data)
2/2 [==============================] - 1s 24ms/step - loss: 0.2439 - accuracy: 1.0000
6. TensorFlow Liteモデルのエクスポート
model.export(export_dir='.')
model.tfliteがカレントディレクトリに生成されます。
このモデルを利用することでメタモンを分類させることができるようになります。
しかしMeraki MV Cameraでは下のドキュメントにもあるように、ただtfliteのモデルを出力すればいいだけではなく、「入力」「出力」のTensorにちゃんと規定があります。
これまでやっていた作業は画像分類モデルの作成であって、画像分類と物体検出を組み合わせないといけないようです。
次回予告
後編では実際に物体検出用のモデルを作成してみてMeraki MV Cameraで実際に動かしてみようと思います。
免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。