「Machine Learning – A Probabilistic Perspective」第3章を読んだ

前回の続き。「Machine Learning – A Probabilistic Perspective」第3章を読みました。

第三章の目次は以下の通り。この章は、離散データをもとにナイーブベイズなどの手法でモデルを生成しようという話です。段々と数学的に難易度が上がってきた。

  • Generative models for discrete data
    • Introduction
    • Bayesian concept learning 65
      • Likelihood
      • Prior
      • Posterior
      • Posterior predictive distribution
      • A more complex prior
    • The beta-binomial model
      • Likelihood
      • Prior
      • Posterior
      • Posterior predictive distribution
    • The Dirichlet-multinomial model
      • Likelihood
      • Prior
      • Posterior
      • Posterior predictive
    • Naive Bayes classifiers
      • Model fitting
      • Using the model for prediction
      • The log-sum-exp trick
      • Feature selection using mutual information
      • Classifying documents using bag of words

この章で例として出てくるのは、いくつかの数字を観測したうえで、どのモデルから数字が生成されているかを推定するというもの。例えばD={16,8,2,64}を観測したうえでは、2の累乗というモデルの確率が一番高くなります。

その他にも、いくつかのデータが追加された場合に事後確率を更新することができる、ということが書かれています。これによりベイズ推定がオンライン学習に適しているということが言えるそうです(詳しくは8章)

ナイーブベイズについてもこの章の後半で述べられています。ナイーブという言葉の意味はフィーチャーが独立であることを仮定しないから付けられたとのことです。もしこの仮定が成り立たなくても、モデル自体がシンプルなためオーバーフィットしづらく、結果的に良い性能が出ることが多いそうです。

最後にはドキュメントの単語から、内容を分類するタスクが述べられています。Dirichlet Compound Multinominalという分布を使うと、一度観測されたデータはより観測されやすいとモデル化できるそうです。単語のようなスパースなデータを扱う際に、一度登場した単語は同じ文章中に再び登場しやすい、という直感的な感覚に合っているモデルです。

「Machine Learning – A Probabilistic Perspective」第2章を読んだ

前回の続き。

2章は確率論の復習です。一通り、確率は習っているのでスムーズに進めました。確率分布の性質などの部分は後から出てきたときに見返せば良いかなという感じです。

最後に情報理論の節があります。データの分布の相関を測るために使われるのかな。

2章の目次は以下の通り

  • Probability
    • Introduction
    • A breif review of probability theory
      • Discrete random variables
      • Fundamental rules
      • Bayes’ rule
      • Independence and conditional independence
      • Continuous random variables
      • Quantiles
      • Mean and vairance
    • Some common discrete distributions
      • The binomial and Bernoulli distributions
      • The multinomial and multinoulli distributions
      • The Poisson distribution
      • The empirical distribution
    •  Some common continuous distributions
      • Gaussian (normal) distribution
      • Degenerate pdf
      • The Laplace distribution
      • The gamma distribution
      • The beta distribution
      • Pareto distribution
    • Joint probability distributions
      • Covariance and correlation
      • Multivariate Student’s t-distribution
      • Dirichlet distribution
    • Transformations of random variables
      • Linear transformations
      • General transformations
      • Central limit theorem
    • Monte Carlo approximation
      • Example: change of variables, the MC way
      • Example: estimating π by Monte Carlo integration
      • Accuracy of Monte Carlo approximation
    • Information theory
      • Entropy
      • KL divergence
      • Mutual information

以下は、メモしておきたいことを列挙。

Bayesianなアプローチをとってモデルを構築することのメリットは、長期間の頻度が手に入らないイベントを予測するモデルを構築出来ることである。

二項係数nCkは”n choose k”と発音する。

ガウス分布は外れ値(outlier)の影響を受けやすいので、そういう場合は The Stuent’s t distribution を使うとよい。

2つの確率密度分布のdissimilarityを測る尺度として、KL divergenceがある。

低い相関係数であっても、高いMIC(maximal information coefficient)があれば、非線形な関係がある。

 

「Machine Learning – A Probabilistic Perspective」第1章を読んだ

