The jonki

呼ばれて飛び出てじょじょじょじょーんき

正規分布間のKLダイバージェンス

皆さん大好きなVariational Auto Encoderですが,目的関数に再構築ロスとKLダイバージェンスによる正則化項を使っています.原論文のAppendix Bで,正規分布間のKLダイバージェンスの導出をしていますが,途中式が省かれていてよく分かりません.ということで勉強がてら自分でも計算してみました.

参考にしたのはこちら様のサイト.一次元の正規分布間と多変量正規分布間のKLダイバージェンスを求めています.多変量正規分布間の計算は,難しくはないですが,式が複雑なのでとりあえず一次を手計算で導出できたらへぇ,っと眺めて最後のところ見れば良いと思います.
sucrose.hatenablog.com


では,肝心のVAE論文のAppendix Bの導出をします.導出はこちらのPDFに書き出したので御覧ください.(すみません,はてなの記事で書いても良かったのですが,sharelatexで書いてしまいました)
github.com

Touch Bar使ってないならApple Scriptで色々しようぜ

あなたのTouch Bar,ちゃんと使ってますか?私は全く使いきれず,買ったことをずっと後悔していました.しかし最近BetterTouchToolを利用することで,簡単に自分好みにカスタムできることができることを知ったので共有しておきます.今の私のTouch Barの様子はこちらです.なんかごちゃごちゃしてますね.
f:id:jonki:20180407095924p:plain


今回は,作例紹介ということで,BetterTouchToolと組み合わせて主にApple ScriptというMac OSスクリプトを動かします.BetterTouchToolは有料ソフトですが,ショートカットのアプリ毎のカスタムなどが気軽にできるので,すでに購入済みの方も多いのではないかと思います.作例は全てGithubに載せてあります.またApple ScriptはBetterTouchTool上でもテストできますが,実行がやや面倒なのでMac純正のScriptEditor(多分もともとインストールされている)を使うのがおすすめです.また今回はChromeを使っている前提のプログラムが多いですが,Safariなどでも一部変更すればできるはずです.またApple Scriptでなくても,Shell Scriptなどでも良いようです.

github.com

ButtonとWidget

BetterTouchToolの[TouchBar]タブを開くと,右下に[+TouchBar Button]と[+Widget]が見えると思います.私はこの2つを利用しています.基本的に,前者はボタンを押した時にイベントが発行するタイプで,後者は,バックグラウンドで動いており,実行結果に合わせてアイコン部にメッセージを動的表示できたりします.以下の作例では前者をButton,後者をWidgetと便宜上呼びます.Actionとして,[Run Apple Script]を選択するとApple Scriptのコードを貼れる画面があるのでそこに色々書く感じです.
f:id:jonki:20180407101224p:plain
f:id:jonki:20180407104704p:plain

作例(Button編)

選択しているテキストとその開いているタブのURLを合わせてコピーする(copy_with_url.scpt)

Chrome上でページ内のテキストを選択した状態でこのボタンを押すと,"テキスト<改行>URL"という形でクリップボードにコピーされます.選択テキストをCmd+cでコピーした後に(選択テキストには直接アクセスできない模様),現在のURLを取得してクリップボードに連結して上書きする形で実現します.delayを少し入れないとクリップボードへの反映が間に合わないようです.

tell application "System Events"
	keystroke "c" using command down
	delay 0.2
	tell application "Google Chrome"
		set the clipboard to (the clipboard) & return & (URL of active tab of front window as text)
	end tell
end tell
選択しているテキストをGoogle翻訳にかけて,日本語か英語に翻訳する

Chrome上でテキストを選択している状態でこのボタンを押すと,そのテキストをGoogle翻訳にかけたページを開きます.先ほどのURLコピーと同様の手順で,一度Cmd+cでテキストをコピーしてから,Clipboardにアクセスしています.また日英翻訳と割り切っているので,ユニコード値で簡単に日本語から英語なのか,英語から日本語なのかを決めています.テキストができたらあとはChromeで翻訳のURLを開きます.

tell application "System Events"
	keystroke "c" using command down
	delay 0.2
	tell application "Google Chrome"
		set text_ids to id of (the clipboard)
		set is_eng to true
		repeat with tid in text_ids
			if tid ≥ 256 then
				set is_eng to false
			end if
		end repeat
		
		if is_eng then
			open location "https://translate.google.com/#en/ja/" & (the clipboard)
		else
			open location "https://translate.google.com/#ja/en/" & (the clipboard)
		end if
		
		activate
	end tell
end tell
現在の日付を出力する(insert_today_str.scpt)

