機械学習に使われる数学

<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B5%A1%B3%A3%B3%D8%BD%AC">機械学習</a>に使われる数学

機械学習に使われる数学

ディープラーニング入門:Chainer チュートリアル
3. 機械学習に使われる数学 — ディープラーニング入門:Chainer チュートリアル

機械学習とは

  • 与えられたデータを元に
    • 未知のデータに対して当てはまる規則やパターンを抽出
    • それらを元に未知のデータを分類予測
  • 応用範囲
    • 画像認識
    • 音声認識
    • 文書分類
    • 医療診断
    • 迷惑メール検知
    • 商品推薦

教師あり学習

  • supervised learning
  • 問題に対してあらかじめ答えを用意
    • 予想された答えと実際の答えの違いが小さくなるように訓練
  • 与えられたデータから関係性を予想
    • 未知のデータに対しても筋の良い見通しを立てることが教師あり学習の代表的な目標の1つ

直線による近似

f(x)=wx+bf(x)=wx+b

  • 1つの入力xを与えると1つの出力を返す関数f
    • 傾きwと切片bの2つのパラメータで特徴づけられる
    • wとbの値をうまく決定して点の集まりにうまく沿うような直線を見つけることができれば新しいxが与えられた時に、tの値がどのような値になりそうかを予測できる
    • 未知のデータに対しても精度よく予測ができることを汎化性能(generalizability)が高いという
    • パラメータを使って何らかの計算を行うことで与えられたデータの特徴や関係性を表すものをモデル(model)と呼ぶ
  • xとtの関係をよく表すモデルのパラメータwとbはどうやって決定すれば良いか
    • 点がもし3次元空間や、4次元、5次元といった人間には想像することが難しい高次元空間に散らばっていたら、目で見ることもできないため困難
    • コンピューターにこれらの点のデータを与えて、自動的に最適なwとbを探させようというのが、機械学習で行われる代表的な処理の一つ

目的関数

  • コンピューターに良いパラメータを自動的に見つけてもらうためには、何が良いパラメータなのかという指標を定義する必要がある
    • 指標を表す関数を目的関数(objective function)と呼ぶ
    • xを入力変数(input variable), yを出力変数(output variable)と呼ぶ
    • 与えられた具体的なxの値を入力値(input value)と呼ぶ
    • 実際の点のもつtの値は、この式が予測したい目標の値なので、目標値(target value)と呼ぶ

二乗誤差関数

  • x1=100x_{1}=100, t1=40t_{1}=40のように置いてみる
    • 別な点も取り出してきて、同じように座標値(x,t)(x,t)(x2,y2)(x_{2},y_{2})と書くことにする
    • 同様に200個点を取り出してきたとすると、200個のxの値x1,x2,...,x200x_{1},x_{2},...,x_{200}t1,t2,...,t200t_{1},t_{2},...,t_{200}が得られる
    • このx1,x2,...,x200x_{1},x_{2},...,x_{200}からt1,t2,...,t200t_{1},t_{2},...,t_{200}を予想するのが目標
      • x1,x2,...,x200x_{1},x_{2},...,x_{200}が入力値
      • t1,t2,...,t200t_{1},t_{2},...,t_{200}が目標値
    • 式により得られた予測値yをy1,y2,...,y200y_{1},y_{2},...,y_{200}とする
    • これらの予測値の正確さを、対応する目標値との差の二乗によって測るのが、二乗誤差関数(squared error function)
  • nn個目の予測値をyny_{n}、目標値をtnt_{n}とすると、以下のような関数

l=(tnyn)2l=(t_{n}-y_{n})^2

  • nn個目のデータに対する予測値と目標値の差異を表す
    • ある1つのデータに対してだけ予測がうまくいっていたとしても、それ以外のえー他に対して全くうまく予測できないのであれば、そのモデルが新しい値に対して正確な予測を行うことは困難
    • 200個のデータすべてにわたって、この二乗誤差を足し合わせ、データ数の200で割って平均を取ったものを考える

L=1200n=1200(tnyn)2L=\frac{1}{200}\sum_{n=1}^{200}(t_{n}-y_{n})^2

  • \sumは総和を表す
    • (tnyn)2(t_{n}-y_{n})^2の値を、n=1n=1から順番にn=2,n=3,...,n=200n=2,n=3,...,n=200まで計算
    • 全てを足し合わせて200で割る
  • 平均二乗誤差(mean squared error)
    • 連続値を予測する回帰問題などでよく用いられる
    • 予測値と目標値が全てのnnに置いて完全一致するときだけ0になる
    • それ以外では必ず正の値をとる
    • この目的関数の値を最小にするwとbが、求めたい最適なパラメータ

