サンプルアルゴリズム「Image Classification(Face)」を使用した顔認識モデルの作成
はじめに
Image Classification(Face) は、S+ Camera Basic で取得した顔画像を元に学習した顔認識モデルを簡単に作成できるサンプルアルゴリズムです。作成したモデルを使用することで、S+ Camera Basic 上で顔認識を行うことができます。当ガイドでは Image Classification(Face) で作成した顔認識モデルを S+ Camera Basic にインストールして、顔認識の結果を SORACOM Lagoon 上のダッシュボードに表示させる設定手順を解説します。 SORACOM Mosaic を初めて利用する場合は、 Getting Started with SORACOM Mosaicをご確認ください。
事前準備: SORACOM Harvest Data の設定を有効にする
顔認識モデルの判定結果は SORACOM Harvest Data に送信されるので、利用している S+ Camera Basic に取り付けた SIM にて設定を有効にする必要があります。既に SORACOM Harvest Data が有効になっている場合はこの手順はスキップしてください。
SORACOM ユーザーコンソール の[Menu]>[SIM 管理]とクリックして SIM 管理画面を開く。
S+ Camera Basic に取り付けた SIM に割り当てたグループ名をクリックする。
[SORACOM Harvest Data 設定]をクリックする。
SORACOM Harvest Data の設定を ON にして [保存] をクリックする。
ステップ 1: S+ Camera Basic を使って学習用の顔画像を収集する
S+ Camera Basic に Image Classification(Face) をインストールする
SORACOM Mosaic の コンソール にログインして、デバイス詳細画面の App(CameraApp0) タブから、Install new algorithm… ボタンをクリックすると以下のようにアルゴリズムを選択するダイアグラムが表示されます。Image Classification(Face) を選択肢、Install ボタンをクリックしてアルゴリズムをインストールしてください。
インストール後、以下のように、CURRENT ALGORITHM が Image Classification(Face) と表示されていることを確認してください。
学習用の顔画像を収集する
S+ Camera Basic を学習させたい顔に向けると、顔画像が SORACOM Harvest Files に送信されます。
撮影された顔画像は以下の手順で確認できます。
- SORACOM の ユーザーコンソール にログインし、画面左上の [Menu] > [データ収集・蓄積・可視化] > [SORACOM Harvest Files] をクリック。
- 以下のように
/image_classification/{MOSAIC ID}/yyyy/mm/dd/
ディレクトリに webp 形式で顔画像が保存されています(顔画像は SORACOM_ENV_WAIT 秒毎に撮影されます)。
次の値は、SORACOM Mosaic コンソールのデバイス詳細画面の App(CameraApp0) タブにあるアルゴリズム (Image Classification(Face)) の環境変数 SORACOM_ENV_FREE_PARAM から変更可能です。
引数名 | 型 | 説明 |
---|---|---|
UInv | integer | データの送信間隔 (この間のデータは破棄)。Default 60 秒 |
SInt | integer | SORACOM Harvest Data/Files への送信間隔 (秒)。Default SORACOM_ENV_WAIT (60)秒 |
UInv | integer | SORACOM Harvest Data/Files へのデータの送信間隔(この間のデータは破棄)。Default SORACOM_ENV_WAIT(秒) |
SInt | integer | この期間は同一の顔と判定されたデータを破棄(秒)。Default SORACOM_ENV_WAIT(秒) |
SData | boolean | true の場合、モデル作成用のデータを作成する。Default true |
ステップ 2: Image Classification(Face) のコンソールを使って顔認識モデルを作成する
モデル作成に必要なデータの作成
モデルを作成するためには SORACOM Harvest Files の /face_detection_v1/detections
にモデル作成用のデータを保存する必要があります。モデル作成用のデータは Image Classification(Face) をインストールした S+ カメラにおいて、顔認識ができない場合もしくは SData を true に設定している場合は、顔認識の結果に関わらず全ての顔についてモデル作成用のデータが作成されます。
新しいモデルを作成する
SORACOM Mosaic コンソールにログインして、画面右上の Support から Mosaic Classifier をクリックすると Image Classification(Face) のコンソールに遷移します。
まず、「New model」をクリックして学習用の新しいモデルを作成します。
NAME にモデル名を入力し TYPE は「Face Detection v1」を選択して [Create model] をクリックします。ここではモデル名を my_model としています。
モデルの作成は数秒で完了し、ステップ 1 で収集した顔画像が古いものから順に 100 枚読み込まれます。読み込まれた顔画像はモデルにより人物ごとに分類されます。ただし、学習前のモデルのためこの段階では判定精度が悪く顔画像をうまく分類できません。以下の画面に表示されている青枠の分類結果を見ると、異なる人物の顔写真が混ざっていることが分かります。
なお、画面上部のプログレスバーでは以下が確認できます。
- Saved:学習済の顔画像の枚数
- Pending:コンソール上に読み込んだ顔画像の枚数
- Remaining:ステップ 1 で収集した顔画像の枚数
分類結果を手動で変更してモデルに学習させる
次に、より精度を向上させるためモデルの分類結果を修正します。具体的には以下の 3 つのアクションがあります。
- 異なる人物にも関わらず同一人物として分類された顔画像を分離する。 (偽陽性への対応)
- 同一人物にも関わらず異なる人物として分類された顔画像を統合する。 (偽陰性への対応)
- 画質の悪い顔画像を学習対象から除外する。
異なる人物にも関わらず同一人物として分類された顔画像を分離する
同一人物として誤って分類してしまった顔画像 (青枠で囲った顔画像) をクリックし Create new person をクリックします。(既にグループが作成されている場合は Move to {統合したいグループのラベル} をクリックします。)
クリックした顔画像は同一人物と判定された他の顔画像と共に元のグループから消えて新しいグループが作成されます。
同一人物にも関わらず異なる人物として分類された顔画像を統合する
下の画面では、同一人物が異なる人物として分類されています。
この誤りを修正するためには、顔画像をクリックし Move to {統合したいグループのラベル} をクリックします。
クリックした顔画像は以下のように同一人物として正しく分類されます。
画質の悪い顔画像を学習対象から除外する
モデルの判定精度を向上させるためには、画質の良い画像を学習させる必要があります。例えば以下のような暗い画像などは学習させるとかえって判定精度が低下する可能性があるため、モデルの学習対象から除外します。
モデルの学習対象からするためには、顔画像をクリックし Ignore this face をクリックします。
クリックした画像は Image Classification(Face) のコンソール上から削除されます。(SORACOM Harvest Files 上からは削除されません。)
顔画像の分類結果を表すラベルを付ける
読み込んだ 100 枚の顔画像に対して上記の修正を実施したら、顔画像の横にある入力ボックスに該当の人物のラベルを入力します。
学習結果を反映し、次の顔画像を読み込む
「Save and load more faces」をクリックすると学習結果がモデルに反映されると同時に、顔画像(次の 100 枚)が読み込まれます。新しく読み込んだ顔画像に対して上記の作業を繰り返します。
作成したモデルは SORACOM Harvest Files の /face_detection_v1/models/
下に <ランダムな文字列>-<作成したモデル名>.json
という名前で保存されます。
ステップ 3: 作成した顔認識モデルを S+ Camera Basic に反映して顔認識結果を確認する
作成した顔認識モデルを S+ Camera Basic に反映する
SORACOM Mosaic コンソールのデバイス詳細画面の App(CameraApp0) タブからアルゴリズム (Image Classification(Face)) の環境変数 SORACOM_ENV_URI に作成したモデルのパスを指定して、Apply をクリックします。
モデルのパスは http://harvest-files.soracom.io/face_detection_v1/models/cjxen9kaiid-my_model.json
というような形式で指定してください。
以下のように Parameters have been updated.
と表示されれば、反映完了です。
モデルによる顔認識を行う
S+ Camera Basic を顔に向けると、判定結果が SORACOM Harvest Data に送信されます。 SORACOM ユーザーコンソール の SIM 管理画面から S+ Camera Basic に取り付けた SIM にチェックを付け、[操作]>[データを確認]をクリックしてください。
顔認識モデルの判定結果が以下のように出力されます。青枠の label
に判定した人物のラベルが出力されます。以下の画面では S+ Camera Basic に写った顔画像は jed であると判定されています。なお、学習した顔画像のどの人物にも該当しない場合は null
と出力されます。
認識がうまくいかない場合には、Device control からデバイスの再起動 (Restart Device)を試してみてください。それでもうまくいかない場合には、 PC を用いたアルゴリズムの開発を参照してください。
ステップ 4: 顔認識結果を SORACOM Lagoon 上で表示する
今回はモデルの出力結果を SORACOM Lagoon 上にも表示します。SORACOM Lagoon を用いることで、撮影した顔画像などもあわせて表示できます。
SORACOM Lagoon を有効化する
SORACOM のユーザーコンソール にルートアカウントでログインし、サイドメニューの「データ収集・蓄積・可視化」>「SORACOM Lagoon」メニューをクリックします。
SORACOM Lagoon を有効化する
「SORACOM Lagoon の利用を開始する」ボタンをクリックします。
プランを選択後、「続行する」をクリックします。なお、本ガイドの手順はどのプランを選択いただいた場合でも実行可能です。
パスワードを設定します。 このパスワードは SORACOM コンソールのルートアカウントのメールアドレスで Lagoon へログインする時に必要なパスワードとなります。
SORACOM Lagoon へログインする
「SORACOM Lagoon にアクセス」ボタンをクリックします。
ルートアカウントのメールアドレスと先ほど設定したパスワードを入力しログインします。
以下のような画面が表示されていれば Lagoon の有効化・ログインは成功です。
SORACOM Lagoon ダッシュボードを作成する
サンプルダッシュボードの設定をインポートする
当ガイドではダッシュボードの全てのパネルを自身で作成するのではなく、JSON 形式で記述された定義ファイルをインポートすることで以下のようなサンプルダッシュボードを作成します。
上記のサンプルダッシュボードの各パネルに表示されるデータは以下のとおりです。
- Face Image: S+ Camera Basic で撮影された顔画像
- Mask: マスクの有無
- Confidence: 学習済の顔画像との類似度
- History: SORACOM Harvest Data に保存されたデータ
SORACOM Lagoon の画面左の +
にカーソルを合わせて、[インポート]をクリックします。
[Or paste JSON] の欄に 本ページ末尾 の JSON を貼り付けて、[Load] をクリックします。
[Import] をクリックします。
サンプルダッシュボードのテンプレート(値が表示されないパネル)が表示されます。
S+ Camera Basic の出力結果を表示するように設定を変更する
Face Image のパネル名から、[編集]をクリックします。
メトリックタブから S+ Camera Basic に取り付けた SIM の IMSI を選択して、顔画像が表示されることを確認してください。顔画像が表示されない場合は、パネル右上の表示期間中に顔画像が存在することを確認してください。
画面上部の保存ボタンをクリックしてパネルを保存します。
画面右上のボタンをクリックしてダッシュボードに戻ります。
同様に Mask パネルのメトリックを設定します。項目は mask
を選択します。
Confidence パネルのメトリックを設定します。項目は distance
を選択します。
History パネルのメトリックを設定します。
以下のように全てのパネルに顔画像或いは値が表示されます。
当ガイドの手順は以上で終了です。
サンプルダッシュボードの定義ファイル
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 2047,
"links": [],
"panels": [
{
"backgroundMeta": {
"height": 100,
"url": "",
"width": 100
},
"backgroundSize": "contain",
"basicAuth": false,
"basicAuthPassword": "",
"basicAuthUsername": "",
"bgimage": "",
"bgimageSuffix": ".png",
"bustCache": true,
"datasource": null,
"displayImage": 0,
"fixRatio": true,
"gridPos": {
"h": 9,
"w": 5,
"x": 0,
"y": 0
},
"height": "400px",
"id": 12,
"links": [],
"mode": "harvest_files",
"series": [],
"seriesList": [],
"targets": [
{
"datatype": "table",
"devicetype": "subscribers",
"pro": true,
"refId": "A",
"target": "",
"type": "timeseries"
}
],
"title": "Face Image",
"type": "soracom-dynamic-image-panel",
"urlValue": "A-image_path",
"valueMaps": {},
"variables": [],
"width": "100px"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": ["#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a"],
"datasource": "Harvest",
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"gridPos": {
"h": 9,
"w": 4,
"x": 5,
"y": 0
},
"id": 8,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "singlestat.value_to_text",
"value": 1
},
{
"name": "singlestat.range_to_text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"tableColumn": "",
"targets": [
{
"datatype": "standard",
"devicetype": "subscribers",
"pro": true,
"properties": "mask",
"refId": "A",
"target": "",
"type": "timeseries"
}
],
"thresholds": "",
"title": "Mask",
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "no mask",
"value": "0"
},
{
"op": "=",
"text": "mask",
"value": "1"
}
],
"valueName": "current"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": ["#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a"],
"datasource": null,
"format": "percentunit",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": true,
"thresholdLabels": false,
"thresholdMarkers": false
},
"gridPos": {
"h": 9,
"w": 6,
"x": 9,
"y": 0
},
"id": 4,
"interval": null,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "singlestat.value_to_text",
"value": 1
},
{
"name": "singlestat.range_to_text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"tableColumn": "",
"targets": [
{
"datatype": "standard",
"devicetype": "subscribers",
"pro": true,
"properties": "distance",
"refId": "A",
"target": "",
"type": "timeseries"
}
],
"thresholds": "",
"title": "Confidence",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "current"
},
{
"columns": [],
"datasource": null,
"fontSize": "100%",
"gridPos": {
"h": 11,
"w": 18,
"x": 0,
"y": 9
},
"id": 10,
"links": [],
"pageSize": 10,
"scroll": true,
"showHeader": true,
"sort": {
"col": 0,
"desc": true
},
"styles": [
{
"alias": "Time",
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"pattern": "time",
"type": "date"
},
{
"alias": "",
"colorMode": null,
"colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
"decimals": 2,
"pattern": "/.*/",
"thresholds": [],
"type": "number",
"unit": "short"
}
],
"targets": [
{
"datatype": "table",
"devicetype": "subscribers",
"pro": true,
"refId": "A",
"target": "",
"type": "timeseries"
}
],
"title": "History",
"transform": "table",
"type": "table"
}
],
"refresh": "10s",
"schemaVersion": 16,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-30m",
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
},
"timezone": "",
"title": " Image Classification ",
"uid": "X8z0KznGz2",
"version": 12
}