2015年8月16日日曜日

fluentd output plugin s3

fluentdからs3にログを残す。
s3プラグイン: http://docs.fluentd.org/articles/out_s3
以下はstoreの設定例。

    type s3 #plugin名
    aws_key_id <アクセスキー>
    aws_sec_key <シークレットキー>
    s3_bucket <バケット名>
    s3_region <リージョン名>
    format json #レコードの出力をjsonに変更
    path webapi/ #バケット配下の階層
    buffer_path /var/log/td-agent/buffer/s3_e #バッファ用ファイルのprefix
    time_slice_format %Y%m%d/%Y%m%d-%H #sliceのフォーマット
    #time_slice_wait 10m
    s3_object_key_format %{path}%{time_slice}_%{index}_%{hostname}_error.%{file_extension} #s3上のファイル名
    utc #標準時形式
    include_time_key true #出力レコードに時刻を追加
    include_tag_key true #出力レコードにタグを追加
    buffer_chunk_limit 256m #バッファファイルが256MBになったら送信
    flush_interval 60s #60秒ごとに送信
    store_as json #保存形式をgzからjsonに変更(AWS Console上で内容を確認したい)

fluentdの基本: centralized logging middle ware

ログシステムの保証レベル
at-most-once:最高で1回の送信。ただし到達を保証しない
at-least-once:少なくとも1回の送信。ただし重複の可能性がある
exactly-once:at-most-onceとat-least-onceの両方を満たす


ログ採取ミドルウェアfluentd
chmod +x install-redhat.sh
./install_redhat.sh
sudo service td-agent start //起動default port 24224


ログ/メッセージに任意のタグをつけて逐次的に収集。
フィルタ(データ加工、集計)、バッファ、ルーティングの後に各種データ出力先へ保存(Output Plugin)する。

fluentd メッセージ
[tag, time, record]

in_exec: 一定間隔ごとに指定パスにあるスクリプトをコマンド実行して、結果を収集する
out_exec_filter: tailプラグインなどで収集したログメッセージに対してデータ加工を行う
out_exec: 収集したログメッセージを指定パスにあるスクリプトの引数として渡して実行する

flush_interval: バッファリングしたメッセージを一括で受け渡しする時間間隔

tailプラグイン:既存のアプリログを収集するのに便利


fluentd設定ファイル
/etc/td-agent/td-agent.conf

有効ディレクティブ
<system> // Fluentdのコア部分の動作を決定する
<source> // プラグインの指定
<match> // ログデータの加工、フィルタリング、外部出力
include // 内部または外部の設定ファイルのロード

以下、設定ファイルの各ディレクティブの説明。[]内はデフォルト設定


system
コマンドラインの引数より優先される
log_level: [info]
suppress_repeated_stacktrace: 連続した同一エラー出力を抑制 [抑制無し]
emit_error_log_interval: 指定時間内の同一エラー出力を抑制 [抑制無し]
suppress_config_dump: 起動時に設定ファイルの標準ログ出力を抑制


source
ログの入力元を決定する。
type: Inputプラグインの指定

<source>
  type <name of plugin>
  tag <output tag>
  <option of plugin>
</source>

tailの場合、formatが必須。formatは正規表現で記述可能。例えばapachなどプリセットも用意されている。


match
ログの出力先を決定する。
type: outputプラグインの指定。フィルタリング、ルーティングも可能。

<match <マッチさせるタグ>>
  type <プラグイン名>
  <プラグインのオプション>
</match>

一度受信したtagをルーティングして、vhostのドメイン部分をタグに含めて再度ルーティングすると、vhostの情報を含むログを出力できる。
outputのプラグインには、fileやs3、mongo、stdoutなどがある。
ルーティング目的では、copy、rewrite_tag_filterなどがある。
一旦matchして出力してしまうと以降のmatchでは引っかからないので、copyなどを利用してうまく設定することが必要。


マッチングタグの記述
*: 1つのタグ要素に合致
**: 0個以上のtag要素に合致
{x, y, z}: x, y, zにマッチ。x, y, zはマッチしたいパターン


fluentdテスト用コマンド
fluent-cat: td-agent付属のコマンド

// 標準出力
echo '{"message":"Hello World."}' | /usr/lib64/fluent/ruby/bin/fluent-cat debug.test // fluent-catにはタグ名を渡す

// ログファイルの参照
sudo less /var/log/td-agent/td-agent.log


example) apache

ログファイルの権限などに注意。間違っている場合td-agent.logにエラーが出力されるので容易にわかる。

2015年8月9日日曜日

Lispによる関数型プログラミング入門2 記法

Lispの記法

・前置記法
1 + 2
→ 
 (+ 1 2)

つまり、関数(ここでは和演算)を最初に宣言して、引数を渡す。これはf(x)と記述するのと同じである。

・defun
means define-function

例)
フィボナッチ数計算:
> (defun fib(n)
>   (if (<= n 1)
>     1
>     (+ (fib (- n 1)) (fib(- n 2)))
>   )
> )

> (fib 5)
 8
> (fib 21)
 17711


Lispの評価と特殊形式quote、function

・quote
関数を評価せずにそのままかえす

例)
> (quote (1 2 3))
 (1 2 3)

・function
シンボルの関数をかえす特殊関数
略記 #'

例)
> (function +)

#<SYSTEM-FUNCTION +>

2015年8月3日月曜日

Lispによる関数型プログラミング入門

SoftwareDesignの2015Aug を読んでLispに興味をもったので、何回かにわけて入門のメモを残す。

Lispの前に、関数型プログラミングの特徴から。

関数型プログラミング

グローバル変数や代入文など副作用を生じる機能を使わずにプログラミングを行う。

・従来の考え方
上記のように変数や配列などの状態をループなどを用いて変更し結果を得る

・関数型プログラミングの考え方
関数(主に高階関数)を利用して副作用無しに結果を得る

・関数型プログラミング向きの問題
状態をもたない再帰的な問題
→探索、整列

・人間には再帰的思考が向いている
数学的帰納法(具体的で小さい問題から大きな全体の問題へ向かう)

