しんさんのブログ

科学や技術のこと読書のことなど

「機械学習入門」 大関 真之著 を読みました

機械学習入門 ボルツマン機械学習から深層学習まで

機械学習入門 ボルツマン機械学習から深層学習まで

表紙が機械学習の本の中ではトップクラスに機械学習らしくなくいい意味で手に取りやすいです。
タイトルに入門とあるように物語仕立てで機械学習のことを知らない人でも楽しんで読めるような内容になっています。
しかし、一方で著者は物理学から機械学習の研究者になり、学術論文もだしているような本物の研究者ですので、
書いてあることは正確で信頼できます。
私は機械学習や深層学習のことをある程度はしっていますので、あぁあのことを言ってるんだなと読んでいて気づいてしまい
タネを知っている手品を見ているような感じでしたが、全体知識がなくても少なくとも6章までは読み進められると思います。
6章から話が抽象的になり始めて理解しにくくなるように感じました。
それでも平易な説明で正確性を損なわずにそれでいて、物語仕立ても崩さずに説明しきっているところはこの手の本ではめったに見ないほどの力作だと感じました。
著者の更なる著作を期待しながら本書を読み終えました。

Visual Studio codeでLatexを使う

Visual Studio CodeLatexを使って文章を書いて、コンパイル、platex2pdfまでやってしまおうという話です.
まずはVSCodeプラグインであるLaTeX Workshopをインストールし設定します.
インストールと設定は以下の解説通りにやればすんなりOKです.

elecho.hatenablog.com

ちょっとした注意としてこのままですとjarticleはコンパイル通りますが、ujarticleはコンパイル通りません.
こちらを使う場合はuplatexを使用する必要があります.

\documentclass[16pt,a4j]{jarticle} % <- platex
or
\documentclass[a4j]{ujarticle} % <- uplatex用

Ctrl+,(カンマ)でVS Codeの設定画面を開きlatexの設定を追加するときに,設定ファイル以下のように"-u"を
追加したものに変更します.

"latex-workshop.latex.toolchain": [{
"command": "ptex2pdf",
"args": [
"-u",
"-l",
"-ot",
"-kanji=utf8 -synctex=1",
"%DOC%"
]
}],

uplatex とplatexの違いについては以下のサイトに詳しいです.
基本的にはuplatexを使用した方がよさそうです.

upTeX,upLaTeX - TeX Wiki

機械学習用ハードウェア

2017年の8月あったHot Chips 2017でマイクロソフトがディープニューラルネットワークの推論処理を高速で実行できる
クラウド環境Project Brainwaveを発表したというニュースは気になりますね。
推論処理のレイテンシを下げることは今後IOTとか自動車とかエンタテインメントにも必須ですから、各社注目しているというわけですね。
マイクロソフトFPGAを用いますが、専用ハードを作るGoogleのような解もあるし、NVIDIAはいまはどちらかというと学習向けにGPUを提供していますが、本来GPUはリアルタイムコンピュータグラフィックスで発展したことを考えると推論エンジンにも進出してくるでしょうし、今後半導体業界を巻き込んで動きがさらに加速すると思われます。

2017/10/11 誤字を修正しました

pythonを使った深層学習用ライブラリkerasのインストール方法

kerasとは?

kerasはTensorFlowやTheanoをバックエンドとして実行するライブラリです。 深層学習のネットワークのアーキテクチャの構築を直感的に記述することが可能なライブラリです。 要は、深層学習をお手軽に書くことができますよ、ということですね。 詳しくは、kerasのホームページをご覧ください。 日本語に翻訳されたページも用意されています。 keras.io

kerasのインストール

Windows10Pro64bit, GPUNVIDIA GTX1050の環境にインストールします。
まずは、以前このブログで書いたように wshinya.hatenablog.com Anacondaを使用してkeras用の仮想環境を作製します。
次に、作成したconsoleを立ち上げ作成した仮想環境をactivateします。
仮想環境のプロンプトがでたら、

pip install tensorflow-gpu
conda install scipy
pip install keras   

