Recurrent neural network based language model

ChainerのRNN Language Models — Chainer 4.3.1 documentationを動かすにあたり、元論文を読んでみることにした。

明確なリファレンスは見当たらなかったが、恐らく "Mikolov, Tomáš / Karafiát, Martin / Burget, Lukáš / Černocký, Jan / Khudanpur, Sanjeev (2010): "Recurrent neural network based language model", In INTERSPEECH-2010, 1045-1048. ではないかと思う。

論文抄録

1.論文の概要

Recurrent neural networkに基づく言語モデル(RNNLM)の音声認識への応用。 複数のRNN LMを組み合わせることで、backoff language modelと比較して、約50%のperplexityの削減が見込める。 Wall Street Journal taskにおける音声認識実験では約18%の単語エラーの減少を示した。

2. 問題設定と解決した点

シーケンシャルデータ予測はML/AIにおいて重要な問題設定。 統計的言語モデルの目的はテキストデータにおいて文脈上の次の単語を予測すること。 従来提示された高度な言語モデリング技術の大半は、ベースラインをわずかに超える改善しかしめせず、実用的ではなかった。

3. 技術や手法のキモ

simple recurrent neural network を採用した。 入力層がx, 隠れ層がs, 出力層がyで、時刻tの入力がx(t), 状態がs(t), 出力がy(t) となる。 順伝播計算は以下の通り。

(1) 
 x(t) = w(t) + s(t-1)

(2) 
  s_j(t) = f(\sum_{i} x_i(t) u_j)

(3) 
  y_k(t) = g(\sum_{j} s_j(t) v_k)

w(t)はone-hot vector。隠れ層sのユニットは30-500。

4. 主張の有効性検証

WSJとNIST RT05で実験を行っている。

読み終えて...

ChainerのExampleで紹介している Recurrent Neural Net Language Model のベースには違いないと思われるが、ExampleにはWord Embedding Matrixが追加されていたり、活性化関数がsigmoidではなくtanhだったり、と細かな違いはあった。

そもそも論文を読み慣れてないし、まとめ慣れてないのでだいぶ戸惑った。 抄録フォーマットも力付きて、全部埋めきれず。何回かやれば慣れると思うが。

リファレンス

抄録フォーマットは以下を参考にさせてもらった。

メモ:PyCharmの設定

PyCharmが素晴らしいという話を聞くので、お試しで使ってみる。

環境

Flake8と統合

  1. Preferences > Tools > External Tools で + マークを押す
  2. Tool Settings で 下記を設定する
  - Program: Flake8の実行ファイル
  - Arguments: $FileDir$/$FileName$ など
  - Working directory: 通常はプロジェクトのルートかな

パッケージのインポート

PyPIに公開されているパッケージは簡単だが、プロジェクト外にある自前パッケージを認識させるのがやや難儀。

f:id:kotaroito2002:20180713161221j:plain

  1. Project Interpreterを選択
  2. 設定アイコンで "Show All..." を選択
  3. "Show paths for the selected Interpreter" を選択

"Interpreter Paths"のダイアログが出現するので、目的のパッケージを追加する。

我が家のフォトストレージ構成 - 2018年版

HDDが壊れてデータリカバリーをする羽目になり、だいぶ金銭的にダメージを負ったので、再発防止としてフォトストレージを見直すことにした。

構成

f:id:kotaroito2002:20180503135247p:plain

写真整理や共有のしやすさを考えて、Google Photoをプライマリーストレージとし、全ての写真を集約することにした。 人的作業ミス(うっかり全削除など)が発生することを考慮し、Amazon Prime Photoをセカンダリーストレージとしている。

ローカルにも保管しておくが、故障や紛失は発生する前提で。あくまで tmp ディレクトリだと考える。

アップロード

自分が所有するスマホからのアップロードは、Google Photo と Prime Photoのクライアントアプリを入れて自動アップロードにした。

デジカメや家族所有のスマホからのアップロードはMacBookに集約する。 MacBookにはGoogle Backup and Sync と Amazon Drive アプリをインストールし、「ピクチャ」と「ムービー」をバックアップフォルダとして設定する。

Google Backup and Sync

f:id:kotaroito2002:20180503140525p:plain

Amazon Drive

f:id:kotaroito2002:20180503140414p:plain

ディレクト

MacBookの「ピクチャ」と「ムービー」は、年単位でディレクトリを切っておく。 家族のスマホやデジカメからインポートしてくる時は、イベントが終わったらその年のフォルダに放り込めばよい。あとはGoogle Backup and Sync と Amazon Drive がよしなにアップロードしてくれる。

f:id:kotaroito2002:20180503140755p:plain

RailsなプロジェクトでReact.jsを利用する1つの例

2016年当時それなりに苦労してRails4.xにReact.jsを導入しましたが、記録に残し忘れていたので、今さらながらブログに書いてみようかと思います。

構成

React.jsを導入するだけならGemからインストールするのが楽なのですが、後日様々なNodeパッケージを導入する可能性を考えて、全てpackage.jsonで管理することにしました。 一方でアセットの配信は既存の仕組みに乗っかりたかったので、assetの配信はSprocketsにお任せすることに。

Node

Rubyはrbenvでインストールしていたので、Nodeもndenvを使うことにしました。

Webpack + Babel

ReactのコンポーネントはES6で書きたくなるので、Webpack + Babelでトランスパイルしています。

