大数据进阶必修课!Spark实战神经网络算法

12.SparkMLlib神经网络算法

12.1 人工神经网络算法

(1)人工神经网络
人工神经网络(Artificial Neural Networks——ANNs)提供了一种普遍而且实用的方法,来从样本中学习值为实数、离散或向量的函数。用反向传播(BackPropagation)这样的算法使用梯度下降来调节网络参数以最佳拟合由输入-输出对组成的训练集合。ANN是基于神经元模型构建的,是一种由许多神经元组成的信息处理网络,具有并行分布结构。每一个神经元具有单一输出,且与其他神经元相连接,有多种输出连接方式,每种方式对应一个连接权重系数。
人工神经网络的研究在一定程度上受到了生物学的启发,因为生物的学习系统是由相互连接的神经元(neuron)组成的异常复杂的网络。而人工神经网络与此大体相似,它是由一系列简单单元相互密集连接构成,其中每一个单元有一定数量的实值输入(可能是其他单元的输出),并产生单一的实数值输出(可能成为其他很多单元的输入)。下图就是一个最简单的神经元的示意图,图右是由神经元前后连接构成的一个三层前馈神经网络,分为输入层,中间层也即隐藏层,输出层。从图中可以看到,输入为 x 1 x_1 x1 x 2 x_2 x2,输入权重分别为 w 1 w_1 w1 w 2 w_2 w2,代表输入对输出的影响程度。 y y y为神经元的处理单元,加入激活函数,完成从输入到输出的映射。
在这里插入图片描述

常用的激活函数有 s i g m o i d sigmoid sigmoid函数和双曲正切函数即 t a n h tanh tanh函数,若采用 s i g m o i d sigmoid sigmoid函数则神经元的输入输出映射关系是一个逻辑回归。注意,这里是有一次见到这个神奇的函数了。

(2)误差逆传播算法BP
上面介绍了人工神经网络的基本原理和示意图,我们可以知道如果设定多个输入,增加层数和中间的隐藏层数,就可以构建一个复杂的从输入到输出的映射拓扑结构。其中最关键的部分就是层与层之间的权重系数。训练数据的输入,不断地去迭代就是去确定这些权重系数的方法,也就是神经网络的自我学习。神经网络从数据中进行学习,由数据自动决定网络参数的值。这里给出了一个寻找最优权重参数的指标——损失函数,常用均方误差来表示。神经网络对数据进行学习的目的就是不断调整参数,降低这个损失函数:

E = 1 2 ∑ k ( y k − t k ) 2 E = \frac { 1 } { 2 } \sum _ { k } ( y _ { k } - t _ { k } ) ^ { 2 } E=21k(yktk)2

y k y_k yk是预测值, t k t_k tk是真实值, k k k为输出值个数
均方误差会计算神经网络输出与数据真实值之差的平方和,每一次训练数据的输入到输出,都可以计算出一个均方误差,神经网络学习的目标就是使得这个均方误差的值越来越小,达到一定范围,即完成训练。神经网络中使用梯度下降的思想来寻找损失函数最小值进行最优化。
误差逆传播算法是最常用的ANN 学习技术,它是从神经网络正向传播的反向来计算输出关于输入和权重的梯度值,从而找到如何调整权重来使得误差函数减小。误差逆传播法可高效计算权重参数的梯度,它基于链式法则,将局部导数进行反向传播, 每经过一个结点,把次节点的局部导数乘以上游传过来的值,再传递给前面的节点,最后传递到整个网络的输入端。将逆传播法应用到神经网络中最小损失函数的求解中,即可得到损失函数对输入层每个输入的敏感程度,同时也可以得到网络中权重参数对损失函数的影响程度。下图即为用计算图来表示一个反向传播计算导数的过程。
在这里插入图片描述
而我们这里说的误差逆传播,就是指的损失函数关于网络权重的逆传播。

(3)基于误差逆传播神经网络的实现
基于误差逆传播算法我们就可以完成一个神经网络的实现,如图是一个误差逆传播神经网络。其训练过程如下:

准备:在神经网络中设置好层数,输入神经元个数和输出神经元个数,并设置好合适的权重和偏置;

第一步:从训练数据中随机选择一部分数据;

第二步:使用误差逆传播法计算损失函数关于各个权重参数的梯度;

第三步:将权重参数沿梯度方向进行微小的更新;

第四步:对上述第一、二、三步进行重复

当损失函数减小到一定程度时停止迭代

输出:参数确定的逆差误传播人工神经网络

12.2 算法源码分析

MLlib对神经网络部分的支持较为充分,源码部分分析如下:

(1)class NeuralNet:ANN神经网络类,需要设置的参数:

  • size——数据格式:Array[Int],神经网络每层的节点个数;
  • layer——神经网络层数;
  • activation_function:隐含层函数,包括sigmoid和tanh;
  • learnRate——学习率;
  • momentum——权重更新参数;
  • inputZeroMaskedFraction——训练数据中加入噪声;
  • scaling_learningRate——学习缩放因子;
  • dropoutFraction——隐含层节点加入噪声;
  • testing——内部变量,用于测试;
  • output_fraction——输出函数支持sigmoid,softmax,linear;
  • initW——初始化权重

