指数衰减学习率是先使用较大的学习率来快速得到一个较优的解,然后随着迭代的继续,逐步减小学习率,使得模型在训练后期更加稳定。在训练神经网络时,需要设置学习率(learning rate)控制参数的更新速度,学习速率设置过小,会极大降低收敛速度,增加训练时间;学习率太大,可能导致参数在最优解两侧来回振荡。
今天我们使用Tensorflow建立一个简单神经网络,然后我们使用指数衰减学习率。
首先我们先建立一个简单的神经网络
import tensorflow as tf
#读取MNIST数据
from tensorflow.examples.tutorials.mnist import input_data
# 从MNIST_data/中读取MNIST数据。这条语句在数据不存在时会自动执行下载
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
#检视数据
print(type(mnist)) #tensorflow.contrib.learn.python.learn.datasets.base.Datasets
print(type(mnist.train.images)) #numpy.ndarray
print(mnist.train.images.shape) #(55000, 784)
print(mnist.test.images.shape) #(10000, 784)
#设定网络参数
training_epochs = 15 #训练次数,比如总体要循环多少次
batch_size = 100 #每批次要提取数据的量,这里是提取100张图片,
learning_rate = 0.8 #学习率
n_hidden_1 = 500 #隐藏层1的神经元个数,
n_input = 784 #输入层的个数
n_classes = 10 #输出层的个数
n_samples = mnist.train.num_examples #训练数据总数
#定义Placeholder(占位符)
x = tf.placeholder("float", [None, n_input])
y = tf.placeholder("float", [None, n_classes])
#构建多层神经网络
def multilayer_perceptron(x, weights, biases):
#第一个隐藏层和RELU激活函数
layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
layer_1 = tf.nn.relu(layer_1)
#最后的输出层
out_layer = tf.matmul(layer_1, weights['out']) + biases['out']
return out_layer
#设定权重与偏移
weights = {
'h1':tf.Variable(tf.random_normal([n_input, n_hidden_1])),
'out':tf.Variable(tf.random_normal([n_hidden_1, n_classes]))
}
biases = {
'b1':tf.Variable(tf.random_normal([n_hidden_1])),
'out':tf.Variable(tf.random_normal([n_classes]))
}
#建立模型
pred = multilayer_perceptron(x, weights, biases)
#设定代价函数
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y ))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)
#准确率
correct_predictions = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
correct_predictions = tf.cast(correct_predictions, "float")
accuracy = tf.reduce_mean(correct_predictions)
#初始化所有变量
init = tf.global_variables_initializer()
#训练模型
#执行会话
sess = tf.InteractiveSession()
sess.run(init)
for epoch in range(training_epochs): #进行15次训练
#初始化评论损失值=0.0
avg_cost = 0.0
total_batch = int(n_samples/batch_size) #总train数据55000/每次100张= 完成一次循环多少次
for i in range(total_batch):
batch_x, batch_y = mnist.train.next_batch(batch_size)
_, c, train_acc = sess.run([optimizer, cost, accuracy], feed_dict={x:batch_x, y:batch_y})
avg_cost += c /total_batch # 循环一次的平均损失值
train_acc += train_acc / total_batch # 循环一次的训练数据的准确率
print("Epoch: {} cost={} acc={}".format(epoch+1, avg_cost, train_acc))
print("Training Completed in {} Epochs".format(training_epochs))
print("Test_Accuracy:", accuracy.eval({x: mnist.test.images, y:mnist.test.labels}))
上面我们用tensorflow建立了一个简单神经网络来预测mnist手写字体数据集。下面我们要使用指数衰减学习率进行优化,我们需要修改以下几个部分
#learning_rate = 0.8 #学习率
global_step = tf.Variable(0)
learning_rate = tf.train.exponential_decay(learning_rate=0.8, global_step=global_step, decay_rate=0.99, decay_steps=550, staircase=True) #指数衰减学习率
首先我们把原先的learning_rate替换成tf.train.exponential_decay
0.8我们设定的初始学习率,global_step 总训练次数这里我们可以设置为0,(在minimize里也一定要加入这个参数,要不学习率不变化),decay_steps 衰减速度,我们希望是55000个数据,每次100个 550次全体数据循环一次后学习率开始变化,那么这里我们要写成550。decay_rate 衰减系数,550次循环后,learning_rate=0.8*0.99按照我们的要求进行减小
#optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost, global_step=global_step)
在minimize里也一定要加入这个参数,要不学习率不变化
for i in range(total_batch):
batch_x, batch_y = mnist.train.next_batch(batch_size)
_, c, train_acc = sess.run([optimizer, cost, accuracy], feed_dict={x:batch_x, y:batch_y})
learning_rate_num = sess.run(learning_rate)
print("batch: {} learning_rate={}".format(i, learning_rate_num))
这里你可以把每次循环的学习率打印出来,看看在多少次的时候学习率开始减小了。
![03b1db9908ff2046869843710c0fcece.png](https://i-blog.csdnimg.cn/blog_migrate/bec7958bdf0f2364e693f33424c145d6.jpeg)
下面是完整代码。
import tensorflow as tf
#读取MNIST数据
from tensorflow.examples.tutorials.mnist import input_data
# 从MNIST_data/中读取MNIST数据。这条语句在数据不存在时会自动执行下载
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
#检视数据
print(type(mnist)) #tensorflow.contrib.learn.python.learn.datasets.base.Datasets
print(type(mnist.train.images)) #numpy.ndarray
print(mnist.train.images.shape) #(55000, 784)
print(mnist.test.images.shape) #(10000, 784)
#设定网络参数
training_epochs = 15 #训练次数,比如总体要循环多少次
batch_size = 100 #每批次要提取数据的量,这里是提取100张图片,
#learning_rate = 0.8 #学习率
global_step = tf.Variable(0)
learning_rate = tf.train.exponential_decay(learning_rate=0.8, global_step=global_step, decay_rate=0.99, decay_steps=550, staircase=True) #指数衰减学习率
n_hidden_1 = 500 #隐藏层1的神经元个数,
n_input = 784 #输入层的个数
n_classes = 10 #输出层的个数
n_samples = mnist.train.num_examples #训练数据总数
#定义Placeholder(占位符)
x = tf.placeholder("float", [None, n_input])
y = tf.placeholder("float", [None, n_classes])
#构建多层神经网络
def multilayer_perceptron(x, weights, biases):
#第一个隐藏层和RELU激活函数
layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
layer_1 = tf.nn.relu(layer_1)
#最后的输出层
out_layer = tf.matmul(layer_1, weights['out']) + biases['out']
return out_layer
#设定权重与偏移
weights = {
'h1':tf.Variable(tf.random_normal([n_input, n_hidden_1])),
'out':tf.Variable(tf.random_normal([n_hidden_1, n_classes]))
}
biases = {
'b1':tf.Variable(tf.random_normal([n_hidden_1])),
'out':tf.Variable(tf.random_normal([n_classes]))
}
#建立模型
pred = multilayer_perceptron(x, weights, biases)
#设定代价函数
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y ))
#optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost, global_step=global_step)
#准确率
correct_predictions = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
correct_predictions = tf.cast(correct_predictions, "float")
accuracy = tf.reduce_mean(correct_predictions)
#初始化所有变量
init = tf.global_variables_initializer()
#训练模型
#执行会话
sess = tf.InteractiveSession()
sess.run(init)
for epoch in range(training_epochs): #进行15次训练
#初始化评论损失值=0.0
avg_cost = 0.0
total_batch = int(n_samples/batch_size) #总train数据55000/每次100张= 完成一次循环多少次
for i in range(total_batch):
batch_x, batch_y = mnist.train.next_batch(batch_size)
_, c, train_acc = sess.run([optimizer, cost, accuracy], feed_dict={x:batch_x, y:batch_y})
learning_rate_value = sess.run(learning_rate)
print("batch: {} learning_rate={}".format(i, learning_rate_value))
avg_cost += c /total_batch # 循环一次的平均损失值
train_acc += train_acc / total_batch # 循环一次的训练数据的准确率
print("Epoch: {} cost={} acc={}".format(epoch+1, avg_cost, train_acc))
print("Training Completed in {} Epochs".format(training_epochs))
print("Test_Accuracy:", accuracy.eval({x: mnist.test.images, y:mnist.test.labels}))
运行代码你们会发现学习率开始变小了,如果想让学习率变的快些,可以适当变小decay_rate 衰减系数,比如变成0.95或者0.9。