gggggraziegrazie

graizegrazieさんのやったこと、学んだことを記録する雑記帳です

TransformerはGoogleが[3]で発表したRNNの一種で、Encoder-Decoderをベースにしています。Encoder-Decoderは、テキスト翻訳のために考えられたモデルであり、入力(翻訳元、ソースと呼ばれる)テキストと出力(翻訳先、ターゲットと呼ばれる)テキストのペアを学習データとして使用します。データは下記のようにシーケンス上に処理されます。そのため、Encoder-DecoderモデルはSequence-to-sequenceとも呼ばれます。なおEncoderはA - Cが入力されているブロック群、Decoderは - Zが入力されているブロック群の部分です。各ブロックは、LSTMやGRUなどの長期記憶を表しています。

f:id:graziegrazie:20201122112617p:plain
Fig. 1 Encoder-Decoderモデル[6]

Encoder-Decoderモデルは、翻訳元テキストをEncoderで1つの文脈ベクトルとして纏めてDecoderに入力しており、単語の語順は考慮していません。これは、時系列情報(単語の語順)を無視していることにほかなりません。そこでAttentionという手法が提案され、単語の語順を考慮するようになりました。

f:id:graziegrazie:20201122112715p:plain
Fig. 2 Attention([4]を参考に作成)

またEncoder-Decoderモデルは、再帰計算が必要なLSTMやGRUを使って長期記憶を実現しているため、並列計算ができず学習速度が遅いという欠点があります。そこで[3]では、Positional Encodingを利用することで、時系列データに直接順序・位置関係の情報を埋め込み、再帰計算を無くしています。

Attentionは、元々翻訳元(ソース)と翻訳先(ターゲット)を組み合わせて計算を行っていました[1][2]。これをSource-Target Attentionと言います(Source-Target Attentionと言い出したのは、[3]からのようですが)。これに加え、TransformerではSource-Source、Target-Targetの組み合わせのAttentionも使われていて、Self-Attentionと総称されています。Self Attentionは、Source-Target AttentionがTargetの隠れ層にSourceの時系列情報の考慮を目的としていることを踏まえると、自身の時系列情報を考慮して隠れ層を学習していくことが目的と考えられます。TransformerではLSTMなどの長期記憶を用いていないので、そういう観点でもSelf Attentionを利用する意図が理解できます。

Positional Encodingは、テキストから生成されたID行列に対し、各単語の位置情報(Aという単語はi番目で、Bという単語は・・・、のような情報)を組み込むことを目的に導入されました。[5]が解説としてわかりやすいかと思います。Positional Encodingは、各単語に対して下記のpを追加します。下記の式のtは単語の位置、kはk < Position Encoding出力の次元数/2、を満たす正数を表します。

f:id:graziegrazie:20201122112810p:plain
Fig. 3 Positional Encodingの出力[5]

最終的に求まるpは、

f:id:graziegrazie:20201122112909p:plain
Fig. 4 Positional Encodingの出力[5]

となります。[5]では、これは位置をビットで表現するようなもので、浮動小数点でビット表現するのはイマイチなのでsin/cosを使っているとと言っています。

f:id:graziegrazie:20201122112954p:plain
Fig. 5 Positional Encodingの直感的イメージ(位置情報のビット表現を浮動小数点表現に変換)[5]

参考文献

1. "NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE"
2. "Effective approaches to attention-based neural machine translation"
3. "Attention is all you need"
4. 巣籠悠輔, "詳細ディープラーニング 第二版", 2019
5. Amirhossein Kazemnejad, "Transformer Architecture: The Positional Encoding", 2019
6. Ilya Sutskever, et al., "Sequence to Sequence Learning with Neural Networks", arXiv, 2014.

imagemagickを使ったgifアニメーション作成

処理画像を作成した後、それをアニメーション化したい時があるかと思います。その時に、私はimagemagickを使ってアニメーションを作成します。その際ファイルサイズの関係から、解像度を落としたり、最適化して圧縮したりなどすることがあります。今回はそれらを調べた結果についてまとめたいと思います。

GIFアニメーションの作り方

convertコマンドを使います。使いかたは下記の通りです[1]。

convert -delay 5 -loop 0 frame_*.png movie.gif

delayの後の数字は、フレーム間の遅延(時間間隔)を、loopの後の数値はループ再生のあり(1を指定)/なし(0を指定、例はこのパターン)を表します。ファイル名のしては、ワイルドカードが使えます。

GIFアニメーションのリサイズ

同じくconvertを使います。使用するオプションは、%で表現したい場合はscale、解像度で直接指定する場合はresizeを使います。具体的には、

convert source.gif -coalesce -scale 50% -deconstruct output.gif

convert source.gif -coalesce -resize 250x250 -deconstruct output.gif
を使います[2]。

GIFアニメーションの最適化
convertとoptimizeオプションを使います[3]。最適化の中身については、[4]が詳しいと思います。

convert in.gif -coalesce -resize 幅x高さ -layers optimize out.gif

ただ個人的には、optimizeしてもファイルサイズは大して減らない印象があります。最適化よりもリサイズの方が圧倒的にオススメです。

Non-holonomic vs holonomic

