アルパカ三銃士

〜アルパカに酔いしれる獣たちへ捧げる〜

AI::MxNet の char_lstm.pl を触ってみた

前々から LSTM に興味があった(何かしらの文章を生成させてみたいと思ってた)ため、今回 AI::MxNet の example に含まれている char_lstm.pl を触ってみた。 github.com

LSTM については以下の記事が丁寧に解説している。 s0sem0y.hatenablog.com

このサンプルはシェイクスピア風の文章を生成するといったサンプル。学習用に使用されるデータは「The Tragedy of Coriolanus」である。サンプルのコードはパッと見た感じ難しく感じるが、ちゃんと読み進めていくと大したことはないため、ここで AI::MxNet に関連する大事な部分のみ解説してみる。

Cell に関してのドキュメントは metacpan公式のページを照らし合わせながら読むと良く分かる。
まずは 175 行目にあるこれ。

my $stack = mx->rnn->SequentialRNNCell();

これを使うことによって複数の cell をスタック形式で保持することができる。

$stack->reset;

とすることによって直近でグラフ描写?に使われた cell をリセットすることができるらしい。
スタックに貯めた複数の cell 全体を一つの cell として扱うことができ、これらを用いることでモデルの学習パフォーマンスや予測値が向上するとのこと。 SequentialRNNCell へ cell を追加するにはこのサンプル場合だと

my $cell = mx->rnn->$mode(num_hidden => $num_hidden, prefix => "lstm_${i}l0_");
if($bidirectional)
{
    $cell = mx->rnn->BidirectionalCell(         
        $cell,
        mx->rnn->$mode(
            num_hidden => $num_hidden,
            prefix => "lstm_${i}r0_"
        ),
        output_prefix => "bi_lstm_$i"
    );
}
$stack->add($cell); # cell の追加

が相当する。ちなみに mx->rnn->$mode はオプションで値を指定しない限り mx->rnn->LSTMCell と等価である。

ここからネットワークの定義を行っていく。
それがサンプルコード内の以下の部分になる。

my $data  = mx->sym->Variable('data');
my $label = mx->sym->Variable('softmax_label');
my $embed = mx->sym->Embedding(
        data => $data, input_dim => scalar(keys %vocabulary),
        output_dim => $num_embed, name => 'embed'
);
$stack->reset;
my ($outputs, $states) = $stack->unroll($seq_size, inputs => $embed, merge_outputs => 1);
my $pred  = mx->sym->Reshape($outputs, shape => [-1, $num_hidden*(1+($bidirectional ? 1 : 0))]);
$pred     = mx->sym->FullyConnected(data => $pred, num_hidden => $data_iter->vocab_size, name => 'pred');
$label    = mx->sym->Reshape($label, shape => [-1]);
my $net   = mx->sym->SoftmaxOutput(data => $pred, label => $label, name => 'softmax');

これらのコードについて以下の qiita の記事を読むとわかりやすい。 qiita.com

こうやって読んでいくと MxNet を用いると簡単にネットワーク層の設計ができるため、非常に良い。

最後にモデルの定義と学習を行うコード。 $model->fit で学習を行っている。 この定義時に使われている context はデバイスに関する情報を渡している。AI::MXNet::Context の metacpan を読むと簡単に書いているのですぐに分かる。

my $model = mx->mod->Module(
    symbol  => $net,
    context => $contexts
);
$model->fit(
    $data_iter,
    eval_metric         => mx->metric->Perplexity,
    kvstore             => $kv_store,
    optimizer           => $optimizer,
    optimizer_params    => {
                                learning_rate => $lr,
                                momentum      => $mom,
                                wd            => $wd,
                                clip_gradient => 5,
                                rescale_grad  => 1/$batch_size,
                                lr_scheduler  => AI::MXNet::FactorScheduler->new(step => 1000, factor => 0.99)
                        },
    initializer         => mx->init->Xavier(factor_type => "in", magnitude => 2.34),
    num_epoch           => $num_epoch,
    batch_end_callback  => mx->callback->Speedometer($batch_size, $disp_batches),
    ($chkp_epoch ? (epoch_end_callback  => [mx->rnn->do_rnn_checkpoint($stack, $chkp_prefix, $chkp_epoch), \&sample]) : ())
);

