当前位置:   article > 正文

深度学习-2:TensorFlow 神经网络构建与优化_qlearning 单函数优化

qlearning 单函数优化

1. 神经网络解决问题的基本步骤

基本步骤列举如下:

  • 提取问题中实体的特征向量作为神经网络的输入(特征工程)。
  • 定义神经网络的结构,及如何从输入得到输出(前向传播算法)。
  • 通过训练数据调整神经网络中参数的取值(优化算法)。
  • 利用训练好的神经网络预测未知的数据(在未知数据上使用前向传播算法)。
1.1 前向传播算法

1.1.1 所需信息

  • 神经网络的输入。
  • 神经网络的连接结构。
  • 每个神经元中的参数。

对于一个没有激活函数的三层(输入层、一个隐藏层、输出层)的简单神经网络而言:
前向传播过程则为:

#第一层的结果为 input 点乘【输入层到隐藏层的参数 weights1】
layer1=tf.matmul(input,weights1)
#输出层的结果为 layer1 点乘【隐藏层到输出层的参数weights2】
output_value=tf.matmul(layer1,weights2)
  • 1
  • 2
  • 3
  • 4

由于线性模型的任意组合仍然为线性模型,因此该简单神经网络等价于:

output_value=tf.matmul(input,tf.matmul(weights1,weights2))
#==output_value=tf.matmul(input,weights3)
  • 1
  • 2

因此需要去线性,才可以使隐藏层有意义,进而解决线性不可分问题。
去线性需要激活函数。

1.1.2 激活函数及偏置项

对每个节点的输出在加权和的基础上做一个非线性变换。
可用的非线性变换主要有三:

  • relu:f(x)=max(x, 0)
  • sigmoid:f(x)=1/(1+e^(-x))
  • tanh:f(x)=(1-e^(-2x))/(1+e ^(-2x))

对于一个激活函数为 relu 的三层(输入层、一个隐藏层、输出层)的简单神经网络而言,前向传播过程则为:

#第一层的结果为 input 点乘【输入层到隐藏层的参数 weights1】
layer1=tf.nn.relu(tf.matmul(input,weights1)+biases1)
#输出层的结果为 layer1 点乘【隐藏层到输出层的参数weights2】
output_value=tf.nn.relu(tf.matmul(layer1,weights2)+biases2)
  • 1
  • 2
  • 3
  • 4

1.1.3 多分类问题的网络结构

  • 对于多分类问题,通常为设置 n 个输出节点,得到一个 n 维数组作为输出结果。其中 n 为类别的个数。
  • 可利用Softmax回归将神经网络的输出变为一个概率分布。
    Softmax(y)=e^ y/(add_all(e^y))

1.1.4 回归问题的网络结构

回归问题需要预测出一个任意实数,因此只有一个输出节点。该输出节点的输出值即为预测值。

1.2 优化算法

优化的思想为寻找一组参数,使得损失函数最小化。

1.2.1 损失函数

(1)分类问题的损失函数

使用交叉熵函数。交叉熵刻画两个概率分布之间的距离,表示通过概率分布 q (predicted) 表达概率分布 p (true) 的难度。可求出Softmax回归后得到的输出 Softmax(y) 与真实值 y_ 概率分布的距离,以表示预测值接近真实值的程度。交叉熵越小,概率分布 p 和 q 越接近。
封装好的 Softmax+交叉熵函数如下:

#labels为真实值,logits为未Softmax处理的预测值。
cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y)
#若分类只有一个正确答案,则可用如下函数加快运算速度。
cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y_,logits=y)
  • 1
  • 2
  • 3
  • 4

(2)回归问题的损失函数

使用均方误差。函数如下:

mse=tf.reduce_mean(tf.square(y_-y)
  • 1

(3)自定义损失函数举例

对于报童模型(即 sign(预测值-真实值)= + or -时的损失分别为 a\b),定义的损失为:

loss=tf.reduce_sum(tf.where(tf.greater(y_,y),b*(y_-y),a*(y-y_)))
  • 1

1.2.2 梯度下降与反向传播

Some tips:

  • 梯度下降算法:沿梯度反方向迭代更新单个参数,使总损失最小化。
    学习率:梯度下降算法中,每次更新的幅度。
  • 反向传播算法:在所有参数上使用梯度下降算法。
  • 只有当损失函数为凸函数时,梯度下降算法才能保证得到全局最优解。

若在全部训练数据上,使损失最小化,则计算时间过长。因此有如下梯度下降的改进:

  • 随机梯度下降:在每一轮迭代中,随机优化一条训练数据上的损失函数;
  • 分 batch 梯度下降:每次优化一个 batch的损失函数,因此分 batch训练。分 batch训练如下:
train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
#同时更新神经网络的参数
train_op=tf.group(train_step)
with tf.Session() as sess:
    for i in range(num_train):
  #得到下一个 batch
         xs,ys=data.next_batch(batch_size)
  #用得到的 batch训练网络,即更新参数值。
         sess.run(train_op,feed_dict={x:xs,y_:ys}) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1.2.3 指数衰减的学习率

可以快速得到一个比较优的解,后随迭代的继续减小,逐步减小学习率。

learning_rate=tf.train.exponential_decay(learning_rate_original,global_step,decay_steps,decay_rate,staircase)
  • 1

参数含义如下:

namemeaning
learning_rate_original初始学习率
global_step全局当前迭代次数
decay_steps通常表示完整使用一遍训练数据所需迭代次数
decay_rate每经过 decay_steps,学习率乘decay_rate
staircase是否阶梯式衰减。value=(True,False)

Note:损失函数下降的速度与迭代结束后的总损失大小无关。

1.2.4 正则化

正则化表示在损失函数中加入显式约束,降低每个参数的影响,以减少过拟合。即优化:

loss=J(Theta)+Lamada*R(w)
  • 1

其中Theta表示神经网络中所有的参数,包括权重 w 及偏置项 b;w为权重。

  • L1正则化:R(w)为所有参数的绝对值相加;
  • L2正则化:R(w)为所有参数的平方和。

正则化函数,得出 R(w)值:

#L2正则化
tf.contrib.layers.l2_regularizer(lamada)(w)
#L1正则化
tf.contrib.layers.l1_regularizer(lamada)(w)
  • 1
  • 2
  • 3
  • 4

对于多层神经网络,可以将每层神经网络的 R(w)加入一个集合,之后再汇总。以下为伪码。

for layers in layers:
    w=tf.Variable(format)
    tf.add_to_collection(collection_name,tf.contrib.layers.l2_regularizer(lamada)(w))
cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y)
tf.add_to_collection(collection_name,cross_entropy)
loss=tf.add_n(tf.get_collection(collection_loss))  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1.2.5 滑动平均模型

