项目地址:https://aistudio.baidu.com/aistudio/projectdetail/1546134
大家好,这里是三岁,给大家带来的是简单感知机(单层感知机)的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_tensor
API)
to_tensor
API可以把数据进行处理,转变成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
总结
这个感知机已经实现了,但是效果不是很好
主要原因:数据量给的太少了如果多添加几组就会得到一个更好的效果
这里是三岁,我们下次见!