今天要介绍的感知机是人类最早的人工智能模型,大概是 60、70 年前的模型了。 数十亿的神经元。神经元是人脑中相互连接的神经细胞,参与处理和传输化学和电信号。树突是接收其他神经元信息的分支。
细胞核或细胞体处理从树突收到的信号,轴突看做神经元用来发送信号的电缆。突触用于连接轴突和其他神经元树突。
受到
一个人的大脑有神经元启发 研究人员沃伦-麦卡洛克和沃尔特-皮茨在 1943 年发表了简化脑细胞的概念。这被称为麦卡洛克-皮茨(MCP)神经元。他们将这样的神经细胞描述为一个具有二进制输出的简单逻辑门。
多个信号到达树突,然后被整合到细胞体中,如果累积的信号超过某个阈值,就会产生一个输出信号,由轴突传递出去。
人工神经元
人工神经元是一个基于生物神经元模型的数学函数,每个神经元接受输入,分别对其进行称重,并将其相加,通过一个非线性函数来产生输出。
- 神经元是在生物神经元上进行建模的数学模型
- 人工神经网络的中基本单元
- 各个输入之间的权重是相对独立的
- 对于输入进行加权求和后,经过非线性激活函数作为输出
- 每个神经元内部具有一个内部状态和激活信号
- 每个神经元都可以接收到输入
- 两层上神经元彼此连接,同层上神经元之间不存在连接
感知机
感知机Perceptron 是由 Frank Rosenblatt 在1957年提出的。他在最初的MCP神经元的基础上提出了一个Perceptron学习规则。感知机(Perceptron)属于监督学习,是二分类器的算法。这种算法使神经元能够一次学习和处理训练集中的元素,那么这里定义感知机是一种算法。
感知机的分类
- 单层感知机: 单层感知器只能解决线性可分离的问题
- 多层感知机: 多层感知器具有两层或多层的前馈神经网络具,因此可以解决非线性这样更复杂的问题
感知机主要学习到一个分类边界,那么监督学习是机器学习一个类别,通过学习带有标注的数据来学习出一个可未知数据进行预测的模型,接下来一段时间我们都会讨论属于监督学习的模型
感知机学习策略
感知器该算法将自动学习到最优的权重系数,然后,输入特征与这些权重相乘,以确定一个神经元是否启动。
感知器接收多个输入信号,输入信号加权求和超过某个阈值,就输出这个信号,否则不输出这个信号。在监督学习和分类的背景下,这就可以用来预测一个样本的类别。
感知机函数
感知机输入是一个向量,权重也是一个向量而偏置 b 是一个标量,输出也是一个标量。
感知机激活函数
感知机解决 OR 问题
感知机计算过程
关于感知机会用到数据基础知识放在后面,如果大家需要可以去简单浏览一下。 接下来我们来解释一下整个计算过程,我们将样本数据集按 label=0 和 label=1 (这里 1 和 0 代表两个不同分类)划分为 P 和 N,这里 P 表示正例样本(label=1)相反 N 表示负例样本(label=0) 那么数据集可以表示为
我们首先随机生成一个权重 w,然后开始循环,每次循环会随机从 抽取一个样本,然后带入
- 如果这个样本是从 P 中抽取,而 则 结束循环再重新开始
- 如果这个样本是从 N 中抽取,而 则 同样结束循环再从新开始
感知机训练停止条件是,感知机看过所有数据后,都能把所有数据正确分类才会停止,这是一个现在看来比较奇怪的终止条件了。
另一个角度来看感知计算过程
这里我们从另一个角度来考虑,例如我们假设 那么如果 表示分类错误这更新参数 和
可以采用梯度下降方法来优化参数,那么对于梯度下降来说他损失函数又是什么呢?他损失函数就是下面的样子,批量大小为 1 的梯度下降。
感知机的局限性
通常对于感知机能够处理问题都是线性可分的,那么对于 XOR 问题,感知机也显得束手无措。
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 0 |
1 | 1 | 0 |
Minsky 在 1969 于感知机无法解决 XOR 问题,导致大家认为这么复杂的模型却无法解决这么简单问题,这直接导致感知机进入第一个寒冬。
感知机的收敛
数据在半径为 区域内,余量 分类二分类 分类正确且有一些余量,对于 感知机保证在 步后收敛。
代码实现
import numpy as np
from sklearn.datasets import make_classification
%pylab inline
这里生成数据集为
separable = False
while not separable:
samples = make_classification(n_samples=100, n_features=2, n_redundant=0, n_informative=1, n_clusters_per_class=1, flip_y=-1)
positive = samples[0][samples[1] == 0]
negative = samples[0][samples[1] == 1]
separable = any([positive[:, k].max() < negative[:, k].min() or positive[:, k].min() > negative[:, k].max() for k in range(2)])
plot(positive[:, 0], positive[:, 1], 'r.')
plot(negative[:, 0], negative[:, 1], 'b.')
len(negative)#500
正例和负例样本个 50 个,接下来我们要做的工作就是将这些数据变为 这种形式然后再进行一次打乱排序。
positive_dataset = np.ones(shape=(len(positive),3))
positive_dataset[:,:2] = positive
negative_dataset = np.zeros(shape=(len(negative),3))
negative_dataset[:,:2] = negative
dataset = np.concatenate((positive_dataset, negative_dataset), axis=0)
np.random.shuffle(dataset)
print(dataset[:10])
[[-0.23285037 -0.84531416 1. ]
[-1.55552102 1.00510574 0. ]
[-0.05428806 -0.88247394 1. ]
[-0.68219944 1.00128174 0. ]
[ 1.86808647 -0.61659097 1. ]
[ 0.0335378 -0.66812554 1. ]
[ 0.03028771 1.00533141 0. ]
[ 1.49430288 1.00160369 0. ]
[ 0.28867377 1.00009757 0. ]
[-0.23721778 0.99877196 0. ]]
def predict(sample, weights):
activation = weights[0]
for i in range(len(sample)-1):
activation += weights[i + 1] * sample[i]
return 1.0 if activation >= 0.0 else 0.0
activation
激活值,这里好处是包括偏置值在内
def train_weights(train, l_rate, n_epoch):
weights = [0.0 for i in range(len(train[0]))]
for epoch in range(n_epoch):
sum_error = 0.0
for row in train:
prediction = predict(row, weights)
error = row[-1] - prediction
sum_error += error**2
weights[0] = weights[0] + l_rate * error
for i in range(len(row)-1):
weights[i + 1] = weights[i + 1] + l_rate * error * row[i]
print('>epoch=%d, lrate=%.3f, error=%.3f' % (epoch, l_rate, sum_error))
return weights
weights
l_rate = 0.1
n_epoch = 5
weights = train_weights(dataset, l_rate, n_epoch)
print(weights)
>epoch=0, lrate=0.100, error=2.000 >epoch=1, lrate=0.100, error=0.000 >epoch=2, lrate=0.100, error=0.000 >epoch=3, lrate=0.100, error=0.000 >epoch=4, lrate=0.100, error=0.000 [0.0, -0.20158537856854422, 0.040592962030502784]
weights = [0.0, -0.20158537856854422, 0.040592962030502784]
for row in dataset[:10]:
prediction = predict(row, weights)
print("Expected=%d, Predicted=%d" % (row[-1], prediction))
Expected=1, Predicted=1
Expected=0, Predicted=0
Expected=1, Predicted=1
Expected=1, Predicted=1
Expected=1, Predicted=1
Expected=1, Predicted=1
Expected=1, Predicted=1
Expected=0, Predicted=0
Expected=0, Predicted=0
Expected=1, Predicted=1
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。