・並列処理に対する強み
状態を持たないので、並列処理を自然に(というのは同期や排他が必要無い)できる。
クラウドやビックデータ向きである。

・関数呼び出しに対する弱み
関数呼び出しはコストが大きいので、低機能コンピュータには向いていない。高機能コンピュータ上で並列処理するのに向いている。

・動的なプログラミングに対する強み
関数自身をオブジェクトとして扱えるため、動的な関数生成や変更をすることができる。(サービス指向コンピューティング)

・抽象的なプログラミングに対する強み
うまく作れれば、状態をもたないので仕様変更に柔軟であるはず。

・バグの現象
副作用が少ないので、バグの温床がつくられることを防げる。

Lisp
・言語仕様が小さい
・インタプリタ言語であり、実行が簡単
・GC、ラムダなど最近の言語では常識であるアイデアの元となった言語
・動的型付け(型推論ではない)
・かっこが多くて見難い
・前置記法が見難い
・動的型付けはリソースを食う

数学的帰納法だと考えるとわかりやすい
・再帰をみつける = 同じことの繰り返しをみつける。

例)
階乗:
・関数型
 →5(N)の階乗は4(N-1)の階乗の結果に5を掛けること
・手続き型
 →1 x 2 x 3 x 4 x 5

Lispのインストール(OSX)

次回はLispの記法から。

2015年6月28日日曜日

アルゴリズムプログラム 積

アルゴリズムをプログラムする方法を学ぶ。

積を計算することは、現代では0位取り表記によって大変容易になったが、古代エジプトなどでは専門性を求められるものであった。

積は和を複数回繰り返すことによって実現できる。コンピュータではビット演算を組み合わせることによってより効率的に積を計算することができる。

以下は、アーメスのアルゴリズムとその改善版を記述したコードである。
コードが最適化されているか常に思考し、よりよいコードに変換する作業を繰り返すことが大切だとわかる。


2015年6月21日日曜日

vagrantとansibleを使ってdocker開発環境をつくる

vagrantは開発環境用のVM構築と共有を簡単に行うためのVMラッパーツールであるが、ansibleを利用して開発環境の設定(プロビジョニング)も繰り返しを避けることができる。

vagrantは、プロビジョニング用の設定をVagrantfileに記述することが可能である。
今回は、プロビジョニングにansibleを利用する。ansibleはplaybookと呼ばれるyaml形式の設定ファイルを参照する。

Vagrantfileには以下のように追記する。ansibleはplaybook.ymlを参照する。

ansibleに使用するplaybookを作成する。

Vagrantfileと同じディレクトリにplaybook.ymlを入れておく。
vagrant up で playbookを利用してプロビジョニングできる。既に vagrant up 済みのVMは以下のように明示的にプロビジョニングする必要がある。

2015年6月19日金曜日

Pythonの軽量WEBフレームワークBottle (WebAPIを手軽に記述)

BottleはPythonの軽量WEBフレームワークである。テスト用に素早くAPIを公開したいなと考えたところ、ピッタリだと思った。

インストール
pipでインストールできる。
pip install bottle

サンプルコード api.py
以下の様な短いコードでWeb APIが動作する。



起動
python api.py
めちゃくちゃ楽できる・・・。今まで使わなかったことを後悔するくらいだ。

2015年6月17日水曜日

vagrantのboxを使って仮想マシンを起動する

vagrantは追加されたboxの内容にしたがって、以下のコマンドで仮想マシンの起動設定を作成することができる。

# vagrant init <box名>

Vagrantfileが作成されるので、以下のコマンドで起動する。

# vagrant up

起動したVMには以下のコマンドでssh接続できる。

# vagrant ssh

vagrantでWeb開発環境用仮想マシンができるところまでをまとめるつもりである。

vagrantのboxを追加する(vagrantコマンドで直接URLを指定してSSLエラーが出る場合)

vagrantのbox追加で指定するURLはローカルファイルでももちろん可能である。以下は、curlでローカルに保存したboxファイルをvagrantに追加する手順である。


vagrant box list で追加できているか確認できれば完了である。

2015年6月16日火曜日

gvmを利用してgradleをインストールする(OSX)

GVM(Groovy management tool)はGroovy環境構築用ツールである。Groovyの実行バージョンの管理や、Groovyを利用するツールのインストールが可能である。

インスール
curl -s get.gvmtool.net | bash

PATHに追加
export PATH=$PATH:$HOME/.gvm/bin

実行
~/.gvm/bin/gvm-init.sh

gradleのインストール
gvm install gradle

以上で完了。zshを利用している場合には、.zshrcもしくは.zshenvにPATHとコマンド初期化の設定が追加されることを確認すること。

2015年6月12日金曜日

Bing画像検索API Pythonクライアント

学習画像を収集するための、Bing画像API Pythonクライアント。
保存ディレクトリとか検索ワードの指定をパラメータで引き渡すようにして少し使いやすくしたつもり。収集する画像の最大枚数を指定することも可能。


Gemでログを標準出力にする(Ruby)

Gemfileに以下を指定して、rails_stdout_logginライブラリを利用する。
gem 'rails_stdout_logging'

2015年6月11日木曜日

Objective-C メモリ管理

Objective-CSwiftはクラスのインスタンスを参照カウンタで管理する。参照回数が1以上であれば、インスタンスはメモリ上に保持される。

ARC(Automatic Reference Counting)は自動で参照カウンタを管理する仕組みである。retain及びreleaseを明示的な記述を禁止し、自動で行う。

オーナーシップはオブジェクト間の関係性を表すが、強参照と弱参照がある。
強参照は参照先のオブジェクトのオーナーシップを持ち、自分が参照を捨てるまで確実に参照可能である。new(alloc)するとインスタンスへの強参照をもつことになる。

一方、弱参照はオーナーシップをもたず、オブジェクトが破棄されると参照できない。delegateやblocksで用いることが多い。

お互いに強参照の関係にある場合、循環参照と呼ばれる。片方の参照を弱参照にすることで回避できる。


docker ログ出力の設定

dockerでコンテナを作成する際は、ログをコンテナ内に残さないほうが良い。

