ELM python实现

日常扯:ELM的Python实现是在上个学期已经完成的工作,这周重新打开,发现对一些基本的操作还是不熟悉,借此机会进行整理

##铺垫
###关于ELM

极限学习机(Extreme Learning Machine) ELM,是2006年由黄广斌提出来的求解单隐层神经网络的算法。最大的特点是输入权值和隐含节点的偏置都是在给定范围内随机生成的,被证实学习效率高且泛化能力强。训练时的主要目的在于输出层的权值求解。

算法步骤
输入 :样本集,激活函数为,隐藏层节点数
输出:输出权值
步骤1: 随机设置输入权值和隐含节点偏置,
步骤2 : 计算隐藏层输出矩阵,
步骤3: 计算输出矩阵的广义逆矩阵,
步骤4: 计算极速学习机的隐含层到输出层的权值.
这里写图片描述
                           (图片来自于《基于随机赋权网络的符号值数据分类》作者:张凡)

关于ELM更多详细的数学解释请参考[ 简单易学的机器学习算法——极限学习机(ELM)][1]

ELM python2.0实现

import numpy as np
from sklearn.datasets import load_iris  #数据集
from sklearn.model_selection import train_test_split  #数据集的分割函数
from sklearn.preprocessing import StandardScaler      #数据预处理

#引入包含数据验证方法的包
from sklearn import metrics

class SingeHiddenLayer(object):
    
    def __init__(self,X,y,num_hidden):
        self.data_x = np.atleast_2d(X)       #判断输入训练集是否大于等于二维; 把x_train()取下来
        self.data_y = np.array(y).flatten()  #a.flatten()把a放在一维数组中,不写参数默认是“C”,也就是先行后列的方式,也有“F”先列后行的方式; 把 y_train取下来
        self.num_data = len(self.data_x)  #训练数据个数
        self.num_feature = self.data_x.shape[1];  #shape[] 读取矩阵的长度,比如shape[0]就是读取矩阵第一维度的长度 (120行,4列,所以shape[0]==120,shapep[1]==4)
        self.num_hidden = num_hidden;  #隐藏层节点个数
        
        #随机生产权重(从-1,到1,生成(num_feature行,num_hidden列))
        self.w = np.random.uniform(-1, 1, (self.num_feature, self.num_hidden)) 
        
        #随机生成偏置,一个隐藏层节点对应一个偏置
        for i in range(self.num_hidden):
            b = np.random.uniform(-0.6, 0.6, (1, self.num_hidden))
            self.first_b = b
   
        #生成偏置矩阵,以隐藏层节点个数4为行,样本数120为列
        for i in range(self.num_data-1):
            b = np.row_stack((b, self.first_b))  #row_stack 以叠加行的方式填充数组
        self.b = b
    #定义sigmoid函数  
    def sigmoid(self,x):
        return 1.0 / (1 + np.exp(-x))
        
    def train(self,x_train,y_train,classes):
        mul = np.dot(self.data_x, self.w)    #输入乘以权重 
        add = mul + self.b                        #加偏置
        H = self.sigmoid(add)                #激活函数

        H_ = np.linalg.pinv(H)               #求广义逆矩阵
        #print(type(H_.shape))
        
        #将只有一列的Label矩阵转换,例如,iris的label中共有三个值,则转换为3列,以行为单位,label值对应位置标记为1,其它位置标记为0
        self.train_y = np.zeros((self.num_data,classes))  #初始化一个120行,3列的全0矩阵
        for i in range(0,self.num_data):
            self.train_y[i,y_train[i]] = 1   #对应位置标记为1
        
        self.out_w = np.dot(H_,self.train_y)  #求输出权重
        
    def predict(self,x_test):
        self.t_data = np.atleast_2d(x_test)    #测试数据集
        self.num_tdata = len(self.t_data)      #测试集的样本数
        self.pred_Y = np.zeros((x_test.shape[0]))  #初始化
        
        b = self.first_b
        
        #扩充偏置矩阵,以隐藏层节点个数4为行,样本数30为列
        for i in range(self.num_tdata-1):
            b = np.row_stack((b, self.first_b))  #以叠加行的方式填充数组
          
         #预测  
        self.pred_Y = np.dot(self.sigmoid(np.dot(self.t_data,self.w)+b),self.out_w)
        
        #取输出节点中值最大的类别作为预测值 
        self.predy = []
        for i in self.pred_Y:
            L = i.tolist()
            self.predy.append(L.index(max(L)))  

    def score(self,y_test):
        print("准确率:")
        #使用准确率方法验证
        print(metrics.accuracy_score(y_true=y_test,y_pred=self.predy))
        
stdsc = StandardScaler()   #StandardScaler类,利用接口在训练集上计算均值和标准差,以便于在后续的测试集上进行相同的缩放
iris = load_iris()
x,y = stdsc.fit_transform(iris.data),iris.target   #数据归一化
x_train, x_test, y_train, y_test = train_test_split(x , y, test_size=0.2, random_state=0)

ELM = SingeHiddenLayer(x_train,y_train,4)   #训练数据集,训练集的label,隐藏层节点个数
ELM.train(x_train,y_train,3)
ELM.predict(x_test)
ELM.score(y_test)

当然,已经证明,隐藏层节点数越多训练精度越高。此参数可以自行进行调整进行测试观察分析结果。


补充说明:
1.数据归一化为何很有必要(参考:[知乎][2])
数据归一化 = 数据标准化。是为了消除数量级的影响,将不同数量级的数据变成同一数量级。比如:在K近邻算法中,如果不对解释变量进行标准化,那么具有小数量级的解释变量的影响就微乎其微了。
这里写图片描述
(此图来自[知乎][2])

2.犯过一个理解上的错
输入权重和偏置的随机取值是在训练时随机取,并把这两值记下,在做预测时使用的输入权重和偏置与训练时使用的应该是同一个值,而不是再次随机-。-
[1]: http://blog.csdn.net/google19890102/article/details/18222103
[2]:https://www.zhihu.com/question/20455227

  • 14
    点赞
  • 147
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Elm 是一种函数式的编程语言,而 Python 是一种通用的高级编程语言。虽然两者都可以用来进行编程,但是它们在语法、特性和使用场景上有很大的不同。 Elm 是一种专门用于构建前端应用的语言,它的主要特点是强调函数式编程、静态类型检查和无副作用。Elm 使用类似于 Haskell 的强静态类型系统,这意味着在编译阶段就可以发现可能的错误,提高了代码质量和可维护性。Elm 还提供了一系列的函数式编程特性,如高阶函数、不可变性、模式匹配等,使得代码更加清晰和易于理解。此外,Elm 还内置了一些用于构建用户界面的库,例如信号模型和视图函数,使得开发者可以方便地构建交互式的网页应用。 Python 则是一种通用的高级编程语言,适用于多种领域的应用开发。Python 的语法简洁易读,具有很强的可读性。它提供了丰富的标准库和第三方库,支持多种编程范式,如面向对象编程、函数式编程和过程式编程。Python 的灵活性使得它非常适合用于快速原型开发、数据分析、人工智能和机器学习等领域。 要在 Elm实现 Python 代码,首先需要理解两者的语法和特性差异,然后根据需求来进行相应的改写。Elm 不支持动态类型、类和对象,所以需要使用 Elm 提供的其他语法和特性来达到相同的功能。相比之下,Python 更为灵活和庞大,可以更全面地满足各种需求。 总之,ElmPython 都有各自的优势和适用场景,使用它们来实现代码需要结合具体需求来选择。无论是前端应用还是通用编程,选择合适的语言都能够提高开发效率和代码质量。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值