宽度学习详解(Broad Learning System)

article/2025/11/9 22:48:16

宽度学习(Broad Learning System)

  • 1:Introduction
    • 1.1:级联相关网络(本节来自周志华《机器学习》)
    • 1.2:随机向量函数连接网络(RVFLNN)
  • 2:宽度学习系统(Broad Learning System)
    • 2.1:不含增量学习的BLS
    • 2.2:增量学习
  • 3:感想
  • 4:实验
    • 4.1:Github
    • 4.2: 不含增量学习的MNIST结果:
    • 4.3:直接求训练集X的伪逆,进而求得W🎂
    • 4.4:含增量学习的MNIST结果

Github已添加含增量学习的代码,主要还是根据之前参考的代码修改,处理MNIST的结果也已经放在最后一节。已经很久不看这方面的内容。欢迎给原作者代码star(链接在4.1)。

我也是最近才知道除了深度学习,还有一个神经网络叫宽度学习(下文统称BLS)。

1:Introduction

宽度学习是澳门大学科技学院院长陈俊龙和其学生于2018年1月发表的文章提出的,文章名为《Broad Learning System: An Effective and Efficient Incremental Learning System Without the Need for Deep Architecture》

据论文所述:深度学习由于计算量太大,计算成本太高,所以提出了一种新的网络结构来解决这个问题。

接下来,我会尽量用最简单的语言来详细介绍这个网络:
你需要提前知道的:BLS的网络结构不是固定的,而是随着学习不断改变的。不要用之前普通深度学习的思路来理解它。

1.1:级联相关网络(本节来自周志华《机器学习》)

在这里插入图片描述
上图中红色部分为级联相关网络的一个基本结构,级联相关网络使深度学习的一种方法,所以,他还是再不断地往深了走,以求找到最佳的深度网络。
再看宽度学习的基本结构:
在这里插入图片描述
这是随机向量函数连接网络(RVFLNN)的结构,也是宽度学习的基础。你可以看到他与级联相关网络的相似之处。一个是往深了走,一个是往宽了走(当然,RVFLNN不是自动横向添加神经元,后面的宽度学习系统才是不断横向添加神经元)

1.2:随机向量函数连接网络(RVFLNN)

现在,我们来介绍一下RVFLNN,这是宽度学习的基础。
BLS是来源于一个叫随机向量函数连接网络 random vector functional-link neural network (RVFLNN)的网络结构。文章给出了图片:
在这里插入图片描述
它是这样的:

给定输入X,普通的网络会把X乘上权重,加上偏差之后传入到下一个隐藏层,但是,RVFLNN不只这样,它乘上一组随机的权重,加上随机的偏差之后传入到一个叫增强层(enhance layer),注意,这组权重在以后不会变了。传入增强层的数据经激活函数(也只有增强层有激活函数)得到H。
之后,把原本的输入X和增强层的计算结果H合并成一个矩阵(这两个矩阵都是*x1的类型),称为A,A=[X|H],把A作为输入,乘上权重,加上偏差之后传到输出层。

把上面的图片中增强层挪到输入层就成这样了。
在这里插入图片描述
第二次计算的权重和偏差才是我们需要计算的结果。那么怎么计算呢??
我们想要让
AW = Y

A是已知的,Y也是已知的。所以W=A-1Y不就计算出来了吗。
但是矩阵A是一个*x1的矩阵,是没有逆矩阵的,但是,没有逆矩阵,还有伪逆。这下,想要的都有了。

假设训练集为500个样本,label有3种类型。按照普通的神经网络,我们会一个一个将样本传入神经网络,用梯度下降来更新权重。但是对于RVFLNN来说,我们一次性将所有样本传入网络。没有权重更新过程,而是一步直接计算出权重。

下面来举个例子

假设训练集有500个样本,属性有4个,label有3种。那么我们的输入X就是500x4的矩阵。我们设定需要的增强节点为300个,那么输入就是500x304,而我们想要的权重则是304x3的矩阵。如此,输入矩阵与输出矩阵相乘,得到的就是500x3的矩阵。按照上面的理论,我们只需要计算一次伪逆就行了。

2:宽度学习系统(Broad Learning System)

BLS在RVFLNN的基础上再一次改进,尤其是增加了增量学习的过程。增量学习就是前文提过的自动横向增加增强节点或者mapping nodes的过程。

2.1:不含增量学习的BLS

