dondakeshimoの丸太

データサイエンス/Webアプリケーション/

Pythonの環境構築奮闘記 あるいは降参記

モチベーション

Pythonは最高だ! コードの見た目は綺麗で,3rdパーティモジュールも豊富, 何よりもiPython kernelの存在が大きいと思う. もっというとJupyterだ. あるいばHydrogen(Atom package)だ. ブラウザでもお好きなブラウザでもコードを書きながら即時実行できる強みは計り知れない.

しかし,Pythonの環境構築周辺はとっちらかっている. 議論もベストプラクティスもハゲ散らかっている. Pythonの環境構築について思い悩んだ挙句, 一旦思考をまとめるのと思考の記録を残す目的で本ログを残す. (注: ほぼポエム)

現状の考察

環境構築ツール

下記サイトなど色々なサイトでまとめられているため,まとめのまとめレベルで記述する.

pyenv、pyenv-virtualenv、venv、Anaconda、Pipenv。私はPipenvを使う。 - Qiita

Pythonバージョン切り替え パッケージ切り替え
pyenv
pyenv-virtualenv
venv
virtualenv
pipenv
anaconda
docker

必要事項

  • Pythonバージョンの使い分け
  • Python仮想環境の独立性
  • Python仮想環境の再現性及び手軽さ
  • 開発環境のストレスフリー

ここでPython仮想環境とはvirtual envやpipenvで作成した環境を指す.

Pythonバージョンの使い分け

絶対に必要がどうかは疑わしいという議論もある. しかし,導入自体はツールさえインストールしてしまえば簡単にでき, tensorflowなどのPythonバージョンに依存するモジュール(知識が古かったらすみません) も容易に使えるようになることや, 実行環境のPythonバージョンが固定されている時のことなども考えると あって損はない機能というか,やっぱり必要機能だと感じる.

Python仮想環境の独立性

これはどこまで仮想環境を切り分けるかという話である. 例えば,pyenvのみを用いた場合はバージョン毎の切り分けは可能だが, プロジェクト単位での環境の切り分けはできない. しかし,プロジェクトの依存関係がはっきりしないプロジェクトというのは, 個人開発の域を出た瞬間になんとも言えない不安感を煽る. イケてないと感じるし,イケてない人だと苦笑いされるのは最悪の気分だ.

Python仮想環境の再現性及び手軽さ

上述の独立性を担保する上で,留意しておきたい点がこの二つである. 独立性を担保し,依存関係がはっきりしていることは非常に好ましいが, さらにその仮想環境を違うマシン,環境でも簡単にサクッと再現できる必要がある. 著者は古くからの requirements.txt はとても好きだ. Simple is best だ. 逆に自分にとって手軽だろうが,自前のシェルスクリプトなどは再現性が下がるので論外となる.

開発環境のストレスフリー

ざっくり分けて環境には2種類あり, それぞれ開発環境と実行環境に分けられる. ここで議論している環境は実行環境を大きく意識した開発環境を整えることである. しかし,実行環境のために開発環境の便利さをトレードオフさせることは避けたい,いやだ,ありえない.

欲しい環境のまとめ

実行環境を意識した上で,バージョンと依存関係がプロジェクト単位で独立しており, その仮想環境を他の環境でも容易に再構築できるが, それら全ては開発環境の機能を損なうものであってはならない.

ベストプラクティスの考察

  • Atom(+ Hydrogen)が好きです
  • pipenv, venv, virtualenv, pyenv-virtualenv だとやはり...
  • anacondaに委ねる
  • docker等,上位の仮想環境で戦う
  • pyenv + pyenv-virtualenv はやっぱりありでは
  • pyenv + pipenv は次世代みがある

Atom(+ Hydrogen)が好きです(ポエム強め)

いきなり個人の趣向が入ってきて,ベストプラクティス(笑)になってしまった. Atom + HydrogenはAtomエディタ上でiPythonを用い, 各行実行や,セクション実行が可能なプラグインである. 布教が目的とかではないけど是非使ってみてほしい.惚れると思う.

さて,このプラグインを実行するためにはJupyter環境が必要になるのだが,これが曲者である. Jupyter入れるだけでしまいやん!とはならない. 上記の必要事項にプロジェクト毎の独立性と書いたが, その要件を満たした場合,Hydrogenの実行カーネルを それぞれのプロジェクトに対して変更する必要がある. ...だが,無理だ. そのような機能は,ない. 管理手法がそれぞれ異なるのにそのような出すぎた要求はできない.

そのため,筆者はどのプロジェクトでも使える共通の,なんでも入りの仮想環境を一つ作り, そのカーネルをHydrogenに登録して用いている. どう考えても,実行環境と開発環境に乖離が生じているためダメだろうという構成である. 仮想環境は最後にその構成で動くかどうか確認し,他人と共有する為のものと化してしまっている.

Jupyterで開発している人もどうしているのだろうか. 全てのプロジェクトにJupyter入れているんだろうか?

Hydrogenを諦めればなんでも綺麗にまとまる気がしてきた. しかし,必要事項の開発環境のストレスフリーに反する為, 結局筆者はこのような環境を現状使い続けるだろう. Hydrogenのカーネルを仮想環境毎に割り振るツールでも作れば良いのだろうが... あれ,それで解決するのでは? 来週の予定,埋まりました.