段々と機械学習の概要や基本的な数学が身についてきたと思うので、巷の評価が高い「Machine Learning – A Probabilistic Perspective」を読み始めることにした。

1000ページを超える大著であるため、挫折しないように章ごとにまとめを書いていきたいと思う。

第一章の目次はこんな感じ

  • Machine learning: what and why?
    • Types of machine learning
  • Supervised learning
    • Classification
    • Regression
  • Unsupervised learning
    • Discovering clusters
    • Discovering latent factors
    • Discovering graph structure
    • Matrix completion
  • Some basic concepts in machine learning
    • Parametric vs non-parametric models
    • A simple non-parametric classifier: K-nearest neighbors
    • The curse of dimensionality
    • Parametric models for classification and regression
    • Linear regression
    • Logistic regression
    • Overfitting
    • Model selection
    • No free lunch theorem

目次を見て分かる通り、第一章は機械学習の分類と概要について。

本のタイトルにProbabilistic Perspectiveとある通り、線形回帰の部分からしっかりと確率的になぜ回帰曲線が選ばれるかということが書かれている。

知らなかった言葉としては、latent factorがある。これは高次元のデータのなかに潜在する多くの変数を説明するfactorのこと。

parametric, non-parametricという用語も何となく聞いたことがあるレベルだったが、モデルが固定長のパラメータを持つ場合はparametric、そうでなければnon-parametricということらしい。

線形代数の復習に「Linear Algebra and its Applications」を読んだ

機械学習とは切り離すことのできない、重要な数学分野である線形代数。はるか昔に習った線形代数を思い出すために「Linear Algebra and its Applications」という教科書を読みました。この本はAx=Bという式について一環して書かれており、評判も良いので選びました。

線形代数自体は昔に習っていたので、問題無いかと思っていましたが、SVD(特異値分解)が線形回帰の文脈で出て来て、「はて、SVDってなんだっけ?」と思い復習することに決めました。また、すでに日本語で知っている用語を英語でなんて言うのかという勉強も兼ねています。

本当に初歩の行列の掛け算から始まり、逆行列、固有値、SVD、線形回帰、PCA、などなど機械学習の初歩的な部分までをカバーしていきます。演習問題も豊富なので独習に向いているかと思います。

例えば、以下のサイトにて言及もあります。

一人で読めて大抵のことは載っている教科書(洋書編):数学からラテン語まで(追記あり)

基本的に日本語で勉強できる内容ではありますが、将来的に英語を使って研究開発を行いたいと考えているのであれば、英語で学んでおくことはとても有意義であると思います。

私の場合は、日本語なら答えられるのに、英語でどう言うんっだっけ?という部分が多かったので初めから英語で学べるのであればこういった本で勉強を始めていくのが良いかと思います。

Kerasによるニューラルネットワーク本「Deep Learning with Keras」を読んだ

Deep Learningの基本的な仕組みなどについては大体把握してきたと思うので、実際に動くコードを書くにはどうすればよいのかということを学ぶために、Kerasによるニューラルネットワーク本、「Deep Learning with Keras」を読みました。

Kerasはご存知の通り、TensorflowやTheanoなどのDeep Learning基盤を使いやすくするためのフレームワークです。実際にKerasを使ってみると、難しそうなイメージがあるDeep Learningは積み木のように構築出来て、結構簡単じゃないかという自信を得られるので、一般的なユーザーには生のTensorflowを使うよりもお勧めです。

この本の内容は、Kerasのインストール、基本的なフィードフォワードNNから始まり、CNN、RNN、WordEmbedding、GAN、転移学習、強化学習、などと幅広くカバーされています。すべての内容にサンプルコードが付いているので、実際に動かすことができます。段々と後ろの章に進むにつれて、学習に時間がかかるコードが増えてくるので、手元の環境で動かそうとする場合にはGPUがあったほうが良いかと思います。サンプルコードはKeras2.0で書かれていますが、現在の最新版だと微妙にAPIが変わっている部分もあるようで修正が必要な個所もありましたが、調べればすぐに出てくるレベルの違いなので(少なくとも現時点では)特に大きな問題にはならないかと思います。