ログを標準出力に出すように変更する。dockerは標準及びエラー出力されたログをホストの/var/lib/docker/containers/<コンテナID>/<コンテナID>-json.logにJSONファイルとして出力する。

docker logsコマンドで見ることのできるログは、上記のファイルである。Docker Remote APIを介して取得することも可能である。

基本方針

  • コンテナに依存せず、ログを収集する仕組みを準備する
  • ログ収集プロセス自体をコンテナとして動作する

標準出力の設定

各コンテナに割り当てたアプリケーションごとに標準及びエラー出力に設定する。


ログ収集
以下の様なツールを起動するコンテナを準備する。

  • Logspout:dockerコンテナ用のログルータ。Docker Remote APIを介して、同一ホストの全コンテナのログを取得する。LogspoutコンテナからSyslogサーバなどへルーティングすると、複数ホスト上で動くコンテナ郡のログをSyslogサーバで確認することができる。
  • Fluentd:fluentdにはdocker用のプラグインがある。/var/lib/docker/containers以下のログファイルを読み込んで、別のあるファイルへ出力させる。またはS3や集計サービスへ送信する。

ログ集約サービス
Logentries:SaaS型のログ集約サービス



2015年6月10日水曜日

Objective-C 基礎

Objective-Cは触ったことがほとんど無い。基礎からひと通り触る際の記録。

Sample.h
Sample.m

カテゴリ
あるクラスのメソッド郡を別のモジュールとして宣言する。

NSString+SampleAddition.h
NSString+SampleAddition.m

vagrantによるdocker環境の構築

vagrantとはVMのラッパーツールである。設定ファイル(Vargrantfile)を使用してVMを起動することができ、環境構築の再現性を高めてくれる。また、Dockerが64bitOSにしか対応していないのに対して、32bitOSをサポートしているため、環境構築のホストOSへの依存度も低下する。

ここでは、vagrantのインストール及びvagrantを使ってdockerコンテナを扱う際の基礎的なコマンドについて記載する。

vagrantはパッケージでインストールする。

vagrantはデフォルトの仮想化ソフトに VirtualBox または VMWare を使うため、どちらかインストールしておく。ここでは、VirtualBoxを利用する。

また、vagrantのプラグイン dotenv をインストールする。
$ vagrant plugin install dotenv
Installing the 'dotenv' plugin. This can take a few minutes...
Installed the plugin 'dotenv (2.0.1)'!

vagrantでVMを起動する
vargrant up

vagrantで起動したssh接続する
vargrant ssh

vagrantのVMのステータスを確認する
vagrant status

vagrantでVMを停止する
vagrant halt

ホストとのファイル共有
synced_folderを使用してローカルマシンとVMの間で特定のディレクトリを共有する。
ソースコードやDockerfileを変更して、そのままVM上でDockerイメージをビルドするために用いる。

      config.vm.synced_folder(
        "../",
        "/home/core/#{File.basename(File.dirname(Dir.pwd))}",
        id: "vmid",
        :nfs => true,
        :mount_options => ['nolock,vers=3,udp'],
      )

Dockerfileを書く際の基本方針
イメージを小さくすること。コンテナの起動、イメージのビルド、push、pullにかかる時間を短くすることができる。

ビルドのレイヤー数
Dockerfileには、関連するコマンドを連結(&&とバックスラッシュを利用すると、コマンドを連結できる)してビルドのステップ数を少なくする。

Vagrantfileとansibleでdockerをインストールする方法はこちら


2015年6月8日月曜日

dockerを使用したシステム設計の原則

dockerを用いてシステム設計する際に注意すべきことがある。1バーチャルマシン(つまりサーバ1台)として捉えるとうまく設計できない。

dockerを用いる場合、「再現性」、「構築フロー」、「デベロッパーがサーバ管理できる」といったメリットがある。

しかし、コンテナやホストマシンの管理、docker自体の頻繁なアップデートによる学習コストなどがデメリットである。

システム設計で大切なこと
dockerコンテナの運用方法自体が簡潔になる方向を模索する。

1コンテナは1デーモンと考える
コンテナはサーバ上で起動する1デーモンと考えること。

コンテナに永続化するデータが存在しないこと
ログを含む永続化対象のデータはすべて、コンテナ外へ保存すること。

設定はすべてアプリケーションコード外で管理すること
設定がアプリケーションコードに依存していると、アプリケーションの変更によって接続先が変わってします可能性があるため。

ホストマシンには出来る限り直接パッケージをインストールしないこと
ミドルウェアを含めた環境全体をコンテナとして動かすこと。
ホストマシンの管理を不要にし、可能な限りコンテナのアップデートコストのみにする。

buildには基本Dockerfileを使用すること
シンプルで簡単だからである。

dockerを扱う際のコマンド

dockerで使用する基礎的なコマンド。環境用のツールにはboot2dockerを使用する。

仮想マシンの初期化
boot2docker init

1回だけ実行すれば良い。2回目は以下の様なメッセージが表示される。
Virtual machine boot2docker-vm already exists

仮想マシンの起動
boot2docker start

シェルの初期化
$(boot2docker shellinit)

dockerのバージョン確認
docker -v

dockerイメージ一覧の表示
docker imges

dockerイメージの起動
docker run -p <local ポート番号>:<コンテナ無いのポート番号> <Dockerイメージ名> <コンテナで実行するコマンド> <引数>

ローカルにイメージが無い場合はpullしてからrunが実行される
コンテナは使い捨てである。ファイルに変更が無い場合、buildしてから使用する。


dockerイメージの作成(コンテナからイメージを作成する)
buildコマンドを使う。buildコマンドは「Dockerfile」ファイルと適用してDockerイメージを作成するコマンドである。(commitはミスの原因になるので使用しない)
docker build -t=<イメージ名:{タグ名}> <Dockerfileを含むコンテナのディレクトリ>

dockerイメージをDocker Hubなどのレジストリにpushする
docker push <イメージ名>


Docker Hubへのログイン
docker login
ユーザ名、パスワード、メールアドレスを入力する

Docker Hub は Dockerレジストリの1つである。Docker社が公式で提供するレジストリであり、イメージの共有をすることができる。