目的関数の最適化

  • ある関数を最小にする入力変数の値を求めることを最適化という
  • 最適化をコンピュータで自動的に行うにはどうするか
  • 関数に適当な値をまず入力してみて、得られた値を使ってその値が小さくなりそうな方向に入力を少し動かす、ということを繰り返していって、関数が最小値をとる入力値を探索する、という方法がある

機械学習で使われる数学

  • このような最適化を行うのに必要になるのが微分(differential)
    • 入力をどちらに動かせば出力が小さな値になりそうか、ということを知るためには、対象の関数を微分する必要がある
  • 1つの値を入力して1つの値が出力される関数を考えてきたが、複数の値を同時に扱いときに必要になるのが、線形代数(linear algebra)
  • 点がもし本当は直線上にぴったり沿うようなデータであったのに、観測時に何らかの理由でノイズが乗ってしまったがために直線の周辺にバラついて出てきているのだとしたら、そのノイズがどの程度の範囲で値のずれを発生させるものなのか、見当をつけておきたくなる
    • そういったときに必要になるのが、確率(probability)・統計(statistics)の知識

その他

Markdown All in One - Visual Studio Marketplace

が便利すぎてなぜ今まで入れていなかったのかと。これで Haroopad から文句なく移行できる。

macOS Mojave で Chainer 環境構築

macOS Mojave で Chainer 環境構築

使用環境

$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.14.5
BuildVersion:   18F132

Install Python

Download Python | Python.org

3.7.3 is the latest.

$ python3 --version
Python 3.7.3

Create virtual environment.

$ python3 -m venv .
$ source bin/activate

Install Chainer

Installation — Chainer 6.0.0 documentation

$ pip install -U setuptools pip
$ pip install chainer
$ pip freeze
cached-property==1.5.1
chainer==6.0.0
chainerrl==0.6.0
cycler==0.10.0
filelock==3.0.12
future==0.17.1
graphviz==0.11
gym==0.12.5
kiwisolver==1.1.0
matplotlib==3.1.0
numpy==1.16.4
Pillow==6.0.0
protobuf==3.7.1
pyglet==1.3.2
pyparsing==2.4.0
python-dateutil==2.8.0
scipy==1.3.0
six==1.12.0
typing==3.6.6
typing-extensions==3.7.2

Run the MNIST example

chainer/examples/mnist at v6.0.0 · chainer/chainer · GitHub

$ python train_mnist.py 
./lib/python3.7/site-packages/chainer/_environment_check.py:41: UserWarning: Accelerate has been detected as a NumPy backend library.
vecLib, which is a part of Accelerate, is known not to work correctly with Chainer.
We recommend using other BLAS libraries such as OpenBLAS.
For details of the issue, please see
https://docs.chainer.org/en/stable/tips.html#mnist-example-does-not-converge-in-cpu-mode-on-mac-os-x.