基本的にはサンプルはそんなに複雑な内容を扱っているわけではなく、コードを部分ごとに解説とともに説明されているので、Kerasの深い知識が無くてもサクサク読むことが出来ました。実際に自分が作りたいアプリケーションに向けて参考にするにはとても良いサンプルが揃っていると思います。

個人的にはGANについて概要レベルで仕組みを知ることが出来たのが大きな収穫でした。何となく理論は知っているんだけど、いざ実際にコードに落とすにはどうしたら良いのか?と思う方にはお勧めです。日本だとChainerがこの手のフレームワークとして人気だと聞きますが、世界的にみるとKerasの人気は強いとも聞きます。今後の開発がどのように進んでいくのかにもよりますが、こういったフレームワークは一つ手を付けておけば他のフレームワークを使う際も似た部分は多いかと思うので、応用が効くかと思います。

次はもう少し数学的な基礎を固めようかと思うので、統計の教科書やMurphy本あたりを読んでみようかと思っています。

Deep Learningによる自然言語処理の教科書「Neural Network Methods for Natural Language Processing」を読んだ

タイトルの通り、Deep Learningによる自然言語処理の教科書「Neural Network Methods for Natural Language Processing」を読みました。全体として色々と理解が深まった部分があるのでお勧めです。

まさにタイトルの通り、自然言語処理とDeep Learningに特化した本でした。そもそもニューラルネットワークとは、というようなところから始まっているのでDeep Learningの深い知識が無くても読み始めることは可能だと思います。

また、自然言語処理の部分についても適宜基本的な内容が解説されながら進んでいくので読みやすいと思います。

図が多いので、CNNやRNNなどのネットワーク構造がどのようになっているのかというのも理解しやすいです。個人的にはこの本で、モヤモヤしていたLSTMやGRUといった内容やAttention機構がどういった仕組みであるかが理解できたのが収穫でした。

最近出たばかりの本なので、いまだ発展途上であるDeep Learningによる自然言語処理という分野で数多くの論文が参照されており、新しいものだと2017年に出た論文もカバーされているところが素晴らしいと思います。

どちらかというと理論的な面が重視して解説されているので、ここからどのように実装に落とし込んでいくかは別途TensorflowやKerasなどの記事を読むことになるかと思います。

 

Fashion MNISTをKerasでCNNを使って分類してみた

ファッションアイテムを識別するタスクであるFashion MNISTというデータセットが登場しました。
https://github.com/zalandoresearch/fashion-mnist


(画像は上記githubページより)

このデータセットが登場した目的は、MNISTが簡単すぎる、MNISTは使われすぎ、MNISTは最近のコンピュータビジョンのタスクを表現していない、などの理由からだそうです。

まずは、データセットをダウンロードします。

git clone https://github.com/zalandoresearch/fashion-mnist.git

データの形式などはMNISTと同じで、分類するクラスも10個(Tシャツ、サンダル、バッグなど)です。

このデータをKerasを使って分類してみようと思います。バックエンドはTensorflowを使っています。
ネットワークの構造はLeNetを構築しています。

from keras import backend as K
from utils.mnist_reader import load_mnist
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Activation, Flatten, Dense
from keras.models import Sequential
from keras.utils import np_utils
from keras.initializers import Constant
from keras.optimizers import Adam
import matplotlib.pyplot as plt

#load_mnistはutilsにある
X_train, y_train = load_mnist('data/fashion', kind='train')
X_test, y_test = load_mnist('data/fashion', kind='t10k')

X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28)
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28)

y_test = np_utils.to_categorical(y_test, 10)
y_train = np_utils.to_categorical(y_train, 10)

K.set_image_dim_ordering("th")
#LeNetを構築する
model = Sequential()
model.add(Conv2D(20, kernel_size=5, padding="same", input_shape=(1,28,28)))
model.add(Activation("relu"))
model.add(MaxPooling2D())