これらのそれぞれの意味は AI::MXNet::Module::Base の metacpan公式に書かれているのを読むとそれぞれのパラメータについて分かりやすい上に、どのようなメソッドが使えるのかも理解できる。

今回感じたこととして、AI::MxNet だけのドキュメントだけを読んで解決しようとしてもそれぞれのメソッドの意味が全く分からなくて辛い。そのため、公式の Python 用のドキュメントも一緒に合わせて読むことで理解を含めることができた。
ちなみにこのサンプルを実行して 1 時間半経過して、この記事を書いていたがそれでもまだ学習が終了しない…

ドキュメント一覧

Go 1.9 Release Party in Okinawa に参加した

とっても楽しかった!!

初めの 1 時間は deeeet さんの資料をみんなで読み進めながら、この機能はどう使うんだ?って話し合っていた。

印象に残っているのは Monotonic Clock の導入について。Go 1.8 の time.Now() はあくまで「現在の正しい時間」の取得に向いている Wall Clock のみだったが、 1.9 から時間計測にも向いた仕様に変更されたとのこと。つまり、閏秒や ntpd による時間の削除(変更)が行われた時もきちんと計測が可能になったとのこと。

もう一つは sync.Map について。これを使うよりは自前で実装した方がシンプルなのでは?といった疑問を持っていたが、この資料を読んで並行処理中の map の排他処理は一筋縄ではいかないようで、自前で実装するくらいなら色々便利な機能が含まれて高速な sync.Map を使った方が良い感じがした。

LT

今回の LT で Go で CLI ツールを作る時に error をどんな感じに返しているか、オプションの処理はどうしているのかといった話をした。

俺はこうして Go の CLI を作っている

最終的に os.Exit へ結果を持っていくような構成にしているため、どんな方法を用いて exitcode を error に合わせた値を返すようにしているのかといった Tips を紹介した。 github.com

こういった知見を久しぶりにちゃんとアウトプットできてよかったし、何よりパーティが楽しかったから本当に参加してよかった。

Golang 勉強会 in Okinawa | Doorkeeper

plenv を使った環境で AI::MXNet を簡単にインストールする

もっと簡単な方法があれば教えてほしいが、公式のインストールガイドを若干変更することで、簡単に依存関係を含めインストールできた。環境は OS X で以下の手順。

brew install swig
cpanm PDL Mouse Function::Parameters

export MXNET_HOME=${PWD}

# AI::MXNetCAPI のインストール
cd ${MXNET_HOME}/perl-package/AI-MXNetCAPI/
cpanm . # ここで Fail するが以下を続ける
install_name_tool -change lib/libmxnet.so \
    ${MXNET_HOME}/lib/libmxnet.so \
    blib/arch/auto/AI/MXNetCAPI/MXNetCAPI.bundle
make install

# AI::NNVMCAPI のインストール
cd ${MXNET_HOME}/perl-package/AI-NNVMCAPI/
cpanm . # ここで Fail するが以下を続ける
install_name_tool -change lib/libmxnet.so \
        ${MXNET_HOME}/lib/libmxnet.so \
        blib/arch/auto/AI/NNVMCAPI/NNVMCAPI.bundle
make install

# AI::MXNet のインストール
cd ${MXNET_HOME}/perl-package/AI-MXNet/
cpanm . # 依存関係のインストール、テストもやってくれるが時間がかかる

これで使える!!

Openblas を Mac へインストールしようとして詰まった

MXNetMac でのインストール手順を頼りに進めていたが、brew install openblas で詰まった。
brewformulas.org に Active といった状態になっているのだが、なぜかインストールができない。 brewformulas.org しまいには homebrew-core リポジトリこんな感じの issue を挙げた。

さて、すぐに issue は解決するはずがないため、ここで行った対応策を記録する。

対応したこと

python で anaconda をインストールしていれば、conda install openblas でいけるはず。僕は anaconda をインストールしてないし、インストールしたくなかったので以下の手順を実行した。

