docker/docker-machine/docker-compose/docker-swarmを学ぶときにわかりやすかった資料達
なにか
Dockerって開発環境構築するときに使うとナウいんでしょ?程度の知識しかない初心者が,Dockerについて学んだときにわかりやすかった資料をまとめたものです.
上から順に読んでいくとわかりやすいと思います.
docker
一言で言うと,dockerはバージョン管理しながらプロセス単位で仮想化するもの
1〜6まである.仮想化とは?から順にdockerのメリットややっていることが理解できる. qiita.com
docker-machine
一言で言うと,docker-machineはdockerの開発環境を作るもの&管理するもの(virtualenv的なもの?).
docker-compose / docker-swarm
一言で言うと,docker-composeは複数のdockerコンテナを管理するもの. docker-swarmは複数のマシンでdockerコンテナを管理するもの.
https://www.slideshare.net/zembutsu/introduction-to-docker-compose-and-swarm
dockerの問題点
以下使用に関する記事
dockerのコマンド
dockerの使用例
dockerfileの開発Tips
Dockerfile のベストプラクティス — Docker-docs-ja 1.9.0b ドキュメント
nginx + mysqlで簡易アプリ作成(みただけ)
docker-machine + docker-compose + docker-swarmの使用例(ちょっと古い)
サービス開発参考
pandas便利な使い方メモ(随時更新)
pandasの便利な使い方を毎度調べたり試行錯誤したりするのは効率が悪いのでここに雑に書き溜める。
もしおすすめの使い方やもっと効率のいい方法などあれば教えていただきたいです!
DataFrame内のあるカラムにある文字列が含まれている行だけ取り出す
要は'hoge' in text
でTrue
になる行だけ選択してくる。
df[df['text'].apply(lambda x: 'hoge' in x)]
同じ要領で、キーが複数ある場合。('hoge', 'huga', 'hogu'で選択してきたい場合)
df[df['text'].apply(lambda x: any([key in x for key in ['hoge', 'huga', 'hogu']))]
あるカラムがnullだったら削除する
df = df.drop(df[df['nanika'].isnull()==True].index)
csv読み込み
df = pd.read_csv(path, names=('hoge', 'huga', 'hogu'), delimiter='nanika')
merge
new = pd.merge(df1, df2, left_on='hoge', right_on='hoge') # カラムの値が一致するものでマージする
shuffle
df = df.reindex(np.random.permutation(df.index))
histogramのxlimを設定する
h = data.hist(column='nanika') h[0][0].set_xlim(-10, 10)
(おまけ)numpy編
条件に一致するものだけ置換する
値が5以上のものを0に置換する
x[ x >= 5 ] = 0
pandasで値の順位を取得したい(おまけにソート方法いろいろ)
pandasでDataFrameにorderを付与したいときのメモ
状況
↓こういうDataFrameに対して、testカラムの値が並び替えた時に何番目になるのかを知りたい
test 0 1 1 4 2 6 3 3 4 2 5 7 6 9
具体的には、こういう結果がほしい
test order 0 1 0 1 4 3 2 6 4 3 3 2 4 2 1 5 7 5 6 9 6
値で並び替える方法はたくさんあるし、並び替えた時に何番目にすればいいのかのindexを取得してくる方法もたくさんあるが、 並び替えた時に何番目になるのかを取得してくる方法が意外となかった。(みんな考えるまでもないのだろうか?)
解決方法
追記
以前の方法(↓に書いてある方法)では同値を適切に扱えてなかった。
scipyを使うとめちゃくちゃカンタンにできた。
stats.mstats.rankdata
という関数がそれ。
from scipy import stats test = np.array([1,4,6,3,2,7,6]) a=pd.DataFrame(test, columns=(['test'])) a = a.assign(order=stats.mstats.rankdata(a.test))
で実現できる
以下のような出力が得られる。同値は小数で表示される。 (この例の場合、indexが2と6のところで5位タイが存在するが、5.5位として表示される)
test order 0 1 1.0 1 4 4.0 2 6 5.5 3 3 3.0 4 2 2.0 5 7 7.0 6 6 5.5
以下追記前の方法
(雑だが)a
というDataFrameのtest
カラムで並び替えた時の順位が知りたい場合、
np.argsort(a.sort_values('test').index)
で取得できる。
全体はこんな感じ
test = np.array([1,4,6,3,2,7,9]) a=pd.DataFrame(test, columns=(['test'])) a = a.assign(order=np.argsort(a.sort_values('test').index))
上のような結果が得られる。
おまけ
単純に並び替える
>>> a.sort_values('test') test 0 1 4 2 3 3 1 4 2 6 5 7 6 9
並び替えた時のインデックスを取得
たまにインデックスだけほしくなる。
>>> a.sort_values('test').index.values array([0, 4, 3, 1, 2, 5, 6])
こうすれば並び替えることができる。
>>> [a.get_value(i, 'test') for i in a.sort_values('test').index] [1, 2, 3, 4, 6, 7, 9]
こういう用途であればそもそもこれで完結するが、
>>> a.sort_values('test').test.values array([1, 2, 3, 4, 6, 7, 9])
以上、メモでした。
rubyでjupyter notebookを使う
rubyでjupyter notebookが使えるというのを発見したので,環境構築してみたがはまったので,改めて環境構築方法を記す.
環境
MacBookPro
macOS Sierra 10.12.3
やったこと
※ここでやったことはうまくいかなかった方法で詰まっている方向けなので,これから環境構築する方は後半を見てください.
とりあえず見つけた以下の記事通りにやってみた.
Railsエンジニアに役立つJupyter NotebookとiRuby - クックパッド開発者ブログ
$ pip install jupyter # python, pip環境が整っていない方は別途整えてください $ gem install iruby $ ruby register # これが動かない $ iruby register # たぶんこう $ jupyter notebook # jupyter notebookが立ち上がり,rubyを選択できるようになってる!
無事,jupyter notebookを立ち上げ,rubyのカーネルを選択することでできるようになった.
しかしここで問題が.
rubyのカーネルを立ち上げ使おうと思ったらうまく立ち上がらない.
ターミナルをみると以下のようなエラーが.
dyld: lazy symbol binding failed: Symbol not found: _zmq_poll Referenced from: /usr/local/lib/libzmq.dylib Expected in: flat namespace dyld: Symbol not found: _zmq_poll Referenced from: /usr/local/lib/libzmq.dylib Expected in: flat namespace
ググってるといろいろな解決法が挙げられていたが最終的には以下の記事が解決してくれた.
Mac で IRuby Notebook 環境を構築する方法 2017年版 - Qiita
ちなみに EI Capitanであればこの記事を見ると良さそう.
結局どうすればよいのか
いろんな記事でrbczmq
をインストールするよう書いてあるがこれがコケてめんどくさい.
上の記事によるとインストールする必要がないようで,以下のようにするとうまくいく.
$ brew uninstall --ignore-dependencies zeromq # installしていたらuninstallする $ brew uninstall czmq # 上に同じ $ brew install zeromq --HEAD # --HEADをつけて最新版を取得する必要がある!!! $ brew install czmq --HEAD $ gem install cztop # rbczmqの代わり?
次に,cztop support
をインストールする.
$ gem install specific_install $ gem specific_install https://github.com/SciRuby/iruby.git $ iruby register --force
これで環境は整った!!
$ jupyter notebook
python並列処理による機械学習の高速化の試み
機械学習をしていると処理の遅さに悩まされることが多々ある.
私は画像系のdeep learningを扱うことが多いので,頻繁に悩まされている.
高速化するにあたってNetworkの処理自体はGPUに任せるしかないので,それ以外でGPUの足を引っ張らないようにするのが大事だと思う.
今回は画像の読み込みを並列で行うことで処理時間の短縮ができるのではないかと思い,やってみた.
この記事でやったこと
* multiprocessingモジュールの簡単な使い方の説明
* Poolクラスを用いて,画像読み込みの並列化&速度測定
* Process, Queueクラスを用いたCNNの処理時間高速化の試み
注意点
Desktop(Ubuntu)とMacBookProで試したのですが,結果が異なってしまったので,あっているのか自信がない…
実装の参考までにしてください.
間違っている点があれば教えていただけると幸いです.
環境
Ubuntu 16.04
プロセッサ: 3.0GHz Core i7
コア数: 16
Pythonにおける並列処理
並列処理には大きく,Threadによる並列化(メモリ共有)とProcessによる並列化(共有なし)があるが,pythonではGIL (Global Interpreter Lock)というインタプリタ上で一度に一つのスレッドのみが動作することを保証する機能があり,Threadによる並列化ができないらしい.
そのため基本的にProcessによる並列化を行う.
multiprocessingモジュール
pythonではmultiprocessingモジュールが提供されており,これを用いることで並列化できる.
[document]
使い方
基本的にはPoolというクラスを用いて以下のように使う.
並列化してもちゃんと順番通りに処理してくれる.
画像読み込みの並列化
以下のように実装した.
結論としては,マルチプロセスにすることで処理速度は向上したがそれほど大きな違いはなかったので,”絶対に並列化するべき!”というほどではない.
が,そんなに難しくない処理なので導入しておくにこしたことはないと思う.
ちなみに,画像読み込み枚数を100, 500, 1000としつこいくらいに細かく調べているのは初めにMacBookProで試したときに想定外の結果がでたので,細かく調査していた名残です.
プロセス数を4にしているのも同様の理由.16にするともっと大きな差がついていた.
CNNでの予測処理高速化の試み
process,queueを用いて,画像の読み込みとCNNでの推定処理を並列に行った.
実装は以下のようにした.(CNNでの推定用コードは省略)
結論としては,並列で画像を読み込んだほうが速いということがわかった.
Process, Queueの導入は逆効果である.という結果がでたのだが,ちょっと納得いかない..
もう少しうまく処理する方法はないのだろうか..
まとめ
multiprocessingモジュールのPool, Process, Queueクラスを用いた並列処理の実装サンプルを示した.
結果,並列化することで処理の高速化を実現できることがわかった.
一番良い方法が並列で画像を読み込む方法だったのだが,Process,Queue等他の方法でもっとうまくやれる方法がある気がする.
間違いがあればご指摘いただけると幸いです.
おまけ
Ubuntuで行う前にMacBookProで試した結果.
Macでは並列化することで悪影響を与えていたので,もしかすると環境次第では並列化しないほうが速いかもしれないので,ご注意ください.
Macで行ったときの結果
Macの環境
実行時のエラー出力をファイルに書き出す
エラーログが多すぎて流れきってしまってエラーを追えないときに困ったのでメモする
エラーログは以下のコマンドでファイルに出力できる.
$ [command] 2>log.txt
2
は標準エラー出力,1
は標準出力.
ちなみに両方出力する場合は,
$ [comannd] 1>log.txt 2>&1 # こうする $ [comannd] 1>log.txt 2>log.txt # これは上書きしてしまうので間違い
Juliusを使ってSiriのような音声認識BOTを作る
ラズパイにSiriみたいなことをさせたい.
が,マイクとスピーカの購入がまだなのでとりあえず手元にあるMacで似たような処理を再現する.
仕様
今回作るもののイメージはこんな感じ
私「ヘイ,ラズパイ!」 Raspi「ポンポンっ」(コマンド受け付けますよ音) 私「今日の天気は?」 Raspi「今日の天気は晴れです」
これを再現したい
実装
音声認識 => Julius
天気情報取得 => OpenWeatherMap(Ruby)
JuliusはOSSの音声認識エンジンで,認識精度自体はDocomo等の音声認識APIには劣るが,ローカルで動き,単語の登録等ができるのが強み.
常時認識しておきたいのでWebAPIを用いるよりこちらのほうがよいと判断した.
手順
Juliusのインストール
ディクテーションキット
- Mac
http://sourceforge.jp/projects/julius/downloads/60416/dictation-kit-v4.3.1-osx.tgz
- Linux
https://ja.osdn.net/projects/julius/downloads/60416/dictation-kit-v4.3.1-linux.tgz
をダウンロードしてくる
$ tar xvzf dictation-kit-v4.3.1-osx.tgz $ cd dictation-kit-v4.3.1-osx $ ./run-gmm.sh
これでJuliusが起動するはず (最新版は4.4 https://ja.osdn.net/projects/julius/downloads/66544/dictation-kit-v4.4.zip だが,試してみた感じ精度が悪そうだったのでとりあえず4.3を使う)
適当にしゃべってみると
<<< please speak >>>Warning: strip: sample 0-66 has zero value, stripped pass1_best: こんにちは sentence1: こんにちは 。 <<< please speak >>>
うまくうごいてそう
このdictation-kitの中には必要ないものも多いので,必要なものだけを取り出してくる.
今回はmodel
,am-gmm.jconf
,bin/julius
,yomi2voca.pl
を取り出してきて適当に新しいフォルダを作る.
$ mkdir julius $ cp dictation-kit-v4.3.1-osx/model dictation-kit-v4.3.1-osx/am-gmm.jconf dictation-kit-v4.3.1-osx/bin/julius dictation-kit-v4.3.1-osx/bin/yomi2voca.pl julius
単語の登録
動くことが確認できたので次に,自分が認識して欲しい単語の辞書を作る(julius/word.yomi)
#julius/word.yomi ヘイラズパイ へいらずぱい 今日の天気 きょうのてんき 明日の天気 あしたのてんき 天気 てんき 今何時 いまなんじ
そしてこれらをJuliusが使える辞書形式に変換する. Juliusは文字コードがEUC-JPなので変換して,辞書形式に変換する.
$ iconv -f utf-8 -t eucjp julius/word.yomi | ./julius/yomi2voca.pl > ./julius/word.dic
登録した辞書を用いる設定ファイルの作成
単語の登録が完了したので,反映させるため設定ファイル(julius/word.jconf)を作成する.
#julius/word.jconf -w word.dic -v model/lang_m/bccwj.60k.htkdic -h model/phone_m/hmmdefs_ptm_gid.binhmm -hlist model/phone_m/logicalTri -n 5 -output 1 -input mic -zmeanframe -rejectshort 800 -charconv EUC-JP UTF-8
※この際,設定ファイルに記載する相対パスは,設定ファイルを起点とするパスになる.
起動の確認
./julius/julius -C julius/word.jconf -C julius/am-gmm.jconf
上記のコマンドで起動できる.
pass1_best: ヘイラズパイ pass1_best_wordseq: ヘイラズパイ pass1_best_phonemeseq: silB h e i r a z u p a i silE pass1_best_score: -2283.777832 sentence1: ヘイラズパイ wseq1: ヘイラズパイ phseq1: silB h e i r a z u p a i silE cmscore1: 1.000 score1: -2283.777832
こんな感じに今まで登録されていな方単語が認識されるようになった.
※注意すべきなのが,登録した単語ありきの認識をするため,なにかしらの言葉を発すると登録した単語のどれかに割り当ててしまうということ.
Rubyとのつなぎ込み
julius gemを使うと簡単にできる.
その際,Juliusはモジュールモードで起動しておくこと.(julius-server.sh)
# julius-server.sh ./julius/julius -C julius/word.jconf -C julius/am-gmm.jconf -module
# main.rb SRC_DIR = File.expand_path(File.dirname(__FILE__)) require 'rubygems' require 'julius' class HeyRaspi def run(julius) begin julius.each_message do |message, prompt| case message.name when :RECOGOUT prompt.pause shypo = message.first whypo = shypo.first confidence = whypo.cm.to_f puts "#{message.sentence} #{confidence}" prompt.resume end end rescue REXML::ParseException puts "retry…" retry end end end puts "接続中…" julius = Julius.new puts "準備OK!" hey_raspi = HeyRaspi.new hey_raspi.run(julius)
ターミナルを二つ立ち上げ,ひとつでjulius-server.sh
を実行.
もう一つはmain.rb
を実行.
そして,準備OKと表示されたら,話しかける!
接続中… 準備OK! ヘイラズパイ 1.0 今日の天気 0.997
いい感じに認識できた〜
あとはここにコマンドの中身を追加すれば完了!
天気の取得
はOpenWeatherMapのAPIを使うと簡単にできる.
実装したものの書くほどでもない気がするので気が向くor要望があったみたいなことがない限り書かない気がする.
参考までに,実装の参考にした記事を記載しておく.
無料天気予報APIのOpenWeatherMapを使ってみる - Qiita
まとめ
とりあえず,今回は音声認識BOTの外枠だけ作成した.
これの中身を変えるとそれぞれの好きなBOTが作れるのではないでしょうか〜