クロス エントロピー。 情報理論を視覚的に理解する (3/4)

【初学者向け】パープレキシティとは。クロスエントロピーとの関係も解説。|Beginaid

クロス エントロピー

4章 の学習 4章の導入では、やKNNといったの手法は人が特徴量(データの注目すべき点)を作りこむ必要がある(すなわち人が介在しなければならない)けれど、()は生データをそのまま学習させることができると書かれています。 個人的には「そうなの?」って思ったんですけど、よくよく考えるとこの本は画像認識を念頭に置いて書かれているので間違っていない気がします。 「この画像に写ってるのは何か?」って話だと確かにそうなのかなって。 (画像認識やったことないのでわかんないですが。 ) ただ、言語処理をやるだとか、多種多様なデータを複合して何かやろうだとかなると、人の手がかなり介在する気がします。 まあこれからの進展でなんでも出来るようになるかもしれませんけども。 4章も3章と同様に3つに分けて勉強していこうと思います。 その1 NNの学習指標:損失関数• その2 損失関数の最小化:数値と勾配法• その3 での勾配法の実装 今回は その1である損失関数のお話です。 損失関数 ではデータから最適な重みを探すための指標として、 損失関数(loss function)と呼ばれるものを用いています。 損失関数は、簡単に言うと NN の性能がどれくらい悪いかを示していて、こいつの値が小さいほど性能が良いと考えられるとのこと。 それで、本の中では損失関数を二つ挙げています。 ひとつは 二乗和誤差(Sum of Squared Error:SSE)、もうひとつが 交差誤差(Cross Entropy Error)です。 今回はこれらを紹介しつつ、何故損失関数を使うのかというところを見ていきます。 二乗和誤差(Sum of Squared Error:SSE) 以下の式で表されます。 (ここで、 は NN の出力、 は に対する正解を表します。 ) 読んで字の如く、(出力と正解の各成分の差の)二乗和による誤差(そういう日本語だと僕は解釈してます。 の方がしっくりきますが。 )です。 出力の各成分の正解との誤差を足し合わせる形なので、かなり分かりやすい誤差ですよね。 因みに絶対値ではなく二乗を使うのは統計的な根拠があるらしいです。 (参考:) あと、本だと何故か「 mean squared error」ってなってました。 の方もこれに準じてるし、にも載ってないけど定義は SSE なんですよね。 何でだろう.. 交差誤差(Cross Entropy Error) 以下の式で表されます。 二乗和誤差よりパッと見わかりにくいかもしれません。 この章での(もしかしたらこの本での?)前提として、 は one-hot (即ち、成分のうちひとつだけが1で他が0であるようなベクトル)、 は となるベクトルとなっています。 なんかこれだけ書くと分かりにくいですが、要は多クラス分類の話で、 は入力がクラス である確率であり、ベクトル の1が立っている場所は正解クラスを示します。 なので正解のクラスを とすれば、 となるので、実質は となります。 より、 は以下のようなグラフです。 1 ; ax. png" 見たら分かるとおり、 が小さいほど交差誤差は大きくなります。 正解であるクラスとなる確率が小さいほど誤差が大きくなるので直感的に自然ですね。 ところでだと、この交差誤差を訓練データに対する尤度から算出してました。 よりもすっきりするかもしれません。 実装 まあ式をそのまま書くだけなので工夫も何もって感じですが。 本当に本のままです。 logの中身が0になると -infになって怒られるので、微小量を加えてうまく誤魔化すのは大事なテクニックですね。 因みに、SSE は回帰問題、交差誤差は分類問題に用いることが一般的だそうです。 ミニバッチ学習 上で実装した損失関数は一個の訓練データに対するものでしたが、実際は沢山の訓練データに対して損失関数を適用し、その和(あるいは平均)を学習の指標とします。 式で書くとこんな感じです。 ただデータがめちゃくちゃたくさんあると、全部の訓練データについて損失関数を計算するのは結構コストがかかっちゃいます。 そこで、訓練データの一部を取り出して損失関数を計算し、それによって学習を行うことを考えます。 これを ミニバッチ学習と呼ぶそうです。 本の中だとミニバッチを取り出す操作を実際にやってみるのですが、前回使ったMnistの訓練データからランダムにデータを選択するだけなのでここで書くほどのコードではありません。 ただミニバッチ学習をする上で、numpyのデータから一部を選択する処理について本の中で高度な機能をさらっと使っていたので少し詳しく触れます。 「そこは遠慮したい」って方は。 numpy. ndarray はの通常のリストとは異なる要素へのアクセス方法を持っています。 詳しくは を参照ですが、ここでさらっと紹介。 その前に、共通の機能を見てみます。 arange 16. (スライシングは他にも色々使い方がありますが割愛。 ) こういった操作は と呼ばれるみたいです。 まあリストと共通の使い方ですしね。 でも numpy. ndarray はもうちょっと特殊なアクセス: ができます。 大きく二つありますが、先に1章にも登場する を紹介します。 この機能はかなり便利で、各行のデータに対してある条件を満たすものだけ残すといったことができます。 Aの2行目: [8 9 10 11] は、 なので除外されます。 numpy. これについては別の機会に書きます。 そして最後に紹介するのが です。 配列に配列を食わせるやり方で、こいつだけ結構特殊なのでくわしく書きます。 実は単純な例だけは1章にも登場していてます。 以下の例です。 print A[np. これだけ見ると、スライシングを個別にできるようになったみたいに見えます。 でも実際はそうじゃない。 自分の行の長さを超える配列を突っ込んだり、 print A[np. print A[np. array [ 2, 0, 3] ,np. 4章でいきなり複数食わせるやつが出てきたので「何じゃこりゃ!?」ってなりました。 本では結果しか説明してないんですよね。 (だからこの Advanced Indexing の節を書いてます。 そして、2次元配列に1次元配列を与える場合は、 「与えた i 番目の配列の j番目の要素が、結果の j 番目の要素の i 軸のインデックスになります。 自分で言っててこんがらがりました。 上の例( A[np. array [2,0,3] , np. array [0,2,1] ])で式展開みたいなことをすると、 A[np. array [2,0,3] , np. 与えた0番目の配列 [2 0 3]は結果の各要素の行のindexに、1番目の配列 [0 2 1]は各要素の列のindexに対応しています。 A[B454][C454]] となります。 配列 B,C の大きさ N に制限は無く、与えた配列と同じ大きさのものが結果として返ります。 ここが Integer array indexing の 最大の特徴だと思います。 Boolean array indexing は、ある配列から(条件を満たす) 一部の要素を抜き出す Indexing でした。 これに対し、Integer array indexing はある配列の 要素を使って新しい配列を作る Indexing と言えます。 注意すべき点は、与える配列の数に制限があるのに対して 形には制限が無いことです。 言い換えると、与える配列の次元は何でも構いません。 本ではスペースの都合上省かれてるんだと思うのですが、使う人は さらっとドキュメント見るのもいいんじゃないかなって思います。 ちなみに、Integer array indexing はもうちょい細かい話があるのですが、これ以上書くと更に本題から外れていくので割愛します。 なぜ損失関数を使うのか? 何の話してましたっけ?ああ、損失関数が今回のテーマでした。 えらく寄り道してしまいました。 冒頭に書いたことを繰り返すと、NNの最適な重みを探すために NN の性能の悪さを示す損失関数を使います。 でも、「そもそも性能の良し悪しなら精度を使えばよいのではないか?」という疑問が沸く人も居るはず。 でもそれでは学習がうまくできないという話。 SSE の方は回帰問題ならそのまま精度みたいなものだと思うので、おそらく著者が言いたいのは多クラス分類問題(例題の手書き文字認識とか)の精度は使うべきではないって話みたいです。 例えば手書き文字認識の場合、100枚中何枚正しく認識できたかを精度にすると、その精度は不連続な値になります。 (1000枚の場合は50. 以下はイメージ図です。 実は性能(performance)が少しずつ上がっていても、切りのいい数字にならないと精度(precision)には反映されないという感じ。 最適な重みを学習させる際には、重みを少しずつ変化させて一番性能が良くなるところを探します。 ただその指標が不連続だと、重みを少し変化させても指標が変化しないので学習仕様がない。 これが不連続な値(例:100中何枚正しく認識したか)を指標に使えない理由だそうです。 で、今回上げた SSE や交差誤差は連続関数なのでOKってわけです。 まとめ 今回は損失関数の話だった.. のですが、完全に Advanced Indexing 回でした。 今回は損失関数紹介するだけだったので正直書くモチベーションが低く、いつのまにか書きかけで二週間も放置してました。 完全にやらかした。 ただ、同時並行で勉強してるの方が法まで来ちゃったので、そろそろ実装も進めないとやばいということで復帰しました。 再出発ということで。 次回はによって損失関数を最小化する勾配法と、それを計算機上で実現する数値の話です。 実装も含んでるしまあ楽しい回になるのではないでしょうか。 ただ個人的な都合で今週中にに行きたいのでさらっと流すかもしれません。 いやそれなら Advance Indexing とか構ってる場合かって話ですけどね。 Integer array indexing についてもうちょい詳しく Integer array indexing は、要素を取り出す配列の次元数だけ配列を指定できます。 print A[np. array [ 0, 0, 0, 0] ,np. shape print "C's shape:", C. 配列の形を 後ろから見ていって、勝手によしなにしてくれます。 (詳しくはを参照。 ) 実際には、 A[B,C]が実行されたとき、B,C はそれぞれ以下の B2, C2 に拡張されます。 ところで、本編で 「 Integer array indexing は配列を複数食わせるのが一般的な形だ」みたいなことを言いました。 ドキュメントの方では、要素を取り出す配列の次元数と同じだけ配列を食わせるのを と呼んでいます。 上で挙げた例も、 2次元配列に配列を 2個食わせるので purely です。 じゃあ、本で出てきた2次元配列に一個だけ配列を食わせる、 print A[np. Numpy の Indexing のドキュメントでは、上記の Purely integer array indexing の後に、Integer array indexing と通常の indexing を組み合わせる、 が登場します。 これの挙動が、purely の方とは全然異なるかつ難しいので注意が必要です。 例には以下の 2次元配列 A を使います。 arange 1, 10. array [ 0, 2] ,:] 略さずに書くとA[np. ちなみに列方向に取り出したい場合は、 print A[:,np. まあ略記なのは良いとして、実際に何が起こってるのかがいまいちよくわかりません。 ここで注目したいのは、与えた配列が1次元なのに対して、結果が 2次元配列だということです。 Purely integer array indexing では、基本的に結果の配列の形状は与えた配列の形状と同じになります。 しかしながら A[np. array [0,2] ,:] で返るのは2次元配列です。 この時点で Purely と動きが異なることが分かります。 で、何が起きているのかをちょっと 直感的に考えてみます。 あくまでイメージなので、実際の処理とは全然異なることにご注意ください。 A[B,C] の場合は、結果の形状は B, Cと同じです。 ] A[? ] ] あとは結果の各要素 A[i][j]の形をしている について、行方向のインデックス i は B 、列方向のインデックス j は C によって決定するというイメージ。 ] A[B[1]][? 現時点の結果の配列の形状は 2, ですが、これが 2, 3 に変化。 ただ、Bの適用範囲がスライスによって広がっているというイメージです。 同じ流れで 今度は A[:, B] を考えてみると、最初のスライスでは一番上の次元の要が3とまではわかります。 内部の形がどうなるか分かりませんが、結果の各要素 A[i][j] の形 の i は この時点で確定です。 ] [? ] [? そして 0行目,1行目, 2行目それぞれにおいて、A[i][j]の j を Bが決めます。 ][B[0]] A[? Integer arrayを基準に考えて、それがスライスによって広がるというのが個人的なイメージです。 ] A[D[0][1]][? ] ] [ A[D[1][0]][? ] A[D[1][1]][? ] A[D[0][1]][? ] ] [ A[D[1][0]][? ] A[D[1][1]][? お詫びとか 勇み足で「続きを書きます!」って言ってたらえらいことになってしまった。 正直うまく説明できなくて悔しいです。 あと、めんどくさがって図を使わなかったせいで非常に見にくい点については申し訳ない。 ドキュメントの方も例示でわかるっちゃ分かるけど「これだ!」って表現が無くてけっこう書いてて困りました。 なんかすっきりした表現ができないんですよね。 実は今回はイメージを書いただけで、Combining advanced and basic indexing を完全に説明したわけではないです。 Indexing を行いたい配列の次元が増えてくると複数の配列と複数のスライスを食わせたいときがあって、並び方で挙動が変わったりするのですがそれについては別の機会に書きます。 イメージは完全についたんですがうまく説明できないので、またうまく説明できるようになったら Advanced Indexing の記事を書こうと思います。 多分 Advanced Indexingだけで2つくらい記事書けそう。 Tawara.

