dlibと呼ばれる画像処理ライブラリを使ってみた
皆さんこんにちは
お元気ですか。私は元気です。
日本ではあまり見られないdlibと呼ばれるライブラリの画像処理ライブラリを
使ってみたいと思います。
dlibについて
dlibとは
公式サイト:dlib C++ Library
Dlib is a modern C++ toolkit containing machine learning algorithms and tools for creating complex software in C++ to solve real world problems. It is used in both industry and academia in a wide range of domains including robotics, embedded devices, mobile phones, and large high performance computing environments. Dlib's open source licensing allows you to use it in any application, free of charge.
Dlibは現実世界の問題を解決するための複雑なソフトウェアを作るためのC++の機械学習アルゴリズムやツールであり、
産業や学術の広いドメインに適用でき、オープンソースで、無料である。
実はコンピュータビジョン勉強会に参加するまではこのライブラリの存在を知らず、
そういえばあったなぁと今から使ってみる次第です。
因みにPythonのパッケージもありますが、Macでは動かなかったので諦めてC++にします。
Ubuntuだと動くらしいです。
Install方法
boostなどのその他ライブラリは入っている前提です。
git clone https://github.com/davisking/dlib cd dlib cd examples mkdir build cd build cmake .. cmake --build . --config Release
因みにXQuartzがないと、動作しません。そのため、ない人は以下のページからXQuartzを入れましょう。
https://www.xquartz.org/
インストール後に、シンボリックリンクを貼りましょう。
ln -s /opt/X11/include/X11 /usr/local/include/X11
そして最初のコマンドを実行するとpipを使ったインストールができます。
因みにこのライブラリ何ができるのか?
公式ホームページから引っ張ってきました。
Algorithms
API Wrappers
Bayesian Nets
Compression
Containers
Graph Tools
Image Processing
Linear Algebra
Machine Learning
Metaprogramming
Miscellaneous
Networking
Optimization
Parsing
実際にニューラルネットワーク、SVRなどの機械学習、画像処理、ベイジアンネットワークなど
計算、機械学習系のサポートが強力です。
SVMのCross Validationの例、ResNetの実行例などもあり、サンプルを見ると使い方はかなり見えるのではないでしょうか。
dlibの画像処理ライブラリ紹介
では、何ができるかを見てみましょう。
ソースコードの解説とかは次回以降にします。
顔の輪郭検出
顔の輪郭検出用のコードは、face_landmark_detection_exを使います。
wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
bzip2 -d shape_predictor_68_face_landmarks.dat.bz2
/face_landmark_detection_ex ./shape_predictor_68_face_landmarks.dat ../faces/2008_004176.jpg
顔検出
./face_detection_ex ../faces/2008_002470.jpg
Hog特徴量の計算
./fhog_ex ../faces/2008_002079.jpg
画像の表示
./image_ex ../faces/2008_002506.jpg
Bandit Problemと強化学習ーこれであなたも大金持ち?ー
皆さんこんにちは
お元気ですか。私は元気です。
本日はBandit Problemと呼ばれる問題を強化学習で解いてみます。
- Bandit Problemについて
- 解き方
- 今回解いた問題
- epsilon greedy algorithm
- Softmax Tempature
- UCB
- 感想
- 参考文献
- ソースコード
Bandit Problemについて
Bandit Problem(和名:バンディット問題)は
当たる確率の異なるスロットマシンから最も大きい報酬を得るには
どうすればよいか?といった問題です。
以下のようなスロットがあったとします。
しかし、実はスロット達、あたる当たる確率が異なるスロットなのです。
そのようなスロットの中で最も報酬を高くするようスロットを選んでいくにはどうすればよいかといった問題を
解くことができます。
つまり、どうすれば大金持ちになれるかわかるということです、もちろん儲かる保証はしません。
因みに一般的な問題としては、A/Bテストに使われているとかいないとか。
解き方
いくつか解法がありますが、今回は3点紹介します。
- epsilon greedy algorithm
- Softmax
- UCB
今回解いた問題
今回は強引に以下の割合で当たる問題を解いてみました。
0.5, 0.3, 0.7, 0.2, 0.9, 0.2, 0.3, 0.2, 0.3, 0.2, 0.4
つまり、最も良いのは0.9でこれを引き続けることが理論上、最も良い作業となります。
epsilon greedy algorithm
epsilon greedy algorithmは一定の確率で、適当に選ぶ振る舞いをし、
基本的に最も期待が高い報酬を選択します。
ある意味直感的にわかりやすい
一定回数実施すると、最も高い報酬のところを選択するよう収束するように動作します。
因みにグラフも書いてみた。
以下のグラフは縦軸が報酬の平均、横軸がトライ回数です。
基本的に報酬は最大に収束するように動作しますが、最悪の行動を選択した場合において
残り続けてしまうため収束が遅くなる可能性があります。
Softmax Tempature
温度と呼ばれる概念を与えたBandit Problemの解き方。
epsilon greedy algorithmでは、ランダムな選択時に全ての行動の選択が等しくなる欠点があり、
その欠点を解消するように挙動する。
基本的にはSoftmax関数であるが、温度(T)と呼ばれる概念が投入されており、
この温度関数が高いと、ランダムに振る舞おうとする傾向が強くなるそうです。
(※ = i番目の期待値、 = i番目を選択する確率)
しかし、この温度と呼ばれる概念
グラフ
UCB
UCBと呼ばれる値を導入した
UCB関数は、選択の頻度が低い値を選ぶよう挙動し、
選択の頻度の低い値を選択し、推定する。式は以下の式であり、Cは定数
nは総プレイ回数で、はindexのiを選択した回数
実際にUCB関数を使ってBandit Problemを解いたグラフが以下
感想
実は何回かepsilon greedyを実行していますが、結構ブレブレな挙動を示す傾向ですね。
かなり乱数に左右されるアルゴリズムであることがわかる。。。
Bandit Problemで実際のスロットやるとどうなるのか気になるけど怖くてできない。
強化学習とは何か、調べてみた
皆さんこんにちは
お元気ですか。私は元気です。
今日は強化学習の勉強がてらメモを書いてみました。
個人的には最近、注目している分野で、ゴールがあるような(クラス分類やRegression)
機械学習と異なり、汎用的に色々問題が解けそうだからというのが理由です。
(なんか色々語弊を生みそう)
間違っていれば教えて下さい。
強化学習
強化学習はある環境ないにおけるエージェントが、
現在の状態を観測し、取るべき行動を決定する問題を扱う
機械学習の一種 by wikipedia
この中で登場するのは、「状態」と「行動を決定する」といったところでしょうか。
つまり、「ある状態の時に、どう行動をするか」といったことを解く問題となります。
強化学習における要因
強化学習について考えなければならないことが4点あります。
①ポリシー(policy)・・・どのように行動するか
②報酬関数(reward function)・・・強化学習問題のゴールを定義する関数
③値関数(value function)・・・長期間に渡る評価指標
④環境モデル(model of the environment)・・・アクション・状態の定義
Policy
ある状態が与えられた時、観測された状態からどう行動するか規則のこと。
一番、簡単な方法はLook up table(「この状態の時は、こうする。」が一覧表で決まっている)
Reward Function
強化学習を実施する時に使うゴール部分
イベントに対して、良いか悪いかをagentに伝える
Value function
Value functionは長期的に行動が悪いか良いかを評価する指標
model of the environment
所謂解きたい問題でしょうか。状態とそれに対するアクションがどういった形式で
定義できるのか。
つまり、これらを絵にするとこんな感じでしょうか。
強化学習で解ける問題
強化学習では解ける問題は以下のような問題です。
ロボットの動作最適化
強化学習 - Google 検索
迷路を解く
http://qiita.com/hogefugabar/items/74bed2851a84e978b61c
Alpha Go
AlphaGo - Wikipedia
つまり、状態を持ち、ゴールを持っており、試行錯誤で解ける問題について
解けるといえるでしょう。
また、n-Armed Bandit Problemも含まれ、こういった部分は勉強していきたいと思います。
参考文献
Richard S. Sutton and Andrew G. Barto「Reinforcement Learning: An Introduction」
Go言語を触ったことのない人間がSensorBeeを使ってみた Part2
皆さんこんにちは
お元気ですか。
前回からあいてしまいましたが、引き続き
SensorBeeのturtorialをやってみます。
こちらは準備段階に2段階あり、elasticsearch,kibanaのインストールとtutrialの実施です。
準備
Elastisearch並びにkibanaのインストール
elasticsearch、kibanaは公式から取得するのが良いと思います。
公式ではversion2.2.0ですが、今回は最新の安定版2.3.2で実行してみます。
$ ./bin/elasticsearch [2016-05-04 23:13:01,634][INFO ][node ] [Impulse] version[2.3.2], pid[41126], build[b9e4a6a/2016-04-21T16:03:47Z] [2016-05-04 23:13:01,635][INFO ][node ] [Impulse] initializing ...
起動確認は以下のcurlコマンドで実施できます。
curlコマンドのレスポンスがかえって来れば問題ありません。nameなどは立ち上げるたびに変わるので・・
$ curl http://localhost:9200/ { "name" : "Aliyah Bishop", "cluster_name" : "elasticsearch", "version" : { "number" : "2.3.2", "build_hash" : "b9e4a6acad4008027e4038f6abed7f7dba346f94", "build_timestamp" : "2016-04-21T16:03:47Z", "build_snapshot" : false, "lucene_version" : "5.5.0" }, "tagline" : "You Know, for Search" }
kibanaの起動確認は以下の通り、こちらも公式サイトから取得しましょう。
$ ./bin/kibana log [23:43:01.165] [info][status][plugin:sense] Status changed from uninitialized to green - Ready log [23:43:01.171] [info][status][plugin:kibana] Status changed from uninitialized to green - Ready log [23:43:01.193] [info][status][plugin:elasticsearch] Status changed from uninitialized to yellow - Waiting for Elasticsearch log [23:43:01.207] [info][status][plugin:kbn_vislib_vis_types] Status changed from uninitialized to green - Ready log [23:43:01.213] [info][status][plugin:markdown_vis] Status changed from uninitialized to green - Ready log [23:43:01.224] [info][status][plugin:metric_vis] Status changed from uninitialized to green - Ready
tutorialの設定
$ go get github.com/sensorbee/tutorial/ml $ cp -r $GOPATH/src/github.com/sensorbee/tutorial/ml/config/* /path/to/sbml/ $ cp -r $GOPATH/src/github.com/sensorbee/tutorial/ml/config/* ./sbml/ $ cd sbml/
fluentd
最後にfluentdです。(ここはLogstashではないのか・・・)
まず、初めにbundlerが入っていことを確認しましょう。versionがコンソールに表示されていなければ
$gem list | grep bundler
入っていなければ、以下のコマンドを実行しましょう。
$sudo gem install bundler
最後にbundle installを使って、fluentdを実行します。
$ bundle install --path vendor/bundle $ bundle exec fluentd --version fluentd 0.12.23
fluentdの起動確認をしましょう。以下のような表示がコンソールに出れば成功です。
$ bundle exec fluentd -c fluent.conf 2016-05-04 23:50:17 +0900 [info]: reading config file path="fluent.conf" 2016-05-04 23:50:17 +0900 [info]: starting fluentd-0.12.23 2016-05-04 23:50:17 +0900 [info]: gem 'fluentd' version '0.12.23' 2016-05-04 23:50:17 +0900 [info]: gem 'fluent-plugin-elasticsearch' version '1.4.0' 2016-05-04 23:50:17 +0900 [info]: adding match pattern="sensorbee.tweets" type="elasticsearch" 2016-05-04 23:50:17 +0900 [info]: adding source type="forward" 2016-05-04 23:50:17 +0900 [info]: using configuration file: <ROOT> <source> @type forward @id forward_input </source> <match sensorbee.tweets> @type elasticsearch host localhost port 9200 include_tag_key true tag_key @log_name logstash_format true flush_interval 1s </match> </ROOT> 2016-05-04 23:50:17 +0900 [info]: listening fluent socket on 0.0.0.0:24224 ^C2016-05-04 23:50:34 +0900 [info]: shutting down fluentd 2016-05-04 23:50:34 +0900 [info]: shutting down input type="forward" plugin_id="forward_input" 2016-05-04 23:50:34 +0900 [info]: shutting down output type="elasticsearch" plugin_id="object:3fc04d87f990" 2016-05-04 23:50:34 +0900 [info]: process finished code=0
今回はtwitterを解析するので、api_keyの設定をします。
api_keyはtwitterの公式サイトより、取得することができます。
公式サイトに掲載されている以下の雛形にしたがって、api_key.yamlを作成しましょう。
$ go get gopkg.in/sensorbee/sensorbee.v0/... $ build_sensorbee sensorbee_main.go $ ./sensorbee run -c sensorbee.yaml INFO[0000] Setting up the server context config={"logging":{"log_dropped_tuples":false,"min_log_level":"info","summarize_dropped_tuples":false,"target":"stderr"},"network":{"listen_on":":15601"},"storage":{"uds":{"params":{"dir":"uds"},"type":"fs"}},"topologies":{"twitter":{"bql_file":"twitter.bql"}}} INFO[0000] Setting up the topology topology=twitter INFO[0007] Starting the server on :15601
この時に立ち上がっていれば、kibana上で以下の画面を見ることができます。
まずは、kibana上で可視化したいelasticsearchのindexを指定します。
indexを指定すると以下の画面を見ることができます。
最後にDiscoveryをクリックするとデータが投入されている様子がわかります。
トラブルが発生している場合は・・・
sensorbee shell -t twitter
まずは、以下のコマンドを入力し、データが取得できているかを確認します。
twitter > SELECT RSTREAM * FROM public_tweets [RANGE 1 TUPLES]; twitter > SELECT RSTREAM * FROM labeled_tweets [RANGE 1 TUPLES];
データが取得できている場合は更に以下のコマンドを実行し、ストリーム生成処理が成功しているかを確認します。
CREATE SOURCE public_tweets TYPE twitter_public_stream WITH key_file = "api_key.yaml";
以下、暫くはBQLの紹介なのでスキップし、機械学習部分に行きます。
機械学習
まずは、既存にある機械学習のモデルを読み込みます。
twitter> LOAD STATE age_model TYPE jubaclassifier_arow OR CREATE IF NOT SAVED WITH label_field = "age", regularization_weight = 0.001; twitter> LOAD STATE gender_model TYPE jubaclassifier_arow OR CREATE IF NOT SAVED WITH label_field = "gender", regularization_weight = 0.001;
評価はEVAL Statementを使うことで実施可能です。
twitter> EVAL jubaclassify("gender_model", { "text": {"i": 1, "wanna": 1, "eat":1, "sushi":1}, "description": {"i": 1, "need": 1, "sushi": 1} });
maleかfemaleのどちらかであることを評価するためにはjuba_classified_labelを使用します。
twitter> EVAL juba_classified_label({ "male":0.021088751032948494,"female":-0.020287269726395607});
機械学習のトレーニングに躓いているので、こちらは余裕があればやることにします。
Go言語を触ったことのない人間がSensorBeeを使ってみた Part1
本日はさくっとSensorBeeを使ってみました。
皆さんこんにちは
お元気ですか。連休でほっとしています。
今回はSensorBeeと呼ばれるライブラリを紹介します。
Machine Learningまでは流石に長過ぎるので、word countまでやってみました。
What is SensorBee
SensorBeeは特徴として以下の内容を兼ね揃えます。
Stateful
機械学習に有用な構造化されていない情報を取得し、ユーザが定義した機械学習のモデルを動作させることができます。
また、ChainerやJubatusに加え、その他SensorBeeで記載できるQueryによっても作成することができます。
Expressive
命令やクエリはBQLで書かれています。BQLはパワフルな言語で簡単に習得でき、SQLに似ています(確かに)。
BQLはスキーマレスで、JSONにかなり近い、データ構造となってます。
LightWeight
SensorBeeはLightweightで軽量です。30MBも必要ないので、Raspberry Piのような
小型であっても動作します。 しかしながら、very smallなデバイスには搭載するには十分ではありません。
将来的には、このようなデバイスにも動作させたいんだそうな。
Install
goを持ってない人はgoからのインストールが必要となります。
Go(Mac)
Go自体のインストールと環境変数となります。
$ brew install go $ export GOROOT=/usr/local/opt/go/libexec $ export GOPATH=$HOME/go $ export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
SensorBeeのインストール
SensorBeeのインストールは簡単です。
$ go get gopkg.in/sensorbee/sensorbee.v0/...
Tutorial
これだけではなんのことかまるでわからないので、Tutorialを実施してみます。
まずは、データの取得と初期化を行います。
データの取得と初期化
$ go get github.com/sensorbee/tutorial/wordcount $ mkdir wordcount $ cp $GOPATH/src/github.com/sensorbee/tutorial/wordcount/config/* ./wordcount/ $ build.yaml sensorbee.yaml wordcount.bql
ビルド用のコマンドとしてbuild_sensorbeeを使う必要があります。
$ go get gopkg.in/sensorbee/sensorbee.v0/cmd/build_sensorbee
$ cd wordcount/
$ build_sensorbee
build.yamlの内容は以下のようになります。
$ cat build.yaml plugins: - github.com/sensorbee/tutorial/wordcount/plugin
サーバの起動
これでSensorBeeを使う準備ができました。
早速、SensorBeeのサーバを起動してみましょう。
$ ./sensorbee run INFO[0000] Setting up the server context config={"logging":{"log_dropped_tuples":false,"min_log_level":"info","summarize_dropped_tuples":false,"target":"stderr"},"network":{"listen_on":":15601"},"storage":{"uds":{"params":{},"type":"in_memory"}},"topologies":{}} INFO[0000] Starting the server on :15601
試しにcurlを投げてみましょう。以下のようなレスポンスが返ってくるはずです。
$ curl http://localhost:15601/api/v1/runtime_status {"gomaxprocs":4,"goroot":"/usr/local/opt/go/libexec","goversion":"go1.5.3","hostname":"{host name}-Pro.local","num_cgo_call":1,"num_cpu":4,"num_goroutine":13,"pid":44076,"user":"Tereka","working_directory":"/Users/Tereka/Programing/Software/SensorBee/wordcount"}
まずは、topologyと呼ばれるものが必要になります。topologyは
RDBMSのデータベースに近いそうです。まずは、これを作成しましょう。
./sensorbee topology create wordcount
出力されているStreaming情報はBQLと呼ばれる文法を使うことで様々なことをすることができます。
まずは、stream(ストリーム)からデータを取得してみましょう。
wordcount> CREATE SOURCE sentences TYPE wc_sentences; wordcount> SELECT RSTREAM * FROM sentences [RANGE 1 TUPLES];
BQN
はじめに
BQNはストリーム間の関連性のデータ命令と関係性を示した命令があります。(あってる?)
ストリームの処理単位を決定することができます。
ストリームの処理単位は以下のような構文で実施することができます。
[RANGE n TUPLES] or [RANGE n SECONDS]. [RANGE n TUPLES]
例えば、以下のように書けます。
SELECT RSTREAM * FROM sentences [RANGE 1 TUPLES];
STREAMは3種類あります。
Stream | 説明 |
RSTREAM | 新しいtupleが到着した時に結果を更新する。(処理をする) |
ISTREAM | 到着したtupleのみ更新し、以前までの時刻は更新しない。(処理をしない) |
DSTREAM | 解説plz |
SELECT文
まずは、SELECT文 SQLと殆ど同じ書き方です。
wordcount> SELECT RSTREAM name FROM sentences [RANGE 1 TUPLES]; {"name":"isabella"} {"name":"isabella"} {"name":"isabella"} {"name":"jacob"} {"name":"sophia"}
WHERE文
これも殆ど同じではないだろうか。
WHERE name = "sophia"の部分で、フィルタリングをかけています。
wordcount> SELECT RSTREAM * FROM sentences [RANGE 1 TUPLES] WHERE name = "sophia"; {"name":"sophia","text":"in velit commodo cillum cillum consequat proident dolore ut"} {"name":"sophia","text":"in aute aliqua irure anim sit et"} {"name":"sophia","text":"mollit sunt commodo id id commodo esse sit"} {"name":"sophia","text":"cillum magna aute tempor eu velit"}
GROUP BY
SQLのGROUP BYと似たような使い方です。出力は名前が以前+今回で何回出てきたかをcountで出力しているようですね。
wordcount> SELECT ISTREAM name, count(*) FROM sentences [RANGE 60 SECONDS] GROUP BY name; {"count":1,"name":"jacob"} {"count":1,"name":"sophia"} {"count":2,"name":"sophia"} {"count":1,"name":"isabella"} {"count":2,"name":"isabella"}
ストリームの作成
既にあるストリームから、新しいストリームを作成することができます。
sentencesを処理して新しいwordsと呼ばれるストリームを作成しています。
wordcount> CREATE STREAM words AS SELECT RSTREAM name, text AS word FROM wc_tokenizer("sentences", "text") [RANGE 1 TUPLES]; wordcount> SELECT RSTREAM * FROM words [RANGE 1 TUPLES]; {"name":"isabella","word":"proident"} {"name":"isabella","word":"id"} {"name":"isabella","word":"eu"} {"name":"isabella","word":"laboris"} {"name":"isabella","word":"sunt"}
これを使うと、以下のようにしてword countを実施することができます。
wordcount> SELECT ISTREAM word, count(*) FROM words [RANGE 60 SECONDS] GROUP BY word; {"count":1,"word":"culpa"} {"count":1,"word":"sunt"} {"count":1,"word":"occaecat"} {"count":1,"word":"ullamco"} {"count":1,"word":"ut"} {"count":1,"word":"consequat"} {"count":1,"word":"minim"} {"count":1,"word":"aute"}
それぞれのワードのカウント最大数と最小数を求めています。
また、以下のBQNによって、出現ワードの最大回数、最小回数を算出することができます。
wordcount> CREATE STREAM word_counts AS SELECT ISTREAM word, count(*) FROM words [RANGE 60 SECONDS] GROUP BY word; wordcount> SELECT RSTREAM max(count), min(count) FROM word_counts [RANGE 60 SECONDS]; {"max":8,"min":8} {"max":8,"min":5} {"max":8,"min":5} {"max":11,"min":5} {"max":11,"min":5}
これで、ワードのカウントをSensorBeeで実施するチュートリアルを完走しました。
チュートリアルが半分残っているので時間に余裕があれば、Part2やります。
間違ってたら後で修正かけます。。