AI-Boosted Microplastics Detector Ep.1

The other day, I was walking on the beach in Tokyo’s bay area. Comparing to other areas in Tokyo, I like its tranquil and peaceful atmosphere. However, suddenly I realized that the beach is full of plastic garbage. Some of them are large plastic chunks, and the others are pretty small or even tiny plastic fragments. But hey, who scattered the garbage all over the beach? It’s obviously us who did this. This is so-called “microplastics”, which pollute both the ocean and the land these days. Some of my friends have talked about microplastics before, but that day was the first time that I realized that the issue is pretty much real. This experience has been the main motivation that I decided to do something against this.

Because I am a software engineer, I thought I can make something that is based on deep neural network technology. It is more like a data-based approach rather than image processing, which is probably a better way because microplastics are very diverse in shapes and colors, which will definitely difficult for a conventional computer vision. The idea is that once the AI is ready, I will put it into a rover with a robotic arm, which autonomously removes plastics from the beach.

The key factor of this project is to build the AI that will tell plastics from mixed debris. More specifically, it will be an image classifier or an object detector using a neural network.

To do this, I need a whole bunch of training data. Luckily (or sadly), there’s a lot of it out there on the beach. So I grabbed some plastic debris and brought them back home.

海洋プラスチック問題 #3

smallplastics and #microplastics that I took still images for deep learning today. This is just ‘batch 1’ and I have a lot more. #AI #DeepLearning

海洋プラスチックAIの深層学習のため、教師データとして本日撮影したプラスチックごみ。念のため袋に入れてとっておきます。各破片10アングル撮影しました。

#AI #深層学習 #microplastics

海洋プラスチック問題 #1

AIを活用して海洋プラスチック問題に取り組んでいます。AIを学習させるためには大量の画像データが必要です。幕張で集めた漂流物を、プラスチックと自然物にひたすら仕分け!

Tackling #microplastic using deep learning. To have my AI get trained, I need to give him a lot of train data!

海洋プラスチック

#AI #深層学習 #microplastics

AIで画像分類をしよう

この記事で得られるもの

  • 理論はさておき画像AIの実装方法が分かる
  • 教師データを何枚準備すればよいかを考えるきっかけ
  • 具体的なコード、ライブラリ、環境などの情報

はじめに

まさに今、皆さんがAIを実装する時代が来ています。ResNetやGoogLeNet、VGGなど、近年の優れたディープニューラルネットワークの発明、そして、クラウドでのGPU環境の勃興も手伝って、今までになく深層学習の応用実装に手が届く時代となりました。しかし、いざ画像分類のモデルを実際に作成するとなると、教師データをどれくらい準備すればよいか試行錯誤するでしょう。もっとも、データの質により、必要な教師データの数は変わってきます。そして、あなたの分類問題自体の本質的な難易度も必要な教師データ数に影響を与えるでしょう。しかし、データの質を定量的に評価するのは難しく、定性的判断と経験値が必要です。

深層学習の理論や数学はさておき、実際に実装作業を行うことで、AI学習を肌感覚で体験してみてはいかがでしょうか。ここでは具体的な分類モデルの作成を行い、2回にわたる試行–教師データの質が原因で失敗した例(試行1)と、その後、それを踏まえて教師データを作り直し、うまくいった例(試行2)とをそれぞれご紹介していきます。

お題 〜カルダモンを分類しよう〜

グリーンカルダモン、ブラックカルダモン

畳み込みニューラルネットワーク(以下、CNN)の応用として、ここではシンプルな画像の分類問題に取り組みます。CNNでの画像分類は、セキュリティの問題[1]を除けば、技術的には確立されたと言ってもよいでしょう。

はじめに、小さい物体は教師データの撮影が作業的に簡単だと考え、(やや唐突なのはご了承いただいて)スパイスの一種であるカルダモン(以下、試料A)とその近縁種であるブラックカルダモン(ビッグカルダモンとも。以下、試料B)の分類を課題とします。ここで、分類の難易度という観点では「難しすぎず簡単すぎず」を考慮しました。なぜなら、例えば五円玉と十円玉のような簡単な分類はニューラルネットワークを使わずとも単純な画像処理で実現可能だからです。その点、カルダモンの分類はクラス間で形が似ており、色が微妙に異なるという点で、AIに適した分類問題と考えました。