pipenv, venv, virtualenv, pyenv-vritualenv だとやはり...

pipenv,ナウいんだろう,知らんけど.

という所感を環境構築のリサーチ中に受けた. これら4つはPythonのバージョン管理は機能として持っておらず, Python仮想環境の構築にのみ特化したものである. 基本的な機能はどれも同じで,少し前までのデファクトがvirtualenv, 最近評価をあげているのがpipenvという印象である. 正直どれでも良い気もするし,venvには触ったことがないしおすすめ出てこないしで一旦スルーする.

pipenvはnpm(JavaScriptの似たような機能のやつ)などの影響を受けているらしい? 必要パッケージだけでなくその依存モジュールまで記録してくれる. npmのようにその環境独自のコマンドを用意することもできる. 最も後発で,機能としては最も完璧に近いと思う. ただ,遅い.依存関係の記録が異常に遅い.ついでに毎回最初に pipenv run つけるの面倒くさい. pipenv shell はわかりづらい.

virtualenvやpyenv-virtualenvは再現性がpipenvと比べて低い. pipenvでは pipenv install の1コマンドで済むところを それぞれの開発者がrequests.txtに応じて開発環境を構築することが必要となる. 逆に開発者それぞれにpipenvの依存関係が軽減されるということでもある. pyenv-virtualenvの方が手軽だが, 多数のプロジェクトを抱える場合,環境の中央集中の一括管理であるため取っ散らかる. virtualenvはactivateするのが面倒だったり,環境の使い回しができないデメリットがある.

やはり...とかなかった. 一長一短だった. 最初はpipenvに落ち着けるつもりだったけど, 書き始めたらむしろ愚痴の方が出てきたため保留.

anacondaに委ねる

anacondaは全部やってくれる. マジで全部.本当に全部.全然全部. 以前はWindows環境の場合,その他のツールが動かないため, anaconda以外の選択肢がなかったし, 実際これさえあればかなりほぼ全ての要求に答えることができる. じゃあ,これでええやん!とならないのがややこしいところである.

anacondaそのものの是非について

Anacondaの利用は是か非か?(またはそれでも私がAnacondaを“今“使う理由) - DEVGRU

この辺に議論が書いてある. 多分批判点(メリット)をざっくりまとめると

  • 権限周りの危険が危ない説がある
  • 大量のパッケージを入れられて容量とかうざい(大量のパッケージ美味しい)
  • pipと競合する(condaの方が楽にインストールできるものも存在する(した))

この辺に突っ込むと長くなりそうだし,完全に把握しているわけではないからこの辺で飛ばす. 現状,anacondaを使うなら全てをanacondaに委ねる覚悟が必要そう. 何かと共存させるのはどうなんだろうという状態らしい. 筆者はpyenvでanacondaをインストールして使っていたが, これは大量のパッケージが事前に入っていて便利だったからである. その程度の理由ならとっととanacondaから撤退した方が吉だろうと思い,全部捨てた.

docker等,上位の仮想環境で戦う

docker最高!Vagrandとかでも全然あり! 速度のオーバーヘッドはあまりないし,ここまで仮想化したら実行環境への意識という点では完璧だ. ...だが,弊環境では難しい. 一つ大きな理由がマシンの容量が怖いところである. メインマシンがストレージ256GBのMacなのが全部悪い. もう一つ運用できないため実際にぶち当たったことはないのだが, 開発環境でストレスが出るのではないかという懸念もある. できればAtomで開発したいのだが,この場合ボリュームを結合するか, 何かの都度書いたスクリプトをdocker環境にコピーする必要がある. jupyterサーバを立てる手もあるため, そこで下書きをしながらスクリプトを書いてコピーという流れが良いのだろうか. マシンをアップグレードすれば非常に興味のある構成なので是非ご教授願いたい.

pyenv + pyenv-virtualenv はやっぱりありでは

筆者が最近環境を再考するまで使用していた構成である. そしてこの投稿を書きながら,Hydrogenを使うに最も適当な構成であると気づき. 再度この構成に落ち着かんとしている. 問題としては環境の再現性が大きいと思うし, 実際のところpipenvの方がイケてる感は否めないので他人に勧めるようなものでもない.

pyenv + pipenv は次世代みがある

目下ネット上の第一おすすめ候補だろう. かっこいいし,いいと思う. 遅い問題については --skip lock オプションをつけることで大きく軽減されるらしい. それでもどこかのタイミングでlockせざるを得ないが. この問題についてはpipenvの開発者も認識しているらしく,近い将来改善されることが期待される. もう一つの仮想環境に入るの面倒あるいわかりづらい問題は, 自分のターミナルを適応させることでなんとかなると思う. というかそういうの考えるのは割と好き.

まとめ

  • 開発環境さえ整えばdockerが最高!(と思う)
  • パッケージ管理特化のツールはpipenvが一つ抜けている気もするが,(まだ)五十歩百歩
  • anacondaは好き嫌い分かれてる
  • 開発環境を完璧に整えるのはdockerに限らず難しい

機械学習,正則化についてまとめ

かなり回を重ねてきたけど,完全に自分のことしか見ていない. 絶対他の人の役には立っていないとわかる. そんなブログで突き進む. 前回同様,深層学習について学んだことをまとめる. 今回のテーマは深層学習における正則化である.

