参加報告:MIRU2020若手プログラムに参加してきました。

MIRU2020の若手プログラムに参加したので忘れないうちに振り返ってまとめておきます。

MIRU若手プログラムは、学生を中心とした若手の研究者の交流企画です。やる内容は毎年独自の企画が設定されていて、今年はプレゼンテーション(プレゼンバトル)でした。
近年では、若手の育成も兼ねた企画が多いので、個人としても非常にためになります(かかる労力はそれなりに大きくて大変ですが。。。)

sites.google.com

参加時の私の状況

私のMIRU若手プログラムの参加は2018年札幌のと合わせて今回で2回目になります。
なるべく毎年参加したいと思ってますが、どこまで参加しても許されるのか悩ましい齢になってきたのが気がかりです。
今回はcvpaper.challengeのCVPR2020サーベイへの参加と博論の最終審査のために博論修正の締め切り、本業の進捗報告などを抱えており、完全に難易度ルナティックでした。まだ息があって本当に良かったです。
私がこんな状態だったので、今回はなるべく自分で仕事を抱え込み過ぎず(個人プレーに走らず)、メンバーの方々と分担してうまくチームをまとめられるか、が課題でした。

グループのプロジェクトについて

プロジェクト始動時期について

今回の企画は、グループでのプレゼンテーションということで、CVPR2020、ICLR2020論文から一本読んで内容をプレゼンとして紹介するという企画でした。
メンバーは委員の福井さんをメンターとして私とM2の方3名、M1の方1名という構成でした。研究で時系列を扱ってるメンバー構成という感じでした。積極的に意見も言ってくれるし、自分から動いて下さる方が多く、頼もしいメンバーでした。
開始は約一ヶ月前の6/26でした。Slack上でグループ分けがなされて、私はグループAのリーダー役を務めることになりました。どうやら一番経験値のある人が各班のリーダーとして抜擢されてるようです。
準備期間は明らかに足りませんでした。この企画なら2ヶ月は必要だったかと思います(この期間内にしっかり仕上げてきた他班は本当にすごいと思います)
振り返ると、進め方を工夫する必要もあったかと思います。

プロジェクトの進捗過程

  • 6/26 プロジェクト始動、slackでの挨拶、論文選定のための調査・提案開始
  • 7/2 第一回MTG:顔合わせ・論文選定(14本くらいから第三候補まで選定)
  • 7/6 第二回MTG:選定論文の読み合わせ会(各自読んできて疑問点について議論→失敗)
  • 7/11 第三回MTG:品川から選定論文の論文紹介(内容についての知識すり合わせ)、役割分担割り当て議論
  • 7/15 第四回MTG:関連研究の調査報告、スライドの進捗状況、発表者・スライド作成の割り当て変更
  • 7/18 全日本CV勉強会で選定論文が紹介されてビビる
  • 7/20 第五回MTG:初期スライド完成、マージして内容を議論、発表スクリプトアウトライン作成
  • 7/25 第六回MTG:各自で修正したスライド、発表構成について議論、発表スクリプトを作成(宿題)
  • 7/29 第七回MTG:事前に発表スクリプトを基に発表練習
  • 7/31 第八回MTG:発表練習
  • 8/1 MIRU若手プログラム当日:山崎先生の講演を受けてスライド修正と発表練習

若手プログラム発表当日の結果

"Retina-Like Visual Image Reconstruction via Spiking Neural Model"について発表しました。 (発表スライドも後日載せると思います)

openaccess.thecvf.com

内容としては、ハイスピードなモーションを手軽な(省電力な)装置で撮影するために、スパイクカメラという輝度をスパイクに変換する特殊なカメラを用いてSpiking Neural Networkと組合わせて高精度な画像再構成を行う手法の提案です。