Dockerfileについて
Dockerfileはmakeに対するMakefileのようなもので、Dockerコンテナの構成ファイルを記述するテキストファイルである。以下が参考になる。

2015年6月6日土曜日

Python Vim 開発設定

Vimを使ってPython開発を快適に行うための設定

開発する上で目指したいのは、以下の様なことではないだろうか。

  • コードの記述量を減らす
  • コードの書式チェックを自動で行う
  • テキストエディタ同様の表示書式
  • 記述中にインタプリタを実行する

設定方法

コードの記述量を減らす

Python補完のVimプラグインを使用するため、jedi-vimを導入する。
以下のページがシンプルでわかりやすい。jedi-vimのインストール部分だけ実行すれば良い。
Vim+Python環境設定メモ


コードの書式チェックを自動で行う
コードの保存時などに、コードをチェックする。

sudo pip install flake8 pyflakes pep8 pylint


テキストエディタ同様の表示書式
~/.vimrcに以下を追加する。

"#####表示設定#####
set number "行番号を表示する
set title "編集中のファイル名を表示
set showmatch "括弧入力時の対応する括弧を表示
syntax on "コードの色分け
set tabstop=4 "インデントをスペース4つ分に設定
set smartindent "オートインデント

"#####検索設定#####
set ignorecase "大文字/小文字の区別なく検索する
set smartcase "検索文字列に大文字が含まれている場合は区別して検索する
set wrapscan "検索時に最後まで行ったら最初に戻る


記述中にインタプリタを実行する
~/.vimrcに以下を追加する。rubyとperlの実行も追加しておくと便利。

autocmd BufNewFile,BufRead *.rb nnoremap <C-e> :!ruby %
autocmd BufNewFile,BufRead *.py nnoremap <C-e> :!python %
autocmd BufNewFile,BufRead *.pl nnoremap <C-e> :!perl %

これでだいぶ作業しやすくなるはず。

2015年6月2日火曜日

Convolutional Neural Network の 畳込み層を出力してみた

オリジナルのCNN実装を使って、Le-Net5でMNISTデータを学習した後の畳み込み層を出力してみた。

conv1





conv2



conv3


2015年6月1日月曜日

lombok (Java)

Lombokはボイラープレートコード(getter/setterなどの決まりきっているが記述が必要なコード)を簡潔に記述するためのライブラリである。

@Data
getter/setterをコンパイル時に記述するアノテーション

ただし、staticなメンバ変数については@Dataや@Getterを指定してもgetterが宣言されないので注意すること。

@Builder
を利用すると、コンストラクタとgetterが宣言される。

Gradleでビルドする場合は、依存関係に以下を追加する。


2015年5月31日日曜日

htop (cmd) OSX

htopコマンドはLinuxのプロセスおよびメモリ使用量のビューアである。macではtopコマンドのオプションがLinuxと異なるため、同様の情報をみたい場合に便利である。
導入も非常に簡単である。

以下が実際に表示した様子である。Linuxのtopコマンドのオプション1よりも視認性が良い。


TBB OSX (C++)

OSXでTBBを利用したいときの最もお手軽な(だと思う)方法


1 minute intro: Intel TBB parallel_for (C++)

TBB(Threading Building Blocks)は C++で並列化プログラムを簡単に記述するためのライブラリである。Intelが基本的な関数の使い方のビデオを公開している。以下はparallel_forのもの。機械学習のコードで大変よく登場する。


コードは以下である。
Threading Building Blocks

2015年5月30日土曜日

stringstream(C++)

stringstreamは、C++のストリームをstringに結びつける機能をもつクラスである。

stringstreamはstringに対して、<< や >>  演算子を提供する。
ostringstreamは出力のみ提供する。逆にistringstreamは入力のみを提供する。


2015年5月29日金曜日

numeric_limits(C++)

numeric_limitsは数値型の取りうる値の範囲についての情報を得るときに利用する。

以下のように使用する。

最小値を得たい場合に注意が必要である。
min()は必ずしも-max()を返すわけではなく、整数型と浮動小数点型とで意味が異なる。
C++11からはlowest()を利用すると良い。

minmax_element (C++)

minmax_elementはC++11から追加された機能であり、最小値/最大値を一括して求めるアルゴリズムの実装である。Boostのminmaxとはことなるので注意。

minmax_elementはvectorなどのコンテナを対象として最小値/最大値を求める。
戻り値の型はstd::pair型である。要素はポインタである。

minmaxもstd::pair型であるが、要素はminmaxのテンプレートのclass型である。


2015年5月28日木曜日

swap(C++)

swapは2つのオブジェクトの値を交換するときに使われるが、オブジェクトによって実装が異なるので動作に注意すること。

プリミティブ型の最大値を超えた場合のstatic_castの動作(C++)

プリミティブ型の最大値を超えている場合、static_cast はどのように動作するか。
出力は以下のようになる。
65535
0
1
65535
0
1

2015年5月25日月曜日

typeid (C++)

typeid演算子を利用して、型情報を取得できる。typeid演算子は、type_infoオブジェクト(type_infoクラスへの参照)を得る。


emplace_back(C++11)

emplace_backはvectorの要素の追加を効率的に行えるようにC++11から追加された。

暗黙的型変換を利用して emplace_back により値をコンテナに格納するとコピーコンストラクタが呼ばれない。その分効率的に処理することが可能だ。ただし、暗黙的型変換を利用せず、自ら引数のオブジェクトのコンストラクタを呼び出すとコピーコンストラクタが呼ばれるので注意。

CharTraits(C++)

CharTraitsはよくわかってない。標準出力などのbasic_streamを引数に受け取って流し込むようにtemplateに指定する使用方法を記載する。

set(C++)

C++のsetは要素の数が有限の集合である。また、setの中の要素はソートされて保持されており、順序づけされたオブジェクトの集合とかんがえることができる。つまり、数学の集合とは意味が異なる。

