前馈神经网络--Rosenblatt感知器模型结构和实现代码

简介: 本文基于深度学习中的感知器,了解一下Rosenblatt感知器的原理和可视化展示。

设计实验(包括生成数据集、设计收敛衡量指标,如MSE),验证其在线性可分二分类问题上的性能(验证该感知器原理是否有收敛性),并作可视化展示。

算法的收敛性证明称为感知器收敛定理。

==完整代码在最后!!==


实现原理


算法:(更新的算法)

1.这是一种错误驱动的在线学习算法 (在线学习算法:来一条样本进行一次学习)

(错误驱动:就是第三点,即分错一个进行更新w)

2.先初始化一个权重向量W = 0 (通常是一个全零向量)

3.每分错一个样本(X,Y)时,即yWT X < 0

4.用当前样本来更新权重

2021031622111349.png

我们可以看第三点 :其中y是一个标量,W X都是向量 去掉y后面相当于进行的点乘运算,得到的即是y_hat 预测值。那么对于w更新的公式:y*x 因为当前是一个分错的样本,那么可以得到yx是异号,所以可以类比于之前学的(逻辑回归?更新是,w减去学习率×梯度?)也可以看成w-一个值

从而推出感知器的损失函数为

20210316221702807.png

对于yWT X


当分错时可知这是一个负值,可得到损失就是yWT X ;


当分类正确时这是正值,取最大值就是0,当前没有损失。


这就是大概的流程,下面以一个例子来可视化一下过程。


设计实验


1.png

生成数据集

造一个十行二列的数据D

2.png

再将特征增加一维,新的一维为1,对应神经元中的偏置

3.png

划分训练集,第二列作为横坐标X1,第三列为纵坐标X2,并随机进行一个划分,用来得到相应的y标签 (例如我的例子是y = (1.5-x)/2 分为两类)

4.png

可视化我当前的数据集

5.png

初始化W (我这里将偏置值b放入w)并将Y中布尔值转化为int类型

6.png


准备模型


Rosenblatt函数 即得到y_hat

7.png

8.png


训练模型


取最大更新上限为T,k记录更新次数

9.png

用MSE数组记录了所有更新的w 来计算MSE指标(均分误差)观察是否收敛

20210316223337719.png

收敛衡量指标 MSE

10.png


可视化展示

11.png

12.png

MSE指标减小,且可视化过程中更新过的W可以看出分类效果逐渐变好,且最后分类正确。


完整代码


import numpy as np
import matplotlib.pyplot as plt
D = np.random.random((10,2))
#D
D_new = np.ones((10,3))
#D_new
D_new[:,1:] = D #将特征增加一维,新的一维为1,对应神经元中的偏置
#D_new
'''
参考我的数据:
array([[1.        , 0.16814338, 0.66474844],
       [1.        , 0.83121908, 0.45326107],
       [1.        , 0.71082789, 0.62126183],
       [1.        , 0.77474789, 0.96576895],
       [1.        , 0.08396405, 0.33528545],
       [1.        , 0.78157961, 0.57065742],
       [1.        , 0.36439544, 0.94370923],
       [1.        , 0.31868589, 0.39326507],
       [1.        , 0.5699746 , 0.09303593],
       [1.        , 0.61981254, 0.25513333]])
'''
# X1 = D[:,0]
# X2 = D[:,1]
X1 = D_new[:,1] #取后两列作为样本值
X2 = D_new[:,2]
#X1,X2
Y = np.array([(x1+2*x2)>1.5 for (x1,x2) in zip(X1,X2)]) 
#Y , X1 , X2
#print(X1[Y],X2[Y])
Y_0 = ((Y-1)*(-1)).astype(bool)
#print(Y,Y_0)
#print(X1[Y_0],X2[Y_0])
plt.scatter(X1[Y],X2[Y],c='r')
plt.scatter(X1[Y_0],X2[Y_0],c='g')
x = np.linspace(0,1,100)
y = (1.5-x)/2
plt.plot(x,y)
plt.show()
w = np.zeros(D_new.shape[1]) #将b归入w
y = Y.astype(int)
y = y*2-1
#D_new,w,y
def Rosenblatt(w_,x): #增加一个参数,w,便于后续计算收敛衡量指标MSE 
    y = np.dot(w_,x)
    # print(y)
    if y>0:
        return 1
    else:
        return -1