そのまんまです.押すと"2018/4/6"みたいな感じでキー出力が行えます.日付のフォーマットは適宜お好みで.

tell application "System Events"
	set {year:y, month:m, day:d} to (current date)
	set customDate to y & "/" & (m as number) & "/" & d as text
	keystroke customDate
end tell
Google Play Musicの再生停止を行う(google_play_music_play_pause_toggle.scpt)

Apple ScriptではJavaScriptも実行できます.下記の例では,Google Chromeの各ウインドウ,各タブに対して,Google Play Musicを開いているタブを探し,見つかったところで,任意のJavaScriptを実行しています.再生停止ボタンがあるのでそれをクリックするJavaScriptを実行しています(結構怖いですね!).Google Play MusicはWebアプリなので,MacBookのメディア再生停止ボタンが効きませんが,これを利用することでそれを代用できます.この機能を実行する時,Chromeがフォアグラウンドである必要もないので結構便利です.

tell application "Google Chrome"
	repeat with w in windows
		set i to 1
		repeat with t in tabs of w
			if URL of t starts with "https://play.google.com" then
				execute t javascript "document.getElementById('player-bar-play-pause').click()"
				return
			end if
			set i to i + 1
		end repeat
	end repeat
end tell
キーアクションを出力する

これはApple Scriptを使わず,BetterTouchToolのみで,[Custom Keyboard Shortcut]を使っています.私の環境ではグローバルショートカットキーでToDoアプリが立ち上がるのですが,覚えられないので使ってる感じです.この他にもPredefined Actionにはアプリ起動など色々便利な定義済みコマンドがあるので見てみるのも面白いです.
f:id:jonki:20180407102143p:plain

作例(Widget編)

Google Play Musicで現在再生中の曲を表示する(google_play_music_show_current_track.scpt)

先ほどの音楽の再生停止の要領でJavaScriptを実行します.returnで文字列を返すとそのテキストがTouch Barに表示されます.また,Google Play Musicを開いていないのであれば,空文字を返してそもそも表示しないようにもできます.ちなみにSpotifyとかでも似たようなことはもちろんできます

tell application "Google Chrome"
	repeat with w in windows
		set i to 1
		repeat with t in tabs of w
			if URL of t starts with "https://play.google.com" then
				set song_title to execute t javascript "document.getElementById('currently-playing-title').getAttribute('title');"
				return song_title
			end if
			set i to i + 1
		end repeat
	end repeat
	return ""
end tell
特定のURLを開いた時に,メッセージを表示する(show_msg_in_specific_url.scpt)

例えば私は,TwitterFacebook見過ぎなのでこんな感じで我に返るようなメッセージを表示しています.アイコンはBetterTouchToolからpngなど設定できます.ネタです.


tell application "Google Chrome"
	set currentTabUrl to URL of active tab of first window
	if currentTabUrl contains "twitter.com" then
		return "またTwitter見てるの?"
	else
		return ""
	end if
end tell

まとめ

今回の私の作例をそのまま使う人は少ないと思いますが,何か作りたくなってきませんか?Apple Scriptは初めて触ったのですが,色々なコードは転がっているのでコピペで結構いけます.皆さんもなんか書いてTouch Bar活用しましょう.

帰納バイアス (Inductive bias)

機械学習において,学習データに現れないデータを予測するためには,何らかの制約が必要となる.この制約のもと,モデルを一般化できる.この制約を帰納バイアス (Inductive bias)と呼ぶ.

例えば線形回帰のinductive biasを考える.入力xと出力yは線形の関係であり,その目的関数は二乗誤差を最小化することにある.という制約が線形回帰のinductive bias.データの分布に何らかの制約(仮定)をおかないと,任意の値を求めるのは事実上不可能である.

下記は各機械学習手法における帰納バイアスの一覧.
The Inductive Biases of Various Machine Learning Algorithms - Laura Diane Hamilton


参考
Inductive bias - Wikipedia



違ったらコメントください.

Dockerでgithubのプライベートリポジトリをsshでcloneする

調べてみると色々方法があるようだったが,下記のリンクの方法が一番よかった.Dockerでcloneする用に鍵を作ってそれを利用する方法.英語読むのダリィという方のため(といいつつ自分の作業用メモ)この記事書いておきます.
tarunlalwani.com

Dockerでcloneする用のsshの鍵を作る

大体の人はデフォルトのパスにすでにid_rsaがあると思うので上書きしないよう注意.