setの良い点は、findによって目的のオブジェクトがsetに含まれているかどうかすぐに判別できる点であり、ソートされて保持された性質を利用して、ソート用途としてsetを使ってはならない。vectorをalgorithm sortでソートするよりもオーバーヘッドが高いからである。オーバーヘッドは、setが指定した要素をfindですぐに見つけられるように要素をinsertする際にインデックスすることからも想像に難くない。

また、ソートされることからわかるように、setの要素となる型にはオペレータ < が定義されている必要がある。これはmapのキーと同じである。

マニピュレータ iomanip (C++)

C++の入出力で書式を設定するのに マニピュレータ を使うと便利である。iosヘッダまたはiomanipヘッダに定義された機能を利用できる。


stdexcept(C++)

stdexceptは標準的な例外クラスを提供する。

これらのクラス群に反映されているエラーモデルの種類
  • runtime error 実行時エラー
  • logic error 論理エラー
実行時エラーは、プログラムの制御の及ばない事象を起因とする。
論理エラーは、プログラムの内部的論理の誤りに起因する。

以下の様なクラスが定義されている。
  • exception
    • runtime error
      • range_error
      • overflow_error
      • underflow_error
    • logic error
      • domain_error
      • invalide_argument
      • length_error
      • out_of_range
これらのクラスは同じpublic関数が定義されており、ジェネリックな呼び出しが可能である。
explicit T(const string& what_arg){} 指定したメッセージをもつ例外オブジェクトの生成 
explicit T(const char* what_arg){} C++11 指定したメッセージをもつ例外オブジェクトの生成
virtual const char* what() const noexcept; メッセージの取得

2015年5月23日土曜日

enum(C++)

C++における列挙型enumは数種類のint型の値しかとることができない型を宣言する。
関数の引数や戻り値の値の意図を記述できる。

  • 値は明示しないと0から順に付けられる
  • サイズは環境依存であるため、通信プロトコルでの利用などでは注意すること

explicit(C++)

explicitは引数を1つだけとる変換コンストラクタが暗黙的に呼ばれることを防ぐ。

よくあるケース
  • explicitを記述しない変換コンストラクタをもつクラスは、= で初期化(コンストラクタ呼び出し)を記述できる
  • クラスの参照を引数に受け取る場合、意図せずして暗黙的に変換コンストラクタが呼び出されることがある

2015年5月22日金曜日

関数宣言(C++)

関数の引数には型のみを指定することも可能

overrideキーワード(C++11)

overrideキーワードは、意図せずして正しいオーバーライドになっていない状態を防ぐものである。

派生クラスの関数が、基底クラスの仮想関数をオーバーライドしていることを示す。


transform(C++)

transformは変換を行うライブラリである。transformの処理内容は、関数オブジェクトやラムダ式を使って記述する。


関数オブジェクト(C++)

()は関数呼び出しの演算子である。クラス定義中に、()をoperatorとしてオーバーロードすると、オブジェクトを関数呼び出しの形で呼び出せる。これが、関数オブジェクトである。

vector_array_for(C++)

配列、vectorforについて整理

配列中の要素を変更するには、参照を取得すること。

vector resize reserve(C++)

vectorresizereserveの動作についてまとめる。


fill(C++)

std::fillは配列やコンテナに対してレンジ指定してすべて同じ値を代入する関数である。


vector iterator(C++)

C++のvectorのイテレータを扱う関数はtemplateで型に依存しないようにしておこう。

nullptr(C++)

C++ではNULLは0でマクロ定義されており、プリミティブ型として扱われる。

nullptrはNULLをポインタ化したものであり、ポインタとして扱いたいときに利用する。


コンストラクタ初期化子(C++)

以下のように使用するコンストラクタのコロンは、後ろにメンバ変数や親クラスを初期化する処理を記述することができる。

コンストラクタの中に処理を記述する場合と異なるのは、変数の初期化を省略できることである。

1億回の繰り返し処理で比較した結果、初期化子(コロンを使用した初期化処理)のほうが高速であった(どのくらい高速化は環境によって異なる)。

ただし、プリミティブ型については初期化の必要がないため、初期化子と代入で効率の違いはでないが、記述方法の一貫性やconst対策、コードの可読性のために初期化子を使用するべきである。

 親クラスの初期化についても以下のサンプルに記述しておく。

2015年5月21日木曜日

alignment(C++11)

アラインメントとは、オブジェクトのための領域をメモリ上に確保する際のアドレスの境界位置のこと。
intのsizeが4バイトの環境では、intのデータを4の倍数のアドレスに配置すると、より高速にアクセスできる場合がある。

alignofの返すアライメント要求は、その型のオブジェクトをアドレス上に配置するためのものである。alignofが4の場合、該当のオブジェクトは4の倍数のアドレスに配置する必要がある。

アラインメントを指定するには、alignasを使う。変数及びメンバ変数のアラインメント属性を指定する。alignas(型名) は alignas(alignof(型名)) と同じである。

複数のアラインメントを指定すると、最も大きなアラインメントが選択される。


size_t(C++)

size_t

長さ、大きさ、サイズ(メモリ量)を表現する型として用いるもので、sizeof演算子が返す符号なしの整数型(unsigned int)である。

immintrin (C++)

immintrinはSIMD演算用の関数ヘッダーファイルである。

以下のようにすると、すべてのSIMD、AVX演算を利用することが可能である。
#include <immintrin.h>

SIMD -SIMDとは-

コンパイラ最適化入門 -明示的にベクトル化されたコードを記述する-

使いこなすの大変だなこれは。

Levenberg-Marquardt(レーベンバーグ・マーカート)

最適化(非線形最小化)手法の1つ。Deeplearning実装のために準備する。

非線形関数の最小値をみつける最適化を行うことが目的。
最も単純な方法は最急降下法であり、コスト関数を微分して小さくなる方向に進む。
最急降下法が大変遅いことを解決するのに、Gauss-Newton法(または単にニュートン法)を利用する。

Gauss-Newton法は、関数を2階微分して0になる箇所を探す。局所解に陥る危険はあるが高速に学習が進む。また、Gauss-Newton法が対象とする関数は2階微分を元の関数の1階微分の2乗で近似できる関数である。そのため、1階微分の2乗が0になる位置を探す。