brewformulas.org で Active なっているということは homebrew-core のリポジトリで formula を探せばいいのではと考え、以下のようなページを見つけた。 github.com

formula が分かれば手動でインストールする方法が分かる。以下の手順通り行った。

wget https://github.com/xianyi/OpenBLAS/archive/v0.2.20.tar.gz
tar xzf v0.2.20.tar.gz
cd OpenBLAS-0.2.20

ここまでやって formula を確認する。 すると以下の 2 行を確認できる。

# Must call in two steps
system "make", "CC=#{ENV.cc}", "FC=#{ENV.fc}", "libs", "netlib", "shared"
system "make", "PREFIX=#{prefix}", "install"

ということは homebrew の環境変数をみれば分かるだろうなということでチェックする。
brew --env を実行するとだいたいこんな感じで表示される。

HOMEBREW_CC: clang
HOMEBREW_CXX: clang++
MAKEFLAGS: -j4
CMAKE_PREFIX_PATH: /usr/local
CMAKE_INCLUDE_PATH: /usr/include/libxml2:/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers
CMAKE_LIBRARY_PATH: /System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries
PKG_CONFIG_LIBDIR: /usr/lib/pkgconfig:/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.11
ACLOCAL_PATH: /usr/local/share/aclocal
PATH: /usr/local/Homebrew/Library/Homebrew/shims/super:/usr/bin:/bin:/usr/sbin:/sbin

つまり、CC は clang を使い、 prefix は /usr/local で良いことが分かった。 ここで分からないのは FC である。これは Fortran Compiler なので、gcc をインストールしている場合、gfortran という fortranコンパイラーが使えるので、 FC=gfortran となる。 ここまで分かれば make は以下のように行える。

make CC=clang FC=gfortran libs netlib shared
make PREFIX=/usr/local install

homebrew の formula はベストなインストール手順が記されているので、読めるようになると後から凄く助かることの連続だろう。

集中力が切れてきたので対応してみた part 2

今日は2日目。こういう集中力が切れた時のハックをみんな積極的に公開して欲しいと思っている。

今日は友達が朝9:45に迎えに来てくれた。それからもう1人を迎えて出発。

今日の目的として、沖縄読谷村にある手動のUFOキャッチャーこと「やどかりの宿」を探しに行くことであった。残波岬の近くにあるということなので、とりあえず残波岬へ向かった。そして到着。

f:id:codehex:20170820204716j:image

こんな感じのところに灯台がある。せっかくなので、上に登って景色を眺めることにした。入場料は中学生以上200円だった。

f:id:codehex:20170820204910j:image

f:id:codehex:20170820204931j:image

こういう感じの景色が楽しめる。広く見渡せることで、沢山のシーンを楽しめた。

それから再び探索を行ったが、目撃情報近くの残波ロイヤルホテルの人に聞きに行ったところ、何年も見かけていないということだったので落胆した。

しかし読谷は素晴らしいので、意外と最近出来た「読谷ファーマーズマーケット」へ行った。

f:id:codehex:20170820205349j:image

このすぐそばにあるこういう建物に入った。

f:id:codehex:20170820205405j:image

ここの3階に「はちれん」というラーメン屋がある。

f:id:codehex:20170820205416j:image

これが名物?の梅風味のつけ麺なのだが、食欲がない時でも食べやすく、さっぱりとした味なのでとても良い。オススメ。

これが午後14:00位で、暫く読谷をウロウロした後友達の家へ行って映画を見た。運転してくれた友達から「THE BLUE HEARTS」が好きなら観るべきだと紹介された映画を観賞した。

リンダリンダリンダ」という映画だった。女子高生が「THE BLUE HEARTS」のコピーバンドを組んで文化祭でやるという内容。

これを観た後オレ達の青春は…ってなったが、凄く面白かった。

9時間位でドライブしてた訳だが、ずっと運転してくれた友達、家に上げてくれて映画を見せてくれた友人に感謝している。

 

今日はもともと自分の好きな曲はどういったものだったか思い出すことができてよかった。(最近ヒップホップしか聞いてなかったため)

今はTHE BLUE HEARTSを家でガンガン流して聴いている。