react-rails

react_component というViewHelperが便利なので、これを使うためだけにインストールしています。

ディレクト

app/frontend を新たに作成し、ここにReactコンポーネントのソースを格納しています。

├── app
│   ├── assets
│   │   ├── images
│   │   ├── javascripts
│   │   └── stylesheets
│   ├── frontend
│   │   ├── src
│   │   └── test
├── config
│   └── webpack
│       ├── development.js
│       └── production.js
├── package.json

設定

主な設定を書いておきます。2年前なので若干古いかもしれません。。

.babelrc

{
  "presets": ["env", "react"],
  "env": {
    "development": {
      "plugins": [
        "react-hot-loader/babel"
      ]
    }
  }
}

package.json

{
  "version": "1.0.0",
  "scripts": {
    "start": "webpack --config config/webpack/development.js --hot",
    "release": "webpack --config config/webpack/production.js",
    "test": "npm run mocha",
    "bundle-size-analyzer": "webpack --config config/webpack/production.js --json | webpack-bundle-size-analyzer",
    "mocha": "NODE_ENV=test mocha --compilers js:babel-register --require app/frontend/test/setup.js app/frontend/test/**/*.spec.js"
  }
}

config/webpack/development.js

const webpack = require('webpack');

module.exports = {
  entry: [
    './app/frontend/src/components.js'
  ],
  output: {
    path: './app/assets/javascripts/build',
    filename: 'components.js'
  },
  watch: true,
  module: {
    loaders: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loaders: ["babel-loader"]
    }]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  }
}

開発

開発に必要な準備は(nodeのインストールを除けば) npm install && npm start するだけです。

エントリーポイントになっている component.js でrequireしておき、

// app/frontend/src/components.js
window.React = require('react');
window.ReactDOM = require('react-dom');
window.PropTypes = require('prop-types');
window.MyApp = Object.assign(
  {
    MyAwesomeComponent: require('./components/MyAwesomeComponent').default
  }
);

Railsのviewでreact_componentを呼び出します。

react_component('MyApp.MyAwesomeComponent', {})

デプロイ

capistranoに下記タスクを追加することで、deploy:compile_assets の前に webpack --config config/webpack/production.js が走ります。

# lib/capistrano/tasks/webpack.rake
namespace :webpack do
  desc "Release build"
  task :build_release do
    on roles(fetch(:ndenv_roles, :all)) do
      within release_path do
        execute :npm, 'run', 'release'
      end
    end
  end

  before 'deploy:compile_assets', 'webpack:build_release'
end

結果、app/assets/jabascripts/build/components.js にファイルが出力されるので、あとはアセットパイプラインのお仕事です。

まとめ

書き殴りになってしまいましたが、RailsなプロジェクトでReact.jsを利用している事例を書いてみました。 2018年に何をいまさら感はありますが、自分の備忘録として。

AWS KMSを利用して、S3に暗号化オブジェクトを保存する

AWSでシークレットを安全に管理・配備する方法として、AWS KMSについて調査したので、そのメモを残しておきます。

AWS KMS

データの暗号化に使用される暗号化キーの作成と管理を容易にするマネージド型サービスで、S3をはじめ様々なAWSサービスと統合されています。 最初の取っ掛かりとして、この記事が分かりやすいです。

dev.classmethod.jp

AWS KMS + S3

Amazon Simple Storage Service (Amazon S3) で AWS KMS を使用する方法 に記載の通り、S3で AWS KMS を使用する方法は、「サーバー側の暗号化: SSE-KMS の使用」「Amazon S3 暗号化クライアントの使用」の2通りあります。それぞれ具体的な方法を見ていきたいと思います。

サーバー側の暗号化: SSE-KMS の使用

AWS SDK, AWS-CLI, S3コンソールなどを利用することで、サーバー側で暗号化を行えます。 最もカンタンな例として、AWS-CLIでの暗号化・復号化をしてみました。

暗号化

aws s3 cp plain.txt s3://${YOUR_S3_BUCKET} \
    --sse-kms-key-id ${YOUR_AWS_KMS_KEY_ID} \
    --sse aws:kms

復号化

aws s3 cp s3://${YOUR_S3_BUCKET} plain.txt \
    --sse-kms-key-id ${YOUR_AWS_KMS_KEY_ID} \
    --sse aws:kms

cp — AWS CLI 1.14.58 Command Reference

Amazon S3 暗号化クライアントの使用

Amazon KMS で保管されるカスタマーマスターキーを利用し、エンベロープ暗号化 を用いてオブジェクトをS3に保管する方法です。

AWS SDK for Rubyも対応しているので、Rubyで扱うことも可能です。

技術的な詳細

エンベロープ暗号化については、下記ドキュメントを読むと良いです。

https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/images/envelope-encryption.png 出典: AWS Key Management Service の概念

事例

blog.honeybadger.io

RubyMineの設定メモ

備忘のためにメモっておく。

Rubymineをインストールしたら最初にやるオススメ設定 - Qiita

RubyMineで参照するRubyのバージョンをrbenvのRubyに変更する - Qiita

RubyMineからbundle execする方法 - くりにっき

なんかI/Oが刺さってるぞ、という時に...

I/Oを確認する方法をメモっておく。

リアルタイム

sudo iotop

または

dstat --top-bio --top-io

あとから

sar -Bb -f /var/log/sa/sa28  -s '13:00:00' -e '16:00:00'