赞
踩
基本步骤列举如下:
1.1.1 所需信息
对于一个没有激活函数的三层(输入层、一个隐藏层、输出层)的简单神经网络而言:
前向传播过程则为:
#第一层的结果为 input 点乘【输入层到隐藏层的参数 weights1】
layer1=tf.matmul(input,weights1)
#输出层的结果为 layer1 点乘【隐藏层到输出层的参数weights2】
output_value=tf.matmul(layer1,weights2)
由于线性模型的任意组合仍然为线性模型,因此该简单神经网络等价于:
output_value=tf.matmul(input,tf.matmul(weights1,weights2))
#==output_value=tf.matmul(input,weights3)
因此需要去线性,才可以使隐藏层有意义,进而解决线性不可分问题。
去线性需要激活函数。
1.1.2 激活函数及偏置项
对每个节点的输出在加权和的基础上做一个非线性变换。
可用的非线性变换主要有三:
对于一个激活函数为 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.1.3 多分类问题的网络结构
1.1.4 回归问题的网络结构
回归问题需要预测出一个任意实数,因此只有一个输出节点。该输出节点的输出值即为预测值。
优化的思想为寻找一组参数,使得损失函数最小化。
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)
(2)回归问题的损失函数
使用均方误差。函数如下:
mse=tf.reduce_mean(tf.square(y_-y)
(3)自定义损失函数举例
对于报童模型(即 sign(预测值-真实值)= + or -时的损失分别为 a\b),定义的损失为:
loss=tf.reduce_sum(tf.where(tf.greater(y_,y),b*(y_-y),a*(y-y_)))
1.2.2 梯度下降与反向传播
Some tips:
若在全部训练数据上,使损失最小化,则计算时间过长。因此有如下梯度下降的改进:
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 指数衰减的学习率
可以快速得到一个比较优的解,后随迭代的继续减小,逐步减小学习率。
learning_rate=tf.train.exponential_decay(learning_rate_original,global_step,decay_steps,decay_rate,staircase)
参数含义如下:
name | meaning |
---|---|
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)
其中Theta表示神经网络中所有的参数,包括权重 w 及偏置项 b;w为权重。
正则化函数,得出 R(w)值:
#L2正则化
tf.contrib.layers.l2_regularizer(lamada)(w)
#L1正则化
tf.contrib.layers.l1_regularizer(lamada)(w)
对于多层神经网络,可以将每层神经网络的 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.5 滑动平均模型
滑动平均更新参数,使模型在未知数据上更加 robust。滑动平均方式为:
renewed_variable=decay_rate*renewed_variable+(1-decay_rate)*variable
代码示例:
#moving_average_decay表示滑动平均的衰减率,global_step为迭代轮数。
variable_averages=tf.train.ExponentialMovingAverage(moving_average_decay,global_step)
#对所有可优化参数移动平均
variable_averages_op=variable_averages.apply(tf.trainable_variables())
以 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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。