基于Paddle2.0训练感知机模型

概述

在机器学习中,感知机(perceptron)是二分类的线性分类模型,属于监督学习算法。输入为实例的特征向量,输出为实例的类别(取+1和-1)。

感知机对应于输入空间中将实例划分为两类的分离超平面。感知机旨在求出该超平面,为求得超平面导入了基于误分类的损失函数,利用梯度下降法 对损失函数进行最优化(最优化)。

感知机的学习算法具有简单而易于实现的优点,分为原始形式和对偶形式。感知机预测是用学习得到的感知机模型对新的实例进行预测的,因此属于判别模型。

感知机由Rosenblatt于1957年提出的,是神经网络和支持向量机的基础。

假设输入空间(特征向量)为X=[x1,x2,x3,x…],输出空间为Y = [1,-1]。

输入 = X

表示实例的特征向量,对应于输入空间的点;

输出 = Y

表示示例的类别。
由输入空间到输出空间的函数为在这里插入图片描述
称为感知机。其中,参数w叫做权值向量(weight),b称为偏置(bias)。
其中在这里插入图片描述
sign为符号函数,即在这里插入图片描述

感知机算法就是要找到一个超平面将我们的数据分为两部分。

超平面就是维度比我们当前维度空间小一个维度的空间, 例如:我们当前的维度是二维的空间(由数据维度确定,x有多少列就有多大的维度),那么超平面就是一维 的,即一条直线。如下图
在这里插入图片描述
上面的图片,其实就是初高中里学的东西,在直角坐标系中,画一条直线,把坐标系分为两部分,假设横坐标是x1,纵坐标是x2.那么直线就可以表示为w1×x1+w2×x2+b=0,这其实就是很简单的直线方程,假设f(x1,x2)表示这条直线,当把在直线上方的点的坐标带入直线中,会有f>0,那么带入直线下方的点的坐标时,会有f<0,这样就把一个空间分为两个部分了。当是三维时,可以想象一间房子,里面有一堵墙把房子分为了两部分,这里的墙就是一个超平面;当是更高维时,就不容易想象了,但是计算机能构造出一个超平面,把空间中的数据分为两个部分。

实现最简单的感知机

#引入必要的包
import paddle
print("本教程使用的paddle版本为:" + paddle.__version__)
import numpy as np
import matplotlib.pyplot as plt

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
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])

#看一下生成点的样子
print(class1.shape)
print(class2.shape)
print(class1)

在这里插入图片描述
上面数据的形状不便于我们操作数据,我们希望数据是这种类型的:[x1,x2,y],所以要转置一下

class1=class1.T
class2=class2.T
#再看一下生成点的样子
print(class1.shape)
print(class2.shape)
print(class1)

在这里插入图片描述
画图看一下

plt.scatter(class1[:,0],class1[:,1])
plt.scatter(class2[:,0],class2[:,1],marker='*')

在这里插入图片描述
接下来就要画线了,让一条直线(超平面)把上面数据分为两个部分。
先将两类数据都放到一个变量里面。

all_data = np.concatenate((class1,class2))
#将数据打乱
np.random.shuffle(all_data)
print(all_data)

在这里插入图片描述

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)
#将数据转化为tensor形式
x_data = paddle.to_tensor(train_data_x.astype('float32'))
y_data = paddle.to_tensor(train_data_y.astype('float32'))

在这里插入图片描述
要画出的直线线的公式是:w1 × x1+w2 × x2+b=0
下面初始化一个感知机

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())

下面开始训练

total_epoch = 50000
#构建训练过程
for i in range(total_epoch):
    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()))

在这里插入图片描述
训练好后开始画直线

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)

在这里插入图片描述

从上图中可以看到训练出来的直线能够很好地把数据分为两部分。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值