「Python で学ぶ画像認識」の画像キャプショニングのプログラムを Mask Predict による非自己回帰型に改修しました。

## 改修を行った動機

音声合成、音声認識、機械翻訳、画像キャプショニングなどで、downsample や upsample を用いて Transformer を非自己回帰的に使う方法を提案させていただきました。画像キャプショニングについては精度があまり良くありませんでした。

https://qiita.com/toshiouchi/items/b991d3ada79f0e1f6ce5

downsample の非自己回帰型プログラムの精度と自己回帰型プログラムの精度の違いの原因は、Transformer Decoder の q 入力、すなわち target 入力に、キャプションに関連した入力を入れるかどうかのように推察されました。donwsample 非自己回帰型プログラムの target 入力は、エンコーダーの出力を downsample したものであり、キャプションとは関係ありません。一方、Mask Predict の target 入力は、キャプションに mask をかけたものなので、キャプションに関係あります。そこで、Mask Predict による非自己回帰型プログラムではどの程度の精度がでるか試すことが目的になりました。現在のところ、downsample による非自己回帰型プログラムより精度は良さそうです。

## 学習に用いたデータ

データは本にある cocodataset の val2014 から、精度を確保するために train2017 へと変更しました。train：90 %、validation：10 % としました。

## 結果

本で demo に用いている画像でキャプショニングを行った結果を掲載させていただきます。

![adorable-1849992_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/c5a39797-0d4c-52ac-7a9f-2132786a3495.jpeg)

&lt;start&gt; a dog and a dog trying to catch a with &lt;end&gt;

![africa-1170179_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/4ca90fd0-583b-48b3-2615-c5f19db69d69.jpeg)

&lt;start&gt; giraffes giraffes giraffes in a grassy area near and and &lt;end&gt;

![airplane-3702676_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/1dc6f373-ad09-88a3-9a35-39cd575e8700.jpeg)

&lt;start&gt; a large air air jet is over airport airport &lt;end&gt;

![automotive-1846910_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/5998787e-b2f3-3c12-2b64-48861e8e7ddc.jpeg)

&lt;start&gt; a red and red red hydrant on a city street &lt;end&gt;

![beach-1837030_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/c8126d9b-c2f4-38c3-9950-9a867beb7cd5.jpeg)

&lt;start&gt; a male boarder is a waves in the ocean &lt;end&gt;

![caravan-339564_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/8c519e2c-e947-6b73-4a79-08b828b98e42.jpeg)

&lt;start&gt; a man with a umbrella standing on a beach &lt;end&gt;

![cat-4467818_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/42d5d8c7-7e8d-6572-6650-b639a677c24b.jpeg)

&lt;start&gt; an orange cat sitting on top of a red skateboard &lt;end&gt;

![cherry-1468933_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/9b34dbae-26d9-4560-812c-d2d48b46aca6.jpeg)

&lt;start&gt; a bowl of a an a a a and and and &lt;end&gt;

![couple-955926_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/c2556b2a-3670-cbfb-a79e-336511d1febb.jpeg)

&lt;start&gt; a woman sitting on bike beach a lots of water &lt;end&gt;

![dog-7367949_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/fa7c3e7b-3fee-e3de-6330-56cb1c4267ed.jpeg)

&lt;start&gt; a man is on a surf board is playing water &lt;end&gt;

![hit-1407826_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/6d49a796-644c-0b63-6a50-3e424d1cac66.jpeg)

&lt;start&gt; a baseball player with a ready to hit a ball &lt;end&gt;

![man-498473_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/aa7d9205-b4f5-b26f-2f8a-b77f8c3da9c3.jpeg)

&lt;start&gt; a snow boarder down a covered on a ski slope &lt;end&gt;

![musician-743973_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/c684214f-65d6-216e-515c-38d443142507.jpeg)

&lt;start&gt; a group of people with with boards boards on the beach &lt;end&gt;

![port-5788261_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/f7d85166-1299-6946-b6e4-d52a4897a01e.jpeg)

&lt;start&gt; a clock building with a tower on a city street &lt;end&gt;

![profile-7579739_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/ff41d937-60fe-eada-858d-cb90bec25c28.jpeg)

&lt;start&gt; a man doing on with on skate board &lt;end&gt;

