转自我和朋友们的微信公众号:AI圈终身学习(ID:AIHomie),欢迎加入打卡群一起学习。

不用框架,代码手撸深度神经网络,系列文章。适合零基础入门,更适合进阶。系列文章,提前关注不迷路,欢迎加入我们打卡学习。适宜人群:
- 深度学者初学者
- 有意向转行AI的IT从业者
- 对深度学习感兴趣的在校大学生
前言
上篇文章我们解释了什么是深度学习,以及神经网络。当然您可能觉得一头雾水,那是非常正常的。本节接着介绍神经网络的基本组成单元-感知器。
一、感知器是什么?
如图,红色加粗部分就是一个感知器:

我们把它抠出来,就变成了这个样子:

感知器为框里的部分,它不包括输入层。因此,其组成如下:
-
权重与偏置项 一个感知器有多个输入
,每个输入有对应的权重
, 此外有个偏置项
。
- 激活函数 感知器有很多种激活函数可选,我们暂时选择阶跃函数f做为激活函数:

所以我们的感知器最后得到的输出结果是:
可能您看得有点晕,俗话说一行代码胜千言,接下来我们用感知器实现一个与门(and)与或门(or)函数。
二、动手实现感知器
2.1 任务与数据介绍
这一节我们实现一个and函数。and函数非常简单,只有当两个输入都为1的时候,它的输出才为1,真值表如下:
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
因此我们的训练数据如下:
# 数据准备
def get_and_training_dataset():
x_train = [[0, 0], [0, 1], [1, 0], [1, 1]]
y_train = [0, 0, 0, 1]
return x_train, y_train
现在,我们有两个输入和
,最终我们获得的权重值是
,这个时候它就是and感知机。我们以输入
进行验证,其他输入请读者自己验算,结果如下:
那么这个权重值是怎么来的呢?这是一种叫梯度下降的训练方式更新出来的,流程如下:
- 第一步 初始化权重
和偏置项
为0.
- 第二步 迭代更新权重
和偏置项
,规则如下:
其中(读delta)叫学习率,
为正确的输出,
(读y hat)为预测的输出。如果这些符号看不懂没关系,直接看下一节的代码就明白了。
为什么是这样的更新规则,我们留在下一节讲,这里您只需要知道流程即可。
2.2 代码实现
import numpy as np
class Perceptron(object):
def __init__(self, input_feature_num, activation=None):
self.activation = activation if activation else self.sign
self.w = [0.0] * input_feature_num
self.b = 0.0
def sign(self, z):
# 阶跃激活函数:
# sign(z) = 1 if z > 0
# sign(z) = 0 otherwise
return int(z>0)
def predict(self, x):
# 预测输出函数
# y_hat = f(wx + b)
return self.activation(
np.dot(self.w, x) + self.b)
def fit(self, x_train, y_train, iteration, learning_rate):
# 训练函数
for _ in range(iteration):
for x, y in zip(x_train, y_train):
y_hat = self.predict(x)
self._update_weights(x, y_hat, y, learning_rate)
def _update_weights(self, x, y_hat, y, learning_rate):
# 权重更新, 对照公式查看
delta = y - y_hat
self.w = np.add(self.w,
np.multiply(learning_rate * delta, x))
self.b += learning_rate * delta
def __str__(self):
return 'weights: {}\tbias: {}'.format(self.w, self.b)
模型和数据我们都有了,接下来直接训练即可获得and感知器:
# 模型训练
x_train, y_train = get_and_training_dataset()
and_p = Perceptron(2)
and_p.fit(x_train, y_train, iteration=5, learning_rate=0.1)
最终预测输出如下:
# 预测数据
print('and 感知机权重:\n', and_p, '\n')
print('1 & 1 = %d' % and_p.predict([1, 1]))
print('1 & 0 = %d' % and_p.predict([1, 0]))
print('0 & 1 = %d' % and_p.predict([0, 1]))
print('0 & 0 = %d' % and_p.predict([0, 0]))

2.3 作业:实现一个or感知机
在这里(https://github.com/AIGroup-Z/deep-neural-network) 查看代码您会发现,我们在Jupyter Notebook上留了这个作业,你可以在我们的代码基础上实现它,以确认自己已经掌握了感知机。
三、结语
本节主要介绍了神经网络中的元单元-感知机,并且使用它做了一个与门与或门,不知道您觉得这节难度如何?好消息是恭喜你走出了深度学习的第一步,后面我们会介绍更加有趣的部分,并且将感知器用于实战当中,敬请期待。
参考资料:
- http://jzqt.github.io/2015/06/30/Markdown%E4%B8%AD%E5%86%99%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/#%E5%B8%8C%E8%85%8A%E5%AD%97%E6%AF%8D
- https://github.com/hanbt
如果您在阅读中有任何问题,您可以在我们的知识星球或者微信群里直接提问。欢迎加入我们微信群打卡学习。

网友评论