バトルの結果としては敗北しました。6チーム中3位までにも入っていませんでした。エフォートは十分取ってもらってたかと思いますので、それでも負けたのは進め方がまずかったのだろうなと思います。
審査員の方からのコメントとしては、説明が込み入ってきた時にどこの話をしているのかが分からなくなったという点がまずかったとのことです。 質問は、カラー画像には使えないのかというlimitationについての質問が1点、評価指標についての質問が2点ありました。
カラー画像についての質問は想定していたので答えられましたが、評価指標については調査が手薄、というか手を抜いたのでうまく答えられませんでした。発表では「この指標はこの分野でよく使われる」みたいな話が発表者から出てしまいましたが、これ自体はおそらくマイナーな手法で、リファレンス画像が無いために著者らが仕方なく設定した手法だと思われます。(論文はメンバーに読んでもらいましたが、よくわからなかったと報告されてから、「まあそこまで重要ではないし、だいたいの気持ちがわかれば良いか」とそのまま放置してしまいました)
発表がうまく伝わらなかったのもあると思うのですが、珍しい指標だったから目を引いてしまう可能性についてもっと考えておくべきでした。モデルの説明に重点を置きすぎて足元がおろそかになっていました。

考察と反省

発表の改善点
  • 今回は手法を重点的に説明するため研究背景を簡略化したのですが、簡略化しすぎました。ハイスピードモーションの撮影がどれだけ難しいか、問題設定の前提を最初に詳しく聴衆に見せるべきでした。他班の上位陣はここがうまかったように思います。
  • モジュールの説明はアニメーション(説明の進度に応じて順番に処理の動きが見えるよう)にすべきでした。聴衆はおそらくどこを説明してるのか途中でわからなくなってしまったのだと思います。オンライン発表ではポインタを使いにくいというのもあり、今回は発表時のアニメーションと説明の時間的なラグも気になるという点もあったので、どちらも控えましたが、今となってはせめて後者を使う方がましだったかなと思います。 端的に言えば時間がないことを言い訳に妥協してしまったというのが敗因かなと思います。
  • スライドのクオリティについて。これは私が指摘しないとまずかったですが、結果の表を論文からそのまま貼り付けてあったのはまずかったです。自分も自分の研究発表ではまずやらないですが、論文紹介くらいだと手を抜きやすいポイントで自分もよくやるので、注意が働かなかったですね・・・
  • 口頭発表の練度について。我々はせっかくの機会だしということで経験値を優先して複数人で行ったのですが、逆に発表の難しさを上げてしまったかと思います。ページめくりをする人と発表者は同じ人1人の方が発表の難易度は低かったと思います(一人の労力は上がってしまいますが)。また、我々には発表練習のための時間が全然足りませんでした。メンバーの皆さんも、本来なら1週間程度時間をかけて発表練習の練度を上げたかっただろうと思いますが、おそらくスクリプトなしでは読めなかったのではないかと思います。これはスライドの作り方にも問題があり、スライドがうまくガイドにしきれなかった点が課題として挙げられます。他班は発表者の決め方や、発表練習など含め、どのような進捗状況だったのかが気になるところです。
準備の進め方について
  • 今回は作業をうまく分担することを念頭に置いていたのですが、担当の分け方が少し甘かったかもなと思います。グループ分けの最大の利点はエフォートを分担できるところですが、スライドづくりや発表は最終的に一人がまとめた方が統一感が出るので、最後まで分担し続けるのは良くなかった可能性があります。むしろ、今回手薄だった関連研究・評価指標の調査に人手と時間をもっと費やすべきだったかもしれません(でもそれは「プレゼンテーション」という企画の主旨からずれてないか?という疑問があり、今回私はこの方向性を選択しようとは思ってませんでした)他の班はどうやっていたのかが気になります。
  • プレゼンテーションの技術について前提を共有すべきでした。最低限の原理原則はありますが、私も自分の中でそれが絶対的なものだとは思ってなかったので、強制することはあまりせず、大部分ではつくってきてもらった元のスライドを活かす方向で改善案を提案して、納得できたら取り入れてもらう形をとってしまいました。これが余計な混乱を招いたと思います。解決策として、分担してスライドをつくるなら、せめてプレゼンについての最低限の資料を最初に共有して読んでもらうべきだったと思います。スライドをつくってもらって「違うそうじゃない」を繰り返す試行錯誤はある程度必要と思いますが、原理原則については則っておいた方が無難です。私もアドバイスとして原理原則と個人の意見をごっちゃにして修正案を出してしまった面があるので、一度前提を共有する機会をつくるべきでした。そうすれば、「これはP.○○の原則に反している」と言えば、言われた方も素直に納得できたと思います。