(2)Nntrain:训练模型的方法,基于梯度下降法进行权重优化计算:

  • InitialWeight:初始化权重;
  • NNtrain方法调用的方法:
  • NNff:前向传播算法实现;
  • NNbp:后向传播算法实现;
  • Nnapplygrads:权重更新;

(3)NeuralNetModel:神经网络模型类:

  • Predict:预测计算;
  • Loss:计算输出平均误差;
    包含参数:权重、配置参数。

12.3 应用实战

12.3.1 数据说明

测试数据使用的是优化算法中的经典测试函数:

1.Sphere Model
函数表达式如下:

搜索范围:-100<=x_i<=100
全局最优值:min(f_1)=f_1(0,…,0)=0
此函数是非线性对称单峰函数主要测试算法的寻优精度。

2.Generalized Rosenbrock
函数表达式如下:

搜索范围:-30<=x_i<=30
全局最优值:min(f_2)=f_2(0,…,0)=0
此函数是难于进行极小优化的病态二次函数,在其函数图像中,全局最优值与可达局部最优值之间有一道山谷,曲面山谷的点的最大下降方向与函数最小值的最好方向垂直。所以该函数在搜索过程中的优化方向难以确定,会使算法难以辩解正确的搜索方向。

3.Generalized Rastrigin
函数表达式如下:

搜索范围:-5,12<=x_i<=5.12
全局最优值:min(f_3)=f_3(0,…,0)=0
此函数基于Sphere函数,通过余弦函数产生大量局部最小值,通过此函数的图像可以发现这是一个典型的具有大量局部最优点的复杂多峰函数,优化算法很容易陷入局部最优值从而得不到全局最优解。

12.3.2 测试函数代码

import java.util.Random
import breeze.linalg.{
  Matrix => BM,
  CSCMatrix => BSM,
  DenseMatrix => BDM,
  Vector => BV,
  DenseVector => BDV,
  SparseVector => BSV,
  axpy => brzAxpy,
  svd => brzSvd
}
import breeze.numerics.{
  exp => Bexp,
  cos => Bcos,
  tanh => Btanh
}
import scala.math.Pi

object RandSampleData extends Serializable {
  // Rosenbrock:
  //∑(100*(x(i+1)-x(i) 2) 2 + (x(i)-1) 2)
  // Rastrigin:
  //∑(x(i) 2 -10*cos(2*3.14*x(i))+10)
  // Sphere :
  //∑(x(i) 2)
  /**
   * 测试函数: Rosenbrock, Rastrigin
   * 随机生成n2维数据,并根据测试函数计算Y
   * n1 行,n2 列,b1 上限,b2 下限,function 计算函数
   */
  def RandM(
    n1: Int,
    n2: Int,
    b1: Double,
    b2: Double,
    function: String): BDM[Double] = {
    //    val n1 = 2
    //    val n2 = 3
    //    val b1 = -30
    //    val b2 = 30
    val bdm1 = BDM.rand(n1, n2) * (b2 - b1).toDouble + b1.toDouble
    val bdm_y = function match {
      case "rosenbrock" =>
        val xi0 = bdm1(::, 0 to (bdm1.cols - 2))
        val xi1 = bdm1(::, 1 to (bdm1.cols - 1))
        val xi2 = (xi0 :* xi0)
        val m1 = ((xi1 - xi2) :* (xi1 - xi2)) * 100.0 + ((xi0 - 1.0) :* (xi0 - 1.0))
        val m2 = m1 * BDM.ones[Double](m1.cols, 1)
        m2
      case "rastrigin" =>
        val xi0 = bdm1
        val xi2 = (xi0 :* xi0)
        val sicos = Bcos(xi0 * 2.0 * Pi) * 10.0
        val m1 = xi2 - sicos + 10.0
        val m2 = m1 * BDM.ones[Double](m1.cols, 1)
        m2
      case "sphere" =>
        val xi0 = bdm1
        val xi2 = (xi0 :* xi0)
        val m1 = xi2
        val m2 = m1 * BDM.ones[Double](m1.cols, 1)
        m2
    }
    val randm = BDM.horzcat(bdm_y, bdm1)
    randm
  }
}

12.3.3 代码详解

基于上述的优化算法测试函数随机生成样本,使用神经网络寻找最优值,观察输出结果:

//导入所需的机器学习包和Spark基础的支持库
import org.apache.log4j.{ Level, Logger }
import org.apache.spark.{ SparkConf, SparkContext }
import org.apache.spark.storage.StorageLevel
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.mllib.linalg.{ Vector, Vectors }
import org.apache.spark.mllib.linalg.distributed.RowMatrix
import org.apache.spark.mllib.regression.LabeledPoint
import breeze.linalg.{
  Matrix => BM,
  CSCMatrix => BSM,
  DenseMatrix => BDM,
  Vector => BV,
  DenseVector => BDV,
  SparseVector => BSV,
  axpy => brzAxpy,
  svd => brzSvd,
  max => Bmax,
  min => Bmin,
  sum => Bsum
}
import scala.collection.mutable.ArrayBuffer
import NN.NeuralNet
import util.RandSampleData

