神经网络模型

每个node包含两种操作:线性变换(仿射变换)和激发函数(activation function)。

其中仿射变换是通用的,而激发函数可以很多种,如下图。

MLLib中实现ANN

使用两层(Layer)来对应模型中的一层:

  • AffineLayer 仿射变换: output = W · input + b
  • 如果是最后一层,使用SoftmaxLayerWithCrossEntropyLoss或者SigmoidLayerWithSquaredError;如果是中间层,则使用functionalLayer(new SigmoidFunction()). 目前MLlib只支持sigmoid函数,实际上ReLU激发函数更普遍

BP算法计算Gradient的四个步骤:

对照BP算法的步骤,可以发现分隔成Affine和Activation的好处。BP1和BP2中的计算,不同的activation函数有不同的计算形式,将affine变换和activation函数解耦方便组合,进而方便形成各种类型的神经网络。

MLLib FeedForward Trainer

训练器重要模块如下:

ANN模型中每层对应AffineLayer + FunctionalLayerModel OR SofrmaxLayerModelWIthCrossEntropyLoss

每个LayerModel实现三个函数:eval, computePrevDelta, grad, 作为输出层的SoftmaxLayerModel有些特殊,额外具有LossFunction特性。

可验证affine+activation LayerModel的计算组合跟BP1-4一致。

AffineLayerModel (仿射变换层)

  • eval

    \(\text{output} = W \cdot \text{input} + b\)

  • computePrevDelta

    \(prev\delta = W * \delta\)

  • grad

    $\dot{W} = input \cdot \delta^l / \text{data size} $

    input is \(a^{l-1}\),前一层的激发函数输出

    \(\dot{b} = \delta^l / \text{data size}\)

FunctionalLayerModel(activate function \(\sigma\))

作为affineModel的activation model,只影响prev\(\delta\) 的计算,grad不计算

  • eval

    \(\text{output} = \sigma (\text{input})\)

  • computePrevDelta

    \(\delta :=\delta * \sigma'(\text{input})\)

  • grad

    pass

SoftmaxLayerModelWithCrossEntropyLoss

作为最后一层激发函数,这一层很特殊。

  • eval

    计算参见手写公式。

  • computePrevDelta

    不计算

  • grad

    不计算

  • loss

    计算\(\delta^L\),公式推导参见手写公式,代码如下:

    ApplyInPlace(output, target, delta, (o: Double, t: Double) => o - t)

返回loss

Softmax输出层的激发函数:

\(a^L_j = \frac{e^{z^L_j}}{\sum_k e^{z^L_k}}\)

计算BP1:\(\delta^L_j = a^L_j -y_j\)

训练mnist手写数字识别

import org.apache.spark.ml.classification.MultilayerPerceptronClassifier
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession} object ann extends App {
val spark = SparkSession
.builder
.appName("ANN for MNIST")
.master("local[3]")
.getOrCreate()
spark.sparkContext.setLogLevel("ERROR") import spark.implicits._ // Load the data stored in text as a DataFrame.
val dataRdd: DataFrame= spark.sparkContext.textFile("handson-ml/data/train.csv")
.map {
line =>
val linesp = line.split(",")
val linespDouble = linesp.map(f => f.toDouble)
(linespDouble.head, Vectors.dense(linespDouble.takeRight(linespDouble.length - 1)))
}.toDF("label","features") val data = dataRdd
// Split the data into train and test
val splits: Array[DataFrame] = data.randomSplit(Array(0.6, 0.4), seed = 1234L)
val train: Dataset[Row] = splits(0)
val test: Dataset[Row] = splits(1) val layers = Array[Int](28*28, 300, 100, 10) // create the trainer and set its parameters
val trainer = new MultilayerPerceptronClassifier()
.setLayers(layers)
.setBlockSize(128)
.setSeed(1234L)
.setMaxIter(100)
.setLabelCol("label")
.setFeaturesCol("features") // train the model
val model = trainer.fit(train) // compute accuracy on the test set
val result = model.transform(test)
val predictionAndLabels = result.select("prediction", "label")
val evaluator = new MulticlassClassificationEvaluator()
.setMetricName("accuracy") println("Test set accuracy = " + evaluator.evaluate(predictionAndLabels))
}

后记

测试集结果精度为96.68%。实际上并不高,同样的数据集使用TensorFlow训练,activation function选择ReLU,同样使用Softmax作为输出,结果可以达到98%以上。Sigmoid函数容易带来vanishing gradients问题,导致学习曲线变平。

