今日の落書き Rubyでアヤメ(Iris)のデータを眺める

データを用意する

https://raw.githubusercontent.com/pandas-dev/pandas/master/pandas/tests/data/iris.csv

Jupyter Notebookを起動する

※ホビーでRubyを手軽に使うのにJupyter Notebookが必ずしもベストとは思わない…

ライブラリを読み込む

CSVファイルを読み込む

SepalLength SepalWidth PetalLength PetalWidth Name
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
5 5.4 3.9 1.7 0.4 Iris-setosa
6 4.6 3.4 1.4 0.3 Iris-setosa
7 5.0 3.4 1.5 0.2 Iris-setosa
8 4.4 2.9 1.4 0.2 Iris-setosa
9 4.9 3.1 1.5 0.1 Iris-setosa

アヤメの品種を確認する

Name
0 Iris-setosa
50 Iris-versicolor
100 Iris-virginica

基礎統計量を表示してみる

PetalLength PetalWidth SepalLength SepalWidth
count 150.0 150.0 150.0 150.0
mean 3.759 1.199 5.843 3.054
std 1.764 0.763 0.828 0.434
min 1.0 0.1 4.3 2.0
max 6.9 2.5 7.9 4.4

グループにしてみる

SepalLength SepalWidth PetalLength PetalWidth
Iris-setosa 5.006 3.418 1.464 0.244
Iris-versicolor 5.936 2.77 4.26 1.326
Iris-virginica 6.588 2.974 5.552 2.026

アヤメの品種ごとにデータをわける

SepalLengthのヒストグラム DataFrameから

Nyaplotを使う場合

※ Daruから NyaplotやGnuplotrb、Plotlyを通してグラフを描けるらしい. 残念ながらNyaplotの開発は止まっている…

SepalLengthのヒストグラム Statsampleから

StatsampleがDaruと統合する前に独自に持っていたグラフ機能が残っている

setosaの散布図を描く

Nyaplotを使うとき

Numo::Gnuplotを使うとき

Daru::Vector→RubyArrayへの変換が必要。

相関係数を求める

SepalLength SepalWidth PetalLength PetalWidth
SepalLength 1.0 0.747 0.264 0.279
SepalWidth 0.747 1.0 0.177 0.28
PetalLength 0.264 0.177 1.0 0.306
PetalWidth 0.279 0.28 0.306 1.0

散布図行列

現状では簡単に描く方法は存在していないとおもわれる。

単回帰分析を行う

Numo::Gnuplotで回帰直線を描く

多分Nyaplotでも描ける

重回帰分析

【Ruby】 Numo::Gnuplot で箱ひげ図 (boxplot)

忘れないうちにメモ

1.配列をさっと比較したいとき

2.ラベル付きのデータのとき

using の設定がややこしいけど、丸暗記するしかないっぽいね

医療とAIの未来について再び妄想する

頭の整理をするために、また医療とAIの未来について考えている。

医療データサイエンス 1.0

これは、近い将来にきっと起きる変化だ。AIの医療応用を考える多くの人が思い描いている未来だ。
具体的には
・CTやMRI画像などが、Deep Learning技術で自動的に診断できるようになる
・医療用のデータセットを作成する患者団体や、病院、学会が現れる
・APIを用いて医療データを取得する手段が整備されはじめる
・データセンタを持つ企業が医療データを低価格で診断するサービスを始めてデータを収集・蓄積しはじめる 
・対抗して、よりオープンな医療データセットやオープンなモデルも公開される
・大病院が工学技師としてデータサイエンティストを雇いはじめる
・もしくは医者がデータサイエンスをかじりはじめる
・少しずつ人工知能が普及しはじめる
・画像診断の精度、血液検査の精度、内視鏡の精度、遺伝子の解析、心電図モニタリングetc
 すべてでコンピュータが人間を上回る