今日のドライブもあんまり行かない場所へ行ったため、気分転換になったし、曲をガンガン聴くことも癒しになるんだということを思い出すことができて本当に良かった。

 

 

集中力が切れてきたので対応してみた part 1

研究室で自ら設定したタスクを日々こなしていくうちに、色々考えすぎてしまって先週くらいから自分のタスク処理速度が落ちてきた。

今までは運動不足による集中する体力を気にして、バッティングセンターに通うようにしていたが、段々とそれすら効果がなくなってしまった。

原因として、4年次になって以降、研究室に篭り続けていたからだと考えた。そこで今日から暫くの間、思い切って休暇を確保することにした。

手始めに今日はその1日目だが、友達と一緒にドライブに行くことにした。沖縄で遊ぶとなると基本は車での移動になる。

友達の提案で「泊いゆまち」へ行った。

そこでは新鮮な海産物が揃っており、中には、ポン酢を垂らしてすぐに食べられる生牡蠣や鰻の蒲焼など調理済みのものまであり、新鮮な材料での食事を堪能することができた。中でも「アーサ汁」がかなり美味しかった。

そのあと、割と最近?できた糸満市にある潮崎町へ行った。そこでドライブしててたまたま着いたのだが、名前が分からない公園っぽい場所があって、なんと歩行用通路と海との距離が近い!こういう感じ。

f:id:codehex:20170819232721j:image

階段を降りると海という謎の設計だけどこれはいい!

歩行用通路にはベンチがありそこに座ると「ここpanchi」と書かれてるM要素のある建物が見えた。

f:id:codehex:20170819232842j:image

このベンチで1時間以上過ごした。

人が少なく環境が素晴らしかったので、無の状態で過ごすことができた。日々考えることが多いので、久しぶりにリフレッシュ出来たのではないのではないかと凄く感じた。(かなり気分がスッキリしたし、考えもまとめられた)

対応して1日目だが、これだけでも気分がだいぶ良くなったし、沖縄はやっぱり素晴らしいと改めて実感することができた。

 

 

Builderscon へ参加してきました :tada:

今回は前夜祭からだったので合計 3 日間参加しました。

前夜祭

前夜祭は記憶がなくなってしまっているので、きっとそれほど楽しかったのでしょう!! 撤退スペシャルで、結構きわどい話が多くて本当に面白かったです。(てっきりこの時はこれが本番と思っていた)

カンファレンス初日

聞きました一覧です。

横山三国志に「うむ」は何コマある?のトークがすごく面白かったです。
これは、「横山光輝 三国志」という漫画のコマを切り抜きながら、セリフをOCRにかけ保存(セリフとコマの画像は結びつけられている)し、それを全文検索で探し出すといったサービスの裏側をどのようにやりくりしているのかをトークされていました。
それで何が良かったかというと、コマ抜きのアルゴリズムにも感心はしましたが、

そもそもサービスが良すぎる

飛び入りで LT をした

なんと今回のビルコンに旅費 + 宿泊費含め 7 万円越えてしまったので、自分で作ったものを紹介しようと思い急遽スライドを作りました。

どれも終了できないものばかりなので、ちゃんと最後まで完成するように継続的に開発はします。 僕の身寄りが増えたので、協力してくださった皆さんには感謝です。勉強会や飲み会などへ招待していただいた際は、今度紅芋タルトか黒砂糖、もしくは泡盛コーヒーをお持ちします。

カンファレンス懇親会

本当に自分でも何を言ってるのか分からなくなっていて、良く分からないくらい楽しかったです。
ネットの記事で見かけるけど、なかなか目にかかれない方々も沢山いらっしゃって、そういった方々と関われたのも非常に良かったです。「フェイル」という最高なしゃもじも貰えたので最高でした!!

カンファレンス最終日

どれももっと聞きたい内容ばかりだったのでビルコンに本当に来て良かったと思いました。
全体的に、様々な分野の技術者がいて、僕も誰かと似つかないような分野での技術磨きをしたいなと強く感じました。次はトークに応募して参加しようと思います💪 今回運営に携わった方やスタッフの皆さん本当にありがとうございました。

f:id:codehex:20170805214541p:plain