Please be aware that Mac OS X is not an officially supported OS.

  ''')  # NOQA
Device: @numpy
# unit: 1000
# Minibatch-size: 100
# epoch: 20

Downloading from http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz...
Downloading from http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz...
Downloading from http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz...
Downloading from http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz...
epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.190276    0.0994537             0.942633       0.9698                    23.8376       
2           0.0747232   0.0705411             0.976717       0.9778                    47.7668       
3           0.0487931   0.0757109             0.984167       0.9769                    72.6437       
4           0.0366443   0.0786135             0.988367       0.9765                    98.4305       
5           0.0273172   0.0694717             0.991467       0.981                     125.23        
6           0.0218385   0.108687              0.99275        0.9726                    153.306       
7           0.0198589   0.0779753             0.993367       0.9791                    188.598       
8           0.0186954   0.0732773             0.993783       0.9823                    218.851       
9           0.0176328   0.0889091             0.994433       0.9785                    249.011       
10          0.0142019   0.0829101             0.995233       0.9814                    279.932       
11          0.0121828   0.113355              0.996433       0.9776                    311.948       
12          0.0144403   0.0905099             0.995367       0.9808                    344.985       
13          0.0137652   0.0838266             0.996067       0.9833                    379.64        
14          0.00821494  0.117748              0.997517       0.9802                    413.659       
15          0.0132004   0.109114              0.996067       0.9817                    449.17        
16          0.0143113   0.112049              0.995533       0.9804                    485.779       
17          0.00892646  0.0957723             0.997017       0.9831                    523.138       
18          0.00662617  0.104108              0.998117       0.9817                    564.709       
19          0.00824879  0.12197               0.99755        0.9808                    604.888       
20          0.0157249   0.111977              0.995883       0.9829                    645.684       

There is a warning message.

./lib/python3.7/site-packages/chainer/_environment_check.py:41: UserWarning: Accelerate has been detected as a NumPy backend library.
vecLib, which is a part of Accelerate, is known not to work correctly with Chainer.
We recommend using other BLAS libraries such as OpenBLAS.
For details of the issue, please see
https://docs.chainer.org/en/stable/tips.html#mnist-example-does-not-converge-in-cpu-mode-on-mac-os-x.

Need to install NumPy separately. Let's try with Anaconda.

$ conda create --name condachainer pip
$ conda activate condachainer
$ pip install -U setuptools pip
$ pip install chainer
$ conda env export
name: condachainer
channels:
  - defaults
dependencies:
  - blas=1.0=mkl
  - ca-certificates=2019.5.15=0
  - certifi=2019.6.16=py37_0
  - cycler=0.10.0=py37_0
  - freetype=2.9.1=hb4e5f40_0
  - intel-openmp=2019.4=233
  - kiwisolver=1.1.0=py37h0a44026_0
  - libcxx=4.0.1=hcfea43d_1
  - libcxxabi=4.0.1=hcfea43d_1
  - libedit=3.1.20181209=hb402a30_0
  - libffi=3.2.1=h475c297_4
  - libgfortran=3.0.1=h93005f0_2
  - libpng=1.6.37=ha441bb4_0
  - matplotlib=3.1.0=py37h54f8f79_0
  - mkl=2019.4=233
  - mkl_fft=1.0.12=py37h5e564d8_0
  - mkl_random=1.0.2=py37h27c97d8_0
  - ncurses=6.1=h0a44026_1
  - numpy-base=1.16.4=py37h6575580_0
  - openssl=1.1.1c=h1de35cc_1
  - pip=19.1.1=py37_0
  - pyparsing=2.4.0=py_0
  - python=3.7.3=h359304d_0
  - python-dateutil=2.8.0=py37_0
  - pytz=2019.1=py_0
  - readline=7.0=h1de35cc_5
  - setuptools=41.0.1=py37_0
  - sqlite=3.28.0=ha441bb4_0
  - tk=8.6.8=ha441bb4_0
  - tornado=6.0.2=py37h1de35cc_0
  - wheel=0.33.4=py37_0
  - xz=5.2.4=h1de35cc_4
  - zlib=1.2.11=h1de35cc_3
  - pip:
    - chainer==6.1.0
    - filelock==3.0.12
    - numpy==1.16.4
    - protobuf==3.7.1
    - six==1.12.0
    - typing==3.6.6
    - typing-extensions==3.6.6
prefix: ~/anaconda3/envs/condachainer

Releases · chainer/chainer · GitHub

v6.1.0 @beam2d beam2d released this 20 hours ago

Oh...never mind.

$ python train_mnist.py 
Device: @numpy
# unit: 1000
# Minibatch-size: 100
# epoch: 20

epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.189819    0.0923269             0.942533       0.9721                    18.4105       
2           0.0730058   0.0963992             0.97735        0.9696                    38.9289       
3           0.0507709   0.0681645             0.983517       0.9796                    60.7336       
4           0.0357853   0.0733023             0.988467       0.9784                    83.1306       
5           0.0286872   0.082298              0.990917       0.979                     106.233       
6           0.0228451   0.0738484             0.99235        0.9806                    131.034       
7           0.0206049   0.0837659             0.993467       0.9796                    155.578       
8           0.0200223   0.0870863             0.993383       0.98                      180.522       
9           0.0133957   0.0855648             0.995667       0.9831                    206.545       
10          0.0175329   0.0806837             0.994467       0.982                     233.34        
11          0.0119728   0.0871093             0.99595        0.9829                    260.76        
12          0.0110821   0.0840505             0.996633       0.9829                    288.536       
13          0.0158595   0.0899242             0.995533       0.9823                    317.186       
14          0.00708507  0.104456              0.99755        0.982                     347.658       
15          0.0122286   0.0986352             0.996533       0.9806                    376.948       
16          0.0142947   0.107316              0.995783       0.9815                    406.64        
17          0.00880313  0.114419              0.9972         0.9815                    438.935       
18          0.00582421  0.0949353             0.998267       0.9826                    471.025       
19          0.00788875  0.123834              0.997783       0.9814                    504.499       
20          0.0126048   0.10169               0.996483       0.9816                    539.86        

1.2x - 1.3x faster than before.

その他

Install -> お試し実行で warning -> Anaconda 使って再度 install -> してる間に Chainer のバージョンが上がる、というオチまでついて環境構築完了。

Chainer は日本発のフレームワークということで色々期待が持てるが Mac はあまり積極的にはサポートされていないので最初っから Ubuntu 用意した方が良かったかもしれない。

Update Rails Gem

Update Rails gem

一昔前に作成したRailsサイトのメンテナンスを怠ったばっかりに依存パッケージにセキュリティアラートが続々と。。。

ここらで一気にアップデートしていく

現状洗い出し

bootstrap-sass
rack
doorkeeper
nokogiri
rails-html-sanitizer
loofah

以上6つがセキュリティアラートあり。

他にも sass-rails が非推奨になってる(!)とか、諸々。

Upgrade

Gemfile を更新していく。

diff --git a/Gemfile b/Gemfile
index 79f19b1..322de1f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,22 +1,22 @@
 source 'https://rubygems.org'
 ruby "2.3.1"
 
-gem 'rails',        '5.0.0.1'
+gem 'rails',        '5.1.2'
+gem 'bootstrap-sass', '3.3.7'
 gem 'bcrypt',         '3.1.11'
-gem 'faker',          '1.6.6'
-gem 'carrierwave',             '0.11.2'
-gem 'mini_magick',             '4.5.1'
-gem 'fog',                     '1.38.0'
-gem 'will_paginate',           '3.1.0'
-gem 'bootstrap-will_paginate', '0.0.10'
-gem 'bootstrap-sass', '3.3.6'
-gem 'puma',         '3.4.0'
+gem 'faker',          '1.7.3'
+gem 'carrierwave',             '1.1.0'
+gem 'mini_magick',             '4.7.0'
+gem 'fog',                     '1.40.0'
+gem 'will_paginate',           '3.1.5'
+gem 'bootstrap-will_paginate', '1.0.0'
+gem 'puma',         '3.9.1'
 gem 'sass-rails',   '5.0.6'
-gem 'uglifier',     '3.0.0'
-gem 'coffee-rails', '4.2.1'
-gem 'jquery-rails', '4.1.1'
+gem 'uglifier',     '3.2.0'
+gem 'coffee-rails', '4.2.2'
+gem 'jquery-rails', '4.3.1'
 gem 'turbolinks',   '5.0.1'
-gem 'jbuilder',     '2.4.1'
+gem 'jbuilder',     '2.7.0'
 gem 'doorkeeper'
 gem 'grape'
 gem 'grape-entity'
@@ -25,20 +25,20 @@ gem 'grape-swagger-entity'
 gem 'grape-swagger-rails'
 
 group :development, :test do
-  gem 'sqlite3', '1.3.11'
-  gem 'byebug',  '9.0.0', platform: :mri
+  gem 'sqlite3', '1.3.13'
+  gem 'byebug',  '9.0.6', platform: :mri
 end
 
 group :development do
-  gem 'web-console',           '3.1.1'
+  gem 'web-console',           '3.5.1'
   gem 'listen',                '3.0.8'
-  gem 'spring',                '1.7.2'
-  gem 'spring-watcher-listen', '2.0.0'
+  gem 'spring',                '2.0.2'
+  gem 'spring-watcher-listen', '2.0.1'
 end
 
 group :test do
-  gem 'rails-controller-testing', '0.1.1'
-  gem 'minitest-reporters',       '1.1.9'
+  gem 'rails-controller-testing', '1.0.2'
+  gem 'minitest-reporters',       '1.1.14'
   gem 'guard',                    '2.13.0'
   gem 'guard-minitest',           '2.4.4'

で、gem を更新

$ bundle install

結果

actionview
critical severity
bootstrap-sass
moderate severity
activejob
moderate severity

ダメだった

actionview あたり、rails 自体上げるか、という感じ

diff --git a/Gemfile b/Gemfile
index 3653cab..537a515 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,8 +1,8 @@
 source 'https://rubygems.org'
-ruby "2.3.1"
+ruby "2.3.3"
 
 gem 'rails',        '5.1.7'
-gem 'bootstrap-sass', '3.3.7'
+gem 'bootstrap-sass', '3.4.1'
 gem 'bcrypt',         '3.1.11'
 gem 'faker',          '1.7.3'
 gem 'carrierwave',             '1.1.0'

rails 上げるには ruby も上げねば、ということで Cloud9 上の環境で

$ rvm install 2.3.3
$ rvm --default use 2.3.3

f:id:kfurue:20190414081425p:plain
Alerts

Yay!

その他

一回作ったのち放置しすぎてやばい。
ぼちぼち触っていこう