Python Ubuntu

Pythonではじめての機械学習~scikit-learn、tensorflow

投稿日:2017年4月16日 更新日:

機械学習

勉強しているところなので、間違っている箇所もあるかもしれません.

機械学習は、高度な数学知識を使って、多数のデータから、有用な特徴を算出するいくつかのアルゴリズムを使った技法のことをいう.
例えば、ニューラルネットワークを使った深層学習は、機械学習の一分野である.

集合知プログラミングは、そんな機械学習のサンプルがたくさんある書籍だったけど、もうさすがに古い内容かも.

anaconda

anacondaは、Pythonの主要なライブラリをパッケージしたオープンデータサイエンスのプラットフォーム.
だいたいこれをインストールしておけば、環境が整う.

Anaconda

jupyter

jupyterは、インタラクティブなプログラミング言語の実行環境.
PythonやRなどのインタラクティブ実行環境Jupyter Notebookをインストールする

scikit-learn

scikit-learnは、Google製の機械学習用のライブラリ集.
scikit-learn.org/stable/

インストール

scikit-learnの使い方

オブジェクトを準備して、fitで学習し、predictで予測する、scoreでスコアを出すことができる.
オブジェクトは、大まかに、分類、回帰、クラスタリング、次元削減に分類できる.
参考:scikit-learn から学ぶ機械学習の手法の概要
今回は、100k以下のデータなので、linear SVNで分類してみる.

学習のために、学習用のデータと回答、性能を検証するために、テスト用データと回答が必要となる.
学習データとテストデータが同一だと、過学習の問題が生じて汎用性が無くなる可能性がある.
なので、必ず学習用データとテスト用データはわけるべき.

サンプルデータ

scikit-learnには、実験用に様々なサンプルデータが用意されている.
これは、乳がんの識別データ.

識別のもとになる特徴はdataに、識別結果はtargetに保管されている.
なお、DESCRにデータの基本情報、feature_namesに特徴の名前、target_namesに識別結果の名前が保管されている.

データ数は569個、1つのデータは30次元のベクトル.

これらを学習用と検証用のデータに分割する.
ShuffleSplitという便利なメソッドを利用して簡単に分割できる.

学習用のデータで学習して、テスト用データで性能を出す.95はなかなか

ネクストステップ

  • 学習用のデータと検証用のデータを分けるのにデータが偏らないようにする.
  • データのクリーニング
  • 特徴量の抽出、標準化など
  • グリッドサーチ
  • scikit-learnでも多層パーセプトロンのモデルを作成できる

tensorflow

tensorflowは、データフローグラフを使って数値演算を行うオープンソースソフトウェア.Google製.
www.tensorflow.org/

インストール

www.tensorflow.org/install/

GPUなしの環境

GPUつきの環境

tensorflowの使い方

モデルを作成して、セッションオブジェクトから、データを与えて学習する.
Hello Worldの例.
グラフ計算という仕組みで、tensorを足したり引いたりしても、すぐには計算せずに、「式」のまま保持されて、Session内でrunすることによって初めて計算される.
レールを組み立てて、最後に鉄道模型を走らせるみたいなイメージ!?

ディープラーニングの仕組みは、おおまかに次の通り.

  1. ベクトルを入力値として、「重み付け」と「バイアス付け」を行う計算をパーセプトロンという一つの単位として、複数のパーセプトロンから出力値を演算するモデルを作成する.複数のパーセプトロンを経由することで複雑な学習が可能になる.
  2. そして、モデルから演算された結果と正しい回答とを比較し、間違っていたら、正しい方向に「重み」と「バイアス」を少しだけ修正する.修正には損失関数を最小化するように動く.
  3. こうした少しだけの修正を可能にするために各パーセプトロンの各レイヤーに活性化関数(シグモイド関数,ReLU)が必要.修正には、勾配という各ベクトルを微分した数値を使うので、微分するためには傾きがある数値である必要があるため.
  4. 識別問題の場合は、出力値を0-1のあいだに収束させるためにソフトマックス関数を最後に使う.ソフトマックス関数を使う際に交差エントロピー誤差というレイヤがあると、学習の計算が楽になる.
  5. データが多いときは、いくつかのデータのまとまりをランダムに作出してミニバッチ処理を行う.

ディープラーニングの仕組みについては次の本がわかりやすかった.

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

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

作者斎藤 康毅

発行オライリージャパン

発売日2016年9月24日

カテゴリー単行本(ソフトカバー)

ページ数320

ISBN4873117585

Supported by amazon Product Advertising API

サンプルデータ

MNIST For ML Beginners
MNISTデータのダウンロード

import tensorflow

宣言など

入力値など仮置きする数値は、placeholderで、学習して変動する数値は、Variableで宣言する.
固定値は、constant.

本当は、Wやbの初期値をゼロに統一するべきではない.学習の方向と量が同じに単調になってしまうから.

パーセプトロンをモデルとして作成

matmulは行列の積を求める関数.つまり、このモデルはWx+bという式.
これにソフトマックス関数を適用する.つまり、今回は単層のパーセプトロン.
求めたい回答はこのモデルの順伝播によって求められる.
だいたい正しそうな回答を出させるために、Wとbを今後学習して調整していく.

損失関数(交差エントロピーを採用)とオブティマイザー(最急降下法を採用)を定義

y_は期待された回答を入力するためのプレースホルダ.
交差エントロピーは、必ず正の値であること、yとy_が近ければ近いほどゼロに近い値を返す性質であることから損失関数として採用されることが多いぽい. 参考:第3章ニューラルネットワークの学習の改善
そして、これを使って逆伝播のためのグラフ計算(モデル)を定義する.
勾配を計算してW、bといったVariableをいい感じに調整してくれる.
optimezerの選択と引数となる学習係数がポイントぽい. 参考:TensorFlowのOptimizerを比較する(mnist_expert編)