滑动平均更新参数,使模型在未知数据上更加 robust。滑动平均方式为:

renewed_variable=decay_rate*renewed_variable+(1-decay_rate)*variable
  • 1

代码示例:

#moving_average_decay表示滑动平均的衰减率,global_step为迭代轮数。
variable_averages=tf.train.ExponentialMovingAverage(moving_average_decay,global_step)    
#对所有可优化参数移动平均
variable_averages_op=variable_averages.apply(tf.trainable_variables())  
  • 1
  • 2
  • 3
  • 4

2. TensorFlow下神经网络程序结构

以 mnist手写字体数据集为例,说明程序结构。

#引入库,导入数据
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("",one_hot=True)
mnist.train.num_examples

#设置参数
input_node=784
output_node=10
layer1_node=500
batch_size=100
learning_rate_base=0.8
learning_rate_decay=0.99
regularization_rate=0.0001
training_steps=10000
moving_average_decay=0.99

#定义前向传播,返回预测值 y。
def inference(input_tensor,avg_class,weights1,biases1,weights2,biases2):
    if avg_class is None:
        layer1=tf.nn.relu(tf.matmul(input_tensor,weights1)+biases1)
        return tf.matmul(layer1,weights2)+biases2
    else:
        layer1=tf.nn.relu(tf.matmul(input_tensor,avg_class.average(weights1))+\
                          avg_class.average(biases1))
        return tf.matmul(layer1,avg_class.average(weights2))+\
                          avg_class.average(biases2)

#定义训练模型
def train(mnist):
    x=tf.placeholder(tf.float32,[None,input_node],name="x_input")
    y_=tf.placeholder(tf.float32,[None,output_node],name="y_input")   
    #初始化参数
    weights1=tf.Variable(tf.truncated_normal([input_node,layer1_node],stddev=0.1))
    biases1=tf.Variable(tf.constant(0.1,shape=[layer1_node]))
    weights2=tf.Variable(tf.truncated_normal([layer1_node,output_node],stddev=0.1))
    biases2=tf.Variable(tf.constant(0.1,shape=[output_node]))    
    #没有移动平均的前向传播
    y=inference(x,None,weights1,biases1,weights2,biases2)
    #总迭代次数
    global_step=tf.Variable(0,trainable=False)
    #定义移动平均
    variable_averages=tf.train.ExponentialMovingAverage(moving_average_decay,global_step)    
    #对所有参数应用移动平均
    variable_averages_op=variable_averages.apply(tf.trainable_variables())    
    #带移动平均的前向传播
     average_y=inference(x,variable_averages,weights1,biases1,weights2,biases2)
    #开始定义loss
    #交叉熵
    cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1))
    cross_entropy_mean=tf.reduce_mean(cross_entropy)
    #L2正则化
    regularizer=tf.contrib.layers.l2_regularizer(regularization_rate)
    regularization=regularizer(weights1)+regularizer(weights2)
    #汇总loss
    loss=cross_entropy_mean+regularization
    #指数衰减的学习率
    learning_rate=tf.train.exponential_decay(learning_rate_base,global_step,\
                                             mnist.train.num_examples/batch_size,learning_rate_decay)
    #优化损失函数
    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
    #同时更新神经网络的参数和每一个参数的滑动平均值
    train_op=tf.group(train_step,variable_averages_op)
    #计算准确率
    correct_prediction=tf.equal(tf.arg_max(average_y,1),tf.arg_max(y_,1))
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))  
    
    #开始会话
    with tf.Session() as sess:
        #初始化
        tf.global_variables_initializer().run()
        #准备数据
        validate_feed={x:mnist.validation.images,y_:mnist.validation.labels}
        test_feed={x:mnist.test.images,y_:mnist.test.labels}
        for i in range(training_steps):
            if i%1000==0:
                validate_acc=sess.run(accuracy,feed_dict=validate_feed)
                print ("global_step is %d" % sess.run(global_step))
                print ("After %d training step(s),validation accuracy using average model is %g" %(i,validate_acc))
            #训练数据
            xs,ys=mnist.train.next_batch(batch_size)
            sess.run(train_op,feed_dict={x:xs,y_:ys})
        print (sess.run(tf.arg_max(average_y,1),feed_dict=test_feed))
        test_acc=sess.run(accuracy,feed_dict=test_feed)
        print ("After %d training step(s),test accuracy using average model is %g" %(training_steps,test_acc))
        #在此导入待预测数据
        x_new=mnist.test.images[:50]
        #导出预测结果
        return (sess.run(tf.arg_max(inference(x_new,variable_averages,weights1,biases1,weights2,biases2),1)))

 #定义主程序    
def main(argv=None):
    train(mnist)
if __name__=="__main__":
    tf.app.run()  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/647520
推荐阅读
相关标签
  

闽ICP备14008679号