つらねの日記

プログラムの進捗やゲームをプレイした感想などを書き連ねる日記。

論文読み 「Improving Language Understanding by Generative Pre-Training」

https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf

前置きと感想

LLM触ることになりそうな気配がしたので、下の方から読んでいく感じ。

この論文自体にはこれと言ったことが書いてなくて、Transformersとlanguage model組み合わせましたーみたいな感じがした。 後半ちゃんと読めてないので、そっちの方には疑問に思っている箇所が書いてあるのかも。

--

GPT-1の画期的な点は当時ラベルなしコーパスで事前学習を行い、各タスクに対してfinetuneを行った最初の大規模言語モデルであるという点にある。

モチベーション

NLPはtextual entailment(含意認識)、question answering(質問応答)、semantic similarity assessment(意味的類似性評価)、document classification(文書分類)など色々なタスクがある

ラベルなしのテキストコーパスは多いが、特定タスク用のデータは少ない

手動ラベリングは大変なので、ラベルなしテキストコーパスから良い初期値を学習できれば、教師あり学習でも少ないデータで良いパフォーマンスを得ることができる

ただし、ラベルなしのテキストから単語以上の情報を学習するのは困難 単語レベルじゃなくて、高次の意味論を捉えたい→できてる証明は?

  1. 事前学習としてのテキスト表現の特徴量を学習するための効果的な最適化目標が不明確
  2. 学習したテキスト表現を適切に転移学習させる方法が不明確

既存技術は各タスクに転移させる際に、モデルを変更したり[43, 44]、複雑な学習[21]、補助的な学習目標を追加[50]などの工夫が必要で、これらの不確性が学習難易度を高めている

手法

unsupervised(教師なし) generative pretrainとsupervised(教師あり) discriminative finetuneを各タスクでやって言語理解を図る

unsupervised generative pretrainによって、広範なタスクに転移可能な普遍的な表現を学習する 良い初期化点をみつけることが目標

target taskは事前学習データと同じドメインでなくても良い→なぜ?

ロバストな転移が可能なTransformer[62]を使用 実際にはmulti-layer Transformer[34]

事前学習

出現したtokenから次のtoken列の尤度を最大化する

転移学習

transformerの活性化層hを線形出力に渡してラベルを予測する

さらにfinetune時にもlanguage modelingを補助的な目的として追加すると、精度も収束も良い方向に向かう

テキスト分類(Classification)では直接モデルをfinetuneできる。

QAや、テキスト含意(Entailment)は構造化された入力がある

事前学習の重みは連続シーケンスからなるため、修正が必要 [44]スタイルではなくて、traversal-style[55]でやることで、タスク間でアーキテクチャに大きな変更を加えなくて良くなる

ここで、Textual entailment, Natural Language Inferenceとは PremiseとHypothesisが与えられ、Entailment(含意)、Contradiction(矛盾)、Neutral(中立)の分類を行う

fish shellでコマンドラインスタック

前置き

zshの便利な機能にコマンドラインスタック(buffer stack)というものがある。 入力途中のコマンドを一時的に退避出来るというものだ。 zshではAlt+qに割り当てられていて、長いシェルとか書いているときに、 ちょっと確認したいことがでてきちゃった時とかにとても重宝する。

on fish

でもfishにはないみたいだった。めっちゃ不便だ…… 積み重なるqの文字の山に我慢しきれなくなったので、作った。

gist.github.com

正確に言うと、絶対誰かやってるでしょって思ってcommandline stackとかbuffer stackで検索したけど、全然出てこなかったので、作った。

その後に、ふと以下の結果が得られたので、

% bindkey | grep q
"^V" quoted-insert
"^[\"" quote-region
"^['" quote-line
"^[q" push-line

push-lineで検索したところ、dedeibel/push-line.fish がみつかった。

fish_postexec functionを関数内で生成して終わったら消すとかいうかっこよすぎる感じだった。

試してみたら、最高という感じだったのだけれども、killingを汚す&C-wとかやっちゃうと当然そっちで上書きされちゃうっていう問題が発生した。 ので自分で作ってた部分と統合して改良した。 まあグローバル変数を汚すのもどうなのだという話はあるけれど。

複数行のコマンドをスタックしようとしたらtest -nのところで怒られたので、修正しないと駄目かも。あとすごい適当にrepaintを呼んでいるので、ちゃんと正確に理解して使いたい。