上述の、Gauss-Newton法が局所解に陥る危険を減らしたものが、Levenberg-Marquardt法である。

コンピュータビジョン最先端ガイド3の岡谷先生によるバンドルアジャストメントの記述が丁寧である。

その他の最適化手法について、以下のスライドが詳しい。
- SGD、モーメンタム、etc・・・
http://www.slideshare.net/beam2d/deep-learningimplementation

unordered_map (C++11)

unordered_mapは連想配列(キーと値をセットで保持)を簡単に利用できるライブラリである。JavaではHashMapが使われる。

unordered_mapは名前のとおり、keyの順序に関係なくHashを使って格納する。
keyの順序によってソートしたい場合は、std::map を使えば良い。

mapへの操作は、unordered_map も std::map も基本的に同じである。

以下に他の機能も詳しく記載されている。

http://program.station.ez-net.jp/special/handbook/cpp/stl/map.asp

2015年5月20日水曜日

virtual function(C++)

virtual function(仮想関数)について

継承関係のあるクラスの関数をオーバーライドしたい場合にポリモーフィズム実現のために利用する 仮想関数 だが(実装を持たない場合、純粋仮想関数)、なぜ 仮想関数 を定義したクラスのデストラクタは virtualでなくてはならないのか。

 【復習】
仮想関数

仮想関数テーブル
virtual function table, vtable という隠しメンバ変数を使って実現される。
ある仮想関数を呼び出したとき、実装にはどの関数かを管理するテーブル 
仮想関数テーブルは実行時、コンストラクタで初期化されてデストラクタで破棄されるので、不要な場合はvirtualにしないほうが仮想関数テーブルの分だけメモリ使用量は節約できるし、効率もあがる。

仮想関数を定義したクラスのデストラクタ
仮想関数の利用シーンは、「子クラスのポインタ」を「親クラスのポインタ」にキャストして使って、仮想関数の実装だけ入れ替えるようにして利用(ポリモーフィズム)がほとんどのはずである。

このとき、親クラスのポインタ(実体は子クラス)に対して delete した際、親クラスのデストラクタがvirtualでない場合、子クラスのデストラクタが呼ばれず、メモリリークが発生する。

また、親クラスが暗黙的に作成するデストラクタはvirutalでは無いので、内容がなかったとしても以下のように明示的に宣言すること。
virtual ~ParentClazz() {}

座標系スケール変換関数(template)

座標系のスケール変換を行う関数をテンプレート使って記述する。


macro

引数つきのmacroについて

以下のように、macroに引数を定義することが可能。うけとった引数の処理は続けて()に記述できる。


2015年5月19日火曜日

namespaceとoperator

namespaceとoperator

assert(C++)

assertでは、コードに開発者の意図を埋め込むことができる。

例えば、以下のコードはassertion failedとなる。

static_cast (C++)

static_cast は 型変換(キャスト) の方法である

以下を満たす場合に使うことができる。

  • 暗黙的変換ができる
  • void * から他のポインターへの変換

汎用ポインタ(C++)

汎用ポインタ void* は、あらゆる型のポインタを代入できる。
void*型からのキャストはstatic_castが推奨される。

cstdint(C++11)

cstdintには、bit数を指定できる整数が用意されている。



参考サイト
C++日本語リファレンス
http://cpprefjp.github.io/reference/cstdint.html

limits (C++)

プリミティブ型の最大値や最小値を取得する際、マクロ変数から取得することも可能だが、型安全な定数やメタ関数を利用して取得する。

 メタ関数は、こんな形式の関数

meta-function<type ...>::value()
typeに対してプリミティブ型でなく、typedefした型を入力すれば、型の変更に合わせてコードを書き換える必要なく値を取得できる。


参考サイト
C++のプリミティブ型が取りうる最大値を取得する。
https://www.c3.club.kyutech.ac.jp/archives/1203

decltype と type traits (C++11)

decltype


decltype(expression) で式の型を得ることができる。

利用シーン


  • プロトタイプ宣言の型指定
  • 関数の戻り値の型を得る
typeinfoを併用して使い方を見てみる。typeinfoは実行時型情報(RTTI RunTimeTypeIdentification)を取得する機能である。

また、C++のコンパイラが名前マングルした(シンボルがuniqueな名前となるように)文字列を閲覧するのではなく、デマングルして宣言した型であることを確認する。

libstdc++cxxapi abi::__cxa_demangle()関数を利用する。


type traits

型の特徴を調べたり、型の特徴を操作する関数
C++11では、type_traitsをインポートして enable_if が使える。
template <bool B, Class T = void>
struct enable_if;
enable_ifは、Bがtrueの時にtypedef T type;をもち、Bがfalseであればtypeをもたない。

SFINAE(Substitution Failure Is Not An Error)用途に使われる。
SFINAEは置き換え失敗はエラーにあらず、という意味で関数をオーバーライドする際、型変換がうまくいかなければオーバーライドの候補から自動ではずすことができる記述である。

ていうかいろんな書き方があってC++レベルが足りてない。以下の様な書き方があるってことを認識しておこう。


2015年5月18日月曜日

3年計画の途中経過

以下の目標を実現できそうなところで仕事させてもらえそうなので、とても嬉しい。

  • 専門性(データマイニング・コンピュータビジョン)が活かせる、またはキャリア・スキルアップになる仕事をする。
  • 世界で仕事が出来る場所にいく

前のプロジェクトが死ぬレベルで忙しすぎてストップしてた英語を再開。
  • TOEIC 900点

DeepLearning 実装 準備編

DeepLearningの実装をスクラッチから行う。

まずは準備編として、3層多クラス分類のニューラルネットワークを実装した。

  • Androidアプリにも取り入れやすい
  • C++への書き換えも割と容易
ということでJavaで実装した。

動作確認用の可視化用クラスは、以下のものが使いやすかったので、多クラス分類用に修正して利用させていただいた。

NN法っていいよね-きしだのはてな

以下がコード。

ニューラルネットワーク


【課題】

  • 学習誤差を出力して、学習の進度を確認できるようにすること


2015年4月5日日曜日