やっておいて良かったこと
  • どの期間にどれくらい忙しいかを事前に聞いていた
  • 一度論文の内容について自分がまとめてメンバーに共有した
  • 分担作業は個人の負担としては多少楽だった(クオリティとのトレードオフがある)
  • メンバーがどのような意見をもっているか割とちゃんと逐一聞けた(独りよがりになり過ぎなかった)
  • 著者に分からない点をメールでちゃんと聞いた(2回目は返ってこなかった)
今回の反省として今後のために備えておくこと
  • スライド作成時のチェックリストをつくろうと思います。いちいち頭で考えてるとどうしても抜けが出ることが今回分かったので、今後はなるべく脳死でチェックできるようにします。
  • 何が起きているのか分かりやすくするために、アニメーションにする労力を厭わないこと(今回のわかりにくさは、アニメーションを厭わず導入すればだいたい解決した問題だった)

MIRU若手プログラム当日(グループのプロジェクト以外の話題)

山崎先生のチュートリアル講演について

当日は午前中に自己紹介と東大の魅力工学で有名な山崎先生にチュートリアル講演がありました。
早速スライドが公開されたようなので、こちらにも貼っておきます。

www.slideshare.net

基本的には、聴衆に認知負荷をかけないように気を遣うという主旨でした。
私も日ごろ指導教員の先生方からボコボコにされてきたので分かりみが深かったです。個人的には、以下の点が自分でまだ改善できるなと思ったのでまとめておきます。

  • イントロでは聴衆の引きを意識する(問いかけ系の導入)
  • 研究背景の説明として、他人の意見を借りる(出来事や、統計情報などを利用して聴衆の納得感を引き出す)
  • 図表の凡例はプロットと結ぶか、プロットに沿えるように配置する(論文の載せ方とは変える)
  • 書いてあることと説明することのギャップをなるべく小さくする(書いてあることはもらさず説明する。書いてないことを説明しない)
  • 見えない情報を作らない(アニメーションで順々に表示していくと負荷を感じる人もいるらしいので、たぶん処理のフローを説明するようなときも半透明で表示して必要な場所だけハイライトする方式にした方が良い)

特に最後の「見えない情報を作らない」という点については新鮮でした。私は見えない情報があるとむしろ「おっこれは何か隠し玉があるな」とワクワクして集中して聴けるので、逆なんですよね。むしろ情報が全部見えてると退屈で眠くなってしまいます。一般的にはそうでもないようなので気を付けたいところです。

各班の発表について

全体的にレベルが高くてぶったまげました。興味深い論文ばかりで面白かったです。個人的な感想も載せておきます。

  • B班:問いかけ型の導入でとても引き込まれました。流石Arakiさんのチームやって感じでした。GANでデータ拡張なんでしないのみたいなことが気になり過ぎて少し説明聞き逃しちゃったのが個人的にもったいなかったです。録画が欲しい。
  • C班:発表された論文の中では一番興味にマッチしてて面白かったです。こういうことに使えるのではないか、みたいな議論もあって納得感があり良かったです。コンテンツが盛りだくさんで少しどこにポイントを置いて話を聞けばいいのかが途中ちょっとついていけませんでした。ただそれは、発表資料が事前共有されてれば問題なかったかなとも思います。
  • D班:ちょっと最初の方でスライドのクオリティが気になりました。中身の説明はポイントを押さえて下さっててだいたい理解できました。論文自体の話になりますが、手法はまあ良く聞く感じの組合せっぽいので適用するタスクがうまくはまってたのだろうなあと思います。
  • E班:前提となるところの知識がとても丁寧で驚きました。手描きの図みたいなものもあり、一番説明のためにスライド作成の労力を割いてたのではないかと思います。ただ、導入が少し長すぎた面はあるかなと思います。この分野の研究動向の発表としては非常によくまとまってたと思います。私はこのチームに投票しました。
  • F班:優勝はこのチームでした。導入がとても丁寧で引き込まれるので、一般向けの説明でも通じそうな気がします。ただ、私は途中あまりの認知負荷の低さに居眠りしてしまったので全体については正当な評価はできないです(申し訳なし・・・)2倍速で聞いてたらたぶんちょうど良かったと思いますが、これはまあ私が想定聴衆でなかったからだろうなという感想です(連日の無理がたたってたのもありますが)

