• 【Tensorflow专题-03】深层神经网络


    • 基本定义:一类通过多层非线性变换对高复杂度性数据建模算法的合集。

    • 激活函数实现去线性化

      在前面所提到的示例中,输入输出与权值有关系:y=xW ,换句话说,对于任何输入输出,都可以通过与权值进行加权求得,但这样的结果,实践证明无法解决高于一维的数据分类问题,由此提出去线性化 的概念,也即激活函数 。以下给出加入了激活函数和偏置项后的神经元结构

      这里写图片描述

      上面的结构使用函数表达为:

      A=f(xW+b)

      对比之前的激活函数,其实就是在其基础上进行了一次函数运算。以下给出了几种常用的非线性函数的激活函数图像

      这里写图片描述

      tensorflow一共提供了7种不同的激活函数,当然,tensorflow也支持自己定义激活函数。

    • 损失函数

      • 损失函数刻画了神经网络的输出结果与目标之间的差距

      • 经典损失函数

      • 对于分类问题,一般会按照分类的数目来确定输出数目,通常n分类问题会有n个输出,比如,对于一个数字识别问题,其实就是10分类问题,这样的输出可以刻画为[0,0,0,1,0,0,0,0,0,0] ,1代表输出的结果为真,反之为假,那么前面的例子标识的就是结果为:3。当然,为了更准确的用数学语言描述,我们需要把输出转换为概率语言表达,通过交叉熵(cross entropy) 来刻画输出向量与期望向量之间的近似程度,对于概率分布p,q ,他们的交叉熵定义为:H(p,q)=-sum_limits xp(x)log(q(x)) 。有的时候,神经网络输出的结果并不一定是概率分布,这时就需要把其转换为概率分布,通过Softmax回归实现这个目标,如下示意:

        这里写图片描述

        Softmax的函数表达式定义为:

        softmax(y)i=yi=eyjnj=ieyj

      • 对于回归问题,输出节点一般仅有一个,对于这种类别,常用的损失函数为均方误差(MSE mean squared error) ,其定义如下:

        MSE(y,y)=ni=1(yiyi)2n

      • 自定义损失函数:损失函数的定义有时需要结合实际问题进行设定,以下给出一个使用自定义损失函数和使用MSE的例子,这里求解的问题为:

      这里写图片描述

      代码如下:

      
      # TensorFlow 在模拟训练集上展示完整的训练过程
      
      
      # author = yooongchun
      
      
      # time = 20180107
      
      
      # 解决商品销量预测问题,同时引入损失函数概念,说明考察的指标不同,则定义的损失函数也应该有异
      
      import tensorflow as tf
      from numpy.random import RandomState
      
      
      # 定义训练集大小
      
      batch_size=8
      
      
      # 输入的placeholder
      
      
      # None参数表示训练集数据放到了一个batch中
      
      
      # 输入2个节点
      
      x=tf.placeholder(tf.float32,shape=(None,2),name='x-input')
      
      # 输出节点,对于回归问题,一般仅有一个输出节点
      
      y_=tf.placeholder(tf.float32,shape=(None,1),name='y-input')
      
      
      # 定义神经网络参数
      
      w1=tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))
      
      
      # 定义神经网络前向传播过程
      
      
      # 仅通过线性加权获得
      
      y=tf.matmul(x,w1)
      
      
      # 定义损失函数
      
      
      # 损失函数参数,分别为多预测和少预测对应的损失
      
      loss_less=1
      loss_more=10
      
      # 使用自定义损失函数
      
      loss=tf.reduce_sum(tf.where(tf.greater(y,y_),(y-y_)*loss_more,(y_-y)*loss_less))
      
      # 使用MSE均方值定义损失函数
      
      loss_mse=tf.reduce_mean(tf.square(y-y_))
      train_step=tf.train.AdamOptimizer(0.001).minimize(loss_mse)
      
      
      # 生成随机数模拟数据集
      
      rdm=RandomState(1)
      dataset_size=128
      X=rdm.rand(dataset_size,2)
      
      
      # 定义标签,并加入噪音(为了区别不同损失函数之间的差别)
      
      Y=[[x1+x2+rdm.rand()/10.0-0.05] for (x1,x2) in X]
      
      
      # 创建会话进行训练
      
      with tf.Session() as sess:
          tf.global_variables_initializer().run()
      
          # 设定训练轮数
          STEPS=5000
          for i in range(STEPS):
              start=(i*batch_size)%dataset_size
              end=min(start+batch_size,dataset_size)
              # 选择样本训练
              sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
          print(sess.run(w1))
    • 神经网络优化算法

      • 反向传播(backpropagation)算法和梯度下降(gradient decent)算法是用来调整神经网络参数的主要算法

      • 梯度下降算法更新参数θ 的公式为:θn+1=θnηθnJ(θn) ,式中,η 代表学习率(learning rate)

      • 梯度下降算法理论上只能达到局部最优,如下示意:

      这里写图片描述

      另外,梯度下降算法对于大量数据收敛很慢,这时提出一种改进算法:随机梯度下降(stochastic gradient descent)算法,即对于每一次参数更新,只选择一部分(batch)数据进行更新,这样能兼顾正确性和收敛速度。

      • 指数衰减学习率

      过大的学习率可能会导致模型参数振荡,而太小的学习率会导致收敛太慢,鉴于此,设置一种先大后小的指数型衰减学习率,以保证模型既能较快收敛又不至于振荡。

      这里写图片描述

      • 过拟合问题

      当模型的参数多到能够完全区分每个变量,这时数据的噪声已经被模型所包含,这样的模型失去了“预测”的功能,称之为:过拟合。如下图示:

      这里写图片描述

      避免过拟合的一个常用方法称之为:正则化(regularization)。正则化的思想是在损失函数中加入刻画模型复杂度的指标。当损失函数为J(θ) 时,加入正则化后优化的目标即成为J(θ)+λR(w) ,其中,R(w) 刻画的就是模型的复杂度,而λ 代表模型复杂度在总损失中占有的比例。常用的R(w) 有两种,其一为L1 正则化,数学描述为:

      R(w)=||w||1=i|wi|

      其二为L2 正则化,数学描述为:

      R(w)=||w||22=i|w2i|

      正则化的目的在于限制权重的大小,使得模型不能任意拟合训练数据中的随机噪声。这两种正则化各有特点,其中,L1正则化会使得模型参数变稀疏(更多参数变为0),而L2则不会;另外,L2正则化公式可导,而L1不可。有时,会把两种正则化方法一起使用,如:R(w)=iα|wi|+(1α)w2i

      • 滑动平均模型:滑动平均模型能保证模型在测试数据集上更健壮。

      Tensorflow提供了tf.train.ExponentialMovingAverage来实现滑动平均模型。初始化时该函数使用一个衰减率(decay)来控制模型更新的速度。该函数对每一个变量维护一个影子变量(shadow variable),其更新规则为:

      shadow_variable=decayshadow_variable+(1decay)variable

      易看出,越大的衰减率,模型更新速度越慢,Tensorflow提供了动态更新decay的机制,当提供一个num_updates 参数时,衰减率更新公式为:

      decay=min{decay,1+num_updates10+num_updates}

      num_updates=10 时,decay取值如下:

      这里写图片描述

      一个使用滑动平均模型的例子

      
      # TensorFlow 滑动平均模型
      
      
      # author = yooongchun
      
      
      # time = 20180113
      
      
      import tensorflow as tf
      
      
      # 定义变量
      
      v1 = tf.Variable(0, dtype=tf.float32)
      
      # step 模拟训练轮数
      
      step = tf.Variable(0, trainable=False)
      
      
      # 定义一个滑动平均类,初始衰减率给定0.99,控制衰减率变量为step
      
      ema = tf.train.ExponentialMovingAverage(0.99, step)
      
      # 定义一个更新变量滑动平均的操作
      
      maintain_average_op = ema.apply([v1])
      with tf.Session() as sess:
          tf.global_variables_initializer().run()
          # 获取参数的滑动平均
          sess.run(maintain_average_op)
          print(sess.run([v1, ema.average(v1)]))
          # 更新变量值
          sess.run(tf.assign(v1, 5))
          sess.run(maintain_average_op)
          print(sess.run([v1, ema.average(v1)]))
          # 更新step
          sess.run(tf.assign(step, 10000))
          sess.run(tf.assign(v1, 10))
          sess.run(maintain_average_op)
          print(sess.run([v1, ema.average(v1)]))
      
          sess.run(maintain_average_op)
          print(sess.run([v1, ema.average(v1)]))
      

  • 相关阅读:
    POJ--3164--Command Network【朱刘算法】最小树形图
    金典 SQL笔记(6)
    hdoj1106排序
    linux程序设计——运行SQL语句(第八章)
    iOS-UITextView-文本输入视图的使用
    HDU 5305 Friends(简单DFS)
    Android IntentService全然解析 当Service遇到Handler
    概要设计的要点
    DispatcherTimer
    原型模式
  • 原文地址:https://www.cnblogs.com/yczha/p/13160252.html
Copyright © 2020-2023  润新知