went-went-takkun135.hatenablog.com

深層学習

深層学習

  • 作者: Ian Goodfellow,Yoshua Bengio,Aaron Courville,岩澤有祐,鈴木雅大,中山浩太郎,松尾豊,味曽野雅史,黒滝紘生,保住純,野中尚輝,河野慎,冨山翔司,角田貴大
  • 出版社/メーカー: KADOKAWA
  • 発売日: 2018/03/07
  • メディア: 単行本
  • この商品を含むブログ (1件) を見る

正則化

深層学習の観点では,正則化手法のほとんどは推定量正則化に基づいている. 推定量正則化は,バイアスの増加とバリアンスの減少を引き換えることで機能する. 過度にバイアスを増加させずにバリアンスを大きく減少させる正則化項が望まれる.

パラメータノルムペナルティ

 \tilde{J}(\mathbf{\theta}; \mathbf{X}, \mathbf{y}) =
  J(\mathbf{\theta}; \mathbf{X}, \mathbf{y}) +
  \alpha \Omega(\mathbf{\theta})

 \alpha \in [0, \infty ]

バイアスパラメータには関与せず重みのみにペナルティを課す.

 L^{2} パラメータ正則化

重み減衰,リッジ回帰,ティホノフ正則化として知られる. ステップごとの観点で言うと,重みの更新に際して一定の割合 ( \varepsilon\alpha, \varepsilon : learning rate) が間引かれながら学習を進めていく頃になる. 学習全体の観点で言うと,パラメータが目的関数を減少させることに大きく寄与する方向には, 相対的に重み減衰の影響が少ない. 逆に学習において重要でない方向に対応する重みベクトルの要素は 訓練全体で正則化を使うことで減衰する.

 L^{1} パラメータ正則化

個々のパラメータの絶対値の総和を減衰項とする.  L^{2} 正則化と比して L^{1} 正則化ではいくつかのパラメータの最適値が0になる スパースな解が得られる. このスパース性を利用して特徴量選択を行うことができる.

条件付き最適化としてのノルムペナルティ

一般化ラグランジュ関数を構築することで制約問題にパラメータペナルティの問題を帰着させると, パラメータ正則化は重みの解の範囲を限定する作用があることがわかる. 減衰項の係数である  \alpha を増減させることで,解の範囲を大まかに制御することができる. 適切な範囲の係数である  k がわかっている場合,  \alpha = k として ペナルティを課すよりも,解が範囲を超えたタイミングで  \Omega(\mathbf{\theta}) \lt k の範囲に再射影する方が最適解ではない極小値に  \theta が陥らず効率的に値を探索できる.

正則化と制約不足問題

正則化を行うことで,サンプルに分散が観察されない時や劣決定系問題を含む場合に 解を定めることができる.

データ集合の拡張

機械学習モデルの汎化性能を高める最善の方法はより多くのデータで訓練することであり, そのために偽データを訓練データの一部として用いることで,訓練データを水増しするアプローチがある. このアプローチは分類において最も簡単な方法となる. ただし,密度推定タスクなど,他の多くのタスクについても簡単に適用できるものではないことに 留意されたい.

特にデータ集合の拡張が効果を発揮している分野として物体認識がある. この分野では画像の回転やスケーリングを行うことでデータの拡張を行う.

ノイズを元データに加えると言う手法もデータ拡張の一つとみなせる. ニューラルネットワークはノイズに対してあまり頑健でないことが証明されている. ノイズへの頑健性を高めるためには単純にノイズを加えたデータで学習をする手法がある. 入力へのノイズの注入は雑音除去自己符号器のような教師なし学習アルゴリズムの一部である. 2014年にPoole et al.によりノイズの大きさを非常に注意深く調整すれば この手法が極めて有効であることが証明された. ドロップアウトもノイズの乗算を用いて新しい入力を構成する皇帝とみなせる.

機械学習アルゴリズムベンチマークを比較する際は, スコアを算出した際にデータ拡張が行われていたか確かめることが重要である. データ集合の拡張の有無によって差が出ている場合, 単純にモデルやアルゴリズムの比較ができないためである.

ノイズに対する頑健性

一般的に,ノイズの追加は,特にノイズが隠れユニットに加えられた場合に, 単純にパラメータを縮小するよりずっと強力になりうる.

出力目標へのノイズの注入

データ集合の拡張で記述したノイズ手法以外に,出力ラベルに対してノイズを含ませる手法も存在する. このような手法の代表的なものがラベル平滑化と呼ばれる手法である.

教師あり学習

表現を学習する手法であるらしいがあまり理解できなかった. Chapelle et al, (2006)に詳細が書いてあるらしい.

マルチタスク学習

異なるタスクに関連づけられているデータで観測される変動を説明する因子の中には, 二つ以上のタスクの間で共有されるものがいくつか存在する と言う事前信念のもとに適用される. モデルの一部を異なるタスク間で共有し,重みも共有することで汎化性能を改善する. このようなモデルのパラメータは

  1. タスク固有のパラメータ
  2. 異なるタスク間で共有されるパラメータ

汎化と汎化誤差の浄化をこれらのモデルによって改善することが可能である.

早期終了

エポック数を回し切った最後のパラメタではなく, 検証誤差が最少となったエポックでのパラメタを返す手法を早期終了という. 早期終了はその単純さと有効性から,深層学習において一般的に最も使われている正則化である.