懇親会含む、全体その他の話について

今回は、前回参加した2018の若手プログラムと比べると、あまりslackの流速が速くなかったなあと思いました。むしろあの世代にノリが良い方が多過ぎるのかもしれません・・・

懇親会では、適当にグループに分かれてCOVID-19の影響の話とか、研究環境のこととか、D進の話とかについて話をしてました。会う学生だいたいD進希望者で驚きました。これは、学生さんを若手プログラムに突っ込めばD進してくれる説がありますね・・・?(気づいてしまった顔)
同世代の方々とも色々な四方山話を話せてとても楽しい時間を過ごせました。またここに来れるように頑張りたいものです。

Defense

博士論文の公聴会(defense)が終わってようやく一息つけました。

ジャーナルを書いて投稿して博論書いてをタイトなスケジュールでこなさなければならなかったのでなかなかしんどかったです。

徐々に論文を読む余裕も気力も無くなってきて新しい論文がtwitterに回ってくるのを見てるしかできないのが一番つらかったのですけど、ようやく通常運転に戻れそうです。いやあ追い込まれてない状態って最高ですね・・・

関西合同音声ゼミ(2019.12.07)@立命館大学OIC

昨日関西合同音声ゼミに行ってきたので感想などを残しておく。

招待講演:コミック工学

まず、招待講演の立命館大山西先生のコミック工学研究の紹介が面白かった。技術が先にあって課題を探す技術指向、課題が先にあって課題を解決するために技術を開発する課題指向という従来研究スタイルに対して、これらを止揚した感じのコンテンツ指向という話をされていた。

コンテンツ指向は、既存の技術から「こんなのできそう」を考えたり、「こんなのあったらいいよね」からどのような課題が必要かを考える研究スタイルとのことだった。私はissueから始めなければ、という意識が最近強かったのだけど、やっぱ考え過ぎだよなあと考えを改めるきっかけになった。

issueから始めるのが重要なのは、工学をしてるつもりで全く役に立たないものを作ってしまうのではという懸念があったからだが、役に立ちたい対象となる人が研究のループに入っているかどうかが重要なポイントだと思った。

コミック工学研究会では漫画家さんなどプロの実務家が参加していて、コンテンツの担い手に直にフィードバックをもらい、この技術はどこでなら役立ちそうか、新たな課題はありそうかなどを建設的に議論してすぐに軌道修正できるしくみづくりがされているとのことで、なるほどそこすごい大事だなと思った。

思えば私の所属している研究室でも、ここで言うようなコンテンツ指向を重要視した指導をされているが、適切な課題の設定を行うのが難しいなと常々感じている。ここは研究者としての腕によるところがあるが、対象とする人がはっきりしているなら、実際に会って課題を切り取っていくことを視野にいれてないとなぁと反省した。

研究紹介の中身もbig pictureと要素技術がはっきり示されていて非常に分かりやすかった。次々に研究になる課題の例が紹介されてくのもすごくて、思わぬ発想もあったりで発想の引き出しの多さに感心させられた。

ポスター発表

ポスター発表に関しては、今回対話関係の発表件数が多かったので、ポスターは対話を中心に見て回っただけで時間が尽きてしまった。(皆熱が入っているのは良さだが、いったん5分くらいにまとめててもらえるとありがたい・・・)

ざっくり総括すると、グラフ系の話、人間っぽい対話振る舞いに関する研究の話、他にも雑談応答モデルの多様性向上の話とか対話における話者認識・匿名化とか、個人性を扱った話などがあった。

知識グラフの二値化CP分解の話は初めて聞いたので面白かった。不勉強ながらHinton’s Straight Through Estimatorを知らなかったので勉強になった。2値化してもある程度ちゃんと動いてるのがすごい。局所解には落ちないんだろうか?落ち着いたらちょっと勉強してみたい。 ググったら今年の言語処理学会の予稿を見つけた:https://www.anlp.jp/proceedings/annual_meeting/2019/pdf_dir/P8-4.pdf