model.add(Conv2D(50, kernel_size=5, border_mode="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D())

model.add(Flatten())
model.add(Dense(500))
model.add(Activation("relu"))

model.add(Dense(10))
model.add(Activation("softmax"))

model.compile(loss="categorical_crossentropy", optimizer=Adam(), metrics=["accuracy"])
history = model.fit(X_train, y_train, batch_size=128, epochs=20, verbose=1, validation_split=0.2)

score = model.evaluate(X_test, y_test, verbose=1)
print("Test score:", score[0])
print("Test accuracy:", score[1])
print(history.history.keys())

#グラフの表示
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

テスト精度は92.16%でした。MNISTだと99%程度の精度が出るネットワーク構造なので、MNISTより難しくなっているというのは本当のようです。

48000/48000 [==============================] - 259s - loss: 0.4973 - acc: 0.8208 - val_loss: 0.3587 - val_acc: 0.8742
Epoch 2/20
48000/48000 [==============================] - 260s - loss: 0.3178 - acc: 0.8861 - val_loss: 0.3043 - val_acc: 0.8893
Epoch 3/20
48000/48000 [==============================] - 258s - loss: 0.2735 - acc: 0.9013 - val_loss: 0.2783 - val_acc: 0.9025
Epoch 4/20
48000/48000 [==============================] - 256s - loss: 0.2397 - acc: 0.9124 - val_loss: 0.2502 - val_acc: 0.9110
Epoch 5/20
48000/48000 [==============================] - 256s - loss: 0.2122 - acc: 0.9229 - val_loss: 0.2716 - val_acc: 0.9058
Epoch 6/20
48000/48000 [==============================] - 266s - loss: 0.1897 - acc: 0.9308 - val_loss: 0.2683 - val_acc: 0.9053
Epoch 7/20
48000/48000 [==============================] - 259s - loss: 0.1679 - acc: 0.9381 - val_loss: 0.2570 - val_acc: 0.9118
Epoch 8/20
48000/48000 [==============================] - 260s - loss: 0.1489 - acc: 0.9460 - val_loss: 0.2557 - val_acc: 0.9114
Epoch 9/20
48000/48000 [==============================] - 260s - loss: 0.1277 - acc: 0.9524 - val_loss: 0.2430 - val_acc: 0.9195
Epoch 10/20
48000/48000 [==============================] - 260s - loss: 0.1156 - acc: 0.9568 - val_loss: 0.2435 - val_acc: 0.9198
Epoch 11/20
48000/48000 [==============================] - 260s - loss: 0.0965 - acc: 0.9639 - val_loss: 0.2452 - val_acc: 0.9183
Epoch 12/20
48000/48000 [==============================] - 259s - loss: 0.0824 - acc: 0.9696 - val_loss: 0.2705 - val_acc: 0.9159
Epoch 13/20
48000/48000 [==============================] - 261s - loss: 0.0689 - acc: 0.9752 - val_loss: 0.2851 - val_acc: 0.9148
Epoch 14/20
48000/48000 [==============================] - 258s - loss: 0.0588 - acc: 0.9790 - val_loss: 0.3054 - val_acc: 0.9178
Epoch 15/20
48000/48000 [==============================] - 275s - loss: 0.0506 - acc: 0.9823 - val_loss: 0.3397 - val_acc: 0.9215
Epoch 16/20
48000/48000 [==============================] - 313s - loss: 0.0423 - acc: 0.9858 - val_loss: 0.3490 - val_acc: 0.9161
Epoch 17/20
48000/48000 [==============================] - 296s - loss: 0.0376 - acc: 0.9866 - val_loss: 0.3412 - val_acc: 0.9215
Epoch 18/20
48000/48000 [==============================] - 289s - loss: 0.0299 - acc: 0.9894 - val_loss: 0.3668 - val_acc: 0.9173
Epoch 19/20
48000/48000 [==============================] - 291s - loss: 0.0313 - acc: 0.9887 - val_loss: 0.3972 - val_acc: 0.9141
Epoch 20/20
48000/48000 [==============================] - 268s - loss: 0.0251 - acc: 0.9911 - val_loss: 0.3806 - val_acc: 0.9194
 9984/10000 [============================>.] - ETA: 0sTest score: 0.362425664179
Test accuracy: 0.9216

出力されたグラフは次の通り。

以上です。MNISTの精度が99%を超えて飽和しつつあるので、今後はこのテストデータが広く使われることになるかもしれません。

交差エントロピー誤差が-∞になるのを防ぐ


機械学習の本を色々と読んでいるのですが、ふと交差エントロピーの数式を見て誤差が-∞になるじゃん、と今更気づいたので、実際に実装上どのようにして回避しているのかを調べました。

交差エントロピーは以下の式で表されます。

$$E=-\sum_{k}t_k\log {y_k}$$

結論から言うと、下記のサイトに答えはありました。どうやら、小さい数値を足しておくことでlog(0)を誤差に足してしまうことを防ぐようです。

「ゼロから作るDeep Leaning」4章:ニューラルネットワークの学習

つまりは以下のコードを誤差関数として利用するということでした。

def numerical_diff(f, x):
    h = 1e-4 # 0.0001
    return (f(x+h) - f(x-h)) / (2*h)

以上です。理論と実装の狭間を少しずつ埋めていきたい。

A Neural Network Playground を使ってみた

Tensorflow グループが A Neural Network Playground というブラウザ上でDeep Neural Networkの動きを可視化するツールを出しています。少しいじってみたので、参考までに書きます。

提供されているデータセットは4種。ノイズパラメータをいじることで、複雑なデータにすることもできます。

UIは直感的なので、色々といじってみると分かるかと思いますが、入力のフィーチャーを選択して、隠れ層の段数や個数を調整して、活性化関数や正則化の方法を選択するなどして左上の再生ボタンを押すとアニメーションでNNがどのようにしてデータを分類しているのかが分かります。

活性化関数を変えてみると、収束までにかかるエポック数が変化するのが分かります。例えばSigmoid関数を使うと収束は遅くなり、最近はSigmoidがあまり使われないというのも納得できるようになります。

その他にも、線形分離可能でないデータ(例えば1番目のデータ)は最初のフィーチャーの選択によっては正しく分類できない場合があることが分かります。(フィーチャーとしてX11とX22を選ぶと円形で分離できるようになりました)

 

何となくDeep Learningがどういうものか分かってきた人が、実際に動かしてイメージをつかむのに良いツールであると思いました。

データサイエンスと機械学習を学ぶのに最適なMOOC

HackerNewsに上がっていた、データサイエンスと機械学習を学ぶのに最適なMOOCというのを抜粋してみます。

https://news.ycombinator.com/item?id=15073441

個人的には、このリストの上から進めていくのが初心者には良いのかなと思います。

Andrew Ng: Machine Learning

https://www.coursera.org/course/ml

ご存知、Andrew Ng先生の機械学習コース。私も実際に修了しましたが、実用例が多く紹介されており、数学的に難しくないので初心者が始めるのに最適だと思います。

Hasti/Tivshirani: Elements of Statical Learning

http://statweb.stanford.edu/~tibs/ElemStatLearn/

これは、私は書籍の方を読みました。数式が結構出てきますが、内容はそれほど高度ではないです。動画と合わせて本を読んでいくことで理解が進みやすいと思います。

Yaser Abu-Mostafa: Learning From Data

https://www.edx.org/course/caltechx/caltechx-cs1156x-learning-data-1120

こちらも私は本を読み終えています。上記二つを終えていれば概念的に難しい内容はそれほどないと思います。数学的にしっかりと、訓練誤差の話などがコンパクトにまとめられているので、こちらも本と合わせて動画を見ることで内容理解が深まるかと思います。

Geoff Hinton: Neural Nets for Machine Learning

https://www.coursera.org/course/neuralnets

私はこのコースを修了しましたが、はっきり言って難しかったです。後半はあまりよく理解できませんでした。動画も、Andrew Ng先生のようなものを期待していたのですが、スライドをただ読んでいく感じで理解するのが難しい部分がかなりありました。

Andrew Ng先生がCourseraで新しくDeepLearningのコースが始まるようなので、このコースよりはそちらを受けてみるのが良いかもしれません。

Hugo Larochelle: Neural Net lectures

YouTubeに上がっている動画コース。見ていないのであまりコメントできませんがNeuralNetsとDeepLearningにフォーカスしている内容のようです。

Daphne Koller: Probabilistic Graphical Models

https://www.coursera.org/course/pgm

このコースも受けてみたいなと思いつつ受けていません。コメントによると他の授業には無い内容が多いが、結構難しいみたいです。