最大のメリットとして,ハイパーパラメタの一つであるエポック数を排除できることが挙げられる. 逆に,デメリットは訓練中に定期的に検証誤差を測定する必要があるということと, 最良のパラメタのコピーを保持する必要があるという点である. しかしパラメタの保持についてはメモリに格納する必要はないため,通常無視することができる.

早期終了では検証集合が必要となるため,一部のデータが訓練で使えないこととなる. これらのデータを使いたい場合,早期終了を行い,最適なエポック数やモデル訓練回数を調べた後に, 同様の回数でもう一度始めから訓練するという手法がある. この場合,パラメタの更新回数を等しくするのかエポック数を等しくするかの2通りの手法がある. また,早期終了で得たパラメタを保持したまま追加分のデータを含めたデータ集合で訓練するという 手法もある. しかし,この手法は一般的に良好な結果を示さない.

パラメタ拘束とパラメタ共有

類似したタスクを,類似した入出力をもつ二つのモデルの重み  w_{i}^{(A)}, w_{i}^{(B)} があるとき,片方の学習時にもう片方の学習済みパラメタに近づけるように ノルムペナルティを課すことをパラメタ拘束といい, 完全に学習済みのパラメタと同じになるように学習することをパラメタ共有という.

畳み込みニューラルネットワーク

パラメタ共有最大の活躍の場は間違いなく畳み込みニューラルネットワークである. 特に画像認識において1ピクセルのずれても猫は猫である. そのため,入力全体に対して同様の重みを持つ隠れユニットを用いて計算することが有効となる.

スパース表現

下記のような正則化を用いることでパラメタのスパース表現が可能になる.

  •  L^{1} ノルムペナルティ
  • スチューデントのt事前分布から導かれたペナルティ
  • KLダイバージェンスペナルティ
  • 直行マッチング追跡

バギングやその他のアンサンブル手法

バギング(Bootstrap AGGregatING)はいくつかのモデルを組み合わせることで汎化誤差を 減少させる手法である. モデル平均化と呼ばれる機械学習の一般的な手法や. アンサンブル手法などが含まれる?

(この辺りの関係はイマイチわかっていないので後で調べるかもしれない)

モデル平均化は汎化誤差を削減する手法としては極めて強力で信頼できるものである.

ドロップアウト

ドロップアウトは最強である

ドロップアウトは大規模なニューラルネットワークに対して バギングを実用的に行う手法であると考えられる. 具体的な手法はランダムに隠れユニットからの出力が0になる場所を作成する. そして,出力のないユニットが覗かれたランダムなモデルを含んだアンサンブル学習を 近似的に行っていると見做すことができる.

ドロップアウトは重み減衰やスパース活動正則化といった標準的で 計算コストの低い他の正則化手法より効果的であることが示されている. ただし,訓練事例がニューラルネットワークに用いる標準的な量と比して, 極端に小さい場合はその限りではないという結果も得られている.

また,ドロップアウトを用いることで各隠れユニットは他の隠れユニットが どのようなものであろうとも性能を発揮できるように学習されるという利点もある.

敵対的学習

ニューラルネットワークは高い線型性を持っているため,入力値の小さな変化に対して 大きく反応してしまうことがある. 例えばパンダの画像にノイズを混ぜると, 人間はその画像をただのパンダの画像としか認知できないが, 元の画像ではパンダと認識できていた深層学習モデルはそれをテナガザルと推論することもある. この事例を逆手に取り,例えばノイズを加えた画像を訓練事例に含めていくことで 誤り率を減少させることが可能である.

接距離,接線伝播法,多様体接分類器

次元の呪いを克服するため,機械学習の分野では多様体仮説を元に学習を行うことが多い. 接距離アルゴリズムと接線伝播アルゴリズムはその仮説をそのままアルゴリズムに持ち込む. 特に接線伝播法はデータ集合拡張や二重逆伝播法,敵対的学習などと関係する.

まとめ

ドロップアウトと早期学習を組み合わせておけばなんかうまい感じによしなになりそうな説!

機械学習,誤差逆伝播法についてまとまらない

前回の続きで今回は深層順伝播型ネットワークにおける誤差逆伝播法についてまとめていく.

誤差逆伝播

順伝播型ネットワークでは訓練時,スカラー値の損失を得るまで順伝播を続ける. 損失を最小化することが訓練の目標であり,最小化するための重みの最適化に使われる情報が勾配である. 解析的に勾配を計算することは困難なため,誤差逆伝播法と呼ばれる手法を用いて導出する.

計算グラフ

説明には,図を用いた方がはるかにわかりやすいが面倒なので,リンクを貼り付ける.

https://qiita.com/t-tkd3a/items/031c0a4dbf25fd2866a3

微積分の連鎖律

基本的な微分の連鎖律は下式である.

 \frac{dz}{dx} = \frac{dz}{dy} \frac{dy}{dx}

これはスカラー以外にも一般化することができる.

 \nabla_{\mathbf{x}^{z}} = \left(
  \frac{\partial \mathbf{y}}{\partial \mathbf{x}} \right) ^ {\mathrm{T}}
  \nabla_{\mathbf{y}^{z}}