T = 250
t = 0 
k = 0
N = len(D_new)
# for n in range(N):
MSE = list() #初始化一个列表  用于保存中间更新的w
while(t<T):
    for i in range(N):
        xi = D_new[i]
        yi = y[i]
        print(i,xi,yi)
        y_hat = Rosenblatt(w,xi) #用y_hat表示一下预测
        if yi * y_hat < 0:
            w = w + yi * xi
            k = k + 1
            print('更新:',k,w)
            MSE.append(w) #对于更新的w进行保存
        t = t + 1
print("last:",w)
#MSE  #用于计算均方误差
'''
参考我的W
[array([-1.        ,  2.15707843,  1.12887558]),
 array([-2.        ,  1.83839253,  0.7356105 ]),
 array([-1.        ,  2.66961161,  1.18887158]),
 array([-2.        ,  2.35092571,  0.79560651]),
 array([-1.        ,  2.71532116,  1.73931574]),
 array([-2.        ,  2.39663526,  1.34605066])]
'''
# yi_hat = np.zeros(y.shape)
MSE_ans = [0] * len(MSE) #用于记录MSE指标的变化
# print(MSE_ans)
for i in range(len(MSE)):
    yi_hat = np.zeros(y.shape) #用于保存每次更新w所对应的预测值y_hat
#     print(yi_hat)
    for j in range(N):
        xj = D_new[j]
        yj = y[j]
#         print(MSE_ans)
        yi_hat[j] = Rosenblatt(MSE[i],xj)
    print(yi_hat)
    print(y)
    MSE_ans[i] += np.sum((y-yi_hat) ** 2)/len(y) #公式计算MSE
#     break
#MSE_ans #均方误差最后结果
plt.scatter(X1[Y],X2[Y],c='r')
plt.scatter(X1[Y_0],X2[Y_0],c='g')
x = np.linspace(0,1,100)
# y = (1.5-x)/2
for i in MSE:
    y = -(i[0] + i[1] * x )/i[2] #对于每个w画图 看图像的变化 逐渐把两个类别分开
    plt.plot(x,y)
plt.legend(MSE) #从上到下的例表示w的变化 
plt.show()
plt.scatter(X1[Y],X2[Y],c='r')
plt.scatter(X1[Y_0],X2[Y_0],c='g')
H = np.array([[-1.5      ,  1,  2], #上面是真实的w
 [-2.        ,  2.39663526,  1.34605066]]) #下面是最后更新的w
x = np.linspace(0,1,100)
# y = (1.5-x)/2
for i in H:
    y = -(i[0] + i[1] * x )/i[2]
    plt.plot(x,y)
plt.legend(['True','Prediction']) #观察真实和预测的区别 都将两个类别分开 
plt.show()


换衡量收敛指标

当然可以使用损失函数可视化来判断收敛效果。

参考大佬的代码及可视化

13.png

14.png

大佬的代码是封装成类的,日常膜大佬!

