Spark2.0机器学习系列之7: MLPC(多层神经网络)
Spark2.0 MLPC(多层神经网络分类器)算法概述
MultilayerPerceptronClassifier(MLPC)这是一个基于前馈神经网络的分类器,它是一种在输入层与输出层之间含有一层或多层隐含结点的具有正向传播机制的神经网络模型。
中间的节点使用sigmoid (logistic)函数,输出层的节点使用softmax函数。输出层的节点的数目表示分类器有几类。MLPC学习过程中使用BP算法,优化问题抽象成logistic loss function并使用L-BFGS进行优化。
算法进一步剖析
Sigmoid函数
中间层使用Sigmoid函数(也叫 logistic函数),看下面的函数曲线,Zi=0时,f(Zi)=0.5,Zi<0时候,f(Zi)<0.5, Zi>0时,f(Zi)>0.5,这样就可以把f(Zi)当概率理解了,大于0.5的概率一类,小于0.5概率的一类。由此可见,Sigmoid函数通常用于二分问题。
Sigmoid函数:
Sigmoid微分:
Sigmoid函数可以连续微分,因此可以用在BP(后向传播)过程中。使用这个函数形式还有一个很重要的原因,Sigmoid函数的微分形式完全可以用自身表达出来,与函数变量x无关,使得Sigmoid的函数很容易使用链式法则。
BP
参考博文:
BP神经网络后向传播原理
http://blog.csdn.net/tingyue_/article/details/38966249
softmax函数
参考:https://en.wikipedia.org/wiki/Softmax_function
假设输出层有K个节点,各节点完成训练后的拟合系数向量为:
w1,w2,...wk...wK,注意这里的wk是第k节点的拟合系数向量,wk本身也是一个向量,wk=[wk0,wk1,...],k=1∼K,
xk是最后一个隐含层向第k个节点的输出向量
X是最后一个隐含层对所有节点的输出矩阵
softmax函数为:
显然对所有输出节点而言,最大概率(P(y=j|X),j=1∼K)所在的位置,就是某个样本最终的分类。
Spark2.0 MLPC 代码(流程)
package my.spark.ml.practice.classification; import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel;
import org.apache.spark.ml.classification.MultilayerPerceptronClassifier;
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession; public class myMLPC { public static void main(String[] args) {
SparkSession spark=SparkSession
.builder()
.appName("MLPC")
.master("local[4]")
.config("spark.sql.warehouse.dir","file///:G:/Projects/Java/Spark/spark-warehouse" )
.getOrCreate();
String path="G:/Projects/CgyWin64/home/pengjy3/softwate/spark-2.0.0-bin-hadoop2.6/"
+ "data/mllib/sample_multiclass_classification_data.txt";
//屏蔽日志
Logger.getLogger("org.apache.spark").setLevel(Level.ERROR);
Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF);
//加载数据,randomSplit时加了一个固定的种子seed=100,
//是为了得到可重复的结果,方便调试算法,实际工作中不能这样设置
Dataset<Row>[] split=spark.read().format("libsvm").load(path).randomSplit(new double[]{0.6,0.4},);
Dataset<Row> training=split[];
Dataset<Row> test=split[];
training.show(,false);//数据检查 //第一层树特征个数
//最后一层,即输出层是labels个数(类数)
//隐藏层自己定义
int[] layer=new int[]{,,,}; int[] maxIter=new int[]{,,,,,};
double[] accuracy=new double[]{,,,,,,,,,};
//利用如下类似的循环可以很方便的对各种参数进行调优
for(int i=;i<maxIter.length;i++){
MultilayerPerceptronClassifier multilayerPerceptronClassifier=
new MultilayerPerceptronClassifier()
.setLabelCol("label")
.setFeaturesCol("features")
.setLayers(layer)
.setMaxIter(maxIter[i])
.setBlockSize()
.setSeed();
MultilayerPerceptronClassificationModel model=
multilayerPerceptronClassifier.fit(training); Dataset<Row> predictions=model.transform(test);
MulticlassClassificationEvaluator evaluator=
new MulticlassClassificationEvaluator()
.setLabelCol("label")
.setPredictionCol("prediction")
.setMetricName("accuracy");
accuracy[i]=evaluator.evaluate(predictions);
} //一次性输出所有评估结果
for(int j=;j<maxIter.length;j++){
String str_accuracy=String.format(" accuracy = %.2f", accuracy[j]);
String str_maxIter=String.format(" maxIter = %d", maxIter[j]);
System.out.println(str_maxIter+str_accuracy);
}
}
}
参数设置,算法调优
Spark2.0中对于这个在1.6版本新加入的机器学习算法还没有什么文档,我们就用下面的办法吧:
//Spark中explainParams函数可以展示某个分类器有那些参数:
System.out.println(multilayerPerceptronClassifier.explainParams());
//有一些不影响结果设置的我就省略了(如输入label列labelCol等等)。
()layers: Sizes of layers from input layer to output layer. E.g., Array(, , ) means
inputs, one hidden layer with neurons and output layer of neurons. (current:
[I@158f492) ()maxIter: maximum number of iterations (>= ) (default: , current: )
()tol: the convergence tolerance for iterative algorithms (default: 1.0E-4) ()solver: The solver algorithm for optimization. Supported options: l-bfgs, gd. (Default l-
bfgs) ()stepSize: Step size to be used for each iteration of optimization (default: 0.03) ()blockSize: Block size for stacking input data in matrices. Data is stacked within
partitions. If block size is more than remaining data in a partition then it is adjusted to
the size of this data. Recommended size is between and (default: , current: )
可以设定的一些参数有: 神经网络结构
(1)layers:???
迭代停止条件
(2)maxIter: 需要运算到结果收敛
(3)tol: 允许误差 一般取0.001~0.00001,当迭代结果的误差小于该值时,结束迭代计算,给出结果。
优化算法-solver
Spark中的优化算法,可以参考本人的另两篇文章:
ML优化算法之一:梯度下降算法、随机梯度下降(应用于线性回归、Logistic回归等等)
http://blog.csdn.net/qq_34531825/article/details/52396165
(4)solver:有两种算法可供选择: l-bfgs和gd;
.stepSize=0.03,tol=0.0001
l-bfgs:上很快能收敛,大约20次,训练速度也更快
maxIter = 5 accuracy = 0.35 training time = 267ms
maxIter = 10 accuracy = 0.74 training time = 429ms
maxIter = 20 accuracy = 0.91 training time = 657ms
maxIter = 50 accuracy = 0.92 training time = 941ms
maxIter = 100 accuracy = 0.92 training time = 914ms
maxIter = 500 accuracy = 0.92 training time = 1052msgd算法:需要多得多的迭代次数,即使在提高学习率和提高允许误差tol的情况下,
还是慢很多,慢10以上倍左右吧。
stepsize=0.2,tol=0.001
maxIter = 100 accuracy = 0.55 training time = 4209ms
maxIter = 500 accuracy = 0.92 training time = 11216ms
maxIter = 1000 accuracy = 0.92 training time = 14540ms
maxIter = 2000 accuracy = 0.92 training time = 14708ms
maxIter = 5000 accuracy = 0.92 training time = 14669ms
由此可见,两种算法要想达到收敛,GB(梯度下降算法)慢很多,建议优先使用L-BFGS。
In general, when L-BFGS is available, we recommend using it instead of SGD since L-BFGS tends to converge faster (in fewer iterations).(Spark document)
(5)学习率stepSize,这是一个比较关键的参数
一般来说学习率越大,权重变化越大,收敛越快;但训练速率过大,会引起系统的振荡。
太高的学习率,可以减少网络训练的时间,但是容易导致网络的不稳定与训练误差的增加,
会引起系统的振荡。
太低的学习率,需要较长的训练时间。
在实际工作中,在时间可以接受的范围内,为了模型的稳定性,还是建议选择尽量选择
小一些的学习率。
(6)blockSize:这个不很清楚究竟是什么?希望计算机牛人告诉我。
Spark2.0机器学习系列之7: MLPC(多层神经网络)的更多相关文章
- Spark2.0机器学习系列之11: 聚类(幂迭代聚类, power iteration clustering, PIC)
在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法: (1)K-means (2)Latent Dirichlet all ...
- Spark2.0机器学习系列之10: 聚类(高斯混合模型 GMM)
在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法: (1)K-means (2)Latent Dirichlet allocation (LDA) ...
- Spark2.0机器学习系列之9: 聚类(k-means,Bisecting k-means,Streaming k-means)
在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法: (1)K-means (2)Latent Dirichlet allocation (LDA) ...
- Spark2.0机器学习系列之1: 聚类算法(LDA)
在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法: (1)K-means (2)Latent Dirichlet allocation (LDA) ...
- Spark2.0机器学习系列之12: 线性回归及L1、L2正则化区别与稀疏解
概述 线性回归拟合一个因变量与一个自变量之间的线性关系y=f(x). Spark中实现了: (1)普通最小二乘法 (2)岭回归(L2正规化) (3)La ...
- Spark2.0机器学习系列之6:GBDT(梯度提升决策树)、GBDT与随机森林差异、参数调试及Scikit代码分析
概念梳理 GBDT的别称 GBDT(Gradient Boost Decision Tree),梯度提升决策树. GBDT这个算法还有一些其他的名字,比如说MART(Multiple Addi ...
- Spark2.0机器学习系列之5:随机森林
概述 随机森林是决策树的组合算法,基础是决策树,关于决策树和Spark2.0中的代码设计可以参考本人另外一篇博客: http://www.cnblogs.com/itboys/p/8312894.ht ...
- Spark2.0机器学习系列之4:Logistic回归及Binary分类(二分问题)结果评估
参数设置 α: 梯度上升算法迭代时候权重更新公式中包含 α : http://blog.csdn.net/lu597203933/article/details/38468303 为了更好理解 α和 ...
- Spark2.0机器学习系列之3:决策树
概述 分类决策树模型是一种描述对实例进行分类的树形结构. 决策树可以看为一个if-then规则集合,具有“互斥完备”性质 .决策树基本上都是 采用的是贪心(即非回溯)的算法,自顶向下递归分治构造. 生 ...
随机推荐
- git init 与 git init --bare 区别
git init 与 git init --bare 区别 发现问题 最早是在公司的wiki上发现了这个命令,google后发现值得记录下来 实践中发现的区别 网上找了很多资料,但说的很乱,干脆在自己 ...
- SQL Server 数据库同步,订阅、发布、复制、跨服务器
随便说两句 折腾了一周,也算把数据库同步弄好了.首先局域网内搭建好,进行各种测试,弄的时候各种问题,弄好以后感觉还是挺简单的.本地测试好了,又在服务器进行测试,主要的难点就是跨网段同步,最后也解决了, ...
- 树莓派安装centos 7系统
1,格式化 https://www.sdcard.org/downloads/formatter_4/eula_windows/ 2,烧录,Win32DiskImager https://source ...
- 数据库 数据库SQL语句四
多表查询 等值连接 --查询员工信息,员工号,姓名,月薪,部门名称 select e.empno,e.ename,d.dname from emp e,dept d where e.deptno=d. ...
- 匿名内部类 Inner class
先说结论 匿名内部类分两种,一种是接口的匿名实现,一种是类的匿名子类!后者往往用于修改特定方法. 再说起因 本来以为匿名内部类很简单,就是接口的匿名实现,直到我发现了下面这段代码: public cl ...
- 【BZOJ】1690: [Usaco2007 Dec]奶牛的旅行(分数规划+spfa)
http://www.lydsy.com/JudgeOnline/problem.php?id=1690 第一题不是水题的题.. 分数规划.. T-T 百度吧..http://blog.csdn.ne ...
- OSG 中 相交測试 模块 工作流程及原理
主要涉及三个类: 1. osgUtil::PolytopeIntersector // 详细不同算法实现类 2. osgUtil::IntersectionVisitor //用来遍历节点树的每一个节 ...
- ejabberd
ejabberd是的Jabber / XMPP协议的即时通讯服务器,持牌GPLv2许可下(自由和开放源码) ,写的爱尔朗/检察官办公室.在其它特性中, ejabberd是跨平台,容错, cluster ...
- Yii2发送邮箱总结
修改配置文件,普通版在(config/web.php).高级版默认配置在/common/config/main-local.php 'components' => [ 'mailer' => ...
- (转)Spring AOP编程原理、Demo
转自: http://pandonix.iteye.com/blog/336873/ AOP原理: http://blog.csdn.net/moreevan/article/details/1197 ...