この式から変数  \mathbf{x} に関する勾配はヤコビ行列  \frac{\partial \mathbf{x}}{\partial \mathbf{x}} に勾配  \nabla_{\mathbf{y}^{z}} を掛けて求められることがわかる. 誤差逆伝播法はこのようなヤコビ行列と勾配の積をグラフ上の各演算で実行するように構成される.

MLPにおける誤差逆転伝播法

上述の連鎖律を使うことでMLPにおける任意の重みに勾配を届けることができる. その実装方法は毎回数値を扱うようなことはせず,シンボリックな表現で行われる. 厳密な計算方法はTorch, Caffeが「シンボルと数値間」の微分であり, Tehano, TensorFlowがシンボリックな記述をグラフに加える手法であるらしいが, 正直よくわからない.

一つの隠れ層に着目してどのように誤差逆伝播が行われていくかをみてみる. 簡単のため各層におけるバイアスを無視し,損失の計算に重みに関する正規化項はなしとする.

損失を  J , 子ノードから渡される勾配に隠れ層の活性化関数を考慮したものを  \mathbf{G} , その隠れ層における入力を  \mathbf{u_i} , その隠れ層における出力を  \mathbf{u_{i+1}} , その隠れ層の重みを  \mathbf{W} とすると

 \mathbf{u}_{i+1} = \mathbf{W}^{\mathrm{T}} \mathbf{u}_i

 \mathbf{G} = \frac{\partial J}{\partial \mathbf{u}_{i+1}}

 \frac{\partial \mathbf{u}_{i+1}}{\partial \mathbf{W}_i} =
  \mathbf{u}_{i}^{\mathrm{T}}

 \frac{\partial J}{\partial \mathbf{W}_i} =
  \frac{\partial \mathbf{u}_{i+1}}{\partial \mathbf{W}_i} \mathbf{G} =
  \mathbf{u}_i^{\mathrm{T}} \mathbf{G}

(えと,行列の微分ちとわからんすぎて最後の式間違ってる可能性がかなり高いです...)

MLPの演算は主に行列あるいはテンソルの加算,乗算,非線型関数の適用でできている. 上記の計算は乗算の場合を記述している.加算の場合はこれより単純なため割愛する. 非線形関数については誤差逆伝播を行いやすいように調整されたものが多い. 特にReLUなどは勾配において0以下のものを0にするという作業を行うだけである. このようにして計算グラフにおいて任意の点で勾配を計算する.

実際の実装ではここまでの簡略化は不可能なので,計算自体はかなりややこしくなる. またメモリやデータ型についても気を使う必要がある.

しれっと説明を回避した問題

  • メモリの管理
  • データ型
  • 単一ノードが複数出力を持つ場合
  • 誤差逆伝播方以外の自動微分が存在すること
  • 高次の微分(TensorFlow等で使用可能)

AtomでMarkdownのプレビューを同期

AtomMarkdown

筆者はAtomを愛用してそろそろ2年くらいなのだが, Markdownの自動スクロールをようやく動かせるようになったので共有したい.

ことの元凶は下記のpackageである.

atom.io

Google先生

atom markdown 自動スクロール
atom markdown sync scroll

などと打ち込んで検索してみてほしい.上記のpackageしか出てこないから. さらに混乱の元となるのは

atom Markdown

などと検索した時に大抵 AtomMarkdownを快適に使うための環境設定 的なページがヒットする. このようなサイトのほとんどで,上記packageが推奨されているのだ.

次に

markdown scroll sync error

とググってみよう.恐れずにGithub issueの英語を読み進める. 2, 3個目のページに神がいた.

github.com

答えは足元に転がっていたらしい.

AtomMarkdownPreview画面をEditor画面と同期

英語読むのだるいよ!って人,つまり日本人のほとんどのためにここに解決策を書いていこうと思う. 解決策は簡単で

atom.io

上記packageをインストールし,下記画像のように設定するだけである.

f:id:went-went-takkun135:20190518213305p:plain
markdown-pureview-plus setting

AtomMarkdownを描こうとする人は大抵すでに入れているpackageかと思うが, 念の為,注意点を上げておくと,このpackageはデフォルトのmarkdown-previewと競合するので, デフォルトの方はDisableするようにしよう.

Atom愛好家,あるいはAtomちょい好き派の方々のお役に立てれば幸いである.

機械学習,深層順伝播型ネットワークについてのざっくりしたまとめ

前回からとっても時間が空いてしまいましたが,機械学習の勉強の続きを上げていきたいと思います!

went-went-takkun135.hatenablog.com

深層学習

深層学習

  • 作者: Ian Goodfellow,Yoshua Bengio,Aaron Courville,岩澤有祐,鈴木雅大,中山浩太郎,松尾豊,味曽野雅史,黒滝紘生,保住純,野中尚輝,河野慎,冨山翔司,角田貴大
  • 出版社/メーカー: KADOKAWA
  • 発売日: 2018/03/07
  • メディア: 単行本
  • この商品を含むブログ (1件) を見る

目次

深層順伝播型ネットワーク