不含增量学习的BLS与RVFLNN极为相似。
此时的BLS不再将原始数据直接输入到网络中,而是先经过一番处理,得到mapping nodes。之后,mapping nodes的输入数据就是之前RVFLNN的输入数据。
mapping nodes不是只有一组。它可以有很多组,每一组叫一个mapping feature。同样,enhancement nodes也不是只有一组,也可以有很多组。
如图:
在这里插入图片描述
这样的网络结构是你提前设定的,有几组mapping nodes,几组enhancement nodes都是你规定好了的。
再举个例子:

假设训练集有500个样本,属性有4个,label有3种。我们想要10组mapping feature,10组enhancement nodes。每组我们都想要100个节点。

这样mapping nodes就有1000个,enhancement nodes也有1000个。那么我们原始的输入X仍然是500x4的矩阵。但是,我们要先把它变成10个500x100的矩阵。所以我们需要10个4x100的权重矩阵,这个权重我们是随机设定的。

当我们得到10组500x100的mapping nodes的输入Z之后,我们还要得到enhancement nodes的输入H。为此,还需要10组100x100的另一个随机权重(这个权重一般还设置成正交的,可能是为了防止enhancement nodes输入彼此之间的相关性)。之后,我们的输入就是A=[Z|H],shape为500x2000。这两个随即权重都不再改变。输入到输出权重W的shape为2000x3,同样由求伪逆即可得到。

2.2:增量学习

但是有时我们设定的网络对训练集不能很好的拟合,所以我们就需要增量学习。不断地增加节点,来得到更好的网络结构。
在这里插入图片描述
当我们按照不含增量学习的网络训练结束之后,发现效果不够理想,我们就增加其中一种或者两种节点。这样节点增加了,权重也增加了,模型变得更加复杂,效果就可能更好。
增加节点之后,我们需要更新权重。但是,如果要重新求逆就得不偿失了,因为新的A矩阵只是在原矩阵上追加了一部分,大部分还是没变的。所以,作者使用广义的逆矩阵。用下面的公式来更新权重:
在这里插入图片描述
这样的话,每次计算就可以在上一次权重的基础上进行了。

因为我们增加节点可以增加mapping nodes,也可以增加enhancement nodes,所以有两种方法。法:
在这里插入图片描述
在这里插入图片描述
两种方法都使用了一个while 循环,当误差一直不满足设定值时,就会一直增加节点。

3:感想

在实际应用中,我们的样本可能有上百万个,特征也可能成千上万,这时,计算一个矩阵的逆简直是不可能的。

但是,bls论文中提出一种办法来解决。当我们第一次计算不含增量的伪逆时,使用的是岭回归,这样就避免了直接计算一个巨大的矩阵的伪逆。之后,我们更新权重只使用广义逆计算。和最初的伪逆计算的计算量相比,要少得多。


4:实验

4.1:Github

bls实现代码:
我的github
主要参考的(有含增量学习的代码)github我在他的基础上删除了一些冗余的部分,添加了更多的注释。

4.2: 不含增量学习的MNIST结果:

测试集上准确率0.93464(未调参)
用bls做MNIST的程序我已经放在Github
上了。

在这里插入图片描述

4.3:直接求训练集X的伪逆,进而求得W🎂

在不含增量学习的bls中,通过对训练集的X乘上一系列随机的权重,得到的结果再乘上一系列随机的权重。最后组合在一块,求其伪逆,和y相乘得到权重W。那么,如果我们不乘那么多随机权重呢。而是直接用原始数据集X求伪逆,再求W呢?

