0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ゼロから作る DeepLearning(Go) Part.2 ~ パーセプトロン ~

Posted at

ゼロから作る DeepLearning(Go) Part.2 ~ パーセプトロン ~

はじめに

こんにちは。みです。

これは、「ゼロから作る DeepLerning ①」を Python ではなく、GO を使用してまとめてみた内容です。
参考:ゼロから作る DeepLerning ①

良ければご覧ください。

****↓ 前回はこちら ↓****
前回:ゼロから作る DeepLearning(Go) Part.1

***************

目次

  1. Python 入門(GO での代用)
  2. パーセプトロン  ← 今回はこちら ★
  3. ニューラルネットワーク
  4. ニューラルネットワークの学習
  5. 誤差逆伝播法
  6. 学習に関するテクニック
  7. 畳み込みニューラルネットワーク
  8. ディープラーニング

パーセプトロン

2.1 パーセプトロンとは

「人口ニューロン」、「単純パーセプトロン」と呼ばれるもの。
複数の信号を入力として受け取り、一つの信号を出力する。
信号とは、電流や川の持つ、「流れ」のイメージ。
電流が同船を流れ、電子を策に送り出すように、パーセプトロンの信号も流れを作り、情報を先へと伝達していく。

二つの信号を受け取るパーセプトロンの例

perceptron.png

$x_1,x_2$は入力信号。
$w_1,w_2$は重み。(w は weight の頭文字。)
図の〇は、「ニューロン」や「ノード」と呼ばれます。
入力信号は、ニューロンに送られる際その固有の重みが乗算される。($w_1x_1,w_2x_2$)
ニューロンでは、送られてきた信号の総和が計算される。
→ その結果ある限界値を超えた場合にのみ、1を出力する。
この限界値を閾値(いきち)と呼び、$\theta$で表す。
以上のことを数式で表すと以下のようになる。

二つの信号を受け取るパーセプトロンの数式

$$
y=
\begin{cases}
0\quad(w_1x_1 + w_2x_2 \leqq\theta) \
1\quad(w_1x_1 + w_2x_2 >\theta)
\end{cases}
$$

パーセプトロンは、複数ある信号のそれぞれに重みを持つ。
重みは、各信号の重要性をコントロールする要素である。
$w_1 > w_2 $の時、$w_1$の信号の重要性は高くなる。

2.2 単純な論理回路

2.2.1 AND ゲート

AND ゲートとは、2 つの入力が 1 のときのみ 1 を出力する。

AND ゲートの真理値表
$x_1$ $x_2$ y
0 0 0
0 1 0
1 0 0
1 1 1

2.2.2 NAND ゲートと OR ゲート

NAND ゲートとは、NOT AND を意味する。
AND ゲートを逆にしたもの。

NAND ゲートの真理値表
$x_1$ $x_2$ y
0 0 1
0 1 1
1 0 1
1 1 0

OR ゲートは、入力信号が少なくとも一つでも 1 があれば、1 を出力する。

OR ゲートの真理値表
$x_1$ $x_2$ y
0 0 0
0 1 1
1 0 1
1 1 1

2.3 パーセプトロンの実装

2.3.1 簡単な実装

ANDゲートの実装
perceptron.go
func And(x1 float64, x2 float64) {
	fmt.Printf("x1 = %g,x2 = %g\n", x1, x2)
	w1, w2, theta := 0.5, 0.5, 0.7
	tmp := x1*w1 + x2*w2
	fmt.Printf("result:")
	if tmp <= theta {
		fmt.Println(0)
	} else {
		fmt.Println(1)
	}
}
main.go
func main(){
    And(0, 0) //0を出力
    And(1, 0) //0を出力
    And(0, 1) //0を出力
    And(1, 1) //1を出力
}
結果
$ go run main.go
    x1 = 0,x2 = 0
    result:0
    x1 = 1,x2 = 0
    result:0
    x1 = 0,x2 = 1
    result:0
    x1 = 1,x2 = 1
    result:1

2.3.2 重みとバイアス導入

AND ゲートは単純なので、実装が簡単でしたが、別の実装方法に変更する。
$\theta$→-b (バイアス)に変更する。

変更後パーセプトロンの数式

$$
y=
\begin{cases}
0\quad(b + w_1x_1 + w_2x_2 \leqq0) \
1\quad(b + w_1x_1 + w_2x_2 >0)
\end{cases}
$$

2.3.3 重みとバイアスによる実装

$\theta$を b に変更し、gonum を使用して AND,NAND,OR ゲートを実装する。

ANDゲートの実装
perceptron.go
func (p *perceptron) And(x1 float64, x2 float64) float64 {
	x := mat.NewDense(1, 2, []float64{x1, x2})
	w := mat.NewDense(1, 2, []float64{0.5, 0.5})
	b := -0.7
	tmp := mat.Sum(p.calc.MulElem(x, w)) + b
	if tmp <= 0 {
		return 0
	} else {
		return 1
	}
}
main.go
	fmt.Println("AND")
	fmt.Println(m.p.And(0, 0)) //0を出力
	fmt.Println(m.p.And(0, 1)) //0を出力
	fmt.Println(m.p.And(1, 0)) //0を出力
	fmt.Println(m.p.And(1, 1)) //1を出力
結果
$ go run main.go
    AND
    0
    0
    0
    1