![ural-owl-4808774_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/ff2199de-9ba4-1798-429f-94c7dba04a4d.jpeg)

&lt;start&gt; a small sitting on a tree branch in a tree &lt;end&gt;

![wine-bar-2139973_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/966a4673-7a9c-fcae-7149-4b3d17b3ed3d.jpeg)

&lt;start&gt; a man in a black shirt holding a wine glass &lt;end&gt;

![woman-3432069_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/1ac75975-e61e-8171-459a-92e6bab330e3.jpeg)

&lt;start&gt; a woman riding on brown horse through a grassy grassy &lt;end&gt;

![zebras-1883654_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/cefc5a86-b6c7-ebc2-a4bf-a9eac5c0eee7.jpeg)

&lt;start&gt; a zebra in a grassy area eating and eating &lt;end&gt;

## Mask Predict とは。

画像キャプショニングで、Mask Predict により非自己回帰型推論を行う試みは、数少ないようです。ですので、ここで、簡単に Mask Predict についてご説明させていただきます。Mask Predict による文章の推論では、学習時と推論時で異なったアルゴリズムを用います。学習時には、キャプションに乱数で発生させた数だけ、乱数で発生させた位置に &lt;mask&gt; をかけます。&lt;mask&gt; をかけるとは、もとの単語を隠して、word_to_id['&lt;mask&gt;'] = 0 とすることです。マスクをかけた文章をTransformer Decoder の target 入力として、Decoder の計算を行います。Decoder の出力に対応する教師データはキャプション自身です。損失は、マスクをかけた位置だけの損失を計算します。

Mask Predict では、キャプション( Transformer Decoder の target 入力）の一部に &lt;mask&gt; をかけ、その &lt;mask&gt; を推論するような形になるため、&lt;mask&gt; についての token と token_id が必要になります。今回は、本の付録の 6_2_dataset.ipynb で、id を i ではなく、i + 1 で採番し、0 を開けた word_to_id と id_to_word の辞書を作りました。加えて、この辞書をプログラムで使用する前、 word_to_id と id_to_word をファイルから読み込んだあとに、wordk_to_id['&lt;mask&gt;'] = 0 と id_to_word[0] = '&lt;mask&gt;' を定義しました。

Mask Predict で、もう一つ学習することは、文章の長さを予測することです。、今回のプログラムでは、エンコーダーの出力に&lt;len&gt; 位置を設けず、エンコーダーの出力を入力して文章の長さを予測するようなニューラルネットワークを encoder、decoder とは別に構成して、学習させました。

一方、推論時には、Transformer Decoder の target 入力には、予測した文章の長さ分の &lt;start&gt;,&lt;mask&gt;,・・・,&lt;mask&gt;,&lt;end&gt; の文章を用います。まず、最初にこの入力を target 入力として、エンコーダーの出力を memory 入力として、 Transformer Decoder の出力を得ます。この出力は完全ではないので、この出力の確率が低い n 個の単語を &lt;mask&gt; に置き換えて target 入力として、エンコーダーの出力を memory 入力として、もう一度 Transformer Decoder の出力を得ます。これを10回程度イタレーションします。&lt;mask&gt; に置き換える n 個は、10回のイタレーションにより、0になるように線形に減らしていきます。

## 学習と推論に用いたプログラムを github に置いておきます。

https://github.com/toshiouchi/ImageCaptioningMaskPredict

## 損失と学習曲線、および、Transformer のパラメーター

損失 loss は

loss = loss0 + loss 1

としました。loss0 は、キャプションの CrossEntropyLoss で、loos1 は、caption_lengths の MSELoss です。

loss0、loss1、loss、 WER の学習時の推移のグラフを掲載します。

![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/b5206614-73e8-d544-e751-86cac83d7f5b.png)

loss0 が、キャプションの CrossEntropyLoss です。このグラフからすると、まだ学習できそうです。

![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/229b7d4c-ca2a-b42a-b210-8e1b0645925b.png)

![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/f603aef7-38d3-2cf6-3599-a93144340534.png)

![fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958180/33620cf4-7bc0-8b48-5684-7b65bc4b32b5.png)

Transformer Decoder のパラメーターは、隠れ変数の次元が 512、FeedForward の中間次元が 2048、ヘッド数が8、Transformer Decoder の層数が 12 としました。