paddle2.0实现单层感知机
项目地址:aistudio.baidu.com/aistudio/pr…
大家好,这里是三岁,给大家带来的是简单感知机(单层感知机)的paddle2.0 实现
感知机
感知机也被指为单层的神经网络,作为一种线性分类器,(单层)感知机可说是最简单的前向人工神经网络形式。尽管结构简单,感知机能够学习并解决相当复杂的问题。
感知机主要的本质缺陷是它不能处理线性不可分问题。
感知器
感知器(英语:Perceptron)又译为感知机是Frank Rosenblatt在1957年就职于康奈尔航空实验室(Cornell Aeronautical Laboratory)时所发明的一种人工神经网络。它可以被视为一种最简单形式的前馈神经网络,是一种二元线性分类器。
感知机的灵感由来
感知机是生物神经细胞的简单抽象。神经细胞结构大致可分为:树突、突触、细胞体及轴突。单个神经细胞可被视为一种只有两种状态的机器——激动时为‘是’,而未激动时为‘否’。
神经细胞的状态取决于从其它的神经细胞收到的输入信号量,及突触的强度(抑制或加强)。当信号量总和超过了某个阈值时,细胞体就会激动,产生电脉冲。
电脉冲沿着轴突并通过突触传递到其它神经元。为了模拟神经细胞行为,与之对应的感知机基础概念被提出,如权量(突触)、偏置(阈值)及激活函数(细胞体)。
定义
感知器使用特征向量来表示的前馈神经网络,它是一种二元分类器,把矩阵上的输入x(实数值向量)映射到输出值 f(x) 上(一个二元的值)。
w是实数的表示权重的向量, w * x 是点积。b是偏置,一个不依赖于任何输入值的常数。偏置可以认为是激励函数的偏移量,或者给神经元一个基础活跃等级。
f(x) (0或1)用于对x进行分类,看它是肯定的还是否定的,这属于二元分类问题。如果b是负的,那么加权后的输入必须产生一个肯定的值并且大于
-b,这样才能令分类神经元大于阈值0。从空间上看,偏置改变了决策边界的位置(虽然不是定向的)。
由于输入直接经过权重关系转换为输出,所以感知器可以被视为最简单形式的前馈式人工神经网络。
举例
此处我们以下图为例子进行代码举例:
# 导入第三方库
import paddle
import numpy as np
解析
我们以维基百科中的单层神经网络为依据
以公式y=x1*w1+x2+w2+b进行举例
假设公式为:y = 2 * x1 + 4 * x2 + 5
| y | x1 | x2 |
|---|---|---|
| 15 | 1 | 2 |
| 21 | 2 | 3 |
| 27 | 3 | 4 |
| 33 | 4 | 5 |
| 31 | 3 | 5 |
| 29 | 2 | 4 |
| 31 | 3 | 4 |
用这个数据进行学习,查看
# 对数据进行定义
x_data = paddle.to_tensor([[1., 2.], [2., 3.], [3., 4.], [4., 5.], [3., 5.], [2., 4.], [3., 4.]])
y_data = paddle.to_tensor([[15.], [21.], [27.], [33.], [31.], [29.], [31.]])
print(f'x_data:{x_data}')
print(f'y_data:{y_data}')
x_data:Tensor(shape=[7, 2], dtype=float32, place=CPUPlace, stop_gradient=True,
[[1., 2.],
[2., 3.],
[3., 4.],
[4., 5.],
[3., 5.],
[2., 4.],
[3., 4.]])
y_data:Tensor(shape=[7, 1], dtype=float32, place=CPUPlace, stop_gradient=True,
[[15.],
[21.],
[27.],
[33.],
[31.],
[29.],
[31.]])
数据的定义(使用to_tensorAPI)
to_tensorAPI可以把数据进行处理,转变成paddle能够处理的张量
利用该API可以把np、列表等数据进行转换
# 定义初始化神经网络
linear = paddle.nn.Linear(in_features=2, out_features=1)
# 查看网络
paddle.summary(linear, (2,))
---------------------------------------------------------------------------
Layer (type) Input Shape Output Shape Param #
===========================================================================
Linear-1 [[2]] [1] 3
===========================================================================
Total params: 3
Trainable params: 3
Non-trainable params: 0
---------------------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
---------------------------------------------------------------------------
{'total_params': 3, 'trainable_params': 3}
对网络进行定义(使用Linear)
paddle.nn.Linear:
线性变换层 。对于每个输入Tensor X ,计算公式为:
Out=XW+b
paddle.summary:
函数能够打印网络的基础结构和参数信息
# 查看初始化值
w1_before_opt = linear.weight.numpy()[0].item() # 获取w1的值
w2_before_opt = linear.weight.numpy()[1].item() # 获取w1的值
b_before_opt = linear.bias.numpy().item() # 获取b的值
print("w1 before optimize: {}".format(w1_before_opt))
print("w2 before optimize: {}".format(w2_before_opt))
print("b before optimize: {}".format(b_before_opt))
w1 before optimize: -0.05054903030395508
w2 before optimize: 0.4207116365432739
b before optimize: 0.0
# 添加损失函数和优化算法
mse_loss = paddle.nn.MSELoss()
sgd_optimizer = paddle.optimizer.SGD(learning_rate=0.001, parameters = linear.parameters())
添加损失函数和优化算法(使用paddle.nn.MSELoss、paddle.optimizer.SGD)
计算预测值和目标值的均方差误差:paddle.nn.MSELoss 参考地址
随机梯度下降算法的优化器:C(paddle.optimizer.SGD) 参考地址
# 训练机器,学习参数
total_epoch = 20000 # 运行轮数
for i in range(total_epoch):
y_predict = linear(x_data)
loss = mse_loss(y_predict, y_data)
loss.backward()
sgd_optimizer.step() # 执行一次优化器并进行参数更新
sgd_optimizer.clear_grad() # 清除需要优化的参数的梯度
if i%1000 == 0: # 每1000轮输出一次
print("epoch {} loss {}".format(i, loss.numpy()))
print("finished training, loss {}".format(loss.numpy()))
epoch 0 loss [2.9675884]
epoch 1000 loss [2.9675617]
epoch 2000 loss [2.9675353]
epoch 3000 loss [2.9675167]
epoch 4000 loss [2.967499]
epoch 5000 loss [2.9674878]
epoch 6000 loss [2.9674761]
epoch 7000 loss [2.9674687]
epoch 8000 loss [2.967461]
epoch 9000 loss [2.9674509]
epoch 10000 loss [2.967448]
epoch 11000 loss [2.967442]
epoch 12000 loss [2.9674382]
epoch 13000 loss [2.9674332]
epoch 14000 loss [2.9674318]
epoch 15000 loss [2.96743]
epoch 16000 loss [2.967428]
epoch 17000 loss [2.9674275]
epoch 18000 loss [2.9674249]
epoch 19000 loss [2.9674246]
finished training, loss [2.9674237]
# 查看训练结果以后的值:
w1_before_opt = linear.weight.numpy()[0].item()
w2_before_opt = linear.weight.numpy()[1].item()
b_before_opt = linear.bias.numpy().item()
print("w1 before optimize: {}".format(w1_before_opt))
print("w2 before optimize: {}".format(w2_before_opt))
e optimize: {}".format(w2_before_opt))
print("b before optimize: {}".format(b_before_opt))
w1 before optimize: 0.7338576912879944
w2 before optimize: 5.197205543518066
b before optimize: 4.780434608459473
总结
这个感知机已经实现了,但是效果不是很好
主要原因:数据量给的太少了如果多添加几组就会得到一个更好的效果
这里是三岁,我们下次见!