LoginSignup
5
6

More than 5 years have passed since last update.

全くの無知から誤差逆伝播法を理解するまで。

Last updated at Posted at 2019-01-30

随時更新

ディープラーニングについて学んでいると、必ず目にするのが誤差逆伝播法。
でもこれがなかなか理解できないので、理解するまでの過程をそのまま記事にしています。

正確性に欠けるところがあるかもしれませんが、少しでも同じことを学んでいる同志のためになればと思い筆を執ることにしました。
中学卒業レベルの知識があれば十分に理解できるように書くつもりです。

長いので、日をまたいで読んでもらったほうが身に付きやすいかもしれませんね。

わからないことがあれば聞いてくだされば、こたえられる範囲で答えますよ!

関数の表現

関数は中学生であれば、$y=2x$ などといった形で習ったでしょうが、
$f(x) = 2x$などの形であらわされることもしばしば…

ですが、難しいことはありません。
$f(x)$と言われたら、$y$とおんなじことなんだな~と思っておいてください。

ちなみに、$f$部分は$a$だったり$g$だったり知らない記号だったりしますが、
かっこがついていて、事前に$f(x) = ...$など($g(a) = a^2$とか$h(x) = 3x$とか)と定義されていたら関数なので注意しましょう。

$x$部分(変数)は、文字や、数字、式に置き換えることができます。
その場合関数中の$x$も()内に連動して指定した式が代入されます。

f(x) = 2x\\
\\
f(1 + y) = 2 \times (1 + y)\\
f(5) = 2 \times 5\\

といったかんじです。

なぜ、このような記法があるかというと、
例えば$y=2x$の$x$に値を代入して式中で使いたいとしましょう。
その時、

y_1 = 2\times1\\
y_2 = 2\times5\\
y_1+y_2

などといちいち立式したり、

2\times1 + 2\times5

という風に関数の枠を取り去ってしまうより、

y(x)=2x\\
y(1)+y(5)

と書いたほうがスマートなわけです。
こんな単純な式では実感しずらいでしょうけれど、実際に計算するときこれはとても役立ちます。

微分

概要

微分に関しては、いろいろなサイトで調べたほうがわかりやすいものがあるかもしれませんが、

  • グラフのある点の接線の傾きを求めるもの。
  • グラフの増加量の変化を求めるもの。

と思っておいてください。
これは特段難しいものではなく、習えば小学生でも活用できるようになるようなものなのでご安心を。

詳細

微分を理解するにあたって、まずはグラフのある点の接線の傾きを求めるものとして理解したほうがわかりやすそうです。

傾きってなんだったっけ?

傾きってなんだったっけ?という人。安心してください。そこからやります。

傾きとは、$x$が変化したとき、$y$はどれくらい変化するか?という値です。

まず、一次関数を考えましょう。
$y=ax+b$
でしたね。覚えている人は、もうわかったはずです。
$a$が傾きそのものなのです。変化の割合のほうがイメージしやすいでしょうか。

$y=ax+b$だとややこしいので$y=2x$として考えましょう。

簡単ですね。$2x$は$2 \times x$と同義ですから、
$y$は$x$の変化量(増加量)の$2$倍変化するはずです。

では$y=\frac{1}{2}x$では?
もちろん。$y$は$x$の変化量の$\frac{1}{2}$倍変化するはずです。

最初の式のように$y=ax+b$ならば、$y$は$x$の変化量の$a$倍変化するというわけですね。
Figure_1.png

傾きを求める。

傾きは、$yの変化量\div xの変化量$で求められます。それもそのはず。
$y=ax$を$a$について解く($a=$の形にする)と

\begin{align}
y&=ax\\
\frac{y}{x}&=a
\end{align}

になるわけですから、当然といえば当然です。

微分する

前置き

微分とは、グラフ上のある点の接線の傾きを求めることですから、

とりあえず接線のことは置いておいて$f(x) = x^2$の$(1,f(1))$から$(2,f(2))$を結ぶ直線の傾きを求めてみましょう。

