1.背景介绍
当前的深度学习模型主要建立在神经网络上,即可以通过反向传播训练的多层参数化可微分非线性模块,周志华老师希望探索深度学习模型的新模式,探索不可微模块构建深度模型的可能性。从而提出了一种深度学习模型-----gcforest(multi-Grained Cascade Forest)
上述算法主要有以下几个特点:
(1)超参数少
(2)模型的复杂度可以通过与数据相关的方式自动确定
(3)无需使用反向传播就可以实现深度模型
作者提出了三个疑问:
(1)深度模型=DNN?
(2)是否可以在不进行反向传播的情况下实现深度模型
(3)是否可以使得深度模型赢得kaggle比赛(就是对小数据集的表现)
2.作者的两个启发
2.1. DNN的启发
此篇论文刊登于2017年,当时一般人认为DNN的成功主要是由于DNN其巨大的模型复杂度,但作者认为不然,因为如此的话,浅层网络也可以通过添加无限数量的隐含层达到巨大模型复杂度的目的,但是浅层网络没有深度网络成功,作者认为模型复杂度并不是DNN成功的关键因素,认为逐层处理才是DNN成功的最关键因素,boosting集成算法及其决策树模型只是在数据的原始特征上做处理,没有对模型内的特征做特征变换,且只有有限的模型复杂度。
作者推测深度模型成功的三个因素为:
(1)逐层处理
(2)特征变换
(3)巨大的模型复杂度
2.2.集成学习的启示
作者认为为了建立一个好的集成模型,个体的学习应该是准确且多样化的,单方面的准确的基学习器不如合并准确的基学习器和一些较弱的基学习器效果好,因为可以达到互补的效果,准确的基学习器可以很好地预测那些容易预测的模块,但是一些较弱的基学习器可能对一些比较难以预测的模块进行准确预测,两方面之间的合并可以达到更好的效果,此方面也就是模型的多样性。
下面是提高模型多样性的一些方法:
(1)数据样本的操作:有放回的随机抽样,随机抽样,聚类抽样等。。。
(2)输入特征的操作:不同的特征的选取生成树的模型是不一样的
(3)学习参数的不同
(4)输出表示操作(将数据的标签进行改变,训练的模型可能会有所不同)
4.代码
gcforest的代码已经开源,这里可以看到。
选择采用scikit学习语法以方便使用,下面将介绍如何使用它。
下面是参数的介绍:
shape_1X:
单个样本元素的形状[n_lines,n_cols]。 调用mg_scanning时需要!对于序列数据,可以给出单个int。
n_mgsRFtree:
多粒度扫描期间随机森林中的树木数量。
window:int(default = None)
多粒度扫描期间使用的窗口大小列表。如果“无”,则不进行切片。
stride:int(default = 1)
切片数据时使用的步骤。
cascade_test_size:float或int(default = 0.2)
级联训练集分裂的分数或绝对数。
n_cascadeRF:int(default = 2)
级联层中随机森林的数量,对于每个伪随机森林,创建完整的随机森林,因此一层中随机森林的总数将为2 * n_cascadeRF。
n_cascadeRFtree:int(default = 101)
级联层中单个随机森林中的树数。
min_samples_mgs:float或int(default = 0.1)
节点中执行拆分的最小样本数 在多粒度扫描随机森林训练期间。 如果int number_of_samples = int。 如果float,min_samples表示要考虑的初始n_samples的分数。
min_samples_cascade:float或int(default = 0.1)
节点中执行拆分的最小样本数 在级联随机森林训练期间。 如果int number_of_samples = int。 如果float,min_samples表示要考虑的初始n_samples的分数。
cascade_layer:int(default = np.inf)
允许的最大级联级数。 有用的限制级联的结构。
tolerance:float(default= 0.0)
联生长的精度差,整个级联的性能将在验证集上进行估计, 如果没有显着的性能增益,训练过程将终止
n_jobs:int(default = 1)
任意随机森林适合并预测的并行运行的工作数量。 如果为-1,则将作业数设置为核心数。
from GCForest import gcForest
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split as TTS
from sklearn.metrics import confusion_matrix as cm,recall_score as recall,roc_auc_score as auc
data = pd.read_csv('data.csv',header=None,encoding='utf-16')
x = data.iloc[:,0:264]
y = data.iloc[:,-1]
#x = x.fillna(0)
x = np.array(x)
#y = y.fillna(0)
y = np.array(y)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(x,y,test_size=0.3)
model = gcForest(shape_1X=264, n_mgsRFtree=30, window=90,)
model.fit(X_train, y_train) #fit(X,y) 在输入数据X和相关目标y上训练gcForest;
y_predict = model.predict(X_test) #预测未知样本X的类别;
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_true=y_test, y_pred=y_predict)
print('gcForest accuracy : {}'.format(accuracy))
没有做参数的选择,可能做了之后效果会好一点。下面是结果:准确率为74.52%,但是这个级联好像没有效果,对于我的这个数据。
手写数字识别的表现:
上面的实在手写数字识别的数据上面的表现,很简单的参数就可以表现很好的效果,达到了98.14%
5.评价
下面给出一些我运行过程中认为有道理的知乎大神的一些评论:
深度森林对小数据分析确实要比深度学习鲁棒性更好。多粒度扫描是真的吃资源,在cv问题中,这是不容忽视的问题,想要应用必须要先优化这个问题。在nlp中可能不存在这个问题,我也不是很清楚。深度森林确实有科研价值,没有跟风DL(毕竟周大佬本来就是搞深度森林的)。如果只是想刷榜,或者落地应用一下,真的比不过DL。所以,深度森林替换深度学习,是不可能的,引用在这里
我的理解:深度森林确实有科研价值,没有跟风DL,但是当前不可能比得过DL,没有核心的转变,替换是不可能的!