ホーム » 「ニューラルネットワーク」タグがついた投稿

タグアーカイブ: ニューラルネットワーク

CNNの目的関数の考察と歴史

こんにちは。

久しぶりの投稿になりました。本日の内容はタイトル通りです。

線形回帰とかの目的関数って最適解を持ちましたね。
しかし、ニューラルネットワークはそうはいかないと言いました。

つまり、目的関数が凸関数ではない可能性が非常に高いんですね。
目的関数や凸関数、勾配法がわからない方は次の記事をみてください。

CNNの目的関数を可視化した論文があります。
その図をお借りして実際にどんな感じか見てみましょう。

skip(residual) connectionとはResNetの特徴であるResidul blockの恒等写像のことです。

ちなみにこれは余談ですが、ResNetとXGBって考え方似てると思いませんか?

見ての通り左は明らかに凸ではないですね、右もマシではありそうですがサドルポイントが見られます。
別の図も見てみましょう。次のはCIFAR-10 datasetの学習の際のプロットになります。

すごくないですか?何がってskip connectionのおかげで少し凸っぽくなってます。

VGGとDenseNetは初見なので調べてみました。というかいろんなモデル多過ぎ、、、
この際なのでニューラルネットワークのモデルをちょろっとみてみましょう。
そもそも現在流行りのCNNの基盤となったアルゴリズムはLeNet-5というものです。
開発者はフランス人のYann LeCun’s Home Pageです。

僕も最近知ったんですがこれ何がえぐいかって1998年に発表されているんです。
1998年ですよ?、どんな時代かググってみました。
パソコンの歴史/年代流行によると
1. Windows98発売
2. アップルが初代iMacを発売
だそうです。まだちょっとすごさがわからないので調べてみると
Windows 98 – Virtual x86
What’s iMac – AirMac
だそうです。言いたいことは今のスマホの足元に到底及ばないスペックです。
まあこの話は置いておいて、VGGとDensenetは僕は初見だったので調べてみました。

まずはVGGです。下のアーキテクチャは論文のものです。
2014年のアルゴリズムで当時はかなり深いとされていたようです。

それほど喋ることが見当たらないのですが強いていうなら
このモデルのアウトプットベクトルが1000なので1000種類の画像を識別できます。
Fine Tuningすればあなたの好みの画像を分類できます。例えば、好みの女優とか?
なんでモデルを最初から作らずFine Tuningするのか?
という問に対する答えは、学習量が減るからのようです。
具体的には元々のモデル上層部の重みは学習データを変えてもそれほど変化しないようなので
そのまま使い下層部つまり出力層に近い重みを更新するようです。
入力が人からキリンとかになったらどうかと思いますがね、、、

続きまして、DenseNetです。
これはResNetの改良版と言えるでしょう。改良版というのは次のようにResNetを問題視したからです。