\begin{align}
f(x) = x^2\\\\
\frac{f(2)-f(1)}{2-1}&=\frac{4-1}{2-1}\\
&=\frac{3}{1}=3
\end{align}

よって傾きは3です。

x squea.png


では次に$f(1)$から$f(1.5)$の傾きを求めてみましょう。

\begin{align}
f(x) = x^2\\\\
\frac{f(1.5)-f(1)}{1.5-1}&=\frac{2.25-1}{1.5-1}\\
&=\frac{1.25}{0.5}=2.5
\end{align}

よって傾きは2.5です。

x squea2.5.png


ん?と思ったそこのあなた。鋭い。では、試しに$f(1)$から$f(1.001)$の傾きを求めると…

\begin{align}
f(x) = x^2\\\\
\frac{f(1.001)-f(1)}{1.001-1}&=\frac{1.002001-1}{1.001-1}\\
&=\frac{0.002001}{0.001}=2.001
\end{align}

x squea 2.001.png

変化した値が小さければ小さいほど、より接線に近い直線であることがわかります。

本番

だったら、増加量が0なら!!!と、思いますがそう簡単にはいきません。

実際に計算してみるとわかりますが、0増加量が0だと0除算が発生してしまいます。
グラフで考えても、点が一点だと直線が確定しません。

ならば、限りなく小さい増加量での傾きを考えてみましょう。
ひとまず、その限りなく小さい増加量は$d$と表すこととしましょう。

こうなるとただの累乗ではなく、多項式(括弧で囲われた式)同士の計算をしなければならないので面倒ですが、分配法則さえ知っていれば解けるはずです。

\begin{align}
f(x) = x^2\\\\
\frac{f(1+d)-f(1)}{1+d-1}&=\frac{1+2d+d^2-1}{1+d-1}\\
&=\frac{2d+d^2}{d}=2+d
\end{align}

$\frac{f(1+d)-f(1)}{1+d-1}$から$\frac{1+2d+d^2-1}{1+d-1}$への変形が理解できない人は補足1を読んでください。

$2+d$において、$d$は限りなく小さいので、0と考えても良いはずです。
ですから、$x^2$において$x=1$の点の接線の傾きは$2$です。

x squea2.png

これで無事接線の傾きが求められました…

っと、ちょっと待ってください。
$2+d$において$d=0$なら$2$だ。 では問題があるのです。
何が問題かというと、$d=0$とすると途中式の$\frac{2d+d^2}{d}$が0除算になってしまいます。

えぇ・・・だったらどうするのさ・・・。大丈夫。そんな時は$\lim$を使います。
$\lim$の意味は

"-を限りなく~に近づける(極限)"

です。

\lim_{d \to 0}2+d=2

という記述になります。

これは、 $2+d$において$d$を限りなく$0$に近づけると2に(ほぼ)等しい
という式ですね。

$d \to 0$などは $\lim$ の下か右下にちっちゃく書きます。

これで0除算を回避できました。屁理屈みたいですが、とても重要な概念なので覚えておきましょう。

これで本当に接線の傾きが求められました。

一般化してみよう

微分が理解出来たら、今度は一般化(汎用化)に挑戦してみましょう。
一般化は、数値部分を文字に置き換えるだけで実現できるので、そう難しいことではありません。

上記の例では$x=1$の際の接線を求めていましたが、$x=a$の時の接線を求めてみましょう。

f(x)=x^2\\
\begin{align}
\frac{f(a+d)-f(a)}{a+d-a}&=\frac{a^2+2ad+d^2-a^2}{d}\\
&=\frac{2ad+d^2}{d}\\
&=2a+d\\
\lim_{d \to 0}2a+d&=2a
\end{align}

$x$が$a$の時の接線の傾きが求められましたね。実際に$a$に1を代入すれば2ですし、ほかの数値でも、その数値で微分したときと同じ結果が得られます。

まとめ

この一般化した関数を導関数と呼びます。

いかにも微分は数値を用いてするもののような説明をしましたが、実は微分というと、一般的にはこの導関数を求めることを言います。

導関数は、元の関数に$'$がついた形であらわされることが多いので覚えておきましょう。

