LoginSignup
1
2

More than 3 years have passed since last update.

Python&機械学習 勉強メモ④:バックプロパゲーションによる機械学習

Last updated at Posted at 2020-04-04

はじめに

https://qiita.com/yohiro/items/04984927d0b455700cd1
https://qiita.com/yohiro/items/5aab5d28aef57ccbb19c
https://qiita.com/yohiro/items/cc9bc2631c0306f813b5
の続き

バックプロパゲーションによる機械学習

出力層のニューロンの重みは、出力と正解の誤差を元に調整する。
また、出力層のニューロンの重みを元に、中間層のニューロンの重みを調整する。

中間層-出力層の重みの調整

中間層-出力層の重みの調整は以下の式で得られる

\delta_{mo} = (出力値 - 正解値) \times 出力の微分 \\
修正量 = \delta_{mo} \times 中間層の値 \times 学習係数

シグモイド関数の微分

上記式の「出力の微分」について、今回のニューラルネットワークの活性化関数に用いているシグモイド関数$f(x) = \frac{1}{1+e^x}$の微分は以下の式で得られる。

f(x)' = f(x)\cdot(1-f(x))

参考:https://qiita.com/yosshi4486/items/d111272edeba0984cef2

ソースコード

class NeuralNetwork:
    # 入力の重み
    w_im = [[1.0, 1.0], [1.0, 1.0], [1.0, 1.0]]  # [[i1-m1, i1-m2], [i2-m1, i2-m2], [bias1-m1, bias1-m2]]
    w_mo = [1.0, 1.0, 1.0]  # [m1-o, m2-o, bias2-0]
    # 各層の宣言
    input_layer = [0.0, 0.0, 1.0] # i1, i2, bias1
    middle_layer = [Neuron(), Neuron(), 1.0] # m1, m2, bias2
    ouput_layer = Neuron() # o

    def learn(self, input_data):

        # 出力値
        output_data = self.commit([input_data[0], input_data[1]])
        # 正解値
        correct_value = input_data[2]
        # 学習係数
        k = 0.3

        # 出力層 → 中間層
        delta_w_mo = (correct_value - output_data) * output_data * (1.0 - output_data)
        old_w_mo = list(self.w_mo)
        self.w_mo[0] += self.middle_layer[0].output * delta_w_mo * k
        self.w_mo[1] += self.middle_layer[1].output * delta_w_mo * k
        self.w_mo[2] += self.middle_layer[2] * delta_w_mo * k

入力層-中間層の重みの調整

入力層-中間層の重みの調整は以下の式で得られる。
後段ニューロンの調整結果をもとに前段ニューロンの重みを調整する方式にすることで、層がいくつであっても調整が可能。

\delta_{im} = \delta_{mo} \times 中間出力の重み \times 中間層出力の微分 \\
修正量 = \delta_{im} \times 入力層の値 \times 学習係数

ソースコード

class NeuralNetwork:
        ...
        # 中間層 → 入力層
        delta_w_im = [
            delta_w_mo * old_w_mo[0] * self.middle_layer[0].output * (1.0 - self.middle_layer[0].output),
            delta_w_mo * old_w_mo[1] * self.middle_layer[1].output * (1.0 - self.middle_layer[1].output)
        ]
        self.w_im[0][0] += self.input_layer[0] * delta_w_im[0] * k
        self.w_im[0][1] += self.input_layer[0] * delta_w_im[1] * k
        self.w_im[1][0] += self.input_layer[1] * delta_w_im[0] * k
        self.w_im[1][1] += self.input_layer[1] * delta_w_im[1] * k
        self.w_im[2][0] += self.input_layer[2] * delta_w_im[0] * k
        self.w_im[2][1] += self.input_layer[2] * delta_w_im[1] * k

学習結果

学習データとして以下を用意する
learning.png

上記で学習させたニューラルネットワークに以下のデータを放り込むと・・・

data_to_commit = [[34.6, 138.0], [34.6, 138.18], [35.4, 138.0], [34.98, 138.1], [35.0, 138.25], [35.4, 137.6], [34.98, 137.52], [34.5, 138.5], [35.4, 138.1]]

東京・神奈川どちらに分類されるかを判定できていることがわかる

Figure_1.png

1
2
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
1
2