であっさり成功、と言いたいところですが、"Fail building wheel for pyyaml"というエラーメッセージで失敗しました。
どうやらインストールスクリプトのどこかで失敗しているようです。
前にも同じような現象に当たったことがあり、その時にはコンソールを管理者モードで起動すると成功したので、
以前と同様管理者モードで立ち上げて上記pip, condaコマンドを実行するとインストールは無事成功しました。
インストールしたパッケージのバージョンは、

    conda list

で見ることができます。
これで確認すると、kerasは2.0.8, scipy 0.19.1, tensorflow-gpu 1.3.0が インストールされていることが分かります。
正しくkerasがインストールされているかどうかを確認するために、pythonを立ち上げて

    import keras

をやってみました。
残念ながら、

    ModuleNotFoundError: No module named 'yaml'

というエラーメッセージが出てしまいました。
yamlがないということなので、

    conda install pyyaml

をコンソールで実行し、再びpythonでimport kerasを行うと今度は無事エラーが消えました。
ちなみにインストールしたpyyamlのバージョンは3.12でした。
いくつかはまりましたがこれでkeras + tensorflow-gpuの環境の構築は成功です。

numpyで行列を扱うときに気持ち悪いこと

例えば以下のような行列計算をnumpyで書くときに皆さんはどのようにしますか。

A:1行2列の行列
B:2行3列の行列
C: C = AxB -> 1行3列の行列

このとき,
A= np.random.rand(2)
B= np.random.rand(2,3)
C= np.random.rand(3)
と書くことが多いですが、
A, B, Cをshapeで見ると

A: (2,)
B: (2,3)
C: (3,)

となっていて、(行の数、列の数)となっていなくて非常に気持ち悪いです

以下のように書くと,
A= np.random.rand(1, 2)
B= np.random.rand(2, 3)
C= np.random.rand(1, 3)
のほうがしっくりくるのですがどうでしょうか。

テンソルの足の縮約を考えた時も上の書き方のほうが数学の表記とあっていてすっきりします。

Windows10でDraknetをビルドしてYOLOを動かして画像認識を試してみました

最近以下のような画像を見かけることが多くないですか?
https://pjreddie.com/media/image/Screen_Shot_2016-11-17_at_11.14.54_AM.png

自分のマシンでも動かしたくなりDarknetをダウンロードしてmakeして,手持ちの写真でやってみましたという話です.
Darknet, YOLOのオリジナルサイトは以下になります.
pjreddie.com

基本的には以下のサイトの解説どおりにやってみました
http://www.lisz-works.com/entry/darknet-yolo

上記サイトにリンクされている、以下のサイトにdarknetのインストールとmake方法が書いてありました.
http://www.lisz-works.com/entry/darknet-install-make

書いてある通りにすると,makeが通りませんでした.

timer関係の定義がないという

include/darknet.h:709:11: error: unknown type name 'clock_t'
float sec(clock_t clocks);

エラーがでてmakeがストップしました.

対処法として
#include
をdarknet.h
に書いたらmakeが通りました.

試しに

./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg
とやったら私のマシンで30秒ほどで処理が終わりました。

makefile
GPU=0

GPU=1
とすればGPUを使用するバージョンになり処理速度は速くなると思いますが、cuda関係のエラーで
今のところmakeできません.

後日、GPU版のmakeを成功させたいと思います.

TensorFlowのMNIST For ML Beginnersを試してみる

前回、TensorFlow始めましたということで TensorFlowのドキュメントを読みながら TFの実行環境整備をしました. 今回はその続きで, MNIST For ML Beginnersを 読みながら実際に実行してみたいと思います.


MNISTとは

MNISTとはプログラミングにおけるHello worldとも呼ばれていて、機械学習を学ぶ上で初心者がまず学ぶコードのために使うデータだそうです.
具体的にはMNISTとは0から9の数値の手書き画像データと正解データ(label)がセットになったデータです.
元データはアメリカの標準技術研究所が提供しています.
学習用データ数は60000件あり、その中にテスト用のデータは5000件あります。もちろん学習用データの一部を使って学習、テストを行っても構いません。