import numpy as np
import pandas as pd
from sklearn import preprocessing  # 用来转化为独热编码
from sklearn.model_selection import train_test_splitclass scaler:def __init__(self):self._mean = 0self._std = 0def fit_transform(self,traindata):self._mean = traindata.mean(axis = 0)self._std = traindata.std(axis = 0)return (traindata-self._mean)/(self._std+0.001)def transform(self,testdata):return (testdata-self._mean)/(self._std+0.001)class net(object):def __init__(self):self.W = Noneself.normalscaler = scaler()self.onehotencoder = preprocessing.OneHotEncoder(sparse = False)def decode(self,Y_onehot):Y = []for i in range(Y_onehot.shape[0]):lis = np.ravel(Y_onehot[i,:]).tolist()Y.append(lis.index(max(lis)))return np.array(Y)def fit(self, X, y):X = self.normalscaler.fit_transform(X)y = self.onehotencoder.fit_transform(np.mat(y).T)self.W = np.linalg.pinv(X).dot(y)   # 784*10print('shape of W is:{}'.format(self.W.shape))def predict(self, X_test):X_test = self.normalscaler.transform(X_test)y = X_test.dot(self.W)print('predictions of y shape:{}'.format(y.shape))return self.decode(y)
if __name__ == '__main__':# load the datatrain_data = pd.read_csv('./train.csv')test_data = pd.read_csv('./test.csv')samples_data = pd.read_csv('./sample_submission.csv')label = train_data['label'].valuesdata = train_data.drop('label', axis=1)data = data.valuesprint(data.shape, max(label) + 1)traindata,valdata,trainlabel,vallabel = train_test_split(data,label,test_size=0.2,random_state = 0)print(traindata.shape,trainlabel.shape,valdata.shape,vallabel.shape)n = net()n.fit(traindata, trainlabel)test_data = test_data.valuespredicts = n.predict(test_data)# save as csv filesamples = samples_data['ImageId']result = {'ImageId':samples,'Label': predicts }result = pd.DataFrame(result)result.to_csv('./mnist_simple.csv', index=False)

最终的准确率:
在这里插入图片描述
已经0.85+了,😀,不含增量学习的bls相比之下提高了0.08的准确率。
这其实也差不多说明不含增量学习的bls其实并非十分高级,增量学习才是bls的核心。

4.4:含增量学习的MNIST结果

在这里插入图片描述
只是简单的添加了增量学习,并没有任何的优化,所以成绩也没有很大的提升。


http://chatgpt.dhexx.cn/article/jnGG1u3l.shtml

相关文章

七、宽度学习系统Broad Learning System

七、宽度学习系统Broad Learning System 1、宽度学习的发展2、宽度学习系统(BLS)3、 BLS的增量形式1、宽度学习的发展 宽度学习系统(BLS) 的提出最早源于澳门大学科技学院院长陈俊龙和其学生于2018年1月发表在IEEE TRANSACTIONS ON NEURAL NETWORKS AND LEARNING SYSTEMS,…

宽度学习(Broad Learning System)

一、宽度学习的前世今生 宽度学习系统(BLS) 一词的提出源于澳门大学科技学院院长陈俊龙和其学生于2018年1月发表在IEEE TRANSACTIONS ON NEURAL NETWORKS AND LEARNING SYSTEMS,VOL. 29, NO. 1 的一篇文章,题目叫《Broad Learnin…

宽度学习(BLS)实战——python复刻MNIST数据集的数据预处理及训练过程

目录 1.宽度学习(Broad Learning System) 2.MNIST数据集 3.复刻MNIST数据集的预处理及训练过程 1.宽度学习(Broad Learning System) 对宽度学习的理解可见于这篇博客宽度学习(Broad Learning System)_颹蕭蕭的博客-CSDN博客_宽度学习 这里不再做详细…

《Linux设备驱动开发详解(第3版)》(即《Linux设备驱动开发详解:基于最新的Linux 4.0内核》)进展同步更新

本博实时更新《Linux设备驱动开发详解(第3版)》的最新进展。 目前已经完成稿件。 2015年8月9日,china-pub开始上线预售: http://product.china-pub.com/4733972 2015年8月20日,各路朋友报喜说已经拿到了书。 本书已经rebase到开发中的Linu…

linux_设备驱动_设备树

一.什么是DTS?为什么要引入DTS? DTS即Device Tree Source 设备树源码, Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。 在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/ma…

Linux设备驱动模型(一)

一、sysfs文件系统 sysfs是一个虚拟文件系统,将内核总的设备对象的链接关系,以文件目录的方式表示出来,并提对设备提供读写接口。 二、kobject kobject是内核中对象表示的基类,可以认为所有的内核对象都是一个kobject kobject单…

Linux设备驱动基础03:Linux字符设备驱动

1 Linux文件系统与设备驱动 1.1 文件系统与设备驱动之间的关系 Linux中文件系统与设备驱动程序之间的关系如下图所示, 应用程序和VFS之间的接口是系统调用;VFS和文件系统以及设备文件之间的接口是file_operations结构体中的成员函数,该结构体…

Linux 设备驱动程序(二)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核 Linux 设备驱动程序(一) Linux 设备驱动程序(二) Linux 设备驱动程序(三) Linux 设备驱动程序(四) Linux设备驱动开发详解 …

