Category Archives: Python

Arxiv論文の翻訳サイト

前回公開した機械翻訳モデルのアプリケーションとして、arXivに投稿された人工知能関連の論文のメタデータ(タイトル・アブストラクト)とCreative Commonsライセンス(CC 0, CC BY, CC BY SA)の本文を日本語に翻訳するサイトを作成した。

Fugu-MT: arxivの論文翻訳

トップページでは投稿日別に最新3日の要約を表示している。メタデータ・本文の翻訳は日付別の参照から確認できる。全文翻訳がある場合はそのリンクを貼っている。

アブストラクトを要約・翻訳して一覧化も行っている。

Fugu-MT: arxivの論文翻訳(概要)

スマホなどで最新の論文をざっくり確認したい場合は便利だと思う。arXivのメタデータはCC 0なので要約や翻訳が可能である。

技術的な話

サイトの構成

このサイトはarXivのAPIを用いて人工知能分野の最新論文を取得、Fugu Machine Transratorを用いて日本語に翻訳している。PDF本文を翻訳するエンジンはリンク先のgithubにあるものを若干カスタマイズして使っている。

静的なWEBサイトで構成するため[1]に、翻訳結果などは基本的にHTML化して保存している。PDF情報もBASE64で埋め込んでいて、HTMLファイルをダウンロードすればどの環境でも翻訳文の閲覧が可能である。

CSSやJSはCDN経由としているので、「wgetでダウンロード」「ブラウザでリンク先を名前を付けて保存」などCSSやJSをローカルに保存する動きをしない方がうまく動く[2]。

2週間程度動かしてみてArxivに投稿された論文をライセンス別に集計すると大体1/3くらいは全文翻訳可能なライセンスとなっていた。最近Openなライセンスの論文が増えている印象で非常にありがたい。

作成したサイトでは30ページを超える論文は翻訳対象外としている[1]。30ページを超える論文の和訳が欲しい・Arxiv以外のサイトで翻訳可能な論文の和訳が欲しいなどの場合はFugu Machine Transratorでこのサイトと同じようなことができる(若干不具合があるので、今月中には修正予定)。

arXivへのアクセスはかなりゆっくりやっていて、API Limitやrobots.txtで決められた待機時間より2倍以上長めのwaitを入れているので更新は遅めかもしれない[3]。

要約処理

アブストラクトの要約にはPEGASUS: Pre-training with Extracted Gap-sentences for Abstractive Summarization論文)を用いている。PEGASUSはAbstractive Text Summarizationタスクで優秀なモデル(CNN / Daily MailでPapers with Code 3位[4])として知られている。論文のアブストラクトをさらに要約するにはExtractiveな手法ではイマイチであり、Abstractiveな要約手法を採用した。結果、まずまず良い感じに要約できているように思う。

所感など

arXivの日本語翻訳を行っているサイトはいくつかあり、また、arXiv Vanity を使ってブラウザの翻訳機能経由で日本語翻訳を行うことを紹介しているものもあった。arXiv VanityはPDFではなくそのソースであるTeXをベースにHTML化しているようで品質が高い[5]。正直、実用的にはこのような方法で十分だと思うが、自作ニューラル機械翻訳モデルの性能評価の意味を込めてサイトを作成してみた。

結果、アブストラクトについては大手翻訳サイトと比べても十分に比較可能なレベルで翻訳ができているように思う[6]。論文本体はPDFのテキスト化、英語文のsentence tokenizeに課題を抱えているためそこまで高精度ではないが「流し読みに便利」程度のレベルにはなっている。

Abstractiveな要約いわゆる抽象型と呼ばれる要約手法はExtractiveな要約(抽出型要約)に比べて安定した性能を出しにくいことが多いが、今回は翻訳を通しても文の破綻が少なくまずまずの性能が出せている。(要約部分も翻訳部分も意訳に近い動きをしているため、内容が変わることも少なからずあるが・・・[7])