雑談応答の多様性向上の話は工夫が面白かったが、その工夫が本当に効いているのか結果からは良く分からなかったので、比較した結果や詳細な分析が見たかった。他の手法も色々あるので比較した結果も見てみたい。

懇親会

弊研からの参加者僕と後輩氏の2人だけでワロタ。(もっとコミュニケーションしようぜ・・・)どの研究室もそうだけど、島でまとまるの良くないと思うんですよね・・・なんかうまい仕掛けが欲しい。今回私は京大島をフラフラしながら山西先生に話かけたりしてました。コミック工学研究会は私のモチベーションにもマッチしそうなので、参加できないかボスらと相談したいところ。自分が何をやってるのか見せようと自分のデモを見せたのだが、デモが動かなかったのには冷や汗をかいた・・・(後で確認したらcudaがエラーを吐いていた。勘弁してほしい・・・)

河原研の学生氏と話していて、河原研はどうやって対話の問題設定を洗練させてくのか聞いてみたら、河原研には社会心理学に精通した博士研究員の方がいてコメントもらえたりするらしい。そういうの良いですね。個人的にはやっぱ人間同士、人間対機械のインタラクションに興味があるので、自分で勉強するだけでなく、そういうのに精通している方に実際に会いに行って話を伺いに行くとかするアクションも、自分の研究を洗練させていく上で重要だなあと思った。

AIPセンターシンポジウム 兼 成果報告会(2017年度)を聴講してきた

AIPのシンポジウムに参加してきた。日本のヒーロー大集合という感じでとても心が躍った。一般に開かれたシンポジウムだったので公開しても大丈夫だろうと判断し、忘れないうちに思ったことなどメモしておく。
社会実装,倫理から基礎数理まで:革新知能研究の最先端 | Center for Advanced Intelligence Project

追記:この記事の編集途中で引っ越しイベントのごたごたがあり、とってあったメモを紛失してしまった。とりあえず途中まで書けていた金出先生の講演についてだけ載せておく。

金出武雄先生の講演

金出先生からは「今後こういう研究が重要だろう」という展望についてのお話があった。
特に強調されていたのが、「良い研究は現実に起きている問題に取り組む中で生まれる」ということだった。
人工知能研究の冬の時代は、現実の問題を人工的につくられた解ける問題に落とし込み過ぎていることが一因だとも仰ってた。問題を解くための研究ではなく、研究業績を出すために問題を用意してるのがいけない、という意味だと受け取った。

「現実に起きている問題に取り組む中で生まれる良い研究」とはどんなものだろうか?金出先生からいくつか紹介があった。曰く、
製品検査、システムの異常検知
・負例が少数で学習が難しく、学習データにない新しい負例が出てくる可能性もある
・センサデータから始まる一貫した研究が必要
・ある製品について検査できるシステムが生まれれば、他の検査システムにも広く応用できる可能性がある
自分の決定を説明できるAI
・内省し、ユーザにわかる形で説明する
会議に参加貢献できるAIシステム
・問題と知識をどう表現するかはAIの根本的な問題
・本当に人のように有能なシステムの実現にはフレーム問題と記号接地問題が現れる
・会議では色々な話題が飛び交うので、データセットの世界に閉じていないAIが必要

どれもなるほど、と思わせられた。現実の問題の中でも、根本的なボトルネックとなっている部分は他の問題でも共通していることが多いから、これを解決できると色々応用が利くので十分なインパクトがある。例えば、機械学習では「学習するためのデータがない、DNNはブラックボックスなどで説明性に欠ける」などが根本的な問題として挙げられる。これらを解決するための学習理論を構築したりするのが肝要だとのことだ。各チームによるポスターセッションでは、確かにどのチームもこういった根本的な問題を研究のモチベーションにしているようだった。

感想