教師データを撮影する

深層学習による画像分類は、一般的に大量の教師データが必要です。多くの画像データを準備するにあたり、インターネットから入手するか、あるいは自分で撮影を行いましょう。今回は撮影します。スマートフォンでカメラ撮影する方法は、まず第一選択となるかと思いますが、撮影角度などの条件を細かく調整したいので、専用の撮影装置を製作しました。仕組みはWEBカメラとモーター制御の円卓をRaspberry Piでコントロールしています。これにより半自動で物撮りをしていきます。

撮影装置

部品はCADで設計し、3Dプリンターで製作しました。

AIの道具たち

ここでAIの道具として、深層学習ライブラリと学習手法を簡単にご紹介します。

PyTorch、ResNet

PyTorch[2]は、高レベルで柔軟な深層学習ライブラリです。また、各種の学習済みネットワークがすぐに利用でき便利です。ここでは高速な学習と高い認識を誇るResNet[3]を使い、あらかじめ学習された重みをもとに学習しなおす転移学習[4]という方法をとります。

転移学習(Transfer Learning)とは

CNNの画像認識をやるとき、ネットワークの重みを初期値から学習させることはまれで、一般的には学習済みの重みが再利用されます。これは転移学習と呼ばれ、比較的少ない教師データ、かつ短時間でネットワークを学習させられるというメリットがあります。これに関しては以下のチュートリアルが分かりやすいです。

TRANSFER LEARNING TUTORIAL

教師データをディレクトリに振り分ける

