# 深度学习炼丹术 —— Taoye不讲码德，又水文了，居然写感知器这么简单的内容

## 前言

• 到底什么是感知器啊
• 如何基于感知器实现逻辑电路以及异或问题的抛出
• 基于两层感知器完美解决异或问题

## 一、到底什么是感知器啊

“感知器，感知器”，既然它是带有一个“器”字，那么我们不妨将其看做一个“机器”？

$y = \begin{cases} 0, & w_1x_1+w_2x_2 \leq \theta\\ 1, & w_1x_1+w_2x_2 > \theta \\ \end{cases}$

$y = \begin{cases} 0, & w_1x_1+w_2x_2+b \leq 0\\ 1, & w_1x_1+w_2x_2+b > 0 \\ \end{cases}$

## 二、如何基于感知器实现逻辑电路以及异或问题的抛出

$y = \begin{cases} 0, & 0.6x_1+0.6x_2-0.9 \leq 0\\ 1, & 0.6x_1+0.6x_2-0.9 > 0 \\ \end{cases}$

import numpy as np
from matplotlib import pyplot as plt

%matplotlib inline

"""
Author: Taoye

Explain: 与门数据的可视化
Parameters:
x_data：数据的属性特征
y_label：数据属性特征所对应的标签
w_1，w_2：权重
b：偏执
"""
def show_result(x_data, y_label, w_1, w_2, b):
plt.scatter(x_data[:, 0], x_data[:, 1], c = y_label, cmap = plt.cm.copper, linewidths = 10)
line_x_1 = np.linspace(0, 1.2, 100)
line_x_2 = (-b - w_1 * line_x_1) / w_2
plt.plot(line_x_1, line_x_2)
plt.show()

"""
Author: Taoye

Explain: 阶跃函数
"""
def out(in_data):
return 0 if in_data < 0 else 1

"""
Author: Taoye

Explain: 模型计算结果
"""
def model(x_1, x_2, w_1, w_2, b):
return w_1 * x_1 + w_2 * x_2 + b

if __name__ == "__main__":
x_data = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y_label = np.array([0, 0, 0, 1])
for item in x_data:
model_result = model(item[0], item[1], 0.6, 0.6, -1.1)
out_result = out(model_result)
print('%d and %d = %d' % (item[0], item[1], out_result))
show_result(x_data, y_label, 0.6, 0.6, -1.1)


$\hat{y} = \begin{cases} 0, & w_1x_1+w_2x_2+b \leq 0\\ 1, & w_1x_1+w_2x_2+b > 0 \\ \end{cases}$

\begin{aligned} e& = \frac{1}{2}(\hat{y}-y)^2 \\ & = \frac{1}{2}(w_1x_1+w_2x_2+b-y)^2 \\ & = \frac{1}{2}(w^Tx+b-y)^2 \end{aligned}

\begin{aligned} E & = e_1+e_2+e_3+...+e_N \\ & = \sum_{i=1}^Ne_i \\ & = \frac{1}{2}\sum_{i=1}^N(w^Tx_i+b-y_i)^2 \end{aligned}

\begin{aligned} \frac{\partial E}{\partial w} & =\frac{1}{2}\sum_{i=1}^N\frac{\partial}{\partial w}(w^Tx_i+b-y_i)^2 \\ & = \sum_{i=1}^N(w^Tx_i+b-y_i)x_i \end{aligned}

\begin{aligned} \frac{\partial E}{\partial b} & =\frac{1}{2}\sum_{i=1}^N\frac{\partial}{\partial b}(w^Tx_i+b-y_i)^2 \\ & = \sum_{i=1}^N(w^Tx_i+b-y_i) \end{aligned}

\begin{aligned} & w^{new}=w^{old}-\eta\frac{\partial E}{\partial w}\ \\ & b^{new} = b^{old}-\eta\frac{\partial E}{\partial b} \end{aligned}

$\hat{y} = \begin{cases} 0, & 0.6x_1+0.6x_2-0.8 \leq 0\\ 1, & 0.6x_1+0.6x_2-0.8 > 0 \\ \end{cases}$

import numpy as np
from matplotlib import pyplot as plt

%matplotlib inline

"""
Author: Taoye

Explain: 与门数据的可视化
Parameters:
x_data：数据的属性特征
y_label：数据属性特征所对应的标签
w_1，w_2：权重
b：偏执
"""
def show_result(x_data, y_label, w_1, w_2, b):
plt.scatter(x_data[:, 0], x_data[:, 1], c = y_label, cmap = plt.cm.copper, linewidths = 10)
line_x_1 = np.linspace(0, 1.2, 100)
line_x_2 = (-b - w_1 * line_x_1) / w_2
plt.plot(line_x_1, line_x_2)
plt.show()

"""
Author: Taoye

Explain: 感知器处理数据
Parameters:
x_data：数据的属性特征
w：权重向量
b：偏执
Return：感知器处理之后的结果，为一个向量形式
"""
def out_result(x_data, w, b):
result = np.matmul(x_data, np.mat(w).T) + b
y = result > 0
return y.astype(np.int)