自分が取り組んでいる問題は現実に起きている問題設定からは少し離れているので私は大変恐縮してしまった。が、改めて考えるとあまりに広く知られている根本的な問題を攻めて世界中の才能とのパイの奪い合いに遅れて参加するのはどうなんだろう?、と思ってしまいイマイチ賛同はできなかった。
取り組むべき問題をきちんと吟味するのが大事というのは完全に賛同できる。個人的には汎用的に応用できる研究も大事だと思うが、多少タスクに依存した問題でも、それが解決することでブレークスルーに貢献するような仕事をしたいなぁと思った。
自分の問題で本当に本質的な問題はどこにあるのかを見直す良いきっかけになったと思う。ちょうど目をつけているところがまさにそうだと思うので、このまま走っていきたい。

jupyter notebookでscroll boxの高さを変える

jupyter notebookでscroll boxの高さを変える方法が検索しても出てこなかったのでメモ。

結論から言うと、以下のようにすればとりあえずできる。

from IPython.core.display import display, HTML
display(HTML("<style>.scroll_box { height:30em  !important; }</style>"))

参考: stackoverflow.com

上記の方法では、下記のような方法でjupyter notebook全体のcellの横の長さを変更できることを紹介している。

from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))

そういえばこいつもブラウザでみれるからHTMLなんだなぁということを思いだし、要素の検証からscroll boxに対応するクラスのスタイルを見つけて中身を変更すればよい。

chainerのVGG16 pretrainモデルを早速使ってみた

最近めっきり記事を書いてないので、今後はメモくらいのつもりでもいいから小出しに書いていこうと思う。

chainerがv1.22.0でVGG16LayersとResNet50Layersをchainer.linksでサポートした。
Standard Link implementations — Chainer 1.22.0 documentation

これによってcaffeの学習済みモデルがより気軽にchainerで試せるようになったようだ。
ちょうど学習済みモデルを手っ取り早く使いたいなと思ったところでタイミングが良かったので早速試してみた。

今回はVGG16Layersのみについて書いていこうと思う。

基本的な使い方

基本的な使い方はchainerのリファレンスをみるのが手っ取り早い。
Standard Link implementations — Chainer 1.22.0 documentation
これによると、以下のように使えると書かれている。

from chainer.links import VGG16Layers
from PIL import Image

model = VGG16Layers()
img = Image.open("path/to/image.jpg")
feature = model.extract([img], layers=["fc7"])["fc7"]

お手軽感がすごい。

特徴

特徴をまとめると以下のようになる。

extractpredictというメソッドがある
  • 入力はPIL.Imageとnumpy.ndarray (height,width)(height,width,channels)(channels,height,width)のどれでもサポートする
  • バッチで与えたいときは、入力を上記のオブジェクトのリストで与えればよい(1つのnumpy.arrayに統合してはいけないので注意)
  • extractはlayers=['fc6','fc7']のようにlayersで指定した層の出力をまとめて辞書形式で返す。
  • predictはfc8(最上層)の出力、つまり各クラスの予測値を返す

主にお世話になるのはextractだと思われる。

chainier.links.model.vision.vgg.prepareというメソッドがある

VGGモデルは、通常入力画像を(batchsize,channels,height,width)、channelsはRGBではなくBGRという形式のnumpyarrayに整形する必要があるが、これはそれらの操作を行ってくれる。また、256x256へリサイズ、224x224へクロップする作業、VGG16の平均画素[103.939, 116.779, 123.68]の引き算も同時に行う。
(extractとpredictにはこれが既に内部に組み込まれているのでわざわざ使う必要はない)

処理の高速化のため、画像のローディングを別スレッドorプロセスで並列に行いたい場合はこれを使えばよいということだと思われる。
その場合、既に1つのミニバッチ化されたデータを入力として、そのままcallすればメインのスレッドorプロセスでの処理はextractよりも少なくて済む。
ちなみに、このメソッド自体は複数入力に対応していないので、リストでなく1つずつ入力する必要がある。

パラメータ固定、fine-tuningでそれぞれ使ってみる

VGG16Layersの良いところはchainer.linksでサポートされてる点だと思っている。書き方を少し工夫すれば、自分で定義したエンコーダにVGG16を隠蔽することができるので仕様に振り回されなくて済む。例えば、以下のようにかける。