多層パーセプトロンとも言う. 順伝播型ネットワークの目的はある関数を近似することである. 線形モデルを拡張して非線形関数を表現する場合, x 自体に線形モデルを適用するのではなく非線型変換  \phi を用いて変換された入力  \phi(x) に対して線形モデルを適用する. 順伝播型ネットワークが非線型な関数を表現する例としてXORの学習がよく挙げられる. サポートベクターマシーンでは  \phi として無限次元の非常に汎用的な関数を用意したが, 深層順伝播型ネットワークではこの  \phi を学習することが関数近似の戦略となる. 順伝播型ネットワークの出力をネットワーク自体に戻すフィードバックのような 接続を含むように拡張されたものは回帰結合型ニューラルネットワークと呼ばれる.

コスト関数

最近のニューラルネットワークはほとんどの場合,最尤法を用いて訓練される. 最尤推定からコスト関数を導出することで,コスト関数の勾配が飽和しづらくなる.

出力ユニット

ほとんどの場合,コスト関数として,単純にデータ分布とモデル分布の間の交差エントロピーが利用されるため,出力の表現方法の選択によって黄砂エントロピーの関数の形が変わる.以下に代表的な出力ユニットを記す

  • ガウス出力分布のための線形ユニット
  • ベルヌーイ出力分布のためのシグモイドユニット
  • マルチヌーイ出力分布のためのソフトマックスユニット

その他の出力の種類として,条件付きガウス分布の分散を学習したい場合の不等分散モデルや,混合ガウス分布のための混合密度ネットワークなどがある.

隠れユニット

隠れ層の中で使用する隠れユニットについて言及する. 現在では,ReLUを使用することが一般的であるが,他にも多くの隠れユニットが利用可能である. 基本的な隠れ層ではベクトル  \mathbf{x} を受け取りアフィン変換  \mathbf{z} = \mathbf{W}^{\mathrm{T}} \mathbf{x} + \mathbf{b} を計算し,要素ごとに非線型変換関数  g(\mathbf{z}) を適用する. よって隠れ層の出力  \mathbf{h}(\mathbf{x})

  \mathbf{h} = g \left(\mathbf{W}^\mathrm{T} \mathbf{x} + \mathbf{b} \right)

となる.

ReLU

 g(z) = \mathrm{max} \{ 0, z \}

上式の活性化関数がReLUである.アフィン変換のパラメータを初期化する場合  \mathbf{b} のすべての要素を0.1などの小さい正の値に設定するとよく機能する.ReLUの問題点としては活性化値が0になるような事例が勾配に基づく学習をできない点である.

ReLUの一般化

ReLUの3つの一般化を以下に記す. 3つの一般化は  z \lt 0 となる場合にゼロでない勾配を得るために工夫されたものとなっている.

  h_i = g(z, \mathbf{\alpha})_i = \mathrm{max}(0, z_i) + \alpha_i\mathrm{min}(0, z_i)

つまり上式の通りとなる. \alpha の値を変えることでその特徴を変える

Absolute value rectification

上式の  \alpha_i = -1 である.よって  g(z) = |z| を得る.これは画像の中の物体認識に使用されている.物体認識では入力の光源の極性反転に対して普遍な特徴量を探すことが道理にかなっているためである.

Leaky ReLU

 \alpha_i = 0.01 として扱う.

Parametric ReLU

  \alpha_i を学習可能なパラメタとして扱う.

マックスアウトユニット

マックスアウトユニットはReLUをさらに一般化したものである.このユニットは活性化関数自を学習するものと考えられる.また,破壊的忘却に対抗する手段としても用いられる.正直よくわからん.

ロジスティックシグモイドとイドとハイパボリックタンジェント

0から離れると勾配に飽和が起きるため,現在の深層学習においてはあまり利用されていない.コスト関数で飽和を打ち消せる場合は使われる場合がある.一般的にハイパボリックタンジェントの方が訓練しやすい.

その他の隠れユニット

他にも多くの隠れユニットが存在するが,頻度は高くない.一般的なものを下記に記す.

  • 恒等関数
  • 同型基底関数
  • ソフトプラス
  • Hard tanh

アーキテクチャ設計

アーキテクチャ設計とはユニットの数やネットワーク全体の構造を意味する.

万能近似性と深さ

万能近似理論はネットワークが十分な数の隠れユニットを持つ場合,線形の出力層と押しつぶすことができる活性化関数を持つ隠れ層が少なくとも1つ含まれる順伝播型ネットワークはどんなバレル可測関数でも任意の制度で近似できると述べている.ただし,表現可能であることが保証されても学習可能であることは保証されていないことには注意が必要である.現在も万能近似理論の証明に関する研究は進んでいるが,ネットワークの深さや効率に関する疑問は解明されていない.

誤差逆伝播

長くなりそうなので,次に回します.できたらリンク貼ります.

I-O DATAのモニターで白い画面がちらつく問題への対処法

フリッカー

みなさんフリッカーをご存知だろうか? そう,かの有名な悪鬼ボクサー間柴が得意とするジャブ…ではなく,蛍光灯などで見られる,光源が高速で点滅している現象である.

視認できるかどうかに関わらず,このフリッカーのあるなしや強度はは人体の疲労感と相関があるらしい.

(ちなみに間柴のフリッカージャブは見極めることが難しい上に高強度で,人体の疲労感というか絶望感を蓄積させる!)

このフリッカー現象だが,筆者が使用しているサブディスプレイで散見されていた.白い画面になると画面が明るい→暗い→明るいと周期的に点滅する,ちらつくのである.本投稿はフリッカー現象をなんでか知らんが,止めることができたため共有しようというものである.