Happy Fishing!!!!

2017/09/28追記

複数行でもエラーが出ないように修正した。

余談

全く関係ないんですが、hatenaの記事を書くときにリアルタイムプレビューが出来るようになったのは割と革命的ですね。パソコンの性能か、若干動作が重くなるのは難点だけど。

You may not change the shell for 'pi'.

事件

ラズパイを買ったので色々設定していたら、突然ログインシェルを変更出来なくなった。

結論

/etc/shellsから現在のシェルを消すと何も出来なくなる

発端

最近fishがお気に入りなので、ラズパイにも入れようと思った。 ここに書いてある通りに入れてchshしてみたら、最新2.6に対してinstallされたのが、2.1だった。(chshして再ログインする前に動作させろという話もある。ついでに言うと割と時間がかかったので先にapt showで確認すれば良かった感が強い。)

しょうがないので手動で入れようという話になった。

進展

github.com 入れ方が全部README.mdに書いてあって、完全に神という感じ。 昔読まずにやっていたので、無いプログラムとか一杯あってくろうした記憶がある。 公式はちゃんと読もう。 どうせ編集とかはしないので、autoconfも入らなくなるし、Releaseの方をやれば良かった感は強い。

sudo apt-get install build-essential ncurses-dev libncurses5-dev gettext autoconf
autoreconf --no-recursive
./configure
make
sudo make install

事件

install出来たし、chshするぞと思ったが、その前に/etc/shellsを書き換えないといけないのだった。と言って/usr/bin/fish/usr/local/bin/fishに変えた。

いざ、chsh -s /usr/local/bin/fish!!!!!!!!!!

f:id:turane_gaku:20170621221532p:plain

すまない、何を言っているのかわからないのだが。

見る人が見たらわかるかもだけど、SHELLがbashなのはコピペとかするときに記法が割と違うので怒られるのが面倒なので、bash on fishしている。

解決

色々やっていたけど、何かが突然舞い降りて、/etc/shellsから/usr/bin/fishを上書きしたのがいかないんじゃないかっていう風に思って追加したら無事変えられるようになった。

vimperatorで/検索するときにエラーが出るやつ

まえおき

vimperator、firefox51?くらいからめちゃくちゃ調子が悪かった。 タブ系統が全滅している問題は解消されているっぽかったけど、/で検索するたびに、TypeError: findbar._setHighlightTimeout is not a function的なエラーが出るのがうざかった。 まあ、エラー出てるけどn押せば一応検索は出来るし、まぁいいかな感があって放置していた。 というか、/で入力しおわる度に何故かEnterキーを二回押さないといけないの不便すぎてアレ。

issue

github.com まさにこれっぽい。

-set hlsearch
+set nohls

vimperatorrcをこうしたら出なくなった。というかhlsじゃないのにハイライト表示されているので、 何のためのオプションだったんだという感じがある。

そのた

:messすると他にも色々出てたりしたので、それもちょっと直した。 StatusLineSecure, StatusLineExtended, StatusLineBrokenのハイライト三種盛りがnot foundとなっていたので、これもコメントアウトした。

vimppmが入っていないと怒られていたので手動で入れた。自動化するべきだと思う。 というか、caret-hint.jsしか入れてないし、結局使ってないので必要無いかもしれない。

fishを始めようとしたら詰った

自分用のメモ的なアレ

.config/fish/functions内のファイルが自動で読み込まれるっぽいので、 そのなかに今まで分離管理していたaliasとかoptionとかpromptとかを入れれば すっきりするなって思って、手始めに.config/fish/functions/alias.fishを作った。

そしたら無限に以下のエラーが画面を埋め尽した。

<E> fish: Could not autoload item 'alias', it is already being autoloaded. This is a circular dependency in the autoloading scripts, please remove it.

やばい。

なんか駄目っぽいので、やっぱ自動で読みこまれるわけじゃないのかと思って、 function内のファイルはそのままに、.config/fish/config.fishにaliasを書いていたら 悪化した。

やばい。

似たようなことで困っている人が全然いなかったので困った。 GitHubのissueとか見ても別にaliasが使えないとかはない。

なんとなく眺めていたら、typeとかaliasとかで調べろ的なのが書いてあって、 でもたぶんそれとは関係ないと思うけど、 function内にalias.fishを置いていることが原因なんじゃないかなって思って、 rmしたら案の定動くようになった。