f'(x) = \lim_{d \to 0}\frac{f(x+d)-f(x)}{x+d-x}

導関数(微分された関数)の表現

導関数(微分された関数)は$\frac{dy}{dx}$などと表されることもあります。
この、$dy$,$dx$,というのは、それぞれ、$y$の増加量、$x$の増加量という意味です。($d \times x$という意味じゃありませんよ)
$d$は$\Delta$(デルタ)の頭文字ですね。$\Delta$は数学においては差を表すときによく使われます。

増加量$y$/増加量$x$なので、被除数($y$)は関数を適用した際の増加量、除数($x$)は増加量です。

\frac{dy}{dx}=\lim_{d \to 0}\frac{y(x+d)-y(x)}{x+d-x}=y'(x)

(y(x)は何らかの関数とする)

ですね。式を見ると割と直感的にわかりやすいですね。

分母に二つある項が分母。
分子の一番外側の関数が分子。

こっちのほうがわかりやすい時もあるのでぜひ覚えておきましょう。

このとき、yをxで微分するといった表現をします。

表現の活用と偏微分

ここからはあまり自信はないのですが

$t=x+y$もしくは$t(x,y) = x+y$のような複数の文字(変数)がある関数において
$\frac{dt}{dx}$のような表現は$x$単体の変化に対する$t$の変化量(増加量)です。$y$の値の変化は考慮されず、固定された値(定数)となります。このような計算を偏微分と呼びます。
この時、xについて偏微分した偏導関数は$\frac{dt}{dx}$以外にも$t_x(x,y)$や、$\frac{\partial t}{\partial x}$と表されます。

$d$と$\Delta$,$\delta$,$\partial$はだいたい同じと覚えておくと役立つかもしれません。

t(x,y)=x+y\\
\\
\begin{align}
t_x(x,y)=\frac{\partial t}{\partial x}&=\frac{t(x+d,y)-t(x,y)}{x+d-x}\\
&=\frac{(x+d+y)-(x+y)}{x+d-x}\\
&=\frac{d}{d}\\
&=1
\end{align}

微分公式で効率的に微分しよう。

これに関しては覚えるしかありません。

こちらのサイトがわかりやすくまとめられているので覗いてみるといいでしょう。

連鎖律

連鎖律は英語で"chain rule"と書きます。連鎖律よりはわかりやすいですね。
その名の通り、連鎖するときのルール(法則)です。
名前はちょっと難しげなので、とっつきずらいかもしれませんが基本はこれ。

複数の関数が合成された合成関数を微分するとき、その導関数がそれぞれの導関数の積で与えられるという関係式のこと。

https://ja.wikipedia.org/wiki/%E9%80%A3%E9%8E%96%E5%BE%8B

だそうです。わかりませんね。
まず、"合成関数"から紐解いていきましょう。

合成関数

合成関数とは、関数を用いた関数のことです。なんのことやらですね。

具体的には、

f(x) = x^2\\
g(x) = 2x\\

f(g(x)) = (2x)^2 = 4x^2\\
g(f(x)) = 2(x^2) = 2x^2

としたときの、$f(g(x))$と$g(f(x))$です。引数が関数ですね。

$f(g(x))$は $(f \circ g)(x)$ なんかと表されることもあります。同様に
$g(f(x))$は $(g \circ f)(x)$ ですね。

ほかにも、

f(x) = x^2\\
g(x) = 2 \times f(x) = 2x^2\\

の$g(x)$や、

v = x^2\\
w = 2v

の$w$なんかもそうでしょう。

基本的にはそれだけですが、注意すべき点は $(f \circ g)(x) \neq (g \circ f)(x)$ というところです。

連鎖律ってどんなもの

合成関数がわかったところで、連鎖律がどんなものか考えてみましょう。

連鎖律と調べると、まず

\frac{df}{dx}=\frac{df}{dg}⋅\frac{dg}{dx}

※$⋅$は$\times$と同義です。
 $x$とややこしいため、$⋅$が使われることがあります。

のような数式が出てくると思います。この意味を紐解きましょう。