import numpy as np
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
class Model:
    def __init__(self,sample_nums,T):
        #样本数
        self.sample_nums=sample_nums
        #迭代次数
        self.T=T
        #生成数据
        self.X,self.Y=self.make_data(sample_nums)
        #划分测试集训练集
        self.X_train,self.X_test, self.y_train, self.y_test=self.split_data(self.X,self.Y)
    def make_data(self,sample_nums):
        # 生成样本吧,有两个特征
        np.random.seed(1)
        X = np.random.random((sample_nums, 2))
        X1 = X[:, 0]
        X2 = X[:, 1]
        Y = np.array([(2 * x1 + x2) > 1.5 for (x1, x2) in zip(X1, X2)])
        return X, Y
    def split_data(self,X,Y):
        X_train,X_test, y_train, y_test=train_test_split(X,Y,test_size=0.4,random_state=0)
        return X_train,X_test, y_train, y_test
    #获得所有样本的损失
    def get_loss(self,X,Y):
        loss=0
        for x,y in zip(X,Y):
            loss+=max(0,-y*np.dot(self.w,x))
        return loss
    def train(self):
        # w需要多加一个分量,表示偏置值b
        self.w = np.zeros(self.X_train.shape[1] + 1)
        y = self.y_train.astype(int)
        y = y * 2 - 1
        one = np.ones(len(self.X_train))
        #需要给原始数据添加一列1,用于乘以偏置值
        X1 = np.c_[one, self.X_train]
        t = 0
        k = 0
        losses=[]
        while (t < self.T):
            for i in range(len(self.X_train)):
                # xi 是原始数据
                xi = self.X_train[i]
                # xi_是添加一列1的数据
                xi_ = X1[i]
                yi = y[i]
                print(i, xi, yi)
                if yi * self.predict(xi_) < 0:
                    self.w = self.w + yi * xi_
                    k = k + 1
                    print('更新:', k, self.w)
                t = t + 1
                losses.append(self.get_loss(X1,y))
        self.losses=losses
    def predict(self,x):
        y=np.dot(self.w,x)
        if y>0:
            return 1
        else:
            return -1
    def visualsize(self):
        #该直线为 w[1] * x1 + w[2] * x2 + w[0] = 0
        #变换一下得 x2=(-w[0]-w[1]*x1)/w[2]
        X=self.X_test
        Y=self.y_test
        Y_0 = ((Y - 1) * (-1)).astype(bool)
        #横坐标
        X1=X[:,0]
        #纵坐标
        X2=X[:,1]
        plt.scatter(X1[Y], X2[Y], c='r')
        plt.scatter(X1[Y_0], X2[Y_0], c='g')
        x1 = np.linspace(0, 1, 100)
        x2 = (-self.w[0] - self.w[1] * x1) / self.w[2]
        y_true = 1.5 - 2 * x1
        plt.plot(x1, x2)
        plt.plot(x1,y_true)
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
        plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
        plt.title('分类情况测试集可视化')
        plt.legend(['predict','true'])
        plt.show()
        #可视化损失
        plt.plot(np.arange(len(self.losses)),self.losses)
        plt.title("可视化损失")
        plt.show()
    def score(self):
        hit=0
        y_test=np.array(self.y_test,dtype=int)
        #将0,1 映射为1 -1
        y_test=2*y_test-1
        for x,y in zip(self.X_test,y_test):
            predict=self.predict(np.insert(x,0,1))
            if predict==y:
                hit+=1
        return hit/len(self.X_test)
if __name__ == '__main__':
    model=Model(100,1000)
    model.train()
    model.visualsize()
    print("正确率为:",model.score())
相关文章
|
3月前
|
传感器 机器学习/深度学习 算法
【UASNs、AUV】无人机自主水下传感网络中遗传算法的路径规划问题研究(Matlab代码实现)
【UASNs、AUV】无人机自主水下传感网络中遗传算法的路径规划问题研究(Matlab代码实现)
132 0
|
2月前
|
机器学习/深度学习 数据采集 人工智能
深度学习实战指南:从神经网络基础到模型优化的完整攻略
🌟 蒋星熠Jaxonic,AI探索者。深耕深度学习,从神经网络到Transformer,用代码践行智能革命。分享实战经验,助你构建CV、NLP模型,共赴二进制星辰大海。
|
3月前
|
机器学习/深度学习 传感器 算法
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
244 2
|
2月前
|
机器学习/深度学习 数据采集 存储
概率神经网络的分类预测--基于PNN的变压器故障诊断(Matlab代码实现)
概率神经网络的分类预测--基于PNN的变压器故障诊断(Matlab代码实现)
328 0
|
2月前
|
机器学习/深度学习 人工智能 算法
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
158 0
|
3月前
|
机器学习/深度学习 缓存 算法
2025年华为杯A题|通用神经网络处理器下的核内调度问题研究生数学建模|思路、代码、论文|持续更新中....
2025年华为杯A题|通用神经网络处理器下的核内调度问题研究生数学建模|思路、代码、论文|持续更新中....
448 1
|
2月前
|
传感器 机器学习/深度学习 数据采集
【航空发动机寿命预测】基于SE-ResNet网络的发动机寿命预测,C-MAPSS航空发动机寿命预测研究(Matlab代码实现)
【航空发动机寿命预测】基于SE-ResNet网络的发动机寿命预测,C-MAPSS航空发动机寿命预测研究(Matlab代码实现)
203 0
|
3月前
|
机器学习/深度学习 算法 调度
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
380 0
|
3月前
|
机器学习/深度学习 并行计算 算法
【CPOBP-NSWOA】基于豪冠猪优化BP神经网络模型的多目标鲸鱼寻优算法研究(Matlab代码实现)
【CPOBP-NSWOA】基于豪冠猪优化BP神经网络模型的多目标鲸鱼寻优算法研究(Matlab代码实现)
|
3月前
|
机器学习/深度学习 传感器 算法
【表面粗糙度】基于粒子群PSO算法优化-BP神经网络的表面粗糙度研究(Matlab代码实现)
【表面粗糙度】基于粒子群PSO算法优化-BP神经网络的表面粗糙度研究(Matlab代码实现)
236 7