リアクティブ(Rx)プログラミングについて自分なりに落とし込んだ

Rxを理解する切り口

サーバ、システム、インフラ

非同期アーキテクチャ、アクターモデル、メッセージ駆動

プログラミング

Push型、イベント駆動、データ構造のストリーム化(※Functional Reactive Programming)、データバインディング

※FRP
業務アプリ実装にFRPを使ってみた http://programplusgirl.tumblr.com/post/52698153869/frp
FRPについて理解するために参考にしたものhttp://qiita.com/busyoumono99/items/b355150fb69eae1584c2

リアクティブ

「反応」を意味する

リアクティブプログラミング

データの変更が流れるように自動的に伝搬していくプログラミング手法

時間変化する値や振る舞いを宣言的に行う(手順的な記述にならない)


プログラミングパラダイム

・オブジェクト指向→オブジェクトとメッセージの集まりを作成し、オブジェクト間のメッセージを定義して問題を解決する
・関数型→プログラムを関数評価の連続とみなす。副作用や状態から関数を切り離す。

宣言型

性質を満たす結果が得られれば、結果を得る方法は気にしない。

データを扱うということ

・データは入力される(最初に揃わない)
・レスポンスを待つ(データはすぐに揃わない)
・データの全体がmassiveなため、部分的にしか使えない

データを扱うということ(課題)

非同期である
→ 時間軸に一様に配置されないから順番を記述しないほうが良い

ざっくり言って

「いつ呼ばれるかに依存しない書き方」ではないか

Rxを実現するのに必要な概念

・ストリーム(データをもつ時間軸、データはユーザからの入力であったりする)
・ストリームをsubscribeするオブジェクト
・ストリーム上で起きるシグナル(シグナルに対する振る舞いを個別にプログラムする)
・Push型のデータバインディング(UIもしくはデータが変更されたときに、変更のイベントが自動で届く仕組み)

RxJava

分かった気になる初めてのRxJava
https://speakerdeck.com/kirimin/fen-katutaqi-ninaruhazimetefalserxjava

この辺りまでの概念を考えた上であれば、適切にEventBusを使えるのではと思う。

EventBus

Implementing an Event Bus With RxJava - RxBus
http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/

EventBus library

EventBus
https://github.com/greenrobot/EventBus

JVM言語 Kotlin

JVM言語 Kotlinは、ScalaやGroovyのように、Javaバイトコードを生成することでJVM上で動作する言語である。

JavaScriptの生成も標準でサポートしており、さらにAndroidまでサポートする。Android開発が軽くなるととても嬉しいので注目している。

以下、設計思想と特徴を簡単にまとめた。

## Kotlinの設計ゴール
  • Java互換
  • Javaバイトコードへのコンパイル
  • JavaScriptコードへのコンパイル
  • Javaと同等以上のコンパイル速度
  • Javaより安全(NULL安全など)
  • Javaより簡潔
  • Scalaよりシンプルな方法
  • 表現力を実用レベルに維持

## 特徴

  • オブジェクト指向である
  • プリミティブ型がなく、すべてがオブジェクトである
  • プロパティ、トレイと、オブジェクト宣言
  • 関数は第一級オブジェクト

2015年1月11日日曜日

Swift言語の簡単な特徴メモ

Swift

ブロック
中括弧で表現{}

型の記述
スタイル:先頭は大文字
指定:変数の後ろにコロンと合わせて記述する。あくまで型推論の補助というポリシーだとわかる。

配列.array
宣言;大カッコ
空配列は型の指定が必要:Pythonよりは型安全だが、型の指定方法は[型]
配列の要素アクセス:大カッコとindex指定
配列の要素入れかえ:大カッコとindex指定
配列の要素挿入:insertとindex指定、+=で最後に要素もしくは配列を連結
配列の要素削除:removeAtIndex(atIndex:)とindex指定
配列の最後の要素を削除:removeLast(要素アクセスと併用でPythonのpop)
配列の要素全削除:removeAll
配列の要素選択:Pythonのrangeにあたる機能、[m...n]でmからn-1までの要素を取得などのrange演算子が使える
配列の代入は完全なlazyコピー
letはimmutable、varはmutable
lazyコピーの効率:2015/1/10時点ではまだissue状態だが、概ね効率的。ただし、大量の再代入は避けるべき。
functionへ参照を渡す処理の場合:inoutパラメータを使用する。再起処理を関数呼び出しで実行する場合には注意。関数の呼び出し側で参照を知らせる&を使用する。
Cocoaフレームワークへの変換:as

ハッシュテーブル.dictionary
宣言:大カッコにkeyとvalueを:で分離
ハッシュテーブルのvalueアクセス:大カッコとkey
ハッシュテーブルのレコードの削除:nil代入
順序:保証しない
Cocoaフレームワークへの変換:as

演算子
比較演算子:極めて一般的な記号
論理演算子:極めて一般的な記号(powを表現する記号は無し)
for-in:一般的、range演算子を使用可能
条件付きfor:小括弧を省略するスタイル、型推論可能
while:小括弧を省略するスタイル
if:小括弧を省略するスタイル
switch:小括弧を省略するスタイル、break不要

関数.function
宣言:func
引数:引数名: 型(代入時の型にも注意)
可変引数:型...で表現
戻り値の分離:-> 型
外部引数名:引数変数の前に名前を指定
外部引数名の関数呼び出し:呼び出し時は外部引数名の指定が必須
ネスト:可能。内側の関数は外側の関数ブロックがアクセス空間

クロージャ.closuer
存在:ある。functionはclosuerの特別な形式。
ボディの分離:-> 戻り値型 in
ボディの分離の省略:
よく使われるケース:コールバックするためのHandler

構造体.structure
宣言:struct
型:値型(value type)
プロパティの型推論:可能
プロパティへのアクセス:ドット
ARC(Auto Reference Count: 参照カウント型のメモリ管理機能)対象外

クラス.class
宣言;class
型:参照型(reference type)
継承:有り。宣言時に:(コロン)で区切ってsuper classを記述する
オーバーライド:継承後のメソッドではsuper必須。
型キャスト:有り
ARC(Auto Reference Count: 参照カウント型のメモリ管理機能)対象

