用ELM极限学习机分类 - python实现

ELM极限学习机python实现

  • ELM
  • python实现
    • ELM实现
    • 随机获取数据
    • 训练与测试
    • 绘制分类彩图
  • 总结

ELM

极限学习机(Extreme Learning Machine),是一种训练单隐层前馈神经网络的随机化算法。
用ELM极限学习机分类 - python实现_第1张图片
它不用BP训练,更像是求解析解。
第一层可以看作Linear层,不过其中的参数 w , b w,b w,b只需要随机初始化,不需要再训练。Linear后跟一个sigmoid。输出一个矩阵H,具体计算为:
用ELM极限学习机分类 - python实现_第2张图片
其中 n n n为样本数, m m m为神经元个数。
第二层为求解析解,我们定义:
β = ( β 1 T , . . . , β m T ) T \beta = (\beta_1^T,...,\beta_m^T)^T β=(β1T,...,βmT)T
优化问题:
min ⁡ β ∣ ∣ H β − Y ∣ ∣ \min_\beta||H\beta - Y|| minβHβY
等价于均方差损失最小,从而求解出:
β ^ = H † Y \hat{\beta} = H^{\dag}Y β^=HY
H † H^{\dag} H是矩阵 H H H的Moore-Penrose广义逆矩阵。
在优化问题中引入正则化项:
min ⁡ β ∣ ∣ β ∣ ∣ + λ ∣ ∣ H β − Y ∣ ∣ \min_\beta||\beta|| + \lambda||H\beta - Y|| minββ+λHβY
λ \lambda λ是控制参数,此时解为:
β ^ = ⎱ ( I / λ + H T H ) − 1 H T Y i f n > m ⎰ H T ( I / λ + H H T ) − 1 Y i f n ≤ m \hat{\beta} = ^{\lmoustache H^T(I/\lambda+HH^T)^{-1}Y\quad if \quad n\le m}_{\rmoustache (I/\lambda+H^TH)^{-1}H^TY\quad if\quad n>m} β^=(I/λ+HTH)1HTYifn>mHT(I/λ+HHT)1Yifnm

python实现

用ELM实现分类任务,博主先尝试分类MNIST手写体,效果很不好,在这里使用随机生成的简单数据集进行分类实验。

ELM实现

import numpy as np
class ELM():
    # 输入数据集X、标签Y、神经元个数m、控制参数L
    def __init__(self, X, Y, m, L):
        self.X = X
        self.Y = Y
        self.m, self.L = m, L
        self.TRAIN_beta()
        
    def sigmoid(self, x):
        return 1.0/(1+np.exp(-x))
    # 训练函数,随机w,b 计算H、beta
    def TRAIN_beta(self):
        n, d = self.X.shape
        self.w = np.random.rand(d, self.m)
        self.b = np.random.rand(1, self.m)
        H = self.sigmoid(np.dot(self.X, self.w) + self.b)
        self.beta = np.dot(np.linalg.inv(np.identity(self.m)/self.L + np.dot(H.T, H)), np.dot(H.T, self.Y)) # 加入正则化且 n >> m
        #self.beta = np.dot(np.linalg.pinv(H), self.Y) # 不加入正则化
        print('TRAIN FINISH beta_shape ',self.beta.shape)
    # 测试函数,计算方法
    def TEST(self, x):
        H = self.sigmoid(np.dot(x, self.w) + self.b) # 使用测试集计算H,其中w、b是之前随机得到的
        result = np.dot(H, self.beta)
        return result

随机获取数据

# 使用sklearn随机生成数据
# make_classification生成三元分类模型数据
from sklearn.datasets import make_classification 
import matplotlib.pyplot as plt

# 关键参数有n_samples(生成样本数), n_features(样本特征数), n_redundant(冗余特征数)和n_classes(输出的类别数)
# X1为样本特征,Y1为样本类别输出, 共400个样本,每个样本2个特征,输出有2个类别,没有冗余特征,每个类别一个簇
X,Y = make_classification(n_samples=10000, n_features=2, n_redundant=0, n_clusters_per_class=1, n_classes=3)
plt.scatter(X[:,0], X[:,1], c=Y, s=3, marker='o')
plt.show()

用ELM极限学习机分类 - python实现_第3张图片

训练与测试

# 训练时将标签改为OneHot编码效果比较好
Y_onehot = np.eye(3)[Y]

# 用前8000个数据训练,5000个神经元,控制参数取0.1
elm = ELM(X[:8000], Y_onehot[:8000], 5000, 0.1)
# 用后2000个数据进行测试
predict = elm.TEST(X[8000:])
predict = np.argmax(predict, axis = 1) # OneHot编码形式 取每行最大值的索引即类别
acc = np.sum(predict == Y[8000:])/2000
print('acc :', acc)

这里由于数据集较简单,且分布集中,能获得较高的正确率

acc : 0.9525

绘制分类彩图

# 绘制分类彩图
import matplotlib as mpl
x_np = np.asarray(X)
y_np = np.asarray(Y)
N, M = 50, 50 # 横纵各采样多少个值

x1_min, x2_min = x_np.min(axis = 0) # 列最小值
x1_max, x2_max = x_np.max(axis = 0) # 列最大值

t1 = np.linspace(x1_min, x1_max, N) # 在min-max间线性采样
t2 = np.linspace(x2_min, x2_max, M)

x1, x2 = np.meshgrid(t1, t2) # 生成网格采样点
x_show = np.stack((x1.flat, x2.flat), axis = 1) # 测试点
y_predict = np.argmax(elm.TEST(x_show), axis = 1)

# 绘制分类图
cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
plt.pcolormesh(x1, x2, np.array(y_predict).reshape(x1.shape), cmap = cm_light)
plt.scatter(X[:,0], X[:,1], c=Y, s=3, marker='o')
plt.show()

用ELM极限学习机分类 - python实现_第4张图片

总结

ELM随机取参数,后面采用解析解的形式。感觉上效果不太好,并且不知道为什么在MNIST数据集上不work。
附一张计算图
用ELM极限学习机分类 - python实现_第5张图片

你可能感兴趣的:(AutoEncoder)