・個別化された医療が行われるようになる
・診断だけではなく、治療にロボットの活用がはじまる
・確実にどんどん成果を生まれ、治療成績も激的に向上していく
・にもかかわらず、不思議なほど医療そのものには何らの変化がない なんでだろう?
・保険点数が厳しく減額され、利益が減少したりする
・IT企業に対する患者の医療訴訟が多発するようになる。高額の賠償が請求される事例も発生する
・IT企業も、次第に状況を理解して(最初は不合理だと思っていた)製薬会社のやり方を真似するようになる
・もしくはもともと無料でサービスを提供できる体力のあるところだけが他の会社を焼き払う形で生き残る
・最初からこうなることを見越していた老舗企業もしぶとく生き残る
・患者とエンジニアの間にゆっくりと失望が広がっていく
・業界の熱気が冷めて、少しずつ落ち着いてくる
・なんかいい感じになる
といった感じだろうか。とってもワクワクしないよね。あまりにも想像するのが容易だ。
妄想にしても陳腐だ。
こういったことに無邪気に夢を感じるには、少し歳をとりすぎた気がする。

問題は、ここからだと思っている。上記の筋書きはちゃんと考えれば誰もが見通せる素直な未来だ。
未来は、だいたい思い描いた通り素直には歩いてくれない。

医療データサイエンス 2.0

上で描いた1.0は人工知能は、あまり医療の本質に触れていない。
つまり1.0は来るが、そのままの形ではこない。

僕が思いつくだけで大きな焦点は2つあると思う。
1つ目の焦点は、割と簡単だ。簡単だということは、乗り越えうるということである。
乗り越えた先は、たとえばアルファ碁のあとの囲碁界みたいな事になっていると思う。ある意味楽しい世界である。

2つ目の焦点も簡単だが、もう少し医療の本質に関わる問題である。
この問題が乗り越えられるかどうかはわからない。乗り越えるとしたら、人工知能は俺が考えているよりもやばい。
少なくとも、今の段階では人工知能がこういった問題を乗り越えることは想像できないな。多分、人工知能はこの問題を乗り越えられずに迂回すると思う。
少なくとも人間は、こういう問題を直接乗り越えるよりは迂回することを好む。

この問題について、ちょうどいいツイートがあったので引用しておく

そしてその根本にある問題や、その他の問題もおぼろげに見える気がする。

いつものことだが妄想日記にしても考えがよくまとまらない。

考えれば考えるほど、やっぱり人工知能も今までの技術革新と同じで、結局は医療は変わらないという説の方を採用したくなるね。

Rubyを使ってDICOM画像で遊んでみる

RubyでDICOM画像を扱う情報がほとんどないので少しずつメモしてみる。

ruby-dicomhttps://github.com/dicom/ruby-dicom

インストール

DICOM画像を読み込む

メタデータを取り出す

画像データを取り出す

IRuby Notebook上にDICOM画像を表示する

imageメソッドで、ImageMagickオブジェクトに変換できる。
内部ではrmagickもしくはmini_magickが動いている。
rmagickは更新が滞っているので、mini_magickがおすすめ。


※画像はDSB2017に使用されたsampleの1つです

ヒストグラムを表示する


Guido ZuidhofFull Preprocessing Tutorial
の序盤をRubyに書き換えてみた。とりあえず動いてくれればOKという発想なので、例によって間違いあるかも。

今日の落書き Ruby の PyCall で Keras の Mnist 画像部類

RubyでPythonっぽいコードを書くと、RubyでPythonが実行できるというPyCallというGemがあります。
このPyCallでDeep Learning用のライブラリであるKerasが動かせるということなので、やってみました。

こちらのサイトを参考にしました。
PyCallを使えばRubyでもKerasでDeep Learningができる(洋食の日記)

短いコードですが、半年ぐらいプログラミングに触れていなかったのでかなり時間がかかりました。

工夫したところ

・RubyからPython呼んでいる時点で無駄が多いことをしている。だから何も気にせずに、ライブラリを贅沢に使おうと思った。
・MnsitをRubyの配列で呼ぶためだけにruby_brainを使用した。
・255で割るためだけにNumo/NArrayを使用した。
・結果として、mnistの元ファイル ⇢ Ruby配列 ⇢ NArray配列 ⇢ テキストファイル ⇢ numpy配列 という情報の変換、受け渡しにとても時間がかかっている。
 (・しかし、これは、PCを使わない人工知能にも広く見られる現象だ)