holonomicな拘束とは、拘束条件が一般化座標と時間だけで成り立つものであり、それ以外の拘束は全てnon-holonomicな拘束という[1-4]。例えば移動ロボットの座標を考えると、横移動できるロボット(例えばメカナムホイール搭載型)はhonomic拘束に従い、横移動できないロボット(例えば自動車)のnonholonomic拘束に従う[5, 6]。前者に関して言えば、好きなように動けるので、座標はその前の座標に依存する。後者に関して言えば、進める方向が制限されているため、座標はその前の座標と速度などに依存することになる。

OpenCVでの行列の掛け算の注意点

OpenCVの行列は、基本クラスのcv::Matと、それを継承した小クラスのcv::Mat_があります。前者はインスタンス生成時に型指定が出来ません。後者は、cv::Mat_のようにして、型指定ができます。

詳細はおっかけていないので結果論ですが、行列の掛け算をするとき、

cv::Mat a, b;
cv::Mat c = a * b

だとアサーションが発生します。そのため、行列の掛け算をする時は、

cv::Mat_<float> a, b;
cv::Mat_<float> c = a * b

のようにしましょう。ただし、データ型としてucharは使えませんでした。コンパイルは通るのですが、結局アサーションが発生しました。

ミュンヘンでの子供の手続き

ミュンヘンで子供が生まれた時、やることは下記の通りです。

  • ミュンヘン市役所へ出生届を出す
    • ミュンヘンでの出生届を出す場合、病院でしかもらえない用紙が必要になります。なのでこちらは用紙をもらったら、必要事項を記入してKVR(市役所)に行き、提出するだけです。その際、両親の婚姻証明と両親のパスポートを忘れずに持っていきましょう。
    • 登録が終わると、自動的にドイツ語での出生証明が3枚発行されます。英語版、もしくはドイツ語版を4枚以上もらう場合、1枚当たり10ユーロで発行してくれます。
    • もしも別日に証明書を追加で取得したい場合、同じ建物の(たぶん)ドイツ式1階(日本式だと2階)の奥(手前に自動券売機のようなものあり)に行けば発行してくれます。
    • なお、この時点で子供には自動的に住民登録が成されます。多分この帰りにKVRの窓口で住民票が貰えるはずです(私はこの時点では知らなかったので、確認できていません)。
  • 日本の市役所へ出生届を出す
    • 念のため、提出先の市役所へメール等で記載内容を確認してもらうといいかもしれません。
  • 日本領事館へ行き、パスポートの申請を行う
    • 申請には写真が必要ですが、特に写真屋さんで取ってもらう必要はありません。デジカメなどで撮影し、dmなどで現像していけば、それでOKです。
    • 発効までに1週間程度かかります。申請後に受け取り日は教えてもらえます。
    • なお、領事館は少ない人数で回しているので、もしかすると受取日の午前中にはもらえない可能性もあります。念のため電話して確認することをお勧めします。私の場合、電話したら「午後からでもいいですか?」と言われました。
  • ビザ申請
    • 私と妻のビザ申請を手伝っていただいた弁護士さんに聞いたところによると、2019年11月現在、赤ちゃんは出生届を出すと自動的に6ヶ月のビザが付与されるそうです。ただし、これは今後変更される可能性もあるので、今すぐビザを取る必要はないけど、早急にビザ申請が必要、または市役所などで確認が必要、と認識ください。

特徴点マッチングの結果を改善する方法

(1)(2)でも書いてありますが、主に3つの手法があります。

  • Ratio test

KNN(K-近傍法)を使って求めたマッチする特徴点のペアに対し、ペア1の点同士の距離とペア2の点同士の距離の比(ratio)を元に、適切な結果かどうかを判断する。(3)のように、Loweらは実験により、その比が0.7を超えるとよいマッチングであることを示した。つまり、

 $d(P_{a}, P_{b, 1}) / d(P_{a}, P_{b, 2}) > 0.7

かどうかをテストするとよい。
(4)に記載のように、ratio testをするためには2個以上のペアが必要なので、Bruto-force法だろうがFLANNを使おうが、どこかのタイミングでKNNを使ってペアを求める必要があります。

  • Cross check

画像Aと画像Bを相互に基準としてマッチングをそれぞれ取った時、同じ点がベストマッチかを調べる、という方法です。画像A中の特徴点を基準とした場合、その点は固定したまま、画像B中の各特徴点との距離を計算します。これでは、Aからみたら最適なペアですが、Bからしたら最適かは保証されません。そのため、同様にして画像Bの特徴点を基準にして最適なペアを求めることで、お互いにとって最適であるかを求める、という方法です。(5), (6)が視覚的にわかりやすい説明かなと思います。

  • RANSAC model

画像Aと画像Bで合致する特徴点がある、ということは、両者の間になんらかの幾何学的な関係が存在することになります。つまりカメラが画像Aを撮影してから、なんらかの並進+回転があった後に画像Bが撮影された、と言えます。全く動いていない場合も含まれます。この幾何学的な関係を、RANSACを用いることで推定し、推定できた(収束した)ら正しいマッチングだとみなします(2), (7)

  1. その他

その他にも、単純に合致する特徴点通しの距離をみる、など、観測モデルを考慮した上でのフィルタリング方法はいくらでも考えられます。

全方位カメラの画像から一般的なカメラと同じ様な画像を取り出す方法

360度パノラマ画像から平面画像への変換手法 - LASTMILE WORKS / DYNAMO TECH - R&D Project - Medium

床井研究室 - 魚眼レンズ画像の平面展開

を見ると、「平面展開する」と言えば良いようです。メモなので雑ですいません。