Optimizer
Stochastic Gradient Descent (SGD)
基础方法,是mini batch中的一种,加了随机
Momentum
即原始的
加上一个负的学习效率乘上一个矫正值
数学公式如下:
一定程度上保留之前更新的方向(像一个醉汉,随着坡度的变大,随着惯性,下降的方向越来越笔直)
AdaGrad
数学公式如下:
相较Momentum,AdaGrad会自动调整learnin rate,从而使得逼近速度越来越快
RMSProp
同时具备Momentum和AdaGrad两个方法的优势,但缺少一部分
Adam
计算m时使用Momentum下坡属性,计算v时使用AdaGrad阻力属性,同时更新m和v
Tensorboard
- 使用placeholder中的name=参数进行tensorboard中的名字显示
- 使用with进行整个层的名字显示
with tf.name_scope('inputs'):
xs = tf.placeholder(tf.float32, [None, 1], name='x_input')
ys = tf.placeholder(tf.float32, [None, 1], name='y_input')
- 将信息存储入一个logs文件夹中
writer = tf.summary.FileWriter("logs/", sess.graph)
- 在命令行中输入
tensorboard --logdir='logs/'
Tensorboard 2
- 查看historygram中的参数内容,表示整个训练过程中的参数变化,通常是一个分布值
示意图如下图所示:tf.summary.histogram(layer_name + '/weights', Weights)
- 定义scalar中的loss,是观察训练过程以及优化的重要手段
tf.summary.scalar('loss', loss)
- 需要在写入文件之前,把这些summary做merge
测试图如下:merged = tf.summary.merge_all() writer = tf.summary.FileWriter("logs/", sess.graph) for i in range(1000): sess.run(train_step, feed_dict={xs: x_data, ys: y_data}) if i % 50 == 0: # 需要将merge后的内容做run result = sess.run(merged,feed_dict={xs: x_data, ys: y_data}) # 然后选择每隔多少间距将结果进行画图 writer.add_summary(result, i)
Classification
- 针对分类问题,比较适合的激活函数为softmax,相应的损失函数也有不同的对应cross_entropy,当然训练的时候也是要对cross_entropy进行最小化。
# add output layer prediction = add_layer(xs, 784, 10, activation_function=tf.nn.softmax) # 使用梯度下降法进行交叉熵的最小化 cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),reduction_indices=[1])) # loss train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
- 使用一部分数据作为test测试数据进行对比,从而看出分类的准确性
def compute_accuracy(v_xs, v_ys): global prediction y_pre = sess.run(prediction, feed_dict={xs: v_xs}) # 比对y_pre和v_ys中最大值的索引,并将其结果转换为float32格式 correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys}) # 所得结果是一个百分数 return result
Dropout
- 定义placeholder来确定要保留的比例,并在add_layer的时候进行dropout操作。
keep_prob = tf.placeholder(tf.float32) # 在add_layer中的部分 # 在原方程的基础上进行dropout Wx_plus_b = tf.matmul(inputs, Weights) + biases # 然后调用dropout进行去除(每次添加层的时候都要调用这部分) Wx_plus_b = tf.nn.dropout(Wx_plus_b, keep_prob)
- 在每次训练的时候保留一半,keep_prob=0.5;而在最后统计结果的时候不需要做出dropout
for i in range(500): sess.run(train_step, feed_dict={xs: X_train, ys: y_train, keep_prob: 0.5}) if i % 50 == 0: # 将结果记录并做出画图添加 train_result = sess.run(merged, feed_dict={xs: X_train, ys: y_train, keep_prob: 1}) test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test, keep_prob: 1}) train_writer.add_summary(train_result, i) test_writer.add_summary(test_result, i)
CNN
卷积是说每次不是要处理一个像素点,而是一片像素区域。会有一个批量过滤器,每次在图片上进行滚动收集一部分的信息。比较典型的CNN结构如下图所示,其中pooling是为了下一层做特征提取。Fully connected全链接层将一个矩阵展开成为一个列向量,从而作为分类器的输入。
coding
- 定义变量,对变量进行初始化(例如weight)
def weight_variable(shape): # 使用正态分布,shape为输出的生成维度,stddev为标准差 initial = tf.truncated_normal(shape, stddev=0.1) # 因为bias是正值,所以使用initial = tf.constant(0.1, shape=shape)生成多维的0.1 return tf.Variable(initial)
- 定义卷积层和池化层工具函数(关于池化层max_pool的参数含义请参考
tf.nn.max_pool函数详解)def conv2d(x, W): # stride步长的定义格式为[1, x_movement, y_movement, 1] # Must have strides[0] = strides[3] = 1 # padding是无填充的方式,相对的有填充的为VALID return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') def max_pool_2x2(x): # stride [1, x_movement, y_movement, 1] return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
- 根据前面的层数规划,定义后面的卷积层以及池化层的结构
## 第一层卷积层 ## # patch为每次读的大小,输入维度为1,输出维度为32 # patch 5x5, in size 1, out size 32 W_conv1 = weight_variable([5,5, 1,32]) # bias和weight对应 b_conv1 = bias_variable([32]) #经过激活函数的激活 # output size 28x28x32 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) # 经过池化后,因为步长为2,所以将图片大小变为14x14,高度没变 # output size 14x14x32 h_pool1 = max_pool_2x2(h_conv1) ## 第二层卷积层 layer ## # patch 5x5, in size 32, out size 64 W_conv2 = weight_variable([5,5, 32, 64]) b_conv2 = bias_variable([64]) # output size 14x14x64 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # 同理,图片大小再次减半 # output size 7x7x64 h_pool2 = max_pool_2x2(h_conv2) ## 第一层全链接层 ## # 将weight矩阵转换成1024维度的列向量 W_fc1 = weight_variable([7*7*64, 1024]) b_fc1 = bias_variable([1024]) # [n_samples, 7, 7, 64] ->> [n_samples, 7*7*64] # 拉伸 h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) ## 第二层全链接层 ## # 将weight矩阵转换成10维度的列向量 W_fc2 = weight_variable([1024, 10]) b_fc2 = bias_variable([10]) prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
Saver
# 保存变量
saver = tf.train.Saver()
save_path = saver.save(sess, ".......ckpt")
saver.restore(sess, ".......ckpt")