式を読む

df/dx

$\frac{df}{dx}$は 合成関数$f(g(x))$または$(f \circ g)(x)$ を $x$で微分するということです。
合成関数は一つの関数ですからひとまず$j(x)$として置いておきましょう。

$f(g(x))=(f \circ g)(x)=j(x)$となると$j(x)$を$x$で微分すると
$j'(x) = \lim_{h \to 0}\frac{j(x+h)-j(x)}{x+h-x}$
ですからなんてことはない普通の微分ですね。

一応$j(x)$を$f(g(x))$に置きなおした式も置いておきます。
$(f(g(x)))' = \lim_{h \to 0}\frac{f(g(x+h))-f(g(x))}{x+h-x}$
※大抵、合成関数の導関数は$(f(g(x)))'$や、$(f \circ g)'(x)$と記述します。

df/dg

$\frac{df}{dg}$は $f(g(x))$を$g(x)$で微分するということです。

$g(x)$が式中で変動することはないのでひとまず$c$としてみてみましょう。
$f'(c) = \lim_{h \to 0}\frac{f(c+h)-f(c)}{c+h-c}$
やっぱり普通の微分ですね。

一応$c$を$g(x)$に置きなおしましょう。
$f'(g(x)) = \lim_{h \to 0}\frac{f(g(x)+h)-f(g(x))}{g(x)+h-g(x)}$
式が多少複雑にはなりましたが、やってることは同じです。

dg/dx

最後に至ってはほんとにただの微分です。
一応式だけ置いておきます。

$g'(x) = \lim_{h \to 0}\frac{g(x+h)-g(x)}{x+h-x}$

まとめ

「全部おんなじじゃないですか!」
はい、同じに見えますが違います。全部おんなじ微分なのでわかりずらいかもしれませんが、導関数をよく見てみましょう。

  • $\frac{df}{dx}=(f \circ g)'(x)$ は合成関数の導関数
  • $\frac{df}{dg}=f'(g(x))$は$f'(c)$と置き換えられましたから、f(x)の導関数
  • $\frac{dg}{dx}=g'(x)$でしたからg(x)の導関数

です。ですから

あの式が何を言っていたかというと、

合成関数$f(g(x))$の導関数は、
合成関数の一番外側の関数$f( g(x) )$を内側の関数$g(x)$で微分した導関数
合成関数の一つ内側の関数$g(x)$の導関数の積は等しい。

と言っているのです。もっとフラットに言えば、

合成関数の導関数は、構成する関数の導関数の積に等しい。
でしょうか。

注意点

$\frac{df}{dx}=\frac{df}{dg}⋅\frac{dg}{dx}$において、
乗算といいましたし、実際分数同士の乗算の(分子と分母が相殺する)ような挙動(覚える分にはそのような認識は悪ではありません。)
を見せていますが、実際には
$\frac{df}{dg}$の$dg_1$と$\frac{dg}{dx}$の$dg_2$は等しくありません。実際に式を見てみましょう。

\lim_{h \to 0}\frac{f(g(x)+h)-f(g(x))}{g(x)+h-g(x)}\\
dg_1 = g(x)+h-g(x)\\
\lim_{h \to 0}\frac{g(x+h)-g(x)}{x+h-x}\\
dg_2 = g(x+h)-g(x)\\
g(x)+h-g(x) \neq g(x+h)-g(x)

同じ値ではありませんね。

実際に簡単な演算をしてみよう

連鎖律が事実であることを確認するために、実際に関数がなければ始まりません。
各自好きな関数を二つとそれらの合成関数を決めてもらいましょう。

この記事では$f(x)=x^2$,$g(x)=2x$合成関数は$f(g(x))$とします。

合成関数を微分してみましょう。

$f(g(x))=f(2x)$ですから、$(2x)^2=4x^2$ですね。
微分公式により$(f \circ g)'(x) = 8x$です。

それぞれの関数を微分してみましょう。

f'(g(x))

$f(g(x))$を$g(x)$で微分しますから、微分公式より$2 ・ g(x)$です。よって$2 \times 2x = 4x$ですので、
$f'(g(x)) = 4x$です。