Linux驱动——字符设备驱动

目录 一、代码编译环境 二、Linux驱动开发分类 三、字符设备驱动开发流程 1.编译驱动模块代码(Makefile) 2.驱动模块的加载与卸载 四、字符设备驱动编写 1.驱动模块 2. 字符设备驱动编写步骤 2.1 设备号的注册与注销 2.2 设备节点的注册与注销 …

【Linux设备驱动】设备驱动分类

Linux设备驱动分类 驱动分为有操作系统设备驱动和误操作系统的设备驱动。 有无操作系统设备驱动 无操作系统设备驱动 不是所有的计算机系统都一定要有操作系统,在许多情况下,操作系统都是不必存在的。对于功能比较单一、控制不复杂的系统&#xff0c…

Linux-设备驱动概述

文章目录 Linux设备驱动概述1. 设备驱动的作用2. 无操作系统的设备驱动3. 有操作系统时的设备驱动4. Linux设备驱动4.1 设备的分类及特点4.2 Linux设备驱动与整个软硬件系统的关系4.3 Linux设备驱动的重难点 5. 源代码阅读6. 设备驱动:LED驱动6.1 无操作系统的LED驱…

Linux设备驱动和设备匹配过程

Linux设备驱动和设备匹配过程 1. 设备驱动匹配简述2. 重点结构体介绍2.1 struct device2.2 struct platform_device2.3 struct platform_driver2.4 struct device_driver 3. device端发起匹配:3.1 流程图3.2 start_kernel时候解析设备树3.2.1 start_kernel3.2.2 set…

Linux设备驱动之字符设备驱动

一、linux系统将设备分为3类:字符设备、块设备、网络设备。 应用程序调用的流程框图: 三种设备的定义分别如下, 字符设备:只能一个字节一个字节的读写的设备,不能随机读取设备内存中的某一数据,读取数据需…

Linux设备驱动基础01:Linux设备驱动概述

目录 1. 设备驱动的作用 2. 有无操作系统时的设备驱动 2.1 无操作系统 2.1.1 硬件、驱动和应用程序的关系 2.1.2 单任务软件典型架构 2.2 有操作系统 2.2.1 硬件、驱动、操作系统和应用软件的关系 3. Linux设备分类 3.1 常规分类法 3.1.1 字符设备 3.1.2 块设备 3.…

Linux设备驱动模型

目录 一、linux设备驱动模型简介1、什么是设备驱动模型2、为什么需要设备驱动模型3、驱动开发的2个点 二、设备驱动模型的底层架构1、kobject2、kobj_type3、kset 三、总线式设备驱动组织方式1、总线2、设备3、驱动4、类5、总结 四、platform平台总线工作原理1、何为平台总线2、…

【linux内核分析与应用-陈莉君】字符设备驱动

目录 1.什么是字符设备 2.如何来描述字符设备 3 struct cdev与const struct file_operations之间的关系 4.struct file_operations源码 5.字符设备驱动框架 6.编写字符设备驱动的步骤 7.字符设备结构 8.字符设备驱动程序的注册 9.从系统调用到驱动程序 10.用户空间与内…

微信小程序云数据库使用讲解

第一步:注册开通 单击云开发 第二步:创建数据库 选择数据库,并点击号创建一个集合 输入名字 创建完毕后点击添加记录即可添加数据 数据库获取: 查询: 查询指令:

微信小程序云开发入门-数据库插入数据(包含批量)

一、前言 文章将介绍如何在微信小程序云开发中向云开发数据库插入数据(单条或批量)。 写法有好几种,文章将会一一进行对比,看看每种写法之间有何优缺点,如何让代码看起来更优雅。 为了更加贴合实际的开发逻辑&#xf…

【微信小程序】如何获取微信小程序云开发数据库的数据并渲染到页面?

前言 上一篇博客我把微信小程序云开发数据库操作(增删改查)的实现方法都已经分享出来啦,可以戳链接进去阅读哦 【微信小程序】小程序云开发实现数据库增删改查(小白速度Get起来!!一步步教你如何实现) 基于微信小程序…

开发一个可以查询并显示数据库内容的微信小程序

使用微信开发者工具可以创建云数据库,并通过代码可以查询并在客户端显示数据库的内容。 附:小程序一个功能页面有wxml(客户端呈现),js(功能函数),json,wxss(个性化处理),这些是局部的文件。还有全局的文件如…