前回TODOに挙げていた事を無視してarXivの翻訳サイトを作ってしまったが、良い経験にはなった[8]。英語のNLPでできる事は非常に多いのでFuguMTを便利に使ってもらえたら嬉しい[9]。

一応、1400万対訳ペアでのモデリング、1400万対訳→1000万対訳ペアへのフィルタリング(高品質化)なんかもやってはいるので、ぼちぼち翻訳エンジンの強化も再始動したいと思う最近。NLP周りの英語での成果を使うためにはEN→JAだけでなくJA→ENも必要なのでそのモデルも作ろうかなーとも思っている[10]。

脚注

[1] VPSのスペックによるもの・・・。
[2] ブラウザがJSやCSSをダウンロードし、リンクを書き換えるとうまく動作しないことがある。
[3] APIのデータは日本時間午前8時頃に更新されるがアクセス過多になっていることが多い。アクセス過多の時のwaitもかなり長めにとっているので新規論文リストを取得&論文のメタデータを取得完了するのは日本時間11時頃になっていると思う。(大体、次の日には和訳できてる、くらいのイメージ)
[4] 2021/2/14現在。リンク先にはExtractiveな要約が入っていない、PwCのLeader boardに載っていない結果もある、などの理由で実際の順位は不明。とはいえ、SOTAと比べて大幅に性能が低いわけではない。(正解が正解か怪しい世界でROUGEという微妙な指標を用いてベンチマークした結果よりも、要約したいドメインでの目検証の方が重要・・・。本件でも実は様々な手法を試している。)
[5] Robots.txt的にTeXファイルの取得はDisallowな気もしつつ、どう実装しているかは謎。
[6] 論文ドメインでのfine tuning無しの素の結果なので結構優秀ではなかろうかと自画自賛。ただ、語彙の点で負けている感はある。ニューラル機械翻訳モデルのパラメータチューニング&(やや反則だが)論文ドメインでのfine tuningを行えば大手翻訳サイトの性能を越えられるんじゃないかと思わなくはない。(がAWS費用がつらい)
[7] 要約文が破綻していても翻訳側で救っている場合もあった。要約結果があまりに変な文だと翻訳側が壊れる(同じ単語を繰り返す)みたいな事も起きる。
[8] 現実のデータと格闘しないと分からないことは多い。
[9] 日本語版のpre trainedモデルがたくさん公開されるとかNLPは日本語版がSOTAみたいな時代が来ると嬉しいが、現実は厳しい気がしている。マルチリンガル方面は流行なので、それで解決される可能性も感じているが・・・。
[10] GPU買っちゃおうかなーとも。対訳データを1円/wordくらいで買ってくれるとこないかな、、、

翻訳エンジンの構築(Marian-NMT)

