Optimizer

Stochastic Gradient Descent (SGD)

基础方法,是mini batch中的一种,加了随机

Momentum

tensorflow2打印tensor的值 tensorflow dag_TF

即原始的tensorflow2打印tensor的值 tensorflow dag_ide_02加上一个负的学习效率乘上一个矫正值tensorflow2打印tensor的值 tensorflow dag_TF_03

数学公式如下:

tensorflow2打印tensor的值 tensorflow dag_ide_04


一定程度上保留之前更新的方向(像一个醉汉,随着坡度的变大,随着惯性,下降的方向越来越笔直)

AdaGrad

数学公式如下:

tensorflow2打印tensor的值 tensorflow dag_2d_05


相较Momentum,AdaGrad会自动调整learnin rate,从而使得逼近速度越来越快

RMSProp

同时具备Momentum和AdaGrad两个方法的优势,但缺少一部分

tensorflow2打印tensor的值 tensorflow dag_ide_06

Adam

计算m时使用Momentum下坡属性,计算v时使用AdaGrad阻力属性,同时更新m和v

tensorflow2打印tensor的值 tensorflow dag_2d_07


Tensorboard

  1. 使用placeholder中的name=参数进行tensorboard中的名字显示
  2. 使用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')

tensorflow2打印tensor的值 tensorflow dag_TF_08

  1. 将信息存储入一个logs文件夹中
writer = tf.summary.FileWriter("logs/", sess.graph)
  1. 在命令行中输入
    tensorboard --logdir='logs/'

Tensorboard 2

  1. 查看historygram中的参数内容,表示整个训练过程中的参数变化,通常是一个分布值
tf.summary.histogram(layer_name + '/weights', Weights)
  1. 示意图如下图所示:
  2. 定义scalar中的loss,是观察训练过程以及优化的重要手段
tf.summary.scalar('loss', loss)
  1. 需要在写入文件之前,把这些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)
  1. 测试图如下:

Classification

  1. 针对分类问题,比较适合的激活函数为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)
  1. 使用一部分数据作为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

  1. 定义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)
  1. 在每次训练的时候保留一半,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全链接层将一个矩阵展开成为一个列向量,从而作为分类器的输入。

tensorflow2打印tensor的值 tensorflow dag_TF_09

coding

  1. 定义变量,对变量进行初始化(例如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)
  1. 定义卷积层和池化层工具函数(关于池化层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')
  1. 根据前面的层数规划,定义后面的卷积层以及池化层的结构
## 第一层卷积层 ##
	# 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")