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

本文涉及的产品
交互式建模 PAI-DSW,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实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
1月前
|
机器学习/深度学习 算法 PyTorch
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
240 1
|
1月前
|
机器学习/深度学习 自然语言处理 数据处理
大模型开发:描述长短期记忆网络(LSTM)和它们在序列数据上的应用。
LSTM,一种RNN变体,设计用于解决RNN处理长期依赖的难题。其核心在于门控机制(输入、遗忘、输出门)和长期记忆单元(细胞状态),能有效捕捉序列数据的长期依赖,广泛应用于语言模型、机器翻译等领域。然而,LSTM也存在计算复杂度高、解释性差和数据依赖性强等问题,需要通过优化和增强策略来改进。
|
5天前
|
机器学习/深度学习 存储 计算机视觉
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现-4
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现
35 11
|
1天前
|
机器学习/深度学习 存储 算法
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现(下)
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现
12 2
|
1天前
|
机器学习/深度学习 运维 算法
R语言用ARIMA模型滑动时间窗口识别网络流量时间序列异常值
R语言用ARIMA模型滑动时间窗口识别网络流量时间序列异常值
|
2天前
|
存储 NoSQL Linux
Redis入门到通关之Redis5种网络模型详解
Redis入门到通关之Redis5种网络模型详解
10 1
|
4天前
|
网络协议 Linux Shell
【linux网络(一)】初识网络, 理解四层网络模型
【linux网络(一)】初识网络, 理解四层网络模型
|
5天前
|
机器学习/深度学习 算法 数据可视化
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现-3
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现
13 0
|
5天前
|
算法 数据可视化
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现-1
r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现
18 0
|
9天前
|
机器学习/深度学习 数据可视化 Shell
用加性多元线性回归、随机森林、弹性网络模型预测鲍鱼年龄和可视化(二)
用加性多元线性回归、随机森林、弹性网络模型预测鲍鱼年龄和可视化
32 1

热门文章

最新文章