ここではこれを使って機械学習アルゴリズムで手書き文字データから正解を導くような機械学習アルゴリズムをTensorFlowでどうやって書くのかを学ぶ初めの一歩を踏み出します.

プログラムと学習データ

mnist_softmax.pyというコードがtensorflowのページにあがっていますので、それを ダウンロードしてセーブします.
学習データ:

  • 画像データ (mnist.train.xs):28x28 pixelの各ピクセル8bitデータ
  • 正解データ(label data) (mnist.train.ys): 10成分のベクトルで正解の数値の成分が1になっている

ここでTFのドキュメントではsoftmaxについて解説があります.
簡単に言ってしまえばsoftmaxは最終出力を正解の確率に変換すると思っておけばいいと思います.
softmaxへの入力は10種類の正解数値の形が持つべき特徴が抽出された形ですので、それを集めてどれだけ正解に近いかに変換し最終的な確率へと変換するのがsoftmaxです.

学習の仕組み: いろいろな入力データに対して、ネットワークの重みWとバイアスbをsoftmaxで得た正解の確率と実際の正解との差を最小化するようにWおよびbを少しずつ変化させて差を最小化します.
この過程を学習といいます.
ちなみに予測と正解の差を大きさを表す指標をcross-entropyと呼ばれています.

今回の学習の手法はディープラーニングではなくsoftmaxを使用したロジスティック回帰と呼ばれるものです.

回帰分析の実行

上で簡単に解説したMNISTデータを学習するためのロジスティック回帰を実際にTFを使って書いていきます. といっても、コードはすでにnist_softmax.pyに用意されていますので、これを読んで でいけばいいわけです. 今回は練習のためにipythonで1行ずつ入力しながら確認していきます. まずは、データの読み込みです.

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

one_hot=TrueというのはデータがすでにMNIST_data/にある場合には新たに読み込まないという意味です.

次にtensorflowをimportし入力データ用の配列を用意する. 配列の要素はfloat32で行数は指定せず、列は画像の解像度である28x28=784を指定.

import tensorflow as tf
x = tf.placeholder(tf.float32, [None, 784])

さらに、画像の要素に掛ける重みとバイアスを入れるたもの配列を用意.

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

最終的な出力結果を定義します.これは先ほど説明したsoftmax関数を通すことで確率に変換されています.

y = tf.nn.softmax(tf.matmul(x, W) + b)

正解を格納する配列を用意する.

y_ = tf.placeholder(tf.float32, [None, 10])

softmax関数の出力結果と正解データがどれだけずれているかの指標であるcross_entropyを定義します.

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))

いよいよ学習させるためのコードです.
このチュートリアルではGradientDecentOptimizerという勾配降下法という方法を使ってcross_entropyの極小を求めます.小さなステップで繰り返し計算して徐々に極小に近づけていくのですが、そのステップを決めるのが以下の記述になります.

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

TFの初期化と変数の初期化

sess = tf.InteractiveSession()
tf.global_variables_initializer().run()

入力データ、正解データを指定して学習を実行する.

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

next_batch(100)の意味は、100このデータを使用して学習するという意味で、range(1000)というのは、それを1000回やりますということです.

学習結果の制度の確認

学習結果と正解の結果が一致したかしないかを判定した結果を格納.

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

学習結果の予想yと正解y_を比較して正しければ1間違えていれば0を配列にしています.

correct_predictionは結果が正しければ1, 間違いなら0の値が入った配列になっていますが、それを正解の確率に変換すし結果をaccuracyという変数に代入します.

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

テストデータを入力して学習しで決定したw,bを使用して画像の数値を予想し、その結果がどれくらい正しかったかの結果を表示します.

print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

私の環境では、0.9195と表示されました.
約92%なので結構正解率が高いように思いますが, もっといいモデルを使うと99.7%まで行っているそうです.
今のモデルをちょっと変えるだけでも97%程度なら到達できるそうです.

以上で, 初心者向けのMNISTは終了です.