こういうのって、大体とか付ければ大丈夫なんでしょって思って、 alias.fishにしたけど、_aliasという関数が定義されたことになるだけだった。 定義はされていて補完もされるけど、whichもtypeもfunctionsも何も返してはくれなかった。 別に支障はなかろうが、ちょっと気持ち悪いので、config.fishに書こうかな。

愉快な鬼ごっこの出現条件

まとめ

メインクエスト64章

なりゆき

グラブルを最近やっている。 シエテをお仲間に引き入れたくて、七星剣をちまちま強化していたのだけれど、 虚ろな魂が必要になった。

これの入手方法的なのを探すと、 霧に包まれた島、22章の愉快な鬼ごっこがいいよという記述を良くみる。 でも自分の22章を見てもそんなクエストはない。 まあとりあえず、必要分は少なかったので、他のクエストをやった。

でも流石におかしいと思って、調べてみればメインクエストが出現条件なんじゃないか みたいな分をみた。 でも、どこまで進めれば良いのかとか書いてない。

きれそう。

しょうがないので、ちょっと進めることにした。 今はメインクエスト半額だし、ちょうど良いし。 この前の半額で63章まで

と思って、64章をクリアしたらクエストが追加されました的な文章が出てきた。 みたら追加されてた。 これで虚ろな魂ゲットだぜ。

でもあと一個だけだったとかなんか悲しみの極みという感じだ…

新年とRubyとQuine

まえがき

新年あけましておめでとうございます。あまりにも寒すぎて、布団がもう一枚欲しくなる季節ですが、如何お過ごしでしょうか。

新年になるとよく交換されるものとして年賀状があります。今年はプログラマブルな年賀状のアイディアが突然舞いおりたので、いままでと趣旨を変えて、それを作って送ったのですが、よくよく考えると、これ見て喜べるのって、理解できる人だけなんじゃないかなというか、わからなかったらただの年間違ってんじゃないか?みたいなものだったので、今では反省してます。後悔はしていないので、公開もします。

年賀状

f:id:turane_gaku:20170102223357j:plain

見てわかる通りのAAである。これだけ見たら、完全に去年用の年賀状じゃんかと言われかねないが、この文字列はもちろん適当に並べているわけではなくて、ちゃんと意味のあるものなのである。

Quine

クワイン(英: Quine)は、コンピュータプログラムの一種で、自身のソースコードと完全に同じ文字列を出力するプログラムである。 クワイン (プログラミング) - Wikipedia

それをAAにしたり、色々な工夫を凝らしたりする文化がある。 以下のような本もあったりしてめっちゃ面白い。

mame.github.io

年賀状の文字列もこのQuineになっていて、実行するとその真の力を現わすようになっている。

実行結果

Before

gist.github.com

After

$ ruby nenga2016.rb
eval$s=%w(y=""<<32;c=y*2+"###(
c)"+y+"ghenar_tnxh".tr("a-z","
n-za-m")+y+"1k1".to_i(36).to_s
          +"      ##
          #"      ;o
  ="";j=-1;e="eval$s=%w("+($
  s*7);"000ov3ov3cn5cn5ijhij
  hi      jh      cz      xi
  y9      iy      lc      n5
  cn      5i      yl      iy
  lc    n5cn      5".scan(/0
  |.{3}/                  ){
  |n                      |q
  ="";0.upto(14){|i|2.times{
  q<<(n.to_i(36)[i]>0?y:e[j+
  =1                      ])
  };                      };
  o<<q.rstrip<<10};o[-7,6]="
  ).join";o<<c;puts(o)).join
  ###(c) turane_gaku 2017###

なんということでしょう。過去のものとなったは消えさり、新たにが現われました。

このを実行すると、に戻ったりはせずに、を生成する。時間は常に一方方向にしか流れないのだ。

あとがき

年賀状を印刷してから、shebangを上に書けば良かったなぁと思いました。 あと、年賀状を送った人達のなかで、Rubyを知らない人にはすまない、本当にすまない。

Quineを作るに当っては、ここがめっちゃわかりやすかった。初心者にも優しい。超絶技巧のソースコードは完全に超絶技巧すぎて辛かった。 d.hatena.ne.jp