こんにちは、技術開発の三浦です。
毎朝コーヒー豆を挽いてコーヒーを淹れるのですが、コーヒーを淹れるためには豆を挽く、お湯を沸かす、フィルタのセットをする・・・といった具合にいくつものタスクをこなす必要があります。
調子のいい日は全てのタスクが無駄なく進み、いい感じにコーヒーが仕上がるのですが、どこか調子が狂うとモタモタしてしまったり、フィルタをセットする前に挽いたコーヒー豆を入れてしまったり、お湯をこぼしてしまうといったミスをしてしまいます。
そしてコーヒーを上手く淹れられない日は、なんとなく他のことも上手くいかないことが多い気がします。朝コーヒーを淹れる習慣は、自分のその日の調子を測る為にもいいなと思い、ずっと続けています。
さて、今回は入力画像に対して説明文を生成するImage Captioningという技術について、ご紹介したいと思います。
Image Captioningとは
Image Captioningは入力された画像に対する説明文を生成するタスクです。画像の意味を理解し、別の形式(モダリティ)のデータであるテキストに変換する、マルチモーダルAIを実現する技術と言えます。
画像をテキストに変換できることによるメリットは色々あります。画像データだけだと管理がしづらいですが、そこにテキストデータが紐づけば検索性も上がりますし、タグ付けなども可能になります。また画像データよりもテキストデータのほうが構造化されたテーブルデータとの相性が良いことが多いので、他のデータと合わせた機械学習モデルの構築などにも利用しやすくなります。また、そうして作られた機械学習モデルは、説明変数として画像の説明文に出現する単語の出現回数などを使用すると思いますので、モデルがより解釈しやすくなる、というメリットもあります。
実現に向けて
Image Captioningは最近はTransformerの構造を取り入れて実現することが主流のようです。Transformerは主に自然言語処理の領域で効果を発揮してきたモデルですが、その領域を画像にも広げており、現在の深層学習を支える非常に重要な技術要素です。
今回は以下の書籍を参考にしながら、Transformerを使ってImage Captioningを行ってみました。学習にはMSCOCO2014のキャプション付きの画像データを使用しました。
- title: Advanced Natural Language Processing with TensorFlow 2
- author: Ashish Bansal
- isbn: 9781800200937
- publication date: February 2021
- publisher: Packt Publishing
上記の書籍の中で、主に「Multi-Modal Networks and Image Captioning with ResNets and Transformer Networks」のchapterを参考にしています。今回はファーストアプローチということで、詳細なことはいったん置いておき、まずは動かして全体を理解することを目標にしました。理解した内容も、文章よりも図で残した方が分かりやすいので、今回はいつもよりも少し図が多めな内容になっています。
モデルのアーキテクチャ
Transformerを導入した、Image Captioningモデルの全体図を以下に図示します。
CNNによる特徴抽出
画像データをTransformerに入力するために、ImageNetデータセットなどで事前学習済みのCNNに入力し、特徴抽出をします。 使用する事前学習済みモデルについては色々と選択の余地があるようで、今回はResNet50を使用しています。ResNet50の出力層を除く最後のレイヤーの出力サイズが7x7x2048で、それをさらにReshapeして49x2048のテンソルに変換したものを特徴量として使用します。
49個の、2,048次元に埋め込まれたトークンで構成されたデータに画像を変換した、というイメージが分かりやすいです。
Transformer-Encoder
CNNで画像から抽出した特徴量は、TransformerのEncoderの構造で、複数のEncoderBlockを通過して変換されていきます。EncoderBlockの構造について、以下に図示してみました。
Transformer-Decoder
Decoderの方は、入力されたトークンに対し、文章として次に来るべきトークンを予測する機能を学習によって獲得させます。DecoderBlockはMulti-Head-Attentionを2つ含んでいて、1つ目は入力シーケンス自身に対するAttention、2つ目はEncoderの出力に対するAttentionです。2つ目のMulti-Head-Attentionで画像データの持つ情報がテキストに取り込まれます。DecoderBlockの構造についても以下に図示してみました。
EncoderよりもDecoderの方が機能も構造も複雑だと思います。1つ目のMulti-Head-Attentionにも工夫があり、シーケンスの順番で自身よりも先にあるトークンについてはAttentionの対象にしないようにしています。Decoderの目的が、入力されたトークンに対し、次に来るべきトークンを予測させることにある為です。
モデルの入力と出力
モデルの入力と出力について、以下の図にまとめてみました。
ポイントはテキストの入力と出力で、入力テキストのトークンに対し、モデルは次に来るべきトークンを予測します。ですので全体でみると入力テキストに対して右にトークンを1つシフトしたテキストが出力されます。モデルを推論で利用する場合、最初は<start>
トークンのみのテキストを入力し、次に来るトークンの予測を得ます。今度は<start>
トークンに予測されたトークンを結合したテキストを入力し、次に来るトークンの予測を得て・・・といったことを<end>
トークンが出力されるまで繰り返し、推論の結果として文章の説明文を得ることが出来ます。
テスト
では実際に画像に対してどのようなテキストが生成されるのかを見ていきたいと思います。
まずはこちらから。以前このブログでも記事にしましたが、私がはんだ付けをしている写真です。
おしいです!"ハサミ"ではなく"はんだ"ですが、人が何かを持っていることまでは認識できているようです。何より、自然なテキストがちゃんと生成されていることに驚きました。
次はこちら。今度は私がblenderという3DCGソフトで作ったスプーンのイラストです。
うーん、これは何だろう。金属っぽさがハサミにつながっているのでしょうか。どこを人として捉えているのでしょう。
最後はこちら。我が家の壁掛け時計です。
時計であることは認識できています。しかしテキストはだいぶ不思議な感じです。なんだか深いです。
今後の方針など
学習データの総量が少ないためか、出力されるテキストの語彙力が弱い印象を受けました。もっとこのモデルに色々なことを知ってもらいたいと、心の底から思いました。もちろんキャプション付きの画像データをもっと集める、というアプローチもありますが、大規模なコーパスデータであらかじめ事前学習させたモデルを利用する、というアプローチも考えられます。
あとは画像特徴量抽出用のCNNを別のものに変える、CNNも学習対象にする・・・など、考えられるアプローチは他にも色々あります。
Image Captioningをやってみて、とても興味深い技術だと感じました。今後、もっと力を入れて取り組んでいきたいです!