"""
Author: Taoye

Explain: 更新迭代w、b参数
Parameters:
x_data：数据的属性特征
y_label: 数据标签
max_iter: 最大迭代次数
learning_rate: 学习率
w: 权重参数
b：偏置参数
Return：训练完成之后最终的w，b参数
"""
def train(x_data, y_label, max_iter, learning_rate, w, b):
for i in range(max_iter):
result = out_result(x_data, w, b)
delta = np.mat(y_label).T - result
w = (w + (learning_rate * np.matmul(x_data.T, delta)).T)
b += (learning_rate * delta).sum()
return w, b

if __name__ == "__main__":
x_data = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y_label = np.array([0, 0, 0, 1])
w, b = train(x_data, y_label, 10, 0.1, np.array([1, 1]), 0)
print(w, b)
show_result(x_data, y_label, w[0, 0], w[0, 1], b)


## 三、基于两层感知器完美解决异或问题

OK，读者短暂的思考过后，想必都已经有了答案。再不济，通过排列组合也就只有六种填入情况，总能得到满足上述题目的要求。

• $s_1$表示的是基于与非门$x_1、x_2$的输出
• $s_2$表示的是基于或门$x_1、x_2$的输出
• $y$表示的是基于与门$s_1，s_2$的输出，也就是异或门最终的输出

1. 输入与门的四组信号，训练出满足与门的参数集$w_{11}、w_{12}、b_{1}$
2. 输入与非门的四组信号，训练出满足与非门的参数集$w_{21}、w_{22}、b_{2}$
3. 输入或门的四组信号，训练出满足或门的参数集$w_{31}、w_{32}、b_{3}$
4. 基于上述训练出的三组参数集，按照上面的模型结构来最终得到异或门的输出

import numpy as np
from matplotlib import pyplot as plt

%matplotlib inline

"""
Author: Taoye

Explain: 数据的可视化
Parameters:
x_data：数据的属性特征
y_label：数据属性特征所对应的标签
w_1，w_2：权重
b：偏执
"""
def show_result(x_data, y_label, w_1, w_2, b):
plt.scatter(x_data[:, 0], x_data[:, 1], c = y_label, cmap = plt.cm.copper, linewidths = 10)
line_x_1 = np.linspace(0, 1.2, 100)
line_x_2 = (-b - w_1 * line_x_1) / w_2
plt.plot(line_x_1, line_x_2)
plt.show()

"""
Author: Taoye

Explain: 感知器处理数据
Parameters:
x_data：数据的属性特征
w：权重向量
b：偏执
Return：感知器处理之后的结果，为一个向量形式
"""
def out_result(x_data, w, b):
result = np.matmul(x_data, np.mat(w).T) + b
y = result > 0
return y.astype(np.int)

"""
Author: Taoye

Explain: 更新迭代w、b参数
Parameters:
x_data：数据的属性特征
y_label: 数据标签
max_iter: 最大迭代次数
learning_rate: 学习率
w: 权重参数
b：偏置参数
Return：训练完成之后最终的w，b参数
"""
def train(x_data, y_label, max_iter, learning_rate, w, b):
for i in range(max_iter):
result = out_result(x_data, w, b)
delta = np.mat(y_label).T - result
w = (w + (learning_rate * np.matmul(x_data.T, delta)).T)
b += (learning_rate * delta).sum()
return w, b

if __name__ == "__main__":
x_data = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
and_label = np.array([0, 0, 0, 1])    # 与门的输出信号
no_and_label = np.array([1, 1, 1, 0])    # 与非门的输出信号
or_label = np.array([0, 1, 1, 1])    # 或门的输出信号

w_1, b_1 = train(x_data, and_label, 10, 0.1, np.array([0, 0]), 0)    # 感知器训练出与门的参数集
w_2, b_2 = train(x_data, no_and_label, 10, 0.1, np.array([0, 0]), 0)    # 感知器训练出与非门的参数集
w_3, b_3 = train(x_data, or_label, 10, 0.1, np.array([0, 0]), 0)    # 感知器训练出或门的参数集

no_and_predict = out_result(x_data, w_2, b_2)    # 与非门感知器模型的结果
or_predict = out_result(x_data, w_3, b_3)    # 或门感知器模型的结果
xor_predict = out_result(np.concatenate((no_and_predict, or_predict), axis = 1), w_1, b_1)    # 异或门感知器模型的结果

xor_label = np.array([0, 1, 1, 0])
for index in range(xor_label.size):    # 多层感知器解决亦或问题的验证
print("%d 亦或 %d = %d, " % (x_data[index, 0], x_data[index, 1], xor_predict[index]),
"%d == %d?, " % (xor_label[index], xor_predict[index]),
xor_label[index] == xor_predict[index])
`

[1] 《深度学习入门：基于Python的理论与实现》：斋藤康毅 人民邮电出版社
[2] 零基础入门深度学习- 感知器：https://www.zybuluo.com/hanbingtao/note/433855

posted @ 2020-12-18 21:18  玩世不恭的Coder  阅读(199)  评论(0编辑  收藏  举报