解決方法

なんでもいいから早くチラツキを消させろくださいの人のために先に解決策を書く.

ディスプレイの右下部にあるMENUで表示モードを「標準」から「写真」または「映画」に変える

これだけである.なんとも簡単.なぜ1年半も気づかずに放置していたのか.兎にも角にも同様の悩みを抱えている人がいれば試してみてほしい.

筆者の使用環境

ここからは筆者がなんでこうしたらチラツキがなくなったのか知りたいため詳細な情報を記述していく.詳しい人いたら教えてくださいお願いします.

筆者のディスプレイは下記のものである.

ちなみにこのディスプレイはそれなりにというかかなり人気で,

モニター おすすめ

とかでGoogle先生に聞くとすぐに出てくるものだ. その他の環境については下記の通りである.

  • MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
  • MacOS Mojave バージョン10.14.4
  • MOBO Type-C Multi Port Adapter
  • HDMIケーブル(High Speed対応)
  • 解像度: 1920x1080
  • フレッシュレート: 60Hz

最後に

当ディスプレイはフリッカーレスモデルとなっており,フリッカーが抑えられた設計であるとの記述を最近改めてみた結果,やはり我が家のディスプレイはおかしいと感じ,色々いじってみると,如何してかはわからないが現象は回避された.不思議すぎるので本当になぜか教えてくれる人いたらお願いします.

機械学習の基礎的な知識についてざっくりとしたまとめ

メリークリスマスイブ!
dondakeサンタによる重ためのクリスマスプレゼントです!

(学術的な)機械学習の基礎

現在、深層学習について勉強中です。 読んでいる書籍は以下になります。

今回、第一部がようやく終わったということで、少し振り返ります。 第一部では下記エントリーの数学の基礎部分と数値計算の基礎、 最後に機械学習の基礎について学びました。

went-went-takkun135.hatenablog.com

機械学習の基礎についてはkaggleに代表されるような技術的なものでも、 企業で使われているような実際的なものでもなく、 あくまで理論的なものになります。 そのため確率やら統計やらの話ばかりで多少イメージしづらかったですが、 論文等を読む際のしっかりとした基本ができたかと思います。 自分のために非常にざっくりと忘備録をつけていきます。

目次

学習アルゴリズム

学習の定義

「コンピュータプログラムは、性能指標Pで測定されるタスクTにおける性能が 経験Eにより改善される場合、そのタスクTのクラスおよび性能指標Pに関して 経験Eから学習すると言われている」

Mitchell(1997)

タスク T

一般的なタスクを列挙する

  • 分類
  • 欠損値のある入力の分類
  • 回帰
  • 転写
  • 機械翻訳
  • 構造出力
  • 異常検知
  • 合成とサンプリング
  • 欠損値補完
  • ノイズ除去
  • 密度推定

性能指標 p

機械学習アルゴリズムの能力を評価するためのものが必要である。 例えば、モデルの精度や誤差率などがこれに該当する。 学習に用いた訓練集合とは別のテスト集合を用いて評価する。

経験 E

機械学習アルゴリズムは大きく 教師あり学習教師なし学習 に 分類されるが、それらの厳格な境界や定義はない。 学習アルゴリズムはデータ集合を経験することで学習する。

線形回帰

学習アルゴリズムの中でシンプルで有名な例として線形回帰を取り上げる。

 \hat{y} = \mathbf{w}^{\mathrm{T}} \mathbf{x}

 \mathbf{w} は重みと呼ばれるパラメータであり、  \mathbf{x} は特徴量である。 訓練集合において、予測と正解の 平均二乗誤差 を最小化するような重みを求めることで、 データ集合からモデルが経験するということになる。 線形の簡単なモデルを扱っているため、微分方程式が正規方程式として知られる形になり、 一意に解が求まることがわかっている。

 \hat{y} = \mathbf{w}^{\mathrm{T}} \mathbf{x} + b

上記のようにインターセプト b を加えたものを線形回帰として扱うこともある。 この場合、  b はバイアスと呼ばれる。統計のバイアスとは異なる。

容量、過剰適合、歌唱適合

この章は汎化に対する話となる。 訓練集合から訓練誤差が最小になるように学習を行うのに対し、 汎化性能を測定するためにはテスト集合から汎化誤差(テスト誤差)を計算する。 訓練集合とテスト集合についてはi.i.d.仮定をおいた上で、学習アルゴリズムが目指すことは

  1. 訓練誤差を小さくする
  2. 訓練誤差とテスト誤差の差を小さくする

この二つの要素は機械学習における二つの中心的な課題に相当し、 それぞれ 過少適合過剰適合 と呼ばれる。 これらの度合いは モデルの容量 を変化させることで制御する。 任意の高い容量という最も極端な状態に到達するには、 ノンパラメトリックモデル の概念を導入する。パラメータが存在しないため、モデルの容量を縛る要素が存在しないモデルである。

ノーフリーランチ定理

データを生成する分布全てを平均すると、 どのアルゴリズムも過去に観測されていない点を分類する際の誤差率は同じになる という定理。 全ての分布を平均した場合、他の機械学習アルゴリズムよりも普遍的に良いと言える 機械学習アルゴリズムは存在しないと主張している。

正則化

