ZENKEI AI ポッドキャスト、シーズン25は2022年1月26日に開催した ZOOMライブの模様です。
この日のテーマは「2022年は、ゆるく、インプット」です。
エピソード4は、メインの第二部、「2022年の画像分類」実践編。ZAF といえば五郎島データセット、ということで実際に新しいモデルを試してみます。
当日の市來の発表資料
zenkei-ai-podcast-20220126-04_q140.m4a
ビデオ見れる人はこちらからご覧ください。
(以下は、OpenAI の Whisper を使って文字起こししたものを修正したものです。)
ここまで、一通りきました。ということで、じゃあ僕たちがね、 ZENKEI AI FORUM が画像分類を実践しようと思ったら何を扱いますか?っていうと、昔々の ZENKEI AI セミナーの頃に遠田さんが持ち込んでくれた五郎島金時、サツマイモの画像分類っていう課題がリファレンスとしてずっとあるので、それで今の新し目のモデルを「挑戦してみよう」っていうことをやってみました。それの紹介が今日のメインの話です。
(ConvNext)
いきますね。 ConvNext はね、プログラムをインストールすれば、さっきも言ったようにFacebookがもう実装をGitHubに上げてるので、"git clone" ってパタパタってやれば、もう入ります。詳しいことは後でノートブックをシェアするかな、と思いますが。 PyTorchの環境があれば pip で、その他必要な timm を使ってますけども、インストールして、あとGitHubからソースコードをクローンして、インポートすればもうそれで使えます。僕が実験した環境ではですね、ローカルにGitHubのところからクローンしたフォルダをインポートするだけで、とりあえず実験してます……しました。
結果は後でまとめますが、っていうかね。 ConvNextのサイトに行ってみよう。FacebookのConvNextのサイトはこいつですね。はい。で、ここにですね、ImageNetの学習済みモデルが、もう提供されてます。で、これ、モデルをいちいち手でダウンロードしなくても、このソースコードをですね、さっきみたいにクローンして、きちんとインポートすればもうそれだけでモデルが使えます。ここにちゃんとファイルもですね、URLがコードに書いてあるので。
モデルのパターンがね、Tiny, Small, Base, Large, Extra Large ありますね。普通のPCで僕たちやってるんで、小さめのモデルを今回は使いました。 ResNetも18とかで結構精、度が出るんで、今回はConvNextに関してはTinyとSmallを実際に使って学習させてみました。モデルインポートして、ConvNextのConvNext SmallでPretrainedをTrueにして、ファインチューニングしました。
結果です。結果を簡単に紹介しますが、学習エポックは100いかないぐらいですね。ガーッと回して。そうするとValidation Accuracyが94%。で、実際に検証用のデータセットに対してサンプル数が794枚の画像に対して、失敗の数がですね誤認識の数が47個。っていうのがConvNextのSmall……じゃないTiny。
Smallの方がTinyよりもでかいんですね。だから精度上がるかな?と思ってたんですけど、全く同じ。全く同じっていうのは、サンプル数が794という、少なかないんですけども、それでも大きくないんで。もう間違いの数がですね47個ってきっちりSmallとTinyで同じだったんで、検証精度は全く同じだったんですけども。そしたら傾向も全部同じなのかな?って思って……。
五郎島っていうのは、今挑戦してるのは「8階級」っていう難しい問題をやってます。AIセミナーってね、2年前に最初に遠田さんが持ち込んだ時は「5階級の分類」っていうのを5クラスの分類をやってて、それはね、結構あっという間に90何% サクッと出て……99%?結構簡単だったんですよ。「そしたら」っていうんで、今、1年後かな、8階級、3つクラスを増やしてこ、「れで分類してほしい」っていう風な、難易度がちょっと上がったんですね。
そうすると結構難しくなって。今のところ僕たちがトライしてる時の社内State of the Artは……。ここでね47個失敗で94.08って上がりましたけども。今の僕たちの色々モデルを挑戦した中のState of the Art、社内のState of the Artは95.2とか、それぐらいのが一番精度がいいやつですね。それに結構、匹敵するぐらい……追い込んでないんで。パラメータチューニングとかモデルのチューニングとかしてないんで、軽い検証、初期検証みたいな形ですけども。ConvNext の Tiny と Small で47個の間違いで94% の精度。
今ここでお話ししたいなと思ってるのは、この2つ。モデルのサイズがちょっと違うだけで、モデルのベースは同じだから、傾向も47 と 47だったら、ほとんど同じなのか?っていう話に対して、「そんなこともないよ」っていうことをご紹介したいんですが。
8クラスのクラスごとに何個間違えてるかとか、どれを間違えてるかって見るとですね、Tinyの方がこんな感じね。で、ここの括弧の後ろに書いてあるのが間違い……分子の方が間違いの数なんですけども。で、これね、アンバランスなデータセットになってますが。2, 3, 2, 4, 9, 9, 1, 3, 5 がTinyの方で、これだけ間違ってるんですね。合わせると、足し算すると47。が、 Small 少し大きめのモデルで学習したら、 1, 5, 2, 5, 9, 7, 9, 9 って、全然数字が違って……全然っていうかね、数字が違ってきてるので、必ずしも同じ傾向で、47個って同じだけども、傾向も同じように間違ってるのか?っていうと、必ずしもそうじゃないな、っていう感じですね。
ここから期待されるのは「アンサンブルをこいつらで取ったら精度あがんじゃね?」っていう直感。当然、思いますよね。答えを言うと、やってみたんですが。このデータセットに関してアンサンブルをですね、いろんなモデル……。今回、今から紹介するのが8個ぐらいあるかな、モデル。全部組み合わせてやってみたんですけども、単独で一番いい精度を上回るような、アンサンブルの方が統計的に……あの、統計平均を取ることによって、モデルの統計平均を取ることによって単独の精度よりも上回るっていうケースが、発生しなかったです。だから、ちょっと期待したんですけどね。あの、傾向……外れ方の傾向が違うので、そういう別のモデルを組み合わせたら精度上がりそうな気がしたんですけども。世の中そう単純じゃないのかな、と今思ってますが。モデルの数が足りないのかもしれない。まだ現在進行形です。
(EfficientNet V2)
続き、いきます。今のは ConvNext。 ConvNextが「すげー、すげー」って言った時に、「EfficientNetのバージョン2を忘れないでね」っていうコメントがありました。なので、EfficientNetバージョン2をやってみましょう。EfficientNetバージョン2はどこにあるか?というと……どこにあったっけ?Qiita のサイトがありましたね。これですね。論文ですね。で、バージョン2の実装が……OK。リンクは後で共有します。
インストールは、ここにスクショがあるな。このサイトからインストールしました。つまり、オリジナルはTensorFlowかな?Jaxかな? PyTorch はオリジナル実装ではなくて、 PyTorch実装っていうものから引っ張ってきました。使い方は、やっぱりさっきの ConvNext と同じようにクローンしてきて、ソースコードを、Pythonの。
で、注意点というかね、注意点っていうほどではないですが、レポジトリの名前に「.」ピリオドが入ってるんで、これってPythonでインポートするときに問題になるんですよ。なのでクローンしたやつをリネームっていうか、シンボリックリンクで「efficientnetv2」っていうフォルダーにシンボリックリンクしといて、そいつをインポートするように、っていうひと手間が必要でしたが、それだけでモデルは使えました。
で、バージョン2でモデルはS, M とかあったかな。やっぱり一番ちっちゃいやつを試しに使ってみました。使い方は、さっき言ったようにインポートして、クラス数がね、イメージネットの pre-trained モデル……こいつはもしかしたらスクラッチからトレインしたかな?ですけども、出力が1000クラスではなくて8クラスにしなきゃいけないんで、最終レイヤーのリニアレイヤーを上書きして、っていうことをやって、五郎島を学習して、学習の結果ですね。
EfficientNetバージョン2は、間違いが55個。精度で言って93% ということで、ConvNext に今ね、仮にペッて100エポック弱くらいを回した範囲においては、ドーンと勝ってはいない、っていう感じでした。
後でまとめますが、クラス別のね間違いっていうのも、やっぱさっきのとまた別な傾向になってますね。「コロ」っていうのは難しいって言ってるモデルもあるんだけども、こいつは「コロ」が90%、1個しか間違いなくて、っていうような感じになったりしてます。
だから、なおのことね、全体で93% とか、さっきの94% だけど、それらをアンサンブルすればいく……と、やっぱり思いますよね、みんなね。なんか俺のアンサンブルの取り方間違っとんのかな?
ちなみにねロジットを出力にしてるので、きちんと、きちんとソフトマックスをして、足し算して、 argmax をしてるんだけど、なんかそれ間違ってるのかな?誰か Kaggler の人とかですね、アンサンブルの初歩で間違ってる人間に、なんか間違ってたら教えてください。
(Swin Transformer)
で、続けます。今のところ ConvNext と EfficientNet バージョン2をやりましたが、 Swin ね。マイクロソフトの Swin。これを試したかったんですよ。これのねインストールに結構手間取って。何が手間取ったかっていうとですね、 Swin の実装自体は今までのと同じようにね git でGitHubで公開されてるのでクローンしてくれば全部ソースコードもらえる……降りてくるんですけども。
それね、ここにまたシンボリックリンクしてます。こいつはねハイフンがあって。これ、ハイフンがあったままだってダメだったのかな?そうだな。マイナスは引き算のオペレーターになってるんで良くないんですね。ドットも良くないんですね。ドットはネームスペースの区切りに使われてるんで。なので Swin Transformer はシンボリックリンクで、ハイフンを除くものにしといて、それをインポートするようにしました。細かいことですけども。
んで、何だっけ。そうそうそうそう。パフォーマンスが欲しければやっぱりAPEXっていうね、 multi-precision のライブラリですね。単精度と半精度……ハーフプリセッションのライブラリーをきちんとインストールしたかったんですけども。PyTorch の CUDA のバージョンと、ドライバーの CUDA のバージョンが同じでないと、まあ当たり前なんですけどね、APEXのビルドが失敗するっていうか、ビルドしてくれない……当たり前なんですけども。ビルドしてくれないっていうんで結構、環境設定はめんどくさかった。それを揃えればできる話……簡単に make 一発みたいな感じでできます。で、それにちょっと時間を食いました、Swin は、っていう。自分が苦労したって話だけ、ですけども。
で、Swin は……そうそう。 Swin はね、学習済みモデルをね、自分で手で僕、ダウンロードしてきた。しなきゃいけなかった。あと Swin は arg... これねパーサーを、コマンドラインツールとして実装されてるんで……。これもね、うまい方法あるのかもしれないですけども、僕はもうやっつけで、とりあえず使いたいばっかりだったんで、ガーッと決め打ちでやっちゃってるのも良くなかったのかな?学習済みモデルのウェイトをローカルにダウンロードしといて、自分でロードしてるようなことをやりました。
でね、これハマったんですけども。みんなはハマらないかどうか分からないですけども。提供されてる state_dict だと思ってるダンプファイルがですね……僕の認識間違ってるのかな?モデルの下に state_dict があるので、load_state_dict() に渡すのはモデルの下だよ、 state_dict['model'] を渡さなきゃいけないよ、っていうのが一つ、ハマりました。 state_dict の中身見りゃすぐ分かる話ですけども。そういう注意点がありました、っていう共有事項で。
そうすると、とりあえず Swin は使えて。結果をお見せすると、こいつは間違いが 46 / 794。今ね 1, 2, 3 と3つ示しましたが、それよりも良いですね。一番、今のところ良い。94.2% のバリデーションアキュラシー。 Swin が今のところ一番良いのか、っていう感じですね。
(RegNet)
そう来といて、今回の新しいやつですね。 RegNetっていうやつも実験して。これは簡単に、もう PyTorchに入ってるんで、モデルを読み込むだけでいいや、って言うんで。ResNet のファインチューニング用のモデルのクラス、僕が書いてるやつ、そいつを置き換えただけにします。何が違うかっていうと、最終レイヤーの……なんだっけ、Adaptive Poolingのレイヤー以降を置き換えるようなモデルにして、っていうんで、RegNet の Y っていうやつの 8 と 16 っていう2つのモデルを試してみました。
で、これが結果だ。 RegNet Yの8は間違いが42個。今までの中で一番良いですね。精度で言って94.7%。もうちょっとでState of the Artに匹敵するところまで来ましたね、という感じです。
16っていうのは多分モデルがもう少し大きいモデルになるんだろうけども。なんかね、やっぱデータセットが小っちゃいのかな?システマティックな挙動が見れないのは、そのせいかなと思ってますが。16の方がちょっと悪いですね。46個間違いで94.2% っていうような感じになってます。
繰り返しになりますが、クラス別の間違いっていうのは、なんかモデルごとに傾向が違ってますね。後でサマリーをしますが、同じ RegNet シリーズの8と16でも、間違いの挙動が違いますね。という感じです。
(ViT)
で、これ最後ですけども。ViT ね。1年半前に、みんながYouTubeから一生懸命見てくれてる、100人くらいビューアーが見てくれてるモデルでね。その時の結果はどうだったかっていうと、これが結果なんです。68%。五郎島でね、ViTでね、やったら68。「全然ダメじゃん! ResNet で一発やっても94%、95% 出るのに」って、そのビデオで僕が叫んでますが。
果たして……果たしてっていうかですね、この頃の PyTorch……今回 RegNet とか出したように PyTorch のバージョンをちょっとアップデートしたので、ちょっと「ViTもやり直してみよう」と思って、やり直してみました、今回。
で、使ったソースコードはViTの PyTorch 実装っていうのをGitHubから、前と同じやつを持ってきました。 HuggingFace もViTのモデルを提供してるのかな?そっちじゃなくて、別なレポジトリーですけど、前使ったやつとそのまま同じやつなんですけども、今回使いました。それはこれですけども。"vit_pytorch" っていうプロジェクトを使ってます。
で、これパラメータとか、ファインチューニングっていうかパラメータチューニング、このチョイスが妥当なものかとか、取っ替え引っ替えしてないんで、もっと良くなるのかもしれない。ですし、こいつと Swin の関係……僕きちんと論文、まだ読んでないんで、こいつの修正版なのか改良版なのか、また別な話に…… Swin っていうのは別なラインになるのか、僕はよく分かってないですけども。
今ね、上でチャカチャカってやったら、 Swin ってそんなに悪くなかったですよね。94% ぐらい精度出てましたね。で、さっき見たように、1年半前、約2年前にViT は、僕がチャチャっと同じモデルでやったら68% っていう、とんでもなく低い結果になって「ViT 本当にいけんの?」っていう話でまとめましたが。さて同じ状況で、 Swin が94% になってるところで、どうなるかやってみたんですね。
結果、やっぱりちょっと悪い。っていうのが、間違いが、他のモデルとか今まで説明してきて、皆さんお聞きになった通りで、40……いいやつで42個の間違い、他のやつで46個とか47個とかでしたけども、こいつ79個間違い。79ってのは、分母が794個の画像ですから、それでも90% を超えてる。90.05% の正解率。なので、2022年1月26日の ZENKEI AI FORUM の市來健吾の検証は、1年半前の「ViT 68% しか出ねえじゃん」っていうのは、ごめんなさい、と。それは僕のトレーニングの仕方が悪かったのかな?68 なんていうことはありません。90% は出てます。が、他のモデル、つまり ConvNext とか EfficientNet バージョン2とか Swin とか RegNet さんたちに比べて、やっぱり明らかに精度が出てないな、と。これどうしてなのかなと、ちょっと要検討課題ですけども。
っていう感じです。ここには同じ詳細っていうか、同じ情報の粒度では上げてませんが、実は、今ね、紹介したモデル、1, 2, 3, 4, 5, 6, 7個のモデルの中で一番良かったのは、間違いが42個、精度として94.710% っていうRegNet Y-8 っていうのが一番良かったんですが、参考としてここに載っけてないですが、古き良き ResNet 18っていう一番小さい ResNet ですね。これPyTorchに入ってるモデルですけども。それを使って、同じデータセットで、今ね、ここ1週間ぐらいの話ですけども回して、トレーニングした結果が、間違いが39個。それがState of the Art。95% を超えてるやつ。出ました。
なので、ちょっとね、混乱してる。っていうか、混乱してるっていうんじゃないな。問題が、今ターゲットにしてる五郎島8階級分類問題っていうのが、サチってるっていうか、サンプル数、データセットのサイズが十分でかくない……さっきも見ていただいたように、これ検証用データの8クラスに対して画像が何個あるかっていうのを見てもらったら分かるんですが、「コロ」っていうクラスに関しては、検証用データ10枚しかないですね。トレーニングの方は、おそらく80% をとってるはずなので、40枚か、それでも。でも、それぐらいで、やっぱり数の規模が少ないのかなっていう懸念はありますが。
こういうね、系統的にいいと呼ばれてるモデルでいい結果が出なくて、古いっていう ResNet が一番いいっていうのは。何かっていうとですね、このグラフね。さっきも紹介したこのグラフの……。これ ImageNet 1000クラスの分類課題っていう、分類課題としては8クラス分類よりもずっと難易度が高い問題。その代わりデータセットが充実してるような問題に対して、いろいろモデルの良し悪しっていうのを議論するのが普通の人たち、っていうか研究の最先端ですけども。そこで ResNet がここで、今言った Swin とか ConvNext はこの辺に来てるよっていう。これ縦軸は正度ですけどね。五郎島8階級だと ResNet が一番よくて、この人たちも全部ドングリの背比べみたいになってる、っていうのは、やっぱり、あれだな。サンプル数が足りないのかな。
っていうですね、いつものいつものパターンで取り止めがないっていう、きちんと明確な結論が出ない形ですが、実際に動かしてみた。で動かした結果として、1年半前のViT さんを悪く言ってごめんなさい、と。90% で出ました。でも君は他の人たちよりも一番悪いよ、と。で EfficientNet もバージョン2とバージョン1、前のやつは PyTorch に入ってるんで比較……ここに今載っけるのは間に合いませんでしたけども、大きく前進、アップデート、改良されてるって感じはないんですね。なんで、やっぱり課題依存なんですよね、やっぱりね。
今回の知見で何が僕自身得られたかっていうと、最新のモデルを使おうと思ったら、画像分類に関してね、使えるような環境が整ったので、ちょっと Kaggle 画像分類コンペとかにちょっと顔出してみようかな、と。今まだ、画像分類のコンペって、 Kaggle でもやってるのかな?最近の Kaggle ってカーネルコンペ多いですよね。あれは、一回マスターすればいいんでしょうけどね。なかなか、久しぶりに、1年ぶりに「よっこらしょ」ってやろうと思うと、もうそこだけで疲れちゃう、っていうのはありますが。
まだ8時10分ですが、今日、僕が準備したお話は以上になります。皆さん楽しんでいただけたかな?あんまりゴリゴリのAIネタではないですが、皆さん楽しめるネタだったんではないかなと期待してますが、どうだったでしょうか?フィードバックいただけると嬉しいです!