夏休みの宿題(?)としてMarian-NMTを使って翻訳エンジンを構築してみた。構築した翻訳エンジンは「英語→日本語翻訳(https://devneko.jp/demo/)」から試すことができる。訳すべき単語を飛ばすなど深層学習な機械翻訳特有のミスをすることも多いが、個人が試作したものとしては相応の性能な気がする。割と訳せていて正直驚いた。ただ、入力文の適切な分割など前処理的な事をほとんどやっていないので変な結果になることも多い。

データセットは「WEB クロール + Universal Sentence Encoderで収集したデータセット」+「Free(Creative Commonsライセンスなど)のデータセット」、使用した手法はTransformer + sentence pieceであり、バリバリのDeep Learningで現時点でも本格的である。ただし、環境制約(というか時間制約&予算制約(後述)からBack Translationは使えていない。)

上記エンジンでは300文字以内の英語文(複数文の場合性能は落ちる) [1] を日本語に翻訳することができる。訳抜けを防止するモードもあるが、カンマや記号で文を分けているだけなので訳抜け防止モードの性能はあまりよろしくない。

翻訳エンジンを作った理由

本当は日本語でGPT-2辺りのfine tuningを試そうと思っていて「Faster than training from scratch — Fine-tuning the English GPT-2 in any language with Hugging Face and fastai v2 (practical case with Portuguese)」という素晴らしい記事を読んでいた。その中に「For example, to obtain a Portuguese GPT-2, we could download from the Transformers library of Hugging Face the OpenAI GPT-2 pre-trained in English and the MarianMT translator」という記載があったものの、残念ながら「日本語→英語」のモデルは公開されているが「英語→日本語」 のモデルは公開されていなかった[2]。

自由に使える翻訳エンジンは役に立ちそう[3]なので自分で構築することにした。車輪の再発明ではあるが、色々と良い経験になったと思う。

翻訳エンジンの作り方

翻訳エンジンを作るにはデータセット、学習用ソフトウェア、学習環境が必要である。今回は下記を用いた。

  1. データセット: WEBをクローリングして収集[4]+Freeで公開されているものを追加 [5]
  2. 学習用のソフトウェア: Marian-NMT (transformer) + sentencepiece [6]
  3. 学習環境: AWS p3.2xlarge インスタンス [7]
Read more »

AI診断の信頼性:XAI(Explainable Artificial Intelligence)とLIME

これまで3回にわたって、AIで植物の病気を診断するサイトを作った時の話をまとめた。「その他」の所に「作ったモデルにイマイチ自信ないわー」と書き続けた気がするので、(正しく)Deep Learningな人工知能(AI)を構築する難しさと、その対応について記事にしてみた。

Deep Learningを使用したモデルはイマイチ信頼できない

ラノベのタイトルみたいだなーと思いつつ・・・。色々な場所で言われている通り、Deep Learningを使用した判別モデルが実際のところ何を行っているかを知るのは簡単ではない。AIに限らずだが、モデル作成を長くやっているとクロスバリデーションで高精度なモデルが現実世界では全く使えない状況に遭遇する。特に、ドメイン知識から考えてモデルに納得感が無い場合、「評価設計が間違えている」「リーク情報(leakage) を拾っている」「データのバイアスが影響している」事が原因で、現実問題に対して有効でない事が多い。納得感はまっとうなモデルを作る上でとても重要である。私は何をやっているかわからない(説明可能性がない、納得感のない)モデルを用いることに恐怖感を感じるし、それを信頼して使うことは出来ない。(そーいうこともあり、でぃーぷらーにんぐは、しょうじき、しごとではあんまつかいたくない。(画像が対象ならいろいろ確認しつつ使うけど・・・。))

Deep Learningを説明する取り組み

Deep Learningのような複雑なモデルを説明する研究が進んでいる。アプローチとしては、Deep Learningの各層がどのような入力に強く反応するかを調べる方法が有名で、Feature Visualizationに詳しい。その他の手法として、入力を変化させながらモデル出力の変化を見る方法がある。前々回紹介した「“Why Should I Trust You?”Explaining the Predictions of Any Classifier」で提案されたLIME(Local Interpretable Model-Agnostic Explanations)は、入力近傍の動きを探ることでモデルの説明を行う方法である。ブラックボックスなモデルであっても、妥当な動きが見られれば信頼できる、少なくとも、信頼を得る材料にはなるという考え方である。

LIMEを試してみた

LIMEを行うソフトウェアは

pip install lime

でインストールできる。LIMEはモデル構築手法を選ばず適用できるが、scikit-learnやkerasを使っていると利用しやすい。植物の病気診断サイトはkerasを用いたモデル構築を行っており、limeのチュートリアルに沿って診断根拠を把握することができる。
下の画像は典型的な黒星病の葉であり、植物の病気診断サイトでは99%の確率で黒星病であると判定される。

これは正しい判断であるのだが、正しく画像を判定して黒星病と診断しているのか、たまたま黒星病と判定しているのか、何らかのリーク情報を拾っているのかはパッと見はわからない。LIMEを利用すると、AIがどこに反応しているかある程度把握できる。LIMEを利用した結果は下記のようなものとなる。(画像の大きさはモデルの前提にあわせて変更している。)

上の画像では黒星病と判定するにあたって注目した部分を黄色で囲んでいる。画像中、左部分と中央部分は黒星病診断で重要となる黒の斑点を診断根拠して提示しており、納得感がある。一方で右上のバラのトゲ部分を診断根拠している点には違和感がある。これは「黒星病の写真にトゲが写っている画像が多く、診断にあたりトゲに注目するモデルができている」「黒星病を(トゲがある)バラ特有の病気だと認識した」などと解釈できる。LIMEの結果は人が解釈する必要があり、それにはドメイン知識とモデル(データセット含む)の知識が必要となる。本件ではデータセットのほとんどがバラの写真であることから、前者の疑いが強い。

上記は「画像は健康な葉か?」を診断した結果であり、緑の部分は「この葉が健康であると診断する場合、ポジティブな要素として用いる部分」、赤の部分は「この葉が健康であると診断する場合、ネガティブな要素として用いる部分」を示す。画像上部の緑一色の部分が「健康そう」とした根拠、黒星病の特徴である黒の斑点が「健康でなさそう」という判断根拠とされている。この点は納得感があるが、地面部分も「健康でなさそう」という判断根拠とされていて、違和感がある。「地面の画像とともに健康な葉が提示されている画像が少なく、黒の斑点以外に注目してしまう」「茶色の地面を”枯れている”と誤認識した」などの理由が考えられる。
LIMEを利用することで、AIがどのように診断しているかをある程度可視化することができ、納得感が無い場合はどのように修正するかを判断できる。本件ではおそらくデータセットに問題がある。一応気をつかって撮影したはずのデータセットを用いていても、このような問題を内包している。きちんとしたAI構築は簡単ではない。(コードを書いて実行するだけなら簡単だけど・・・。)

XAIの重要性

説明可能なAIをXAI(Explainable Artificial Intelligence)と呼ぶ。前述のLIMEはXAIを実現するための1手法としても位置づけられる(完璧とは言いがたいが)。XAIは、AIが実務で使用されるにつれ重要となっていくテクノロジーであり、私は2つの側面があると考えている。

  1. モデル構築者の不安を解消するテクノロジー
  2. 社会にAIが受け入れられるためのテクノロジー

1.の観点は前述の通りで、ある程度説明性がないと、構築したAIが現実でうまく動くのか不安で仕方ない私のような人を手助けするモノである。(が、この点を重視する人はほぼいない)
2.の観点は重要である(というか本来的な意味はこっちの方である)。これに関連し、モデルの判断について「説明を受ける権利(right to explanation)」があるとする考え方もあり、GDPR2018でも話題になった。GDPRにおいて「説明を受ける権利」が存在しているかは議論がある(左記が整理された論文その日本語の解説)が、この手の権利が今後重視されることは間違いない。

公平性、FADM(Fairness Aware Data Mining)

公平性の観点からも判断理由の説明は重要である。例えば、「この家を買うと、収入に比べて、借入額が多すぎます。そのため、あなたにはお金を貸しません。」という判断には納得感がある。ある意味、相手のことを思い「無理な返済計画の後、破産しないよう」判断しているとも言える。一方で「あなたの名前は怪しいので、お金を貸しません。」という判断には納得できないだろう。不利に判断される名前が、ある地域に特有のものであれば、差別に繋がる判断として大問題となる可能性すらある。
Deep Learningだ、AIだ、人工知能だ、とテクノロジーを使って何らかの判断をするのは良いのだが、データセットや手法に依存して、差別的なモデルが作成される可能性がある。このようなモデルが運用されると、差別を助長する方向で判断がなされ、その拡大につながりかねない。クロスバリデーションで確認した、統計分析した、など理由があっても、現実世界で「差別的な判断」は受け入れられないだろう。
前述のお金を貸す例でいうと、差別は下記のように広がる。

  1. 特定の名前の人(複数)がお金を返さなかったデータが存在する状況下で
  2. 何も考えずに、名前も判断材料とする「AI」を作り、運用すると
  3. 「AI」は特定の名前の人に不利な結果を返すため、その名前の人に提示される金利は上がり
  4. 特定の名前の人の破産率は上がって、1.に戻る

名前には地域や生まれ年(=年齢)が反映されており年収と関連する。「名前」を入れることで精度が上がる「AI」は作成可能だが(現時点でも)実務屋としては「これはダメです」と言わないといけないんだろーなーと思っている。書いていても思うが、実際の関連性も怪しいし。
現時点では微妙としても、GDPRのような規制が進んでいくと、差別的な判断が法的・社会的に問題となるだろう。現在、持てるデータをすべてつっこみ作られた作成者すら何が起きているかよくわからない「AI」が増えている。知らず知らずのうちに差別的な「AI」を運用し、その結果大炎上する可能性は高い。公平性・説明可能性は今後重要性を増していく。
公平性はFADM(Fairness Aware Data Mining)といったキーワードで研究が進んでいるが決定打となるテクノロジーは存在しない。いくつかの手法が提案されているが、差別の定義が難しかったり、計算コストが高かったりと運用が難しい。一方で、今でも(人間の判断でも)差別が行われている可能性はある。差別とは何か?が定式化され、数学的に差別がないと保証された方法ができれば、世の中が良くなるかもしれない。人工知能ブームでいろんな議論が盛り上がっているし、企業によってはお金もあるしで、この手の研究が進めばよいなーと思う。(結局、結論は前回と同じ)

WEBアプリ構築(keras+uwsgi+bottle)編+まとめ&AI構築の悩み(3/3)

前回、前々回から引き続き、植物の写真から病気を判別するサイト(http://www.plant-check.jp/)を作ったときのまとめ。今回はWEBサイトを構築したときのまとめ。

WEBサイトの概要

リンクにあるとおり、WEBサイトはシンプルな作りとなっている。大きなユースケースは下記の2つ。そしてやることはほとんど同じ。

  1. ユーザがサイトの「写真を撮影」ボタンを押すと、自分のスマホから写真を撮ることが出来る。次に「病気をチェック」ボタンを押すと、取った写真の植物が病気か判定される。
  2. ユーザがサイトの「写真を選択」ボタンを押すと、自分のPC/スマホから写真を選択することが出来る。次に「病気をチェック」ボタンを押すと、選んだ写真の植物が病気か判定される。

HTML部分

スマホ経由で写真を取らせるにはcapture=”camera”を使えばOK。

 <input type="file" accept="image/*" capture="camera" id="camera" style="display:none;" name="upload" />

それ以外の部分として、labelタグを使ってボタンを隠したり、若干JavaScriptでボタンの活性・非活性を切り替えたりしているが特殊なことはやっていない。

サーバ部分

サーバ部分の構成は次の通りで、こちらも特殊な構成ではない。

  • sakuraのVPS(ubuntu 16.04 LTS)
  • Docker
  • nginx
  • uwsgi
  • Pythonのアプリ
    • bottleを利用してモデル部分(keras + tensorflow)とWEBアプリ部分をつなげた。

uwsgiとnginxのつなぎはSocketを使用した。(nginx側 uwsgi_pass unix:/path_to/uwsgi.sock、uwsgi側 socket = /path_to/uwsgi.sock )良くわからない場合は、公式サイトのサンプルを見ながら書くのが一番だった記憶がある。
Pythonのアプリ部分はbottleを用いて書いた。毎回毎回モデルをロードするアプローチはさすがに富豪過ぎるので、起動時に判別モデル(植物か否か、病気か否か)をロードしてそれを使いまわすようにしている。
一点はまった点としてuwsgi.confでthreads = 1、enable-threads = falseとしないと動作しなかった。当時forumを確認した感じではkerasのpredict処理がマルチスレッドに対応していないのが原因だったと記憶している(が、モデル読み込み時にフリーズしたような記憶もある)。それと、bottleの制約のようだが、巨大ファイルをアップロードされた場合の対策(chunkごとに読みこんで、一定以上のサイズの場合は処理を停止)を自分で書かないといけないのが面倒だった。

まとめ

モデル構築部分のコード行数は約100行(×2)、サーバ部分のコード行数は約200行だった。「AI(人工知能)が病気を診断!」というサイトがこの程度の行数で書けてしまうのは、便利なライブラリが整備されたおかげで、作者に感謝である。もっとも、モデル構築部分はノウハウ含めて自動化されていくはずで、大手各社もAutoML、Azure Machine Learning、・・・と言った名前でそのような環境をリリースしている。
AIやら人工知能やら何やらの主戦場は、結局何するの?という方向か、ほんまに使えるの?という方向になる気がしていて、クロスバリデーションベースのモデル精度を競っても無意味な時代になりつつあるんだろうなーと思う。(ということで私は自動化大歓迎、その他の思いはその他へ)
今後、情熱が復活すれば他の病気への対応を行う予定。もう少し実験したいことがあるので、コードを公開するのはその後になる見込み。
Read more »

モデル構築(keras/tensorflow+InceptionV3+Data augmentation)編(2/3)

前回から引き続き、植物の写真から病気を判別するサイト(http://www.plant-check.jp/)を作ったときのまとめ。

モデル構築の流れ

前回書いたとおり、今回、(1)植物の葉かそれ以外かを判別する2値分類モデル+(2)植物の葉が病気か否かを判別する多値分類モデルを作成した。構築方法は(1)、(2)ともに同様でkeras, tensorflowを用いて転移学習を行った。モデル構築の流れは下記の通り。バリバリのDeep Learningなので、人工知能(AI)を利用し、植物の病気判定を行った!と言っていいはず(大事なことなので2回目)。

  1. 写真をラベルごと((1)は「植物の葉/それ以外」、(2)は「健康な葉/黒星病/うどん粉病/その他カビ系の病気」)ごとに別のディレクトリに格納する。
  2. kerasを使ってImageNetを学習したInception V3をロードする。
  3. ロードしたモデルの一部(今回は250層以降)を学習可能に設定する。
  4. 問題(2値 or 多値)に応じて、Inecption V3の後段のネットワークを設定する。
  5. 写真データを学習用と検証に分ける。
  6. 写真データをdata augmentationするよう設定する。
  7. 学習、検証する。

モデル構築のコード

上記1.~7.のフローはkeras (+ tensorflow)を用いると簡単に実装できる。2値分類モデルにおける、2.~4.は下記のように実装可能。多値の場合は最終層を「predictions = Dense(クラス数, activation=”softmax”)(x)」てな感じに変えて「loss = “categorical_crossentropy”」とすればよい。ざっくりいうとニューラルネットワークの前段として学習済みのネットワークを用い特徴量抽出等を再利用(=転移学習)し、本件で必要な分類を行うネットワークを追加している。

base_model = InceptionV3(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation="relu")(x)
x = Dropout(0.5)(x)
x = Dense(256, activation="relu")(x)
predictions = Dense(1, activation="sigmoid")(x)
model = Model(inputs=base_model.input, outputs=predictions)
for layer in model.layers[:249]:
   layer.trainable = False
for layer in model.layers[249:]:
   layer.trainable = True
model.compile(loss = "binary_crossentropy", optimizer = optimizers.SGD(lr=0.0001, momentum=0.9), metrics=["accuracy"])

Data augmentationは画像を変形(回転、移動、縮小、拡大などなど)させながらデータを増やして学習する方法である。画像を変形させることで、1つの画像から複数のパターンを生み出す。日本語だとデータ拡張とか呼ばれている(はず)。写真の撮られ方に依存する差異等が吸収できるので、未知データに対する性能の向上に効果がある(と私は思っている)。モデル適用時にも変形させながら何パターンか適用し、その平均を取ると性能向上効果がある(こともある)が、こっちをデータ拡張と言うかはよくわからない。
kerasだと「ImageDataGenerator」を使って簡単に書ける。多値の場合は「class_mode = “categorical”」に変更すればよい。学習データと検証データのsplitを事前に行っていれば、同じようにtest_generatorをかける。

train_datagen = ImageDataGenerator(
    rescale = 1./255,
    horizontal_flip = True,
    fill_mode = "nearest",
    zoom_range = 0.3,
    width_shift_range = 0.3,
    height_shift_range=0.3,
    rotation_range=90)
train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size = (img_height, img_width),
    batch_size = batch_size,
    class_mode = "binary")

学習は下記のように行えばよく、チェックポイントごとにモデルが保存され、精度に応じて自動でストップされる。nvidia-dockerのコンテナでGPU版のtensorflowを入れていれば、GPUを用いた学習が行われる。とても便利。

checkpoint = ModelCheckpoint("/保存用ディレクトリ/モデル名_{epoch:02d}.h5", monitor='val_acc', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)
early = EarlyStopping(monitor='val_acc', min_delta=0, patience=10, verbose=1, mode='auto')
model.fit_generator(
    train_generator,
    samples_per_epoch = nb_train_samples,
    epochs = epochs,
    validation_data = validation_generator,
    nb_val_samples = nb_validation_samples,
    callbacks = [checkpoint, early])

今まで紹介したコードは、だいたいkerasのsampleコードをベースにしている。自分でやってみたい方はkerasのチュートリアル(https://keras.io/ja/内のリンクから飛べる)を読むのがお勧めである。

モデル構築のポイント

コード自体は簡単に書け、実行してみると検証データでの精度も良いと見える結果が得られる。が、実際に重要なのは「未知データに対する予測性能」で、思ったとおりの結果にならないことがある。これは学習・検証データの関連が強すぎるから(=独立じゃないから)で、学習結果を評価する上で重要なポイントとなる。この手の問題への対応はとっても難しい。私は人工知能やらAIやらと呼ばれるモノの中には、正しく評価されていない、過大評価なヤツも多いと思っている。
Deep Learningを使った場合(特に本件のような非常に複雑なネットワークを組んでいる場合)、「黒星病の特徴である黒の斑点を見て、黒星病と判断している」など「AIの判定に納得感があるか」はわかりにくい。検証すると、「AIはバラが植わっている鉢の色に注目して病気だと判別する」場合もある(詳しくは後述*1)。
このような動きはモデルの説明可能性の文脈でよく話題になっていて、たとえばKDD 2016の「“Why Should I Trust You?”Explaining the Predictions of Any Classifier」に詳しい。論文中の対応案は、まずまず良く動くが、速度面など使い勝手はイマイチという印象を受けた。説明可能性は重要な分野だが、現時点で決定打となる対応策は存在しない。
本件では写真を撮ったのが自分自身ということもあり、背景や鉢が注目点とならないよう気を使っている。具体的には病気の葉と健康な葉それぞれを同じ木・背景で撮影する、様々なパターンを混ぜるなど、変な場所に注目されないようにデータを作成している。
モデルの学習時には完全に未知のデータで検証がされるようにし、また、手動でAIが間違いやすいパターンの解析・チェックを行っている。割と丁寧に判別モデルを作っているが、それでも、「未知データに対する判別能力」は「検証結果として数学的に求められた能力」ほど高くはないんだろうなーと思っている。
Read more »