from chainer import links as L
class Encoder(Chain):
    def __init__(self,n_image):
        super(Encoder, self).__init__(
            model = L.VGG16Layers(),
            fc = L.Linear(4096,n_image))

    def __call__(self, x, train=True, finetune=False):
        x = Variable(self.xp.asarray(x,dtype=np.float32),volatile=not finetune)
        h = self.model(x,layers=['fc7'], test=not finetune)
        h = h['fc7']
        if finetune==False:
            h = Variable(h.data,volatile=not train)
        return F.tanh(self.fc(h))

    def make_optimizer(self):
        return optimizers.Adam(alpha=2e-4, beta1=0.5)

pretrainモデルをimage-captioningなどのEncoderとして用いる場合、最初からfine-tuningするとまだ学習が進んでいないDecoderのエラーが伝搬してpre-train部分が悪影響を受けることがある。従って、pre-train側とそうじゃない部分は分けて学習できるようになっているのが望ましい。今回の例ではEncoderの後段がpretrainモデルじゃない場合のEncoderという想定で書いてみた。訓練フェイズでpretrainモデル部分を固定にするかfine-tuningをするか切り替えるには、単純にVariableの中身を一度取り出して再度Variableでラッピングして計算グラフを切るか切らないかで切り替えることができる。

torchのnarrowメソッド

torchのnarrowメソッドがパッと見よくわからんので試してみた結果のメモ。
[Tensor] narrow(dim, index, size)

↑のサイトを参考にした。
narrowメソッドは何をするかというと、テンソル内部のある次元のある部分を切り取って返す関数である。ちなみに参照渡しなので注意。

[Tensor] narrow(dim, index, size)の3つの引数はそれぞれ、
・dim:切り取る次元(行列(2次テンソル)なら行方向で切るか(1)列方向で切るか(2)の2種類 (ただし、dim > 0)
・index:切り取る部分の始点 (ただし、1 < index <= Tensorsize(dim))
・size:切り取る部分のサイズ(始点からどこまで切るか) (ただし、index+size-1 <= Tensorsize(dim) )
※ここで、Tensorsize(dim)はテンソルのdim次元の最大のindexの長さとする

例(参考サイトから引用)

th> x = torch.Tensor(5,6):zero()
                                                                      [0.0001s]
th> print(x)
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
[torch.DoubleTensor of size 5x6]

                                                                      [0.0003s]
th> y = x:narrow(1,2,3)
                                                                      [0.0001s]
th> print(y)
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
[torch.DoubleTensor of size 3x6]

                                                                      [0.0003s]
th> y:fill(1)
 1  1  1  1  1  1
 1  1  1  1  1  1
 1  1  1  1  1  1
[torch.DoubleTensor of size 3x6]

                                                                      [0.0003s]
th> print(x)
 0  0  0  0  0  0
 1  1  1  1  1  1
 1  1  1  1  1  1
 1  1  1  1  1  1
 0  0  0  0  0  0
[torch.DoubleTensor of size 5x6]

                                                                      [0.0003s]

これは、2次元テンソルつまり行列の例で、y=x:narrow(1,2,3)は「行方向に2行目からスタートして2+3-1行目まで切ったものをyに代入する」という意味になる。
これは参照渡しになっているので、y:fill(1)するともとのxもそれに応じて変化する。

試しに列方向にも切ってみる。

th> r = x:narrow(2,3,4)
                                                                      [0.0001s]
th> r
 0  0  0  0
 1  1  1  1
 1  1  1  1
 1  1  1  1
 0  0  0  0
[torch.DoubleTensor of size 5x4]

                                                                      [0.0003s]
th> r:fill(2)
 2  2  2  2
 2  2  2  2
 2  2  2  2
 2  2  2  2
 2  2  2  2
[torch.DoubleTensor of size 5x4]

                                                                      [0.0003s]
th> x
 0  0  2  2  2  2
 1  1  2  2  2  2
 1  1  2  2  2  2
 1  1  2  2  2  2
 0  0  2  2  2  2
[torch.DoubleTensor of size 5x6]

                                                                      [0.0003s]

これは「列方向に3行目からスタートして3+4-1行目まで切ったものをrに代入する」という操作に対応する。エラーが起きないように注意が必要な操作だ・・・