メソッド.method
タイプ:インスタンス、static有り

包括型.Any
包括クラス型.AnyObject、Cocoaフレームワーク(主にNSArrayとNSMutableArray)への変換

ナル表現
nil

その他の表現
オプショナル型、ラップ状態の表現:?、nilチェックに使えるので楽

アンラップ表現:!

2015年1月7日水曜日

2015/01/11までの目標


  • ERFilter 論文
  • ERFilter Train
  • Playframework2.3 テンプレートエンジン、CSS、js周り
  • 英単語 + 1000
  • 英語漬け + 毎日
  • 英文法 2/6

playframework2.3 for Java (Macに移行)

play2.3 for javaの環境をMacに移行したのでメモ

今年はplay2.3 for javaでつくったWEBアプリをサイトに組み込む。

公式ドキュメント


参考にしたブログ


インストール

playは2.3からactivatorを利用する。
まずはactivatorをインストール。
以下からダウンロード。

適当な場所に展開する。
$ cd ~
$ mkdir app
$ cp activator-1.2.12-minimal.zip /User/masai/app
$ cd /User/masai/app
$ unzip activator-1.2.12-minimal.zip
$ ln -s activator-1.2.12-minimal activator
$ export PATH=$PATH:/User/masai/app/activator

activatorコマンドが使えるかどうか、以下で確認
$ activator -help

activatorを使って、playフレームワークのアプリケーションを作成する。
$ activator new my-first-app play-java
(scalaで開発する場合は、play-javaをplay-scalaにする)

ユーザのhomeディレクトリにアプリケーションディレクトリが出来る。
$ cd /User/masai/my-first-app
$ activator
ここで依存関係の解決にけっこう時間がかかるので途中でやめないように注意。

以下のコマンドでデフォルトのアプリケーションを起動することができる。
$ activator run

では、アプリケーションをEclipseに取り込んでみよう。

開発環境

Eclipse は Scala IDE for Eclipseを使う。

$ activator eclipse
[info] Loading project definition from /Users/masai/my-first-app/project
[info] Set current project to my-first-app (in build file:/Users/masai/my-first-app/)
[info] About to create Eclipse project files for your project(s).
[info] Successfully created Eclipse project files for project(s):
[info] my-first-app

処理が完了したら、Eclipseからmy-first-appのディレクトリをインポートする。

Eclipseでインポートしたら、Playアプリケーションのファイル構成を確認しよう。

routes

routesを使って、URLとコントローラをひもづける。
サンプル・アプリケーションには2つの設定が記述されている。
GET / controllers.Applications.index
これは、/に対してGETリクエストを受け取ると、controllers.Application.indexが呼び出されることを意味する。

controller

□Application.java
・index.renderがindex.scala.htmlの描画を担当する。
・index.renderの引数はmessageとして、index.scala.htmlへのパラメータになる。
・OkはHTTPステータスコード200を返す。

view

xxx.html.indexの形式で作成しておくと、コンパイル時にview.htmlパッケージ内に
xxxオブジェクトが作成される。この動作を前提として、コントローラのクラスを記述するため、
Application.javaではindex.renderを記述できる。

□index.scala.html
・変数の宣言
@(message: String)
これは、String型のmessageという変数を使用する、という宣言であり、とても安全である。

@main
main関数の呼び出し。main.scala.htmlの呼び出しである。
mainの引数はtitleとして、main.scala.htmlへのパラメータになる。

@mainアノテーション中の @play.weblcome もmain.scala.htmlに渡すパラメータである。
play20のwelcomeメソッドを呼び出す。
変数を渡すこともできるし、style = “Java” のように、styleという変数名で、Javaというvalueで
渡すことができる。

play20のwelcomeメソッドで様々なhtmlを生成して表示する。

□main.scala.html
本体のhtmlである。
・変数の宣言
@(title: String)(content: Html)
これは、String型のtitle、Html型のcontentという変数を使用する宣言。

@titleの部分で、index.scala.html のmainメソッドから渡された値が使用される。

@routes.Assets.at
routesは、conf.routesファイルで定義される。
routesには、/Assets.atが定義されている。/assetsから、GETでfileを取得するように記載している。

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)

assetsでアクセスするファイルは、パスpublicとしている。
実際、以下のディレクトリには、stylesheetsとimages、javascriptsディレクトリがある。
/Users/masai/my-first-app/public/main

@content
これは、index.scala.htmlのplay20.welcomeメソッドが生成したHtml型のオブジェクトが渡される。play29.welcomeはplayのライブラリに含まれる。

バージョン管理からはずすファイル

logs
project/project
project/target
target
tmp
dist

.cache

次回

テンプレートエンジン

2015年1月6日火曜日

2015年の目標


2015は目標をもって進んでいこう

今年の目標!!3年計画の1年目

  • 英語。6年間の復習、キクタン制覇、英文解釈読了。TOEIC受験。
    • 本腰いれて英語やる。世界で仕事したい。
  • 機械学習の入門資料準備。
    • 自分の復習も兼ねて、一緒にやれる人も増やしたいので。
  • ComputerVisionとObjectRecognitionで新たな研究の実装。
    • こちらは大学院。新しい研究を始めるので、とにかくアイデアと実装までいく。
  • 自分のホームページつくる
    • いままでブログだったけど、エンジニアとして発信するのに文字だけというのはどうかなと思ったのがきっかけ。
  • 自分のホームページに価値のあるコンテンツを置く(機械学習とそのコード、物体認識デモ)
    • ホームページつくるならコンテンツがほしい。価値が出せるのは恐らく機械学習とか画像処理とかで実装したところ。ライブラリみたいに出来れば一番いいけどまずは解説とかコードを公開するといったことを目標にする。

中期目標!!3年で実現すること

  • TOEIC 900点以上
  • 専門性が活かせる、またはキャリア・スキルアップになる仕事をする。
  • 世界で仕事が出来る場所にいく。
  • もう一本ComputerVision系の論文を発表する
  • ホームページをバイリンガル対応に(英語)