「女の子」か「男の娘」か分からなかったのでAIを使って判別してみた
Keras + 畳み込みニューラルネットワークを使った分類と推論
この記事は klis Advent Calendar 2020 8日目の記事です。
What’s Klis? → http://klis.tsukuba.ac.jp/
目次
- 機械学習?
- やってみた!
- 結果
- あとがき
- コードと解説
解説とかいいからさっさと結果見せろって方には3まで。
女装文化に定評のある某大学付近。ある朝,
「どんがらがっしゃーん」
せっかく集めた男の娘の画像が女の子なのか男の娘なのかわからなくなりました。
何かが始まる予感…
はいっ,機械学習が始まりますね!
というわけで混ざってしまった写真を分類するために畳み込みニューラルネットワーク(; CNN)で教師あり学習をします。
今回の方法を使えば一般のご家庭でも簡単に出来ます。
GoogleのColabインフラを贅沢に使ってGPUで学習させていきます。
1. 機械学習?
機械学習とは今話題のえーあいの一つです。機械学習には
・教師あり機械学習(回帰・分類)
・教師なし機械学習(クラスタリング・主成分分析)
・強化学習(深層強化学習)
があります。
今回使うのは「教師あり」の「分類器」の「畳み込みニューラルネットワーク(CNN)」です。
CNNは画像を行列にしたあと,ある大きさの画像の特徴を読み出せるフィルターで特徴を順番に読み取っていって保存,保存したものをまたフィルターにかけ保存…というようどんどんデフォルメしていきます。
具体的には足し算と掛け算をしています。学習モデルを作るときにたくさん足し算と掛け算をして,結果を得るときにも足し算と掛け算をします。
こうして足し算と掛け算をしていき,
となったときに判断します。最小二乗法ですね。
2. やってみた!
実際の工程について説明します。
まず教師ありなので教師データが必要です。教師データはネットからそれぞれ「男の娘」と「女の子」の画像を収集します。
教師画像を収集:今回は300枚ほどあつめます。
最近はスクレイピング禁止のサイトが多いので,Selenium と ChromeDriverを用いてGoogle Chromeを自動制御して画像を保存します。
選別する
「日本はまだまだ元気だなぁ」とか「日本の未来が心配」になるような画像が沢山混じっているので選別して教師にふさわしいデータにします。150枚前後になりました。
データを増やす
150枚程度だと学習がはかどらない可能性があるので,データを水増しします。具体的にはKerasのImageDataGeneratorクラスを使い回転したり引き伸ばしたりします。それだけでいいのかと思うのですが,実際に精度は上がります。これで800枚ほどです。
前処理
フィルターで認識できるようにするためnumpy arrayという行列にしていきます。一般的なカラー画像はRGBですので1色ごとに1回読み取ります。そのため画素を一列にならべたもの×3の行列を作ります。
学習
学習モデルを作っていきます。今回は
- 男の娘
- 女の子
- ねこ
を分類していきます。ねこも可愛いのでわからなくなる可能性がありますからね。
ClassNames = ["男の娘", "女の子", "ねこ"]
仕様は入力が16×16,6層のPoolingはMaxPoolingです。
モデルを作って…
学習を進めます…
テストする
学習が終わったらテストをします。テストと言ってもあらかじめ教師データから何枚か分けておき,正しく認識する割合を見ます。割合が低ければ教師データを多くしたり,パラメーターを変更して直します。
やはり猫と人間は区別が付きやすいらしく,猫が特出して良いです。
精度7割はものたりない感がいなめませんが,めんd…
このまま行きたいと思います。
推論機
推論機をつくります。ファイルをアップロードすると推論結果が出てくるようにします。
3. 結果
まずは皆さんご存知lenaからです。さっそく間違った判定がでています。日本人のみの画像を使ったからでしょうか?
やはり日本人のデータの場合正しく認識出来ているようです。右下は女装したモデルさんです。
では本命,筑波大の男の娘といえば…
ミスコンにも出場したあの人です。
ん??
女の子でしたね。
また一つ筑波大学のレベルの高さを示してしまいました。
やはり門などという概念にとらわれていないだけあります。
4. あとがき
今回のアドカレもおもちゃで遊んだ感想でした。
お付き合いいただきましてありがとうございました。
メリークリスマス。
5. 解説的なにか
コードを置いておきます。
スクレイピング
こちらを参考にしてSeleniumを使いました。
データの水増し
データの水増しにはKeras ImageGeneratorクラスというKerasの標準クラスを使います。
datagen = ImageDataGenerator(rotation_range=90)
パラメータをいじることで様々な加工ができ,今回の場合は-90°〜90°の間でランダムに6枚生成します。
35行目の詳しい挙動ははあくしていませんがbatchを生成することで保存をしているようです。おそらくメモリにdatagenに展開したものを先頭から取り出しているのかなと思います。
本体
関数化して,前処理,モデル作成,推論機があります。こちらを参考にしています。
前処理は既にImageGeneratorで生成しているのでnumpy arrayを作成するのみになっています。
学習モデルではMax Pooling / Average Pooling /Poolingなしを試しましたが,MaxPoolingでDropOutが0.25のときに収束と精度のバランスが良かったです。
推論機の本体ではColabにあわせてアップロードしパスを取ってくるようにしてあります。
参考
Pooling関連
https://keras.io/ja/layers/pooling/
https://arakan-pgm-ai.hatenablog.com/entry/2018/11/16/090000