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

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
模型训练 PAI-DLC,5000CU*H 3个月
简介: 本文基于深度学习中的感知器,了解一下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())
相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
22天前
|
消息中间件 存储 Serverless
函数计算产品使用问题之怎么访问网络附加存储(NAS)存储模型文件
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
21天前
|
Kubernetes 负载均衡 网络安全
Kubernetes 网络模型与实践
【8月更文第29天】Kubernetes(K8s)是当今容器编排领域的佼佼者,它提供了一种高效的方式来管理容器化应用的部署、扩展和运行。Kubernetes 的网络模型是其成功的关键因素之一,它支持服务发现、负载均衡和集群内外通信等功能。本文将深入探讨 Kubernetes 的网络模型,并通过实际代码示例来展示服务发现和服务网格的基本概念及其实现。
37 1
|
17天前
|
网络协议 数据安全/隐私保护 网络架构
计算机网络模型
【9月更文挑战第2天】
43 24
|
10天前
|
机器学习/深度学习 人工智能 自然语言处理
机器学习模型之深度神经网络的特点
深度神经网络(Deep Neural Networks, DNNs)是一类机器学习模型,通过多个层级(层)的神经元来模拟人脑的工作方式,从而实现复杂的数据处理和模式识别任务。
14 1
|
11天前
|
编解码 人工智能 文件存储
卷积神经网络架构:EfficientNet结构的特点
EfficientNet是一种高效的卷积神经网络架构,它通过系统化的方法来提升模型的性能和效率。
18 1
|
15天前
|
算法
基于GA遗传优化的离散交通网络双层规划模型设计matlab仿真
该程序基于GA遗传优化设计了离散交通网络的双层规划模型,以路段收费情况的优化为核心,并通过一氧化碳排放量评估环境影响。在MATLAB2022a版本中进行了验证,显示了系统总出行时间和区域排放最小化的过程。上层模型采用多目标优化策略,下层则确保总阻抗最小,实现整体最优解。
|
19天前
|
分布式计算 负载均衡 监控
p2p网络架构模型
P2P(Peer-to-Peer)模式是一种网络架构模型,在这种模型中,每个节点(peer)既是服务的提供者也是服务的消费者。这意味着每个参与的节点都可以直接与其他节点通信,并且可以相互提供资源和服务,例如文件共享、流媒体传输等。
21 6
|
16天前
|
网络协议 安全 网络安全
C语言 网络编程(四)常见网络模型
这段内容介绍了目前被广泛接受的三种网络模型:OSI七层模型、TCP五层模型以及TCP/IP四层模型,并简述了多个网络协议的功能与特性,包括HTTP、HTTPS、FTP、DNS、SMTP、TCP、UDP、IP、ICMP、ARP、RARP及SSH协议等,同时提到了ssh的免费开源实现openssh及其在Linux系统中的应用。
|
19天前
|
网络协议 安全 网络性能优化
OSI 模型详解:网络通信的七层架构
【8月更文挑战第31天】
102 0
|
24天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的正则化技术:提升模型泛化能力的关键策略探索AI的奥秘:深度学习与神经网络
【8月更文挑战第27天】在深度学习的探索旅程中,我们常常遭遇模型过拟合的困境,就像是一位探险者在茫茫林海中迷失方向。本文将作为你的指南针,指引你理解并应用正则化技术,这一强大的工具能够帮助我们的模型更好地泛化于未见数据,就如同在未知领域中找到正确的路径。我们将从简单的L1和L2正则化出发,逐步深入到更为复杂的丢弃(Dropout)和数据增强等策略,为你的深度学习之旅提供坚实的支持。