ここの操作の注意点は、そのまま$2x$ではなく、$2$に$g(x)$をかけなければならないという点でしょうか。私はここで躓きました。

微分公式を使うときはは$g(x)$などを$c$などに置き換え公式を適応し、のちに元の形に戻して計算すると間違えが減りそうです。

もう一つは、関数に数を掛けるという操作。これは$g(x)$を$g$としてイメージしましょう。
$g=2x$ですので、$2 \times g = 2 \times 2x$です。

g'(x)

次に$g(x)$を$x$で微分します。$2x$なので微分公式より$g'(x) = 2$です。

結局連鎖律って成立するの?

$f'(g(x)) ・ g'(x) = 4x \times 2 = 8x$
導関数の積は$8x$。実際に微分した結果も$8x$だったので連鎖律は成立しました。
補足3にて、g(f(x))でも成立するか実際に演算しているので良ければご覧ください。

連鎖律の連鎖

合成関数といっても、何もすべての合成関数は二つの関数によって構成されているとは言えません。
たとえば、$h(g(f(x)))$だって、二つの関数ではありませんが、合成関数なわけです。
※$h$,$g$,$f$は何らか単変数関数

でも大丈夫。見方を変えてみましょう。

$h((g \circ f)(x))$

内側の二つの関数を一つの関数として考えてしまいましょう。すると、

( h((g \circ f)(x)) )' = h'((g \circ f)(x)) ・ (g \circ f)'(x)

ですから、さっき(2関数の時)と何ら変わりません。次に、式中の合成関数も連鎖律に従って変形してみましょう。

\begin{align}
( h((g \circ f)(x)) )' &= h'((g \circ f)(x)) ・ g'(f(x)) ・ f'(x)\\
&= h'(g(f(x))) ・ g'(f(x)) ・ f'(x)
\end{align}

よって、連鎖律の、

合成関数の導関数は構成する関数の導関数の総積に等しいという原則は成り立つこととなります。

\frac{dh}{dx}=\frac{dh}{dg}・\frac{dg}{df}・\frac{df}{dx}

参考

https://ja.wikipedia.org/wiki/%E9%80%A3%E9%8E%96%E5%BE%8B
https://qiita.com/namitop/items/c0c3a1a873f1bc53f36e
https://qiita.com/namitop/items/31326293c92522cf11c1
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1116364326
http://www.geisya.or.jp/~mwm48961/kou3/complex_fun1.htm
https://www.youtube.com/watch?v=CHf7CS8FMQs
https://atarimae.biz/archives/19410

補足

補足1

$\frac{f(1+d)-f(1)}{1+d-1}$から$\frac{1+2d+d^2-1}{1+d-1}$へは、$f(1+d)$が$1+2d+d^2$に変形しています。
途中式を省かずに書いてみましょう。

$f(x) = x^2$

\begin{align}
&=(1+d)(1+d)\\
前の括弧を後ろの括弧へ分配\\
&=1(1+d)+d(1+d)\\
&=1+d+d+d^2\\
&=1+2d+d^2\\
\end{align}

わかりましたか?わからなければ、乗法公式で検索してみましょう

補足2

f(x)=x^2\\
\begin{align}
\frac{f(2+d)-f(2)}{2+d-2}&=\frac{4+4d+d^2-4}{d}\\
&=\frac{4d+d^2}{d}\\
&=4+d\\
\lim_{d \to 0}4+d&=4
\end{align}\\
f'(a)=2a\\
f'(2)=4\\

補足3

f(x) = x^2\\
g(x) = 2x
\begin{align}
g(f(x)) &= g(x^2)\\
&= 2(x^2)\\
&= 2x^2\\
(2x^2)' &= 4x
\end{align}
\begin{align}
g'(f(x)) &= _{f(x)}(2 \times f(x))\\
&= 2\\
\end{align}
\begin{align}
f'(x) &= (x^2)'
&= 2x
\end{align}
(g \circ f)'(x) = 4x = 2 \times 2x
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6