概况:
在机器学习中,感知机(perceptron)是二分类的线性分类模型,属于监督学习算法。输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机对应于输入空间中将实例划分为两类的分离超平面。感知机旨在求出该超平面,为求得超平面导入了基于误分类的损失函数,利用梯度下降法 对损失函数进行最优化(最优化)。
感知机的学习算法具有简单而易于实现的优点,分为原始形式和对偶形式。感知机预测是用学习得到的感知机模型对新的实例进行预测的,因此属于判别模型。
感知机由Rosenblatt于1957年提出的,是神经网络和支持向量机的基础。
定义
假设输入空间(特征向量)为X=[x1,x2,x3,x…],输出空间为Y = [1,-1]。
输入 = X,表示实例的特征向量,对应于输入空间的点;
输出 = Y,表示示例的类别。
由输入空间到输出空间的函数为
f(x)=sign( w T w^T wTx+b)
称为感知机。其中,参数w叫做权值向量(weight),b称为偏置(bias)。表示 w T w^T wT 和x的点积
w
T
x
w^Tx
wTx=
w
1
w_1
w1∗
x
1
x_1
x1+
w
2
w_2
w2∗
x
2
x_2
x2+
w
3
w_3
w3∗
x
3
x_3
x3+…+
w
n
∗
w_n∗
wn∗
x
n
x_n
xn ,
w =
[
w
1
,
w
2
,
w
3
.
.
.
,
w
n
]
T
[w_1,w_2,w_3...,w_n]^T
[w1,w2,w3...,wn]T
sign为符号函数,即
s
i
g
n
(
x
)
=
{
+
1
,
A
≥
0
−
1
,
A
<
0
sign(x)=\left\{ \begin{aligned} +1&, A \ge 0 \\ -1&, A< 0 \end{aligned} \right.
sign(x)={+1−1,A≥0,A<0
感知机算法就是要找到一个超平面将我们的数据分为两部分。
超平面就是维度比我们当前维度空间小一个维度的空间, 例如:我们当前的维度是二维的空间(由数据维度确定,x有多少列就有多大的维度),那么超平面就是一维 的,即一条直线。如下图
代码实践:
1.引入库
#引入必要的包
import paddle
import numpy as np
import matplotlib.pyplot as plt
2.生成数据
np.random.seed(0)
num=100
#生成数据集x1,x2,y0/1
#随机生成100个x1
x1=np.random.normal(6,1,size=(num))
#随机生成100个x2
x2=np.random.normal(3,1,size=(num))
#生成100个y(全身不都是1哦)
y=np.ones(num)
#将生成好的点放入到一个分类中
class1=np.array([x1,x2,y])
class1.shape
#接下来生成第二类点,原理跟第一类一样
x1=np.random.normal(3,1,size=(num))
x2=np.random.normal(6,1,size=(num))
y=np.ones(num)*(-1)
class2=np.array([x1,x2,y])
#将(3,100)转成(100,3)
class1=class1.T
class2=class2.T
#画图看下数据长啥样
plt.scatter(class1[:,0],class1[:,1])
plt.scatter(class2[:,0],class2[:,1],marker='*')
3.数据处理
#将两类数据都放到一个变量里面
all_data = np.concatenate((class1,class2))
#将数据打乱
np.random.shuffle(all_data)
#看下数据长啥样
print(all_data)
可以看到数据都被打乱了,label的-1 和 1是乱序的。
print(all_data.shape)
#截取出坐标数据
train_data_x=all_data[:150,:2]
#截取出标签数据
train_data_y=all_data[:150,-1].reshape(150,1)
print(train_data_x.shape)
print(train_data_y.shape)
#打印结果:
(200, 3)
(150, 2)
(150, 1)
#此时的Y代表的是标签,即输出结果,X代表的是一个坐标。
这是个二分类,从前面数据的图可知。
我们的任务是拟合 y =
w
1
w_1
w1
x
1
x_1
x1 +
w
2
w_2
w2
x
2
x_2
x2+b
w
1
w_1
w1,
w
2
w_2
w2,b 为学习的参数。
4.初始化感知机
#初始化一个感知“鸡”
#这个感知“鸡”的公式可以去看一下官方文档哦
linear = paddle.nn.Linear(in_features=2, out_features=1)
#初始化一个优化函数帮助我们训练感知“鸡”
mse_loss = paddle.nn.MSELoss()
sgd_optimizer = paddle.optimizer.SGD(learning_rate=0.001, parameters = linear.parameters())
5.开始训练:
# 定义一下要训练多少回合,这只鸡看起来就不太聪明咱们多训练一会
total_epoch = 50000
#构建训练过程
for i in range(total_epoch):
#将数据给到定义好的linear感知“鸡”中,对就是要 赶 只 鸡
y_predict = linear(x_data)
#获取loss
loss = mse_loss(y_predict, y_data)
#反向传播
loss.backward()
sgd_optimizer.step()
sgd_optimizer.clear_grad()
#获取感知“鸡”中的w1
w1_after_opt = linear.weight.numpy()[0].item()
#获取感知“鸡”中的w2
w2_after_opt = linear.weight.numpy()[1].item()
#获取感知“鸡”中的b
b_after_opt = linear.bias.numpy().item()
#每1000次输出一次数据
if i%1000 == 0:
print("epoch {} loss {}".format(i, loss.numpy()))
print("w1 after optimize: {}".format(w1_after_opt))
print("w2 after optimize: {}".format(w2_after_opt))
print("b after optimize: {}".format(b_after_opt))
print("finished training, loss {}".format(loss.numpy()))
6.训练结果
#训练完后看看结果
plt.scatter(class1[:,0],class1[:,1])
plt.scatter(class2[:,0],class2[:,1],marker='*')
x=np.arange(10)
#画线的公式
y=-(w1_after_opt*x)/w2_after_opt+b_after_opt
plt.plot(x,y)
总结:
可以看到效果还是挺不错的。我在参加百度飞桨领航团图像分类零基础速成营的课程学习,算是任务,也顺带总结一下课程知识,学起来还是挺有劲的,课程群里也是很活跃,如果有问题可以一起交流学习。
课程链接:https://aistudio.baidu.com/aistudio/course/introduce/11939?directly=1&shared=1