・ハマったのは、Kerasでmnist読み込む時と、ruby_brainでnnist呼びこむ時のデータ形式の違い。

よかったところ

・うごく!
・Rubyでディープラーニングする手段がある。0と1では大違い。

不満が残るところ

・PyCallでKerasを実行している最中に Ctrl+C でターミナルを停止できない
・エラーメッセージがもっと改行してくれると嬉しい
・やはり Ruby ←→ Pyrhon の情報のやりとりに不自由を感じる
 ・Rubyで前処理して一度ファイルに保存、Pythonで処理するのが現実的かもしれない

ASUS ZenBook に Keras を入れるまで

常用していた中古のノートパソコンをMacbookに買い換えました。周囲のMac使用率が50%に近づいている現在、Macを購入する最大のメリットは、周囲とのコミュニケーションの心理的な促進作用だと思います。Macには人と人とのつながり、コミュニケーションを誘発する作用があります。そこにはスペックだけ見ているとわからない、お金にできない、大きな価値があります。それに、Macを使っていると気分がいいです。Macについて語るとき、みんな笑顔になります。洗練されたGUIとシンプルなソフトウェアに囲まれて作業していると、落ち着いた気持ちになります。そう、間違いなくMacを選択するメリットは大きいのです。そうだMacbook Proを購入しよう。2年ぶりにUbuntuからMacに戻ろう。鼓動の高なりを感じながら、僕は家を出た。


そして、ASUSとともに帰宅。


Intelのシールの右に、緑色のNVIDIAのシールが張られている。GeForce 940MX搭載である。つまりCudaが使える。それからMacは高い。そりゃあなた、お金は大事ですよ。(しかし現行MacにGeForce搭載されていたら本当にMacbookを買っていたと思う)

以下困った時のためにKeras導入までの自分用メモ。

① まず購入して真っ先に、Intel等のシールをはがす。Macでは不要な作業。

② ブートUSBの作成
UNetbootinではなくこちらを使用した。とくに不具合なし。Ubuntu 16.04
UbuntuのブートUSB作成 (usb-creator を使用)

③ 画面の解像度がおかしい
→ソフトウェアアップデートして再起動

④ Cuda8.0のインストール
第456回 Ubuntu 16.04 LTSでCUDA 8.0を使用する 2017年2月1日 柴田充也
→ こちらの情報が適確で初心者にもわかりやすいのでその通りにした
→ deb(network)を選択した
→ 自動的にnvidia-375がインストールされる。NVIDIAのサイトでsupported productにGeForce 940MXが含まれていることを確認
→ PATHの設定、LD_LIBRARY_PATHの設定
→ nvcc –version や echo $LD_LIBRARY_PATH で確認

⑤ nvidia-smiコマンドが見つからない
→ F2でBIOSの設定に入り secure boot をdisableに変更して起動

⑥ cuDNN のインストール
CUDA 8.0とcuDNN 5.1をUbuntu 16.04LTSにインストールする
→ こちらの通りにした。
→ cuDNN のバージョンは要注意

⑦ Anacondaの導入
公式サイトの通り

⑧ 新しい環境の作成:
conda create -n keras .anaconda python=3.5
→ 最新過ぎるとはまりやすいという感覚で何となく3.5に

⑧ tensorflowのインストール
公式サイトの通り(Ubuntu/Anaconda使用版)

⑨ pythonでtensorflowを読み込んだ時のエラー
ImportError: libcudnn.5: cannot open shared object file: No such file or directory
→ まずはLD_LIBRARY_PATHの設定を見直し → 改善せず
→ stackoverflowの中段の解決策が有効
→ そもそもディレクトリのなかにlibcudnn.5が存在しないので、シンボリックリンクを作成
→ ln -s libcudnn.so.6* libcudnn.so.5
→ import tensorflow as tf が動作することを確認

⑩ Keras のインストール
公式サイトの通り
pip install keras
→ 公式exampleのmnist(MLP)が動作することを確認
→ nvidia-smi で確かにCPUではなくGPUで動作していることの確認