$ mkdir keys
$ ssh-keygen -t rsa -b 4096 -C "xxxxxx@yyyyy.com"
Enter file in which to save the key (/home/jonki/.ssh/id_rsa): /home/jonki/keys/id_rsa
Enter passphrase (empty for no passphrase): 何も入力せずエンター
Enter same passphrase again: 何も入力せずエンター
Your identification has been saved in /home/jonki/keys/id_rsa. 

// known_hostsをid_rsa,id_rsa.pubがあるところに作っておく
$ ssh-keyscan github.com >> keys/known_hosts
公開鍵をgithubに登録

githubの設定から,[New SSH key]を押し,作成されたid_rsa.pubをコピーして貼り付ける.

cloneするDockerfileを準備

Imageは何でも良いのだが,入れるImageによってはgitのインストールコマンドも記述する必要がある.また作成した鍵を含むkeysディレクトリをDockerfileと同じディレクトリに置いておく.うまく行けば,「Successfully tagged ...」みたいなログが出るはず.

$ cd <your work space>
$ mv /home/jonki/keys .
$ vim Dockerfile
FROM python:3.6.3

# 作ったkeysディレクトリをコンテナ上にコピー
RUN mkdir -p /root/.ssh
COPY keys /root/.ssh

# 入れるImageによってはgitをインストールするコマンドを入れる必要がある
# RUN apt-get -y update && apt-get -y install --no-install-recommends git ssh みたいな

# git clone
WORKDIR /work
RUN git clone git@github.com:username/your-private-repo.git

CMD ["/bin/bash"]
実行して確かめる
$ docker build -t private-repo .
$ docker run -it private-repo
root@xxxxxxx:/work# ls
private-repo

海外からLightsailで日本国内にプロキシサーバーを立てる

f:id:jonki:20180310111817p:plain

私的利用のために必要になったので,書いておきます.日本国内(あるいは海外)にプロキシサーバーを自前で建てようとした場合,VPSの契約などが必要になると思います.そこで以前にもお世話になった某サイトでサーバーを借りようとした所,リソースが余っていないので無理!とまさかの契約出来ない自体になりました.大したことしないんで,AWSでもいいんですが,あの課金システムが心臓によく無い..と思ってたら,同じくAmazonLightsailというサービスを見つけました.正直ちゃんと説明読んで無いんですが,AWSの簡易版&固定料金版という感じです.固定料金に惹かれて月5ドルプランを契約しました.

使い方&セットアップ

使い方はめちゃくちゃ簡単で,マシンのリージョン,使いたいOSを指定するだけで終わります.SSHの設定などもデフォルト設定であればブラウザ上からいつでもできるので鍵の管理などしなくても大丈夫.私は東京にサーバーを建てたかったので「東京、ゾーン A (ap-northeast-1a)」を選択しました.さらにグローバルIPも追加料金なしで確保できたのでアタッチしました.ファイアウォールの設定が簡易化されいて,アクセス元IPアドレスは指定できずにポート番号の指定しかできないので,ガチガチに固めたい場合は不向きです.しかしこのUIの簡易さは捨てがたいものがあります.

プロキシはsquidで.squidのインストールは簡単です.私はUbuntu(16.04)を選択したのでUbuntuのコマンドおよび設定ファイルを書いておきます.Lightsail上では細かいファイアウォールは設定できないので,squidアプリ上ではしっかりアクセスコントロールしておきましょう.

$ sudo apt-get install squid
$ vim /etc/squid/squid.conf

# アクセスコントロール
acl my_home_net src xx.xx.xx.xx/24
http_access allow my_home_net
visible_hostname unkown

# プロキシ情報の隠蔽
forwarded_for off
request_header_access X-FORWARDED-FOR deny all
request_header_access Via deny all
request_header_access Cache-Control deny all

http_access deny all

# プロキシポート
http_port 12345

ポートを解放する必要があるので,Lightsailのネットワーキング,ファイアウォールから,【Custom TCP 12345】と設定します.これでプロキシサーバーにうーん,簡単.

コンフィグを編集し終えたらサービスを再起動(ちょっと時間かかります).またサービスが自動起動するようにしておきましょう.うまく言ってるかどうかは,ログを眺めてればわかると思います.

$ sudo service squid restart
$ sudo update-rc.d squid defaults
$ sudo tail -f /var/log/squid/access.log


プロキシを設定したら診断くんで,IPが変わっているか確認しましょう.私の環境で,「疑惑 ~20%:proxy の可能性もわずかにあります。」と出ました.

まとめ

Lightsailめっちゃ簡単でびっくりしました.また月額固定金も割り切ってて私には合っていました.またプロキシも十分に働いてくれています.(変な使い方はしないようにね)