次の

出力層で使うソフトマックス関数

クロス エントロピー

「平均符号長」という観点から、この式を解釈してみます。 グラフを書いてみれば、この不等式が成り立つことはすぐに分かるかと思います。 これでシャノンの補助定理の骨子は証明できました。 続いて等号成立条件について考えます。 と、いきたいところなのですが、実はそう簡単にはいきません。 これを使ってもう一度証明してみましょう。 一度まとめておきます。 エントロピーの最大値 シャノンの補助定理を用いると、エントロピーが最大となる場合を簡単に求められます。 やってみましょう。 したがって、次の定理を得ます。

次の

ソフトマックス関数とシグモイド関数でのクロスエントロピー誤差関数について

クロス エントロピー

損失関数とは 損失関数とは何か 損失関数とは、2つの数値にどれだけの誤差(損失)があるかを計測する関数です。 例えば機械学習モデルを作成するにあたり、訓練用のデータ(x)とそれに対応する正解データ(t)があったとします。 ニューラルネットワークを作成し、そこにデータ x を渡すと、y が出力されますね。 そこで出力された y と、正解データである t にどれだけの誤差(損失)があるかを計測するのが、損失関数です。 なんのために損失関数を用いるのか 前の記事で、「学習」(自動で重みとバイアスを獲得すること)の重要性をまとめました。 その学習を行うために、損失関数は用いられます。 そもそもの機械学習の目的とは、最適な機械学習モデルを作成するということです。 では、最適な機械学習モデルとはどのようなものなのでしょうか。 モデルは一般的に、訓練用データを用いて作成されます。 このデータを x とした時、モデルに x を渡したときの出力を y とします。 優れたモデルとは、この時の出力 y が正解データ t と高い確率で一致するような計算を行うことができるモデルということができます。 しかし、初めから y と t が適合するモデルは作ることができません。 したがって、当面の間は y と t が近付くように(パラメータを調整することによって)モデルを調整しなければいけません。 では、 y と t がどれだけ異なっているかということをどのようにして計測すれば良いでしょうか。 そこで登場するのが、損失関数です。 損失関数は2つの引数をとり、その2値がどれだけ差分を孕んでいるか、ということを計算してくれます。 ですので、モデルを調整するたびに、新モデルの出力 y と 正解 t を損失関数に計算させて、その損失が 0 に近づけば近付くほど、モデルが優れたモデルになりつつある、と判断することができます。 以上の理由、モデルの出力を最適化する(学習させる)、という目的の下、損失関数が用いられます。 二乗和誤差 損失関数・二乗和誤差とは では具体的な損失関数について説明を行なっていきます。 紹介する一つ目の損失関数は「二乗和誤差」と呼ばれるものです。 名称から処理を推測すること人もいるかもしれません。 この損失関数は、モデルの出力 y と正解データ t をそれぞれ二乗し、その差分を誤差(損失)として返却するような関数になります。 数式 二乗和誤差は、次のような数式で表されます。 E 出力される損失値です。 カッコ内の計算結果を全て足し上げます。 対象データが k 個存在することを示しています。 y モデルから出力された値です。 k 個のデータそれぞれを対象とすることを示しています。 t モデルから出力された値に対応する正解データの値です。 k 個のデータそれぞれを対象とすることを示しています。 二乗和、という言葉から連想されるように、モデルの出力値 y と正解データ t のそれぞれの値を突合させ、その二乗をとる、という内部処理を持った構成です。 イメージ 図にすると、下記のようなイメージになります。 上の図は、モデルが最適されておらず、モデルからの出力が正解データと異なっている場合です。 モデル出力と正解との乖離がそのまま損失値に結びついてくるので、この場合における損失は 0. 43 と大きくなっています。 この場合、この損失が小さくなるようにパラメータを更新する必要があります。 上の図は、モデルが最適化されており、モデルからの出力と正解が一致している場合です。 モデル出力と正解との乖離が小さいので、損失値は 0. 03 ととても小さくなっています。 学習で目指すのは、このように損失が小さくなるようなパラメータを発見し、モデルに設定することとなります。 実装 では二乗和誤差の実装を行います。 import numpy as np 損失関数 損失関数は、ニューラルネットワークの性能の悪さを示す指標。 ネットワークの重みとバイアスに対して損失関数を求め、その損失が最小になるように重みとバイアスを 調整する、などのように使用する。 二乗和誤差 入力値と正解値の差を二乗し、その総和を求める。 総和が小さいほど、入力と正解が近いことを示す。 array [0. 1, 0. 2, 0. array [0. 7, 0. 2, 0. array [0. 3, 0. 3, 0. 3 0. 3 0. 4 ] 正解 [ 0 0 1 ] における二乗和誤差 : 0. 27 交差エントロピー誤差 損失関数・交差エントロピー誤差とは 機械学習における損失関数として、二乗和誤差と同様によく用いられるのが交差エントロピー誤差という関数です。 考え方は二乗和誤差と大きな違いはなく、モデルの出力と正解データとの乖離を測る関数です。 二乗和誤差は モデル出力値 から 正解データ値 を減算した値を二乗したものの総和を計算しましたが、交差エントロピー誤差では、 自然対数eを底とするモデル出力値のlog値と正解データ値を乗算したものの総和を、損失とします。 それは、このネイピア数 e が底になっている自然対数 log に秘密があります。 自然対数logx は、次のようなグラフで表されます。 自然対数logは、logに渡される x の値が 0 に近い時には絶対数の大きな出力を返し、 x の値が 1 に近いほど、絶対数が 0 に近い出力を返します。 すなわち、正解データ t が 1 の時、それに対応するモデル出力 y が 1 に近い数値を出力できていれば、 t と x の乗算結果は小さくなり、 x が 0 に近い誤った数値を出力していれば、 t と x の乗算結果は大きくなる、という論理です。 モデル出力 y の2番目は 0. 3 正解を判断できていない で、その log をとると -0. 49 となり、この正負をひっくり返した 0. 49 という値が損失として出力されます。 対して、こちらは正解を判定できている場合です。 上と同じように、モデル出力 y の2番目の値を見てみると 0. 8 となっており 正解を判定できている 、その log値は -0. 09 です。 先ほどと同じように損失を求めると、こちらの損失は 0. 09 と出力されました。 このように、二乗和誤差の時と同様に、正解を正しく判定できている場合に、損失が小さくなる、ことを確認できます。 実装 では最後に、交差エントロピー誤差の実装を行います。 array [0. 1, 0. 2, 0. array [0. 7, 0. 2, 0. array [0. 3, 0. 3, 0. 3 0. 3 0. 4 ] 正解 [ 0 0 1 ] における交差エントロピー誤差 : 0. 9162904818741863 次の問題 さて、このように損失関数を用いることで、現在のモデルが最適化されているかどうかを判定することができました。 損失が小さいほど優れたモデル(パラメータ)であると判断することができるので、モデルを構築するときは、この損失がなるべく小さくするようにパラメータを設定すれば良いのでした。 では、損失が大きかったとき、どのようにパラメータを変更すれば良いのでしょうか? その問題を解決するためには、「入力 x に関する損失関数の微分」 を求め、「微分値に従い、損失が小さくなる方向へパラメータを更新する」という手順を踏む必要があります。 ということで次回は、損失関数の微分や、パラメータの更新という点についてまとめていきたいと思います。 まとめ• 機械学習モデルのパラメータを最適化するために、学習を行う。 学習を行うために、損失関数を用いる。 損失関数は、特定のパラメータが設定されたモデルの出力と正解データを比較し、その損失を数値として算出することができる。 損失が少ないほど、優れたパラメータを設定できたモデルである、と判定することができる。

次の