細かい不具合あるかもしれないが、これで手元でKerasを勉強できる環境が整った。

UbuntuでRuby2.4.1にTkをインストールする

TkがRuby本体から分離されましたが、オプションは今までの通りでも大丈夫なようです。

gem install tk — –with-tcltkversion=8.6 \
–with-tcl-lib=/usr/lib/x86_64-linux-gnu \
–with-tk-lib=/usr/lib/x86_64-linux-gnu \
–with-tcl-include=/usr/include/tcl8.6 \
–with-tk-include=/usr/include/tcl8.6 \
–enable-pthread

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装 を買った

書店をぶらついていると、真っ赤なタイトルの本が目に飛び込んできた。

ページをめくってみた。すごい。勉強になる。数式読めない人けど、なんとなくDeep Learningが理解できるかも知れないきざしのきざしの兆候を感じる。すごい。うじゃひょぇえええええ!!!!!期待にドキドキ胸が鼓動を早める。そう、これは…買っただけで勉強しない時の予感。

ふと、ページをめくる指が震える。
おかしい。何かがおかしい。かすかに感じるこの違和感はなんだろう。もしかして、この素晴らしい本には、ひょっとして一点だけ欠陥と言わざるをえないところがあるのではないか。すべて整っているのに肝心のところで、どこか画竜点睛を欠くのではないか。

その原因は、最初はぼんやりとしていたが、次第に誰の目にもわかるほど明瞭になっていった。

どういうわけか、本文中のコードに Ruby + NArray が一行も使われてないのである。 そのかわり Python + numpy という一風変わった言事とライブラリが使用されている。Python? パイソン? 聞いたことがない新鮮な響きだ。Rubyはどこへいったのだろう? 公園だと思ったら行ってみたら墓地だった。そんな衝撃を想像してほしい。

これでは作者の美的センスを疑わざるをえない状況である。それだけではない。近代文明社会への冒涜、民主主義への挑戦というものではなかろうか。久々に怒りで額に汗が流れた。グルグルと景色が回りはじめ、書棚に並ぶ本たちの笑い声がドッと湧いてこだました。

※ 本文はフィクションです。謹んで勉強させていただきます。

無知をさらす
・損失関数についてあまり意識してなかった
 ・交差エントロピー誤差というものを知らなかった
 ・なるほどsoftmaxと交差エントロピー誤差はセットなのね
・数値微分という言葉を知らなかった
・勾配によるニューラルネットワークの更新がよく理解できない
・chainerって連鎖率(chain rule)から名前がつけられたのだろうか
 ・合成関数の微分は合成関数を構成するそれぞれの関数の微分の積によって表すことができる
・ハイパーパラメータという言葉はよく聞くが、なぜハイパーというのか知らなかった
・ミニバッチはランダムにサンプルを取得するものだと知らなかった(順番にサンプル取得するものだとばかり思っていた)
・加算、乗算の計算グラフによる逆伝播を理解した
・Adamが理解できないぞ?
・Xavierの初期値は、sigmoidやtanhに有効だが、ReLuには「Heの初期化」がある。へー。
・Batch Normalization 今度やってみよう
・ハイパーパラメータの最適化は結局総当り式?
・特徴マップという言葉を知らなかった
・im2colねえ…。これRubyだけで実装するとやっぱりfor(each)使わざるを得ない気がするが。

自信をもったところ
なんだかんだですでに実装したことがあるような内容も多い。①パーセプトロン、②2層ニューラルネットワーク、③計算グラフ ④バッチ処理 ⑤CNNみたいな順番で勉強してきてよかったなと。経験的に好きな事はつまみ食い的に勉強した方が、かえって効率的に勉強できる気がする。むしろこの本だけでDeep Learning勉強しようとしていたらどこまで理解出来てたか疑問だ。

この本のおかげでchain ruleと計算グラフについて少し理解した。
加算ノードの逆伝播と、乗算ノードの逆伝播理解したから。Numo::NArrayでLSTMにもう一回挑戦してみたいな。

RubyでKaggleのMnistを試してみた

