今回は画像認識AIに加えて、ソケット通信が登場します。簡単のため、ラズパイ内でサーバー、クライアントを作成し、ソケット通信を介した画像認識をやってみました。
開発環境
■ハードウェア
・Raspberry Pi 3 Model B
I-O DATA Raspberry Pi メインボード Bluetooth(R) Wi-Fi対応モデル Raspberry Pi 3 model B 安心の1年間ハードウェア保証 UD-RP3
posted with amazlet at 20.02.15
アイ・オー・データ (2017-02-20)
売り上げランキング: 1,375
売り上げランキング: 1,375
■OS
・Raspbian GNU/Linux 9.11 (stretch)
■プログラミング言語、主なライブラリとバージョン
・Python 2.7.13
・socket
・Keras 2.1.5
・numpy 1.12.1
・theano 1.0.1
・matplotlib 2.0.0
※ラズパイのAI環境開発は以下の本が参考になります。
講談社 (2018-03-14)
売り上げランキング: 72,812
売り上げランキング: 72,812
プログラム
GitHubにサンプルプログラムを公開します。
https://github.com/kotetsu99/cnn_socket
■各プログラム等の概要
(1)01-cnn_train.py: 画像学習プログラム
・画像をAIに学習させ、画像認識AIモデルを生成。
・AIモデルは、CIFAR-10 画像データセット向けのAIモデル(9層畳み込みネットワーク)
(2)02-cnn_server.py: 画像認識AIソケットサーバー
・ソケット通信サーバー。(3)のクライアントから画像ファイルを受信し保存。
・受信した画像ファイルに対し、(1)で作ったAIで画像認識させ、結果をクライアントに返す。
(3)03-socket_client.py: 画像送信ソケットクライアント
・ソケット通信クライアント。画像ファイルを(2)のサーバーにバイナリデータで送信。
・サーバーの画像認識結果を受信して、コンソール画面に表示。
(4)dataset: 画像データセット保存ディレクトリ
・train:
-学習用の画像ファイルを保存。
-サブディレクトリが存在し、配下に画像データセットを保存しておく。
・validation:
-検証用の画像ファイルを保存。
-サブディレクトリが存在し、配下に画像データセットを保存しておく。
・sc:
-(2)が受信した画像ファイルの保存先ディレクトリ。
(5)model: 画像認識AIモデル保存ディレクトリ
プログラム使用方法
例として、
・スマホブラウザのスクリーンショット画像をサーバーにソケット通信
・サーバー側で画像認識、認識結果をクライアントに返す。
・クライアント側で、認識結果をコンソール画面に表示。
という流れで実行していきます。
# スマホ画面の認識を取り上げてるのは、↓の記事で記したモバイルテスト自動化の件とつながってます。
https://nine-num-98.blogspot.com/2020/03/katalon-studio-ai-01.html
(1)データセットの準備
スクリーンショット画像ファイルを、dataset/trainおよびvalidationの各サブディレクトリ配下に保存します。
・dataset/train:
-apple
-rakuten
-yahoo
・dataset/validation:
※以下のディレクトリ構成は、trainと同じ
ディレクトリ名を見れば何となく分かると思いますが、各サイト名をサブディレクトリ名としています。yahooディレクトリであれば、以下のような画像ファイルを複数枚保存しておきます。

サブディレクトリ名は画像認識で分類するクラス名に一致します。
[apple, google, rakuten, yahoo]
認識する画像が↑の4クラスのいずれかに分類されるわけです。
(2)画像学習プログラムの実行
以下のコマンドを実行します。
$ nohup python 01-cnn_train.py model/cnn_model.h5 &
バックグランドで画像学習処理が進みます。進捗状況は、nohup.outファイルに出力されるので、以下のコマンドで確認できます。
$ tail -f nohup.out
以下のようなログが確認できます。
Using Theano backend. クラス名リスト = ['google', 'apple', 'rakuten', 'yahoo'] モデル新規作成 Found 33 images belonging to 4 classes. Found 4 images belonging to 4 classes. ('trgen_len(train_steps)=', 5) ('vagen_len(val_steps)=', 1) Epoch 1/200 1/5 [=====>........................] - ETA: 2:44 - loss: 1.4584 - acc: 0.3750 2/5 [===========>..................] - ETA: 2:03 - loss: 3.2370 - acc: 0.3125 3/5 [=================>............] - ETA: 58s - loss: 2.2783 - acc: 0.5417 4/5 [=======================>......] - ETA: 32s - loss: 1.7240 - acc: 0.6562 5/5 [==============================] - 179s 36s/step - loss: 2.3537 - acc: 0.5600 - val_loss: 1.6856 - val_acc: 0.2500 ・・・(中略)・・・ Epoch 31/200 1/5 [=====>........................] - ETA: 2:42 - loss: 0.0607 - acc: 1.0000 2/5 [===========>..................] - ETA: 2:02 - loss: 0.0446 - acc: 1.0000 3/5 [=================>............] - ETA: 1:21 - loss: 0.0551 - acc: 1.0000 4/5 [=======================>......] - ETA: 37s - loss: 0.0441 - acc: 1.0000 5/5 [==============================] - 202s 40s/step - loss: 0.0522 - acc: 1.0000 - val_loss: 0.0194 - val_acc: 1.0000 Epoch 00031: early stopping ('process_time = ', 105.34722700119019, '[min]')
最後の学習に要した所要時間結果
('process_time = ……)
が確認されたらプログラム終了です。
(3)画像認識AIサーバープログラムを実行
以下のコマンドを実行します。
$ python 02-cnn_server.py model/cnn_model.h5
ソケットサーバーが準備できたら、以下のような画面出力になります。
Using Theano backend. クラス名リスト = ['google', 'apple', 'rakuten', 'yahoo'] クライアントからの接続待ち...
(4)画像送信ソケットクライアントプログラムを実行
画像認識させたい画像ファイル「file.png」を準備して、実行プログラム「03-socket_client.py」と同一ディレクトリに置きます。

さっきのyahooのページ画像を送ってみます。
以下のコマンドを実行します。
$ python 03-socket_client.py file.png
以下の結果が表示されます。
file.pngをサーバーに送信 認識結果: yahoo
認識結果がサーバーから返ってきましたね。送った画像ファイルを見事、正解通り画像認識して、「これはyahooのページです。」と応えてくれました。
一方のサーバー側では以下のように結果が出ています。
$ python 02-cnn_server.py model/cnn_model.h5 Using Theano backend. クラス名リスト = ['google', 'apple', 'rakuten', 'yahoo'] クライアントからの接続待ち... 受信ファイル認識結果: [('yahoo', 0.9910015), ('apple', 0.008614799), ('google', 0.00036144815), ('rakuten', 2.2250342e-05)] =======================================
4つのクラスが、可能性の高い順にが表示されています。一番可能性(確率)の高いクラス名(サイト名)が「yahoo」です。この結果をクライアント側にソケット通信で返してくれています。
ラズパイとは別のPCでこのソケットクライアントを使う場合は、
# サーバーIPアドレス定義 host = "0.0.0.0"
の箇所のhostのIPアドレスを、ラズパイのものに変更すればOKです。
プログラムの使用方法については以上です。
画像データセットを、目的に合わせて変更したり、サーバー-クライアントをラズパイの中だけで完結させずに、別々のPCで動かしたりと、色々使い道はあるのかなと思います。
各プログラムの解説は以下の記事にアップしました。
画像学習プログラム解説:
https://nine-num-98.blogspot.com/2020/03/ai-socket-02.html
ソケット通信プログラム解説:
https://nine-num-98.blogspot.com/2020/03/ai-socket-03.html