教師データのディレクトリ構造は以下のように学習用と評価用(それぞれ「train」、「val」に分け、下層にクラスごとにディレクトリを作ります。学習の際はルートのディレクトリ名(ここではcardamon1)を指定します。

cardamon1  
 ├train/  
 │ ├black/ (400ファイル)  
 │ └green/ (400ファイル)  
 └val/  
   ├black/ (100ファイル)  
   └green/ (100ファイル)

ここでは、ファイルの振り分け用に以下のようなスクリプトを作成しました。

(split_image_data.py)

試行1: とにかく数を、しかし過学習に

試料AとBをそれぞれ5サンプル、2台のWEBカメラで7.2度刻みで回転させながら撮影という戦略を取ります。これにより、サンプルごとに100枚を撮影でき、合計で1000枚の画像データが得られます。この時点では、十分な量の教師データだろうと考えていました。

試行1: 学習させる

学習を行う環境は、クラウドのGPUインスタンスが安価で便利です。ここではAWS(Amazon Web Services)のP2インスタンスをDeep Learning AMIで起動し、ライブラリやツールの準備をほとんどすることなくすぐに学習にとりかかります。AWSでの基本的なPyTorchの学習は以下をご参考にしてください。

PyTorchでシンプルな畳み込みニューラルネットワークを作ろう

AWSインスタンスを作成できたら、SSHで接続し教師データと学習用スクリプトをアップロードしましょう。WinSCPなどのファイル転送クライアントを利用してもよいでしょう。学習用スクリプトの全コードは以下です。

(transfer_learning.py)

学習が完了するとモデルが保存されるので、ダウンロードします。

試行1: 結果

結果的には過学習を起こしました。クラスにつき5サンプルという試料の少なさは、たとい細かく撮影角度を変えて大量の画像を用意したところで、各クラスの特性を一般化するには情報が少なすぎると推察できます。学習用スクリプトを実行した結果が以下です。

# python transfer_learning.py cardamon1

Epoch 0/9
----------
train Loss: 0.5644 Acc: 0.7242
val Loss: 0.3478 Acc: 0.9075

...
...
...

Epoch 9/9
----------
train Loss: 0.2609 Acc: 0.8952
val Loss: 0.0930 Acc: 0.9884

Training complete in 1m 33s
Best val Acc: 0.994220

試行2:

試行1ではサンプル数が小さく汎化性能が悪かった、つまり、各クラスの特徴を一般化できていなかったと考えています。そこで次は、試料の数を増やし、クラスごとに30サンプルを用意しました。グリーンカルダモンが50粒、ブラックカルダモンが50粒あります。また、それにより撮影時間が大幅に増えそうなので、撮影角度を大幅に大きくして120度としました。合計で600枚の画像のうち、500枚を教師データとします。学習の結果は以下です。

# python transfer_learning.py cardamon2

Epoch 0/9
----------
train Loss: 0.6062 Acc: 0.6595
val Loss: 0.3957 Acc: 0.8441

...
...
...

Epoch 9/9
----------
train Loss: 0.2917 Acc: 0.8689
val Loss: 0.1027 Acc: 0.9839

Training complete in 1m 16s
Best val Acc: 0.989247

推論

テストとして推論に使用するスクリプトは以下です。

(cardamon.py)

まとめ

以上、試料の数を変えて、2回にわたり教師データの作成と学習を行いました。また、試料は多い方が、全体の教師データ数が小さいとしても、結果的な学習の質は良いことも分かりました。数の観点では、教師データが多すぎて性能が落ちるということはないのですが、しかし現実的には、時間やその他のリソースとのバランスを考える必要があり、十分な性能が得ら得る最小のサイズの教師データ数がポイントとなります。しかし、それは定量的に判断しにくく、感覚や経験が効いてくるところでもあります。ぜひこれを参考にしていただければ幸いです。

参考情報

[1]ディープラーニングにもセキュリティ問題、AIをだます手口に注意
https://tech.nikkeibp.co.jp/it/atcl/column/15/061500148/111400137/

[2]PyTorch
https://pytorch.org/

[3]ResNet
https://arxiv.org/abs/1512.03385

[4]TRANSFER LEARNING TUTORIAL
https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html

WEBカメラの露光のばらつき

ロジクールのHD Webcam C270を利用して、深層学習の教師データを作成しています。WEBカメラは一般的なデジカメと比較してRaspberry Piからコントロールしやすく、安価で汎用性があるのが利点です。ただ、試験的に静止画を撮影するうちに、ある現象に気付きました。露出の設定値を固定しているのにも関わらず、撮影画像の明るさにばらつきがあるということです。もちろん、光源は安定した環境で撮影は行っています。

図1.サムネイルで明度のばらつきが確認できる

そこで、どの程度の明度差が生じているかを定量的に観察すべく、分析を行いました。方法としては、画像をグレースケールに変換し、画素値の平均をヒストグラムにプロットしました。

図2.グレースケール画像の画素平均

これより、明るい場合、暗い場合と2つの場合が傾向として観察できます。これは、サムネイルをざっと目視で観察していたときの印象と合致する結果です。原因はおそらくWEBカメラにあると推察しており、ハードウェア的にこの現象を回避するのは容易ではなさそうです。

そこで検討せねばならないのは、この現象をどう取り扱うかです。最終的な目的として、深層学習による未知画像の推論があります。その際に利用するのはやはり同じC270のWEBカメラであり、1枚撮影しただけでは比較対象がないため、明るくとれているのか、あるいは、暗くとれているのかを判断することができません。つまり、どちらの場合でも正しく推論できたほうがよく、教師データもそれに準じているべき、つまり、明るい画像と暗い画像両方を学習していればよい、ということが考えられます。

そもそも、教師データに与えるカメラ特性の影響はノイズであり、認識対象物に直接関係する情報ではありません。今回の考察により得られた課題として、学習に付随するノイズが推論に与える影響というテーマが浮かび上がりました。画像認識用の教師データにおける背景などについても同じことが言えると思います。この状態でいちど、学習を行ってみてもよいかもしれません。

ロジックレベルを3.3Vと5Vで双方向にコンバートする

Qiitaに執筆しました。

ロジックレベルを3.3Vと5Vで双方向にコンバートする
https://qiita.com/sudamasahiko/items/49b922e6ac8d050cde3d

とあるプロジェクトで、Raspberry Pi(以下ラズパイ)からマイクロサーボSG90を動かす必要がありました。その際気づいたのは、ラズパイからサーボ駆動に必要な5VのPWM信号が出力できないということ。困った(ただ、実際は3.3Vの信号でも動くケースが多いみたいです)。続きはこちら