artificial neural network in spark MLLib的更多相关文章

  1. 人工神经网络 Artificial Neural Network

    2017-12-18 23:42:33 一.什么是深度学习 深度学习(deep neural network)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高 ...

  2. 吴恩达深度学习第1课第4周-任意层人工神经网络(Artificial Neural Network,即ANN)(向量化)手写推导过程(我觉得已经很详细了)

    学习了吴恩达老师深度学习工程师第一门课,受益匪浅,尤其是吴老师所用的符号系统,准确且易区分. 遵循吴老师的符号系统,我对任意层神经网络模型进行了详细的推导,形成笔记. 有人说推导任意层MLP很容易,我 ...

  3. Neural Network and Artificial Neural Network

    神经网络的基本单元为神经元neuron,也称为process unit,可以做一些基本的运算操作.   人脑和动物大脑的发育,依赖于经验的积累和学习.神经网络就是一个用来仿照人脑进行学习的机器,其包含 ...

  4. What is “Neural Network”

    Modern neuroscientists often discuss the brain as a type of computer. Neural networks aim to do the ...

  5. 论文笔记系列-Neural Network Search :A Survey

    论文笔记系列-Neural Network Search :A Survey 论文 笔记 NAS automl survey review reinforcement learning Bayesia ...

  6. 机器学习之Artificial Neural Networks

    人类通过模仿自然界中的生物,已经发明了很多东西,比如飞机,就是模仿鸟翼,但最终,这些东西会和原来的东西有些许差异,artificial neural networks (ANNs)就是模仿动物大脑的神 ...

  7. Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.1

    3.Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.1 http://blog.csdn.net/sunbow0 ...

  8. Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.2

    3.Spark MLlib Deep Learning Convolution Neural Network(深度学习-卷积神经网络)3.2 http://blog.csdn.net/sunbow0 ...

  9. Spark MLlib Deep Learning Convolution Neural Network (深度学习-卷积神经网络)3.3

    3.Spark MLlib Deep Learning Convolution Neural Network(深度学习-卷积神经网络)3.3 http://blog.csdn.net/sunbow0 ...

随机推荐

  1. websocket activemq

    websocket:应用与服务端保持长连接 不停通信 activemq:偶发通信  心跳机制

  2. How to use external classes and PHP files in Laravel Controller?

    By: Povilas Korop Laravel is an MVC framework with its own folder structure, but sometimes we want t ...

  3. 如何获取堆的dump 的信息,如何分析

    获取方式: 1. jdk 自带启动参数 -XX:+HeapDumpBeforeFullGC -XX:HeapDumpPath=/x/x 产生dump日志,然后用visualVm分析 2. jmap 命 ...

  4. 2017/2/16:自己ajax+json习惯性写法 代码拼接的写法 +json用post提交乱码的原因

    1.先导入jquery的包 2.ajax的写法跟注意点 返回一个list的写法 代码拼接写法: html层: 2.script处 4:在你前面传递参数的时候没有遇到乱码问题的情况下,你使用json并且 ...

  5. GC收集器种类

    转载:https://wangkang007.gitbooks.io/jvm/content/la_ji_shou_ji_qi.html 收集器 1.1 Serial(串行)收集器 Serial收集器 ...

  6. Reading CLR via c# 4th Edition

    In fact, at runtime, the CLR has no idea which programming language the developer used for thesource ...

  7. python学习 day09 (3月14日)----函数

    一.函数的进阶 1.1 动态参数 1.2* ** 1.3*args , **kwargs 1.4 函数的注释 1.5名称空间 1.6函数的嵌套全局变量 : 贴边写的局部变量 : 不是贴边写的. ''' ...

  8. Tkinter添加图片

    Tkinter添加图片的方式,与Java相似都是利用label标签来完成的: 一.默认的是gif的格式,注意将png后缀名修改为gif还是无法使用,文件格式依然错误. photo = PhotoIma ...

  9. rails 新建user的phonenumber字段

    1.新建字段 //rails g migration add_字段名_to_表名 字段名:字段类型 rails g migration add_title_to_contents title:stri ...

  10. trunc()用法和add_months()

    TRUNC函数用于对值进行截断. 用法有两种:TRUNC(NUMBER)表示截断数字,TRUNC(date)表示截断日期. (1)截断数字: 格式:TRUNC(n1,n2),n1表示被截断的数字,n2 ...