NANDゲートの実装
perceptron.go
func (p *perceptron) NotAnd(x1 float64, x2 float64) float64 {
	x := mat.NewDense(1, 2, []float64{x1, x2})
	w := mat.NewDense(1, 2, []float64{-0.5, -0.5})
	b := 0.7
	tmp := mat.Sum(p.calc.MulElem(x, w)) + b
	if tmp <= 0 {
		return 0
	} else {
		return 1
	}
}
main.go
	fmt.Println("NAND")
	fmt.Println(m.p.NotAnd(0, 0)) //1を出力
	fmt.Println(m.p.NotAnd(0, 1)) //1を出力
	fmt.Println(m.p.NotAnd(1, 0)) //1を出力
	fmt.Println(m.p.NotAnd(1, 1)) //0を出力
結果
$ go run main.go
    NAND
    1
    0
    0
    0
ORゲートの実装
perceptron.go
func (p *perceptron) Or(x1 float64, x2 float64) float64 {
	x := mat.NewDense(1, 2, []float64{x1, x2})
	w := mat.NewDense(1, 2, []float64{0.5, 0.5})
	b := -0.2
	tmp := mat.Sum(p.calc.DivElem(x, w)) + b
	if tmp <= 0 {
		return 0
	} else {
		return 1
	}
}
main.go
	fmt.Println("OR")
	fmt.Println(m.p.Or(0, 0)) //0を出力
	fmt.Println(m.p.Or(0, 1)) //1を出力
	fmt.Println(m.p.Or(1, 0)) //1を出力
	fmt.Println(m.p.Or(1, 1)) //1を出力
結果
$ go run main.go
    OR
    0
    1
    1
    1

2.4 パーセプトロンの限界

パーセプトロンを用いれば、三つの論理回路を実装することができた。

2.4.1 XOR ゲート

XOR ゲート「排他的論理和」と呼ばれる論理回路。
$x_1$と$x_2$のどちらかが 1 の時だけ、1 が出力されます。
(排他的とは、自分以外は拒否することを意味する。)
これは、これまでのパーセプトロンでは、実現できない。

XOR ゲートの真理値表
$x_1$ $x_2$ y
0 0 0
0 1 1
1 0 1
1 1 0

AND、OR ができて、XOR が実現できない理由を視角的に考えてみます。

OR ゲートの視角的挙動

重み・パラメーター(b,$w_1$,$w_2$)=(-0.5,1.0,1.0)
式:

$$
y=
\begin{cases}
0\quad(-0.5 + x_1 + x_2 \leqq0) \
1\quad(-0.5 + x_1 + x_2 >0)
\end{cases}
$$

この式は、$ -0.5 + x_1 + x_2 = 0$の直線で分断された二つの領域を作成する。
図に表すと以下のようになる。
※図は大雑把なイメージです。

orgate.png

$(x_1,x_2) = (0,0)$の時 0(〇)
$(x_1,x_2) = (0,1),(1,0),(1,1)$の時 1(△)
すべて直線によって正しく分けることができる。

2.4.2 線形と非線形

XOR ゲートは、先の OR ゲートのように 1 本の直線では表すことができません。
※直線という制約をなくせば表すことができる。
図に表すと以下のようになる。
※図は大雑把なイメージです。
xorgate.png

パーセプトロンの限界は、1 本の直線で分けた領域だけしか表現できない点。
XOR ゲートの図のようなく曲線はパーセプトロンでは表現できない。
曲線による領域を非線形、直線による領域を線形と呼ぶ。

2.5 多層パーセプトロン

パーセプトロンは、層を重ねることで非線形を表現できるようになる!

2.5.1 既存ゲートの組み合わせ

XOR ゲートの表現を AND、NAND、OR を使用して表現してみる。
xor.png

上記の図が本当に XOR を実現できているのか真偽値表を埋めてみます。

XOR ゲートの真理値表
$x_1$ $x_2$ $s_1$ $s_2$ y
0 0 1 0 0
0 1 1 1 1
1 0 1 1 1
1 1 0 1 0

$x_1$、$x_2$、y に着目してみると、XOR ゲートの出力になっています。

2.5.2 XOR ゲートの実装

先ほどの XOR ゲートを Go で実装してみます。

xor.go
func (p *perceptron) XOr(x1 float64, x2 float64) float64 {
	s1 := p.NotAnd(x1, x2)
	s2 := p.Or(x1, x2)
	y := p.And(s1, s2)
	return y
}
main.go
	fmt.Println("XOR")
	fmt.Println(m.p.XOr(0, 0)) //0を出力
	fmt.Println(m.p.XOr(0, 1)) //1を出力
	fmt.Println(m.p.XOr(1, 0)) //1を出力
	fmt.Println(m.p.XOr(1, 1)) //0を出力
結果
$ go run main.go
    XOR
    0
    1
    1
    0

今回作成した XOR は多層構造になったネットワークでした。
層を複数重ねたパーセプトロンを多層パーセプトロンという
※AND、OR などは単層のパーセプトロン

2.6 NAND からコンピューターへ

多層パーセプトロンは、これまでの回路より複雑な回路を作成できる。
例)

  • 足し算を行う加算器
  • 2 進数を 10 進数に変換するエンコーダ
  • パリティチェック用の回路
  • コンピュータ

コンピュータの処理は、NAND ゲートの組み合わせだけで再現できる = パーセプトロンでも、コンピュータを表現できるということ。

2.7 まとめ

パーセプトロンはシンプルなので理解事態はしやすいものでした。
コンピュータのような複雑そうな処理をしているものが、意外とパーセプトロンを組み合わせるだけでできるとは驚きでした。。。
パーセプトロン、奥が深いです。

次回

Part.3:ニューラルネットワーク

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?