アルパカ三銃士

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

関係者じゃないけど、沖縄複雑系研究会へ参加してきた

今日朝っぱらから、辺野古にある沖縄工業高等専門学校へ向かった。
非常に天気が良く遊びに行くのであれば最高なシチュエーションだったんだろうなと思った。 f:id:codehex:20170921000950j:plain

続きを読む

MXNet の基礎を Perl で学んでみた part 2

前回の「MXNet の基礎を Perl で学んでみた part 1」では NDArray api, Symbol api を組み合わせて計算を試した。今回は、前回使用した api も使ってデータセットをどう準備するか、ニューラルネットをどのように組み立ていくかのチュートリアルを行う。

以下のサイトを参考にしながら進めた。

medium.com

続きを読む

MXNet の基礎を Perl で学んでみた part 1

最近 MXNet の論文を読んだり、MXNet はこれから使われるのかどうかについて調査していた。
結構将来ありそうな感じがした。

そこで、何かしら基本になりそうなチュートリアルはないかと漁っていたら以下のページにたどり着いた。 becominghuman.ai

MXNet の基礎をそれぞれ重要だろうなと思った部分部分で分けてやっていこうと思う。 Perl の repl である Reply を用いた結果を記していく。

続きを読む

どのページでも熱盛を表示するブックマークレットを作った

こんな感じでどんなウェブページにも熱盛を表示できる!凄い!!

f:id:codehex:20170830192126p:plain

以下のコードをブックマークへ追加して使ってください!!

javascript:(function(){document.body.innerHTML+='<div id="atsumori"><img src="data:image/png;base64,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"></div>';var t=document.getElementById("atsumori");t.style.right=0,t.style.bottom=0,t.style.position="fixed";t.style.zIndex=9999})();

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 . # 依存関係のインストール、テストもやってくれるが時間がかかる

これで使える!!