An advantage of ResNets is that the gradient can flow directly through the identity function from later layers to the earlier layers. However, the identity function and the output of H` are combined by summation, which may impede the information flow in the network.

そもそもResNetの背景には深層における勾配消失問題があります。
この対策としてidentity functionが導入されResNetができたのですがDenseNetでは
それはメリットである一方、モデルにおける情報フローを阻害していると考えたようです。
言われてみるとそうかも知れませんね。そこで考えたれた

ResNetの特徴Residul blockに対するDense blockです。見ての通り前工程の出力を全て入力に使っています。
で、使われたモデルはこんな感じで

ResNet含め、その他のアルゴリズムとの比較結果がこれ

青の数値がDenseNetです。エラーが小さいのでいい精度であることがわかります。
長くなりましたがいろんなCNNと目的関数の凸性を見てみました。

ちなみにこれら全てkerasにあります。
Applications
便利な時代ですね。。。。そしてこれらも勾配法使われていると思うとエグい、、、

でわ。

READMORE

交差検証(Cross-Validation)をPythonでやる

こんにちは。

前回、交差検証というワードに触れ、その図を確認して終わりました。今回はその交差検証をしっかりと理解しましょう。

What is Cross-Validation?

モデルの誤差値を検証すること

この精度であっているのか?などの疑問を交差検証により解決します。

Cross-Validation consists of two main parts

  • Leave one out Cross-Validation (LOOCV)
  • K-Folds Cross Validation

という基本的な2つを紹介します。Holdout methodというものが他にありますがK-foldの下位互換と思っていいでしょう。

まずは「K-Folds Cross Validation」についてです。

  1. データセットをK分割する(k-foldと名付ける)。
  2. \forall i \in \{1, \cdots, k \}に対して
    i-foldを除いた他の全foldでモデルを学習させる
    i-foldを用いてモデルのerrorを計算する
  3. k個のerrorを平均する

図で確認しましょう。

では次に「Leave one out Cross-Validation (LOOCV)」についてです。これは上においてK=データの数としたものです。なのでerrorの平均は次のようにかけます。

    \[CV(n) = \frac{1}{n} \sum_{i=1}^n \left( y_{i} - \hat{y_{i}}^{(-i)}    \right)^2  \]

ただしnはデータ数、\hat{y_{i}}^{(-i)}i番目を除いたデータで学習をしたのちのy_{i}に対するpredictionです。しかし、こちらが利用されている例を見たことがありません。なので特に気にしなくていいでしょう。

交差検証=KFOLD

で行きましょう。では以下で実装例を見て見ましょう。ちなみにニューラルネットワーク前処理についての記事を復習しておくといいかもしれません。(ニューラルネットワークについては新しい記事を書く予定です)

話が逸れてしまいましたがこれで交差検証は大丈夫そうですね。次回からは再度、正則化についてのお話です。

でわ

READMORE

ねぇPython、CNNって何?(理論編 Part-1)

本日からはニューラルネットワークweek。最新のものまで突っ走りましょう。

てゆーか、ニューラルネットワークってなんだったっけ?

入出力数とか層数などは気にせずこんな風にニューロンを使った関数がニューラルネットワークでした。そして層が比較的深いものを多層パーセプトロンといいました。よく見ると

入出力がベクトル

になっていますね。いいんです。実際データなんてベクトル形式なんです。各学生のテストのデータも、競馬のデータも株価も終値とかを横並びにしてベクトルです。

しかーーし!

これ今日僕がとって虹なんですけど。こんな風に画像を入力としたい場合はベクトルじゃなくないですか?実際サイズは(691 × 502)ですし、しかもRGBなんです。RGBはレッド・グリーン・ブルーの略です、つまり3次元。

この画像のニューラルネットワークの入力として使いたいとするとこのままだと無理なので作戦を考える必要があります。

  1. とりあえずグレースケールにする(RGBからモノクロ)

こうするととりあえずデータのシェイプ(横,縦,奥)が(691\times 502\times 1)になります。しかしまだ行列のままなのでもう一工夫

  1. 各行を横に並べて1\times (502\times 691)のベクトルにするもしくは縦に並べたベクトルにする

こうすることで画像をベクトルとして扱えるようになりました!わーい

それは無理やりすぎる

ごもっともです。行列をベクトルにするなんて邪道すぎますね。行列入力できるニューラルネットワークが

畳み込みニューラルネットワーク(Convolutional Neural Network)

なんです。そう、画像に特化したニューラルネットワーク

けどどうやって行列入力可能にしたんや?

その前に、そもそもなんで画像をベクトルとして扱うべきでないかというと

たとえばこの画像、四角で囲ったところを1ピクセルだとします。ここだけ見ても何もわからなくないですか?というのはこのピクセルから学習できそうなことはあるのか?ということです。一方で

こう見るとどうですか?虹がハッキリと映っていてさっきよりは意味あるピクセルになっていますよね、つまり、コンピューターが画像を学習するには今までのようなベクトルの要素単位ではなくもっと大きな範囲を1単位として見る必要があるからです。それが

畳み込み

なんです。この場合だと真ん中の(2\times 2)行列がコンピューターの目となりKernel matrixといったりします。これをずらしていって手前の出力を作るんですがとりあえず一気に定式化します。

  • 入力シェイプはW_1 \times H_1 \times D_1
    フィルタ数: K
    フィルタサイズ: F
    スライド幅: S
    パディング: P
  • 出力シェイプはW_2 \times H_2 \times D_2
    W_2 = (W_1 − F + 2P)/S + 1
    H_2 = (H_1 − F + 2P)/S + 1
    D_2 = K

フィルタサイズとはKernelサイズのこと、スライド幅はフィルタのずらし幅、パディングは画像の縁に新たなピクセルを組み込むことzero-paddingがメジャー。これは縁に0ピクセルを付け加えること、こうすることで

  • 縁の畳み込み回数が増える
  • パラメータの更新数が増える
  • カーネルのサイズを調節できる

などのメリットがあります。

そして出力のシェイプで分母にSとありますがこれについては次の図を見てください。緑が入力、オレンジが出力

スライド幅: 1

スライド幅: 2

 

緑のブロックにカーネルを重ね合わせ線型結合を計算します。この際、スライド幅が適切でないシェイプが少数になるのでそこだけ注意。

CNNでは畳み込みに加えてPoolingという操作があります。これは画像の縮小です。今までのニューラルネットワークでは隠れ層のノード数を減らすことで次元を落としていました。これを行列入力においても可能にしようというものです。

具体的な方法はMax-poolingというものです。(2\times 2)のKernelでスライド幅2だと次のようになります。

定式化すると

  • 入力: W_1 \times H_1 \times D_1
    フィルタサイズ: F
    スライド幅: S
  • 出力: W_2 \times H_2 \times D_2
    W_2 = (W_1 − F)/S + 1
    H_2 = (H_1 − F)/S + 1
    D_2 = D_1

となります。しかし、Poolingという操作はあまり人気がないらしいのでスライド幅の大きい畳み込みで対処するようです。

最後に次のリンクが非常に参考になるので見てみてください。

 

本日はここまでです。でわ。

ねぇPython、前処理って何?

こんちには。良いバックパックがほしい、そんな日々が続きます。

僕は機械学習を勉強してきていろんなアルゴリズムを使ってきました。その都度いろいろなデータ触れてきました。

そもそもデータをそのままアルゴリズムに突っ込むのは正しいのか?

たとえばPCAの場合データの平均を0にしてからPCAにかける必要があります。

ところでデータは不完全な形でやってきます。今回は次のような車のデータを考えます。

みての通り「文字」「NaN」が混在しています。まずはこれをどうにかする必要があります。対処法は主に次の3パターンかと思います。

LabelEncorder

例えば[dog,cat,dog,mouse,cat]を[1,2,1,3,2]に変換する

OneHotEncorder

例えばdog cat monkey dogの4つのデータを[dog, cat, monkey]で表しそれぞれ

    \[[1,0,0], [0,1,0], [0,0,1],[1,0,0]\]

の4つにします

LabelBinarizer

OneHotEncorderとほぼ同じ。

 

さて、本題のデータの前処理なんですが、

  • 標準化(standardization)
  • 正規化(normalization)

の2種類がメインです。これらの手法をスケーリングといいます。重要なのは違いと必要性ですがその前に定義をみてみましょう。

標準化

    \[ x' = \frac{ x - \mu }{ \sigma }  \]

ただし\mu, \sigmaは平均、分散とする。

こうすると平均0、分散1の分布へと変換されます。

正規化

    \[ x' = \frac{ x - min }{ max - min }  \]

ただしmax,minはデータの最大値、最小値とする。

こうすると新たなデータは[0,1]へとスケーリングされます。標準化と違い範囲が固定されるわけではありません。

で、なんでスケーリングする必要があんの?

もちろんです。

スケーリングなんかせんでもいい

という場合ももちろんあります。例えば、生徒会長を決めるための投票データは「支持する」or「支持しない」のバイナリになります。この場合スケーリングをする必要がないのは明らかでしょう。他には男女別の五教科の点数のデータを分析する際、僕は前処理をする必要性を感じません。なぜならデータの範囲は[0,100]ですし、数値がめちゃめちゃ大きいわけでもないからです。

では、いつスケーリングやねん

これは正直難しい問題だと思います。なにを分析したいのかという状況・目的に大きく左右されると思います。ですが、冒頭でも言ったようにPCAなど特定のアルゴリズムは特定の前処理を必要とします

僕の経験上、正規化よりも標準化の方がポピュラーです。というか僕は正規化はしたことないです。理由としては標準化にはセンタリングが含まれるからです。また、そもそも世の中のほとんどデータは正規分布に従っているんです。IQのデータとか身長とか標高でさえ正規分布に従うようです。加えて数学の世界にはいい定理があります。「大数の法則」と「中心極限定理」です。

  1. 大数の法則:        データ超多かったら、その分布の真の平均と実測値の平均が一致!!
  2. 中心極限定理:     データ超多かったら、正規分布に従うと思ってOK!!

これらも標準化がポピュラーな理由の1つでしょう。(1の証明は簡単、マルコフとチェビシェフの不等式を使う)

では次にスケーリングのメリットについてです。1つは学習速度でしょう。次の図をみてください。

 

各軸でデータの範囲が大きく異なる場合、図左のように学習が遅くなることがあります。一方で右図はスラリと学習できています。これより勾配法を使うアルゴリズム

  • ロジスティック回帰/ソフトマックス回帰
  • ニューラルネットワーク/SVM

とかは恩恵を受けるでしょう。

他にはK-meansは一般にはユークリッド距離を用いてクラスタリングします。この際、各特徴を同じ程度重要視して距離を測りたい場合は標準化は効果を発揮するでしょう。(一方、マハラノビス距離は特徴量ごとに距離に重み付けする)

しかし、やはり簡単な問題ではないので何が目的か何をしたいのかを明確にして使い分ける必要がありそうですね。。ここでは標準化・正規化の2つでしたが無相関化(独立主成分分析)などもあります。

 

最後に簡単な実装を載せておきます。

 

READ MORE