はじめてのKaggle

 先のエントリーで医用画像認識ソフト開発の米EnliticがKaggleでエンジニアを集めているということを知って、技術者でもなんでもないけどKaggleをちょっと試してみたくなった。

Mnist

 チュートリアルでMnist手書き文字認識があるそうなので、以前作成したRubyでニューラルネットでMnist認識するコードを使って投稿してみた。使用したニューラルネットワークはこんな感じ。隠れ層が大きくなると実行に時間がかかるので200程度にとどめておいた。

 3層のニューラルネットワークなので、少し無理をすればディープラーニングの定義に当てはまるかも知れない…いや、やっぱり無理かな。

バックプロパゲーションだけで多層ニューラルネットワークを学習させてみる

 なぜ単純なバックプロパゲーションだけで多層ニューラルネットワークが学習できてしまうのかというと(Mnist手書き文字認識が簡単な問題だからかも知れないが)10点中10点満点で正解した場合でも「おまえはまだまだ出来るはずだ。次から100点を取らないと。まだ90点足りないよ!」いう感じ(ニューラルネットがつらそうですね)で大げさに誤差を逆伝播させる仕組みにしているからだと思う。多分。以前試した時は4層〜6層ぐらいの先細りの多層パーセプトロンなら、denoising autoencoder等の方法を使わなくても学習できていた。(softmaxがよくわかってなかった頃に思いつきで実装しただけなので、何という手法なのかは知らない。そしてこの方法で作られた重みはdenoising autoencoderで学習させた重みと比較して可視化した時にあまり綺麗とは言えない。)

結果

結果は正解率 0.97657 で1218チーム中470番ぐらいでした。(でもこれ画像の並行移動してなかったら、Mnistの出典データを参照するだけで正解率100%簡単に出せるんじゃ…)

学習時間は手元のパソコンで2時間弱かかった。

改善できそうなところ

 これまでにもParallelsによる並列計算による改良を何回か試みたけどうまくいってない。順伝播(評価時)はうまくいく。パイプで返却されるデータが少ないためかThreadの待ちがうまく動く。CPUのファンがぶんぶん回って、htopコマンドで4つのCPUの使用率100%になるのを見るのは爽快だ。しかし逆伝播では、パイプで返却される重みのデータ量が多すぎるせいか、Threadの待ち合わせがうまく動いてくれない。STDOUT.sync = true すればいいとかそういう問題でもないみたいだ。ここを上手くやって複数のCPUで動いてくれれば、もうすこし高速化できると思うけど難しい。

 あとは旧NArray + opencl_ruby_ffiを使えばGPUによる高速計算もある程度できると思う。しかしC言語も読み書きできない私のような素人さんにはちょっと敷居が高すぎるというのが正直なところだ。NarrayからGPUのメモリに移動して、GPUのメモリからNArrayに移動して、NArrayからGPUのメモリに移動して、を繰り返す時間的ロスってどのぐらいなのか気になる。OpenCLは手元のパソコンで試していてPCがフリーズしたりした時に萎えるけど、Amazon EC2 のGPUインスタンスでもopencl_ruby_ffiが動くことを確認したので今度試してみたいところ。

 ひと通りKaggle体験を楽しんだあと、日本にもKaggleのようなサイトがないか探してみた。いくつかみつかったけど、どこもKaggleほどの活気はなく、なんだか閑散としていてほんの少し寂しい気持ちになったのでした。

Amazon EC2 試してみた

 chainerでより気軽に遊ぶためにAmazon EC2を試してみた。そして思った。凄いなあと。ディープラーニング向けのレンタルサーバーはこれからの分野のようで、IDCフロンティアは、近日サービス開始となっている。アリババにはGPUクラウドがあるみたいだけど日本語の情報が少なすぎて敷居が高い。手元のパソコンでDeep Learningを試したい人は初期費用20万円ぐらい計上してGPU付きのPCを準備する必要があったけど、もうそんな時代ではないみたいだ。でも、いい事ずくめで興奮しているのに、どうしてもクラウドコンピューティング万歳という気分にはなれない。なんでだろう。それはともかく、はやくRubyでNArray使って簡単にGPU計算できる時代になりますように。