交差エントロピーはもっと簡単にかける.
ちがうみたい.今回のケースで置き換えたら正答率下がっちゃった.
参考:TensorFlow の softmax_cross_entropy_with_logits() と活性化関数について

各数値の初期化

バッチ処理

バッチ処理で、学習.mnist.train.next_batch()で次の学習用データが取れる.

結果

92%の正答率はいまいち.
やり方(Wbの初期値のランダム化、多層パーセプトロン、畳込みニューラルネットワーク、畳込みとプーリング処理、ドロップオフによる過学習の防止など)によって99%まであげることができる.
詳細は、Deep MNIST for Expertsに詳しい.
TensorFlow Deep MNIST for Experts 翻訳

多層パーセプトロンにチャレンジ

単純にモデルを増やしてみる

もう1組Wとbを定義する.深さは適当に半分の392にしてみた.

そして、前の計算結果を単純に次のパーセプトロンにいれて、最後にソフトマックス関数を適用する.

結果、めちゃ正答率さがる….

Wとbの初期値を適当にバラす

ここを参考に初期値をランダムにしてみた.

結果、戻してきたけど、単層のときより数値がいまいち

ReLU関数を適用してみる

活性化関数として最初のパーセプトロンにReLU関数を適用してみる.

結果、おおお

所感

  • 多層パーセプトロンにすると、表現力が増える(XOR問題)かわりに、パラメータが増えすぎて学習が遅くなる傾向にあるらしい.
    Variableの初期値が全部ゼロだと学習の方向性が均一化したりして活性化しないパラメータがでてきたりして、うまく学習できない.
    次に隠れ層が線形関数だと、勾配(微分)を使った学習がうまく機能しなくなるので、活性化関数は必須.
    結論として、Variableの初期化と活性化関数は大事ということがわかった.
  • 隠れ層の深さは適当に半分にしてやってみたが、次元数を増減しても正答率に大差はなかった.
  • ただし、3層にして深さを調整したところ、0.976まで正答率が伸びた.
    つまり、深さを入力値より大きく1000とかにすると、学習に時間がかかるが正答率が伸びた.隠れ層の数の問題と同じで表現力が増すぽい.
  • Variableの初期化の際のパラメータで、バラツキを増やすため標準偏差を増やしてみたら正答率が下がった.
    所詮ランダムなので、期待する方向と逆方向の初期値だと学習に時間がかかってしまったりするので、活性化するだけなら微妙なバラツキで十分だということだと思われる.
  • 参考にしたリンク先ではWはランダム、bはゼロという初期化だった.bはゼロでも正答率に大差なかった.
  • Variableの初期化をせずにReLU関数を適用してみても、正答率はやはり大差がなかった.
    活性化関数の適用以前に学習が機能していなかったからと思われる.
  • 活性化関数はReLU関数のほかにシグモイド関数などもあるが、今回のケースではシグモイド関数よりもReLU関数のほうが結果が格段によかった.

tf.contrib.layersを使う

fully_connected

パーセプトロンの典型パターンは、contrib.layersなどにまとめてあるので、とりあえずこれを使うことができる.
www.tensorflow.org/api_docs/python/tf/contrib/layers/fully_connected

単層パーセプトロンのこの部分のコードを、

だいたい、このように置換えられる.

上の多層パーセプトロンならこうで、Wとbの定義がいらない.

fully_connectedの初期値は下の通りで、inputsとnum_outputsを与えれば基本的なパーセプトロンとして機能する.
最後の場合は、activation_fnにtf.nn.softmaxを与えればよい.
初期化関数のxavier_initializerは優秀ぽい 参考論文

TensorBoardで可視化

TensorBoard

tensorflowにはデータ可視化のためにTensorBoardというサーバが付属している.

データ保存

まずは、対象データを保存する.

グラフ

すると、グラフ計算を図示してくれる.

正答率の推移

次に正答率の推移をグラフ化する.
先に、accuracyを定義してから、summary.scalarを定義する.
summaryはTensorBoardにデータを載っける系のライブラリ.
スカラー値はベクトルじゃない単なる数値.

で、add_summaryで、global_stepをx軸として、値を追加する.
なお、print(ast)とかしても、スカラー値ではなくバイナリデータなので注意.

学習の経過がグラフ化される.

-Python, Ubuntu
-, , ,

執筆者:

関連記事

Raspberry Pi3とsense HATで遊ぶ

By: Su Yin Khoo – CC BY 2.0 目次1 Raspberry Pi32 Raspbian3 Raspbianでsshを使う4 raspi-configで初期設定5 R …

Ubuntu Desktopで指紋認証〜Fingerprint GUI

By: Chris Costes – CC BY 2.0 目次1 Fingerprint GUI2 インストール3 指紋登録4 Done Fingerprint GUI launchpad …

no image

Ubuntu Server12.04にRedmine2.0.3をインストール

環境 Ubuntu Server12.04にrvmでrubyをインストール 目次1 準備2 MySQLを準備3 nginxのインストール4 Redmineのダウンロードと展開5 config/data …

Pythonではじめての機械学習2〜scikit-learnとpandasで決定木

By: vaboo.com – CC BY 2.0 目次1 決定木(Decision Tree)2 サンプルデータの用意3 学習用データと検証用データにわける4 scikit-learn5 …

企業レベルのコンテンツマネジメントシステムAlfresco Community5.1をubuntu server14.04にインストールしてみた

By: jenny downing – CC BY 2.0 目次1 Alfresco Community2 ダウンロード3 LibreOfficeのライブラリのインストール4 Alfres …