object Test_example_NN {

  def main(args: Array[String]) {
    //1 构建Spark对象
    val conf = new SparkConf().setAppName("NNtest")
    val sc = new SparkContext(conf)

//基于经典优化算法测试函数随机生成样本
    //2 随机生成测试数据
    // 随机数生成
    Logger.getRootLogger.setLevel(Level.WARN)
    val sample_n1 = 1000
val sample_n2 = 5
//在此处选择所需的随机数生成函数,从前述的函数中
    val randsamp1 = RandSampleData.RandM(sample_n1, sample_n2, -10, 10, "sphere")
    // 归一化[0 1]
    val normmax = Bmax(randsamp1(::, breeze.linalg.*))
    val normmin = Bmin(randsamp1(::, breeze.linalg.*))
    val norm1 = randsamp1 - (BDM.ones[Double](randsamp1.rows, 1)) * normmin
    val norm2 = norm1 :/ ((BDM.ones[Double](norm1.rows, 1)) * (normmax - normmin))
    // 转换样本train_d
    val randsamp2 = ArrayBuffer[BDM[Double]]()
    for (i <- 0 to sample_n1 - 1) {
      val mi = norm2(i, ::)
      val mi1 = mi.inner
      val mi2 = mi1.toArray
      val mi3 = new BDM(1, mi2.length, mi2)
      randsamp2 += mi3
    }
    val randsamp3 = sc.parallelize(randsamp2, 10)
    sc.setCheckpointDir("/user/local/checkpoint")
    randsamp3.checkpoint()
    val train_d = randsamp3.map(f => (new BDM(1, 1, f(::, 0).data), f(::, 1 to -1)))
    //3 设置训练参数,建立模型
    // opts:迭代步长,迭代次数,交叉验证比例
    val opts = Array(100.0, 50.0, 0.0)
    train_d.cache
    val numExamples = train_d.count()
    println(s"numExamples = $numExamples.")
    val NNmodel = new NeuralNet().
      setSize(Array(5, 7, 1)).
      setLayer(3).
      setActivation_function("tanh_opt").
      setLearningRate(2.0).
      setScaling_learningRate(1.0).
      setWeightPenaltyL2(0.0).
      setNonSparsityPenalty(0.0).
      setSparsityTarget(0.05).
      setInputZeroMaskedFraction(0.0).
      setDropoutFraction(0.0).
      setOutput_function("sigm").
      NNtrain(train_d, opts)
    //4 模型测试
    val NNforecast = NNmodel.predict(train_d)
    val NNerror = NNmodel.Loss(NNforecast)
    println(s"NNerror = $NNerror.")
    val printf1 = NNforecast.map(f => (f.label.data(0), f.predict_label.data(0))).take(20)
    println("预测结果——实际值:预测值:误差")
    for (i <- 0 until printf1.length)
      println(printf1(i)._1 + "\t" + printf1(i)._2 + "\t" + (printf1(i)._2 - printf1(i)._1))
    println("权重W{1}")
    val tmpw0 = NNmodel.weights(0)
    for (i <- 0 to tmpw0.rows - 1) {
      for (j <- 0 to tmpw0.cols - 1) {
        print(tmpw0(i, j) + "\t")
      }
      println()
    }
    println("权重W{2}")
    val tmpw1 = NNmodel.weights(1)
    for (i <- 0 to tmpw1.rows - 1) {
      for (j <- 0 to tmpw1.cols - 1) {
        print(tmpw1(i, j) + "\t")
      }
      println()
}
}
}
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
华为数字化转型必修课PDF是一本关于华为数字化转型的必修教材,旨在帮助企业了解和应对数字化时代的挑战。该教材包含了华为在数字化转型过程中的经验和教训,为企业提供了一套完整的转型方案和方法论。 首先,华为数字化转型必修课PDF从理论与实践相结合的角度出发,全面介绍了数字化转型的背景、必要性和现实意义。它提供了一系列的案例分析,详细解析了华为在数字化转型中所面临的问题和解决方案。通过这些案例,企业可以更好地理解数字化转型的过程和关键因素。 其次,该教材详细介绍了数字化转型的五大要素:战略与愿景、组织与文化、架构与能力、技术与平台、落地与实践。它提供了一套系统化的框架和方法来帮助企业在数字化转型中找到适合自身发展的路径。同时,华为还分享了自己的数字化转型实践,包括战略调整、组织架构调整、技术平台建设等方面的经验。 此外,华为数字化转型必修课PDF还提供了一些关键的工具和技巧来帮助企业进行数字化转型。比如,它介绍了如何通过建立敏捷的创新机制来加速转型进程;如何利用大数据和人工智能来发现和分析潜在的商机;如何构建数字化生态系统来实现持续创新和价值输出等等。 总之,华为数字化转型必修课PDF是一本非常实用的教材,适用于任何希望通过数字化转型来提升企业竞争力和创造更多价值的企业。它的内容丰富,可操作性强,能够帮助企业深入理解数字化转型的本质和要求,并提供了一套可行的转型方案和方法论。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值