モデルの容量を変更する以外で過少適合、過剰適合を制御する方法として 正則化 があげられる。 正則化とは他の解に対して優先度を表現する方法の総称である。 一般的には正則化項と呼ばれるペナルティをコスト関数に追加することでモデルを正則化する。

ハイパーパラメータと検証集合

ほとんどの機械学習アルゴリズムにおいて、挙動を制御するための設定値が存在し、 それらは ハイパーパラメータ と呼ばれる。 最適なハイパーパラメータを選ぶために 検証集合 が必要になる。 検証集合は訓練データから構成される。

ほとんどのデータ集合は訓練集合とテスト集合に分けられているが、 その中の訓練集合を訓練集合と検証集合に分割する。 訓練集合でモデルを学習、検証集合でハイパーパラメータの最適化を行い、 テスト集合でモデルの汎化性能を測定する。

定量、バイアス、バリアンス

点推定量

関心のある量について「最良の」予測を一つ提示する試みである。

バイアス

 \mathrm{bias}(\hat{\theta}_m) = \mathbf{E}(\hat{\theta}_m) - \theta

 \mathrm{bias}(\hat{\theta}_m) = 0 になるものは不偏と呼ばれ、好まれる推定量である。

分散と標準誤差

定量のバリアンスとは単に推定量の分散である。 推定量の分散や標準誤差は、潜在的なデータ生成過程からデータ集合を別々に再サンプリングする際に、 データから計算した推定量がどのように変化するかを示す尺度を提供する。

平均二乗誤差を最小化するためのバイアスとバリアンスとのトレードオフ

バイアスは関数やパラメータの真の値からの期待偏差を測定する。 バリアンスはデータのサンプル化の方法に起因すると考えられる期待推定力の偏差を測定する。 平均二乗誤差はこれら二つの誤差を組み込んだものである。

 \mathrm{MSE} = \mathbf{E} [ ( \hat{\theta}_{m} - \theta )^{2} ] = \mathrm{bias} ( \hat{ \theta }_{m}^{2} ) + \mathrm{Var} ( \hat{\theta}_{m} )

バイアスとバリアンスの関係は、モデルの容量や過少適合、過剰適合という機械学習の概念と 密接に関係している。

最尤推定

最尤推定を解釈する方法の一つとして、最尤推定は訓練集合で定義される経験分布とモデル分布の差を 最小化するとみなす方法がある。 最尤法は負の対数尤度(NLL)の最小化、交差エントロピーの最小化、KLダイバージェンスの最大化 として捉えることができる。

ベイズ統計

点推定に対し、予測を行う際に  \theta の取りうる値全てを考慮するものが考えられる。 この手法はベイズ統計の分野となる。 事前確率分布を先験的に仮定し、事例の経験によって、その分布を書き換えていくことで 値の分布を推定する。

最大事後確率(MAP)推定

パラメータの完全なベイズ事後分布を用いた推定を行うことが最も理にかなった手法ではあるが、 点推定を行うことが望ましい場合も多い。これを行う方法の一つとしてMAP推定が挙げられる。

教師あり学習アルゴリズム

確率的教師あり学習

最終的な出力を0~1の値に押し込むことで確率を予測することができる。

サポートベクトルマシン

線形回帰をベースとして、カーネルトリックと呼ばれる技法を用いることで、 非常に高い性能を発揮した手法。 データ集合が大きい場合、訓練の計算コストが高くなってしまうというデメリットがある。

その他の教師あり学習アルゴリズム

  • k近傍法
  • 決定木

教師なし学習アルゴリズム

古典的な教師なし学習はデータの、より単純な表現を探す手法ということができる。 より単純なに関する定義として

  • より低次元な表現
  • 疎な表現
  • 独立した表現

の三つが挙げられる。

主成分分析(PCA)

元の入力よりも次元が低い表現を学習し、 また成分が互いに線形な相関を持たない表現 (独立ではない)を学習する。 詳細は割愛。

k平均クラスタリング

k個のクラスタに分割し、疎な表現を実現する。 詳細は割愛。

確率的勾配降下法

1回のステップに対し、訓練集合の全てを用いては計算コストが大きくなってしまう。 したがって、アルゴリズムの各ステップにおいて、 訓練集合から一様に抽出されるサンプルのミニバッチをサンプリングし、 それら数百のデータを用いて1回の学習ステップを行うことで計算時間を軽減する。 この手法を確率的勾配降下法と呼び、 更新毎の計算量が訓練集合の大きさに依存しないというメリットを得る。

機械学習アルゴリズムの構築

  • データ集合の仕様
  • コスト関数
  • 最適化手順
  • モデル

上記4つを組み合わせることで機械学習アルゴリズムは構築される。

深層学習の発展を促す課題

次元の呪い

次元が大きくなると構成される空間が大きくなりすぎる。

局所一様と平滑化

機械学習アルゴリズムにおいて、ある正解データの近傍にあるものは その正解データと大きく変わらない値に学習されるように、 事前分布が仕込まれていることがほとんである。 その場合、正解データが多く集まっている場所に関しては極めてよく学習できても、 それ以外のデータが集まっていないだけで、同様の分布を持っている場所については 正しく予測できる保証がない。

多様体学習

多様体は連結した領域であり、各店の周りの近傍に関連づけられた点の集合である。 ある表現の整理の仕方によって次元が変わるということだと思われる。