1、tf.clip_by_value函数可以将一个张量中的数值控制在一个范围之中
v = tf.constant([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0]])
print(tf.clip_by_value(v, 2.5, 4.5).eval())
#输出[[2.5, 2.5, 3.],[4.,4.5,4.5]]
上例中,小于2.5的都被换成2.5,大于4.5的都被换成4.5.
2、*和tf.matmul函数的区别。
import tensorflow as tf
v1 = tf.constant([[1.0, 2.0], [3.0, 4.0]])
v2 = tf.constant([[5.0, 6.0], [7.0, 8.0]])
sess = tf.Session()
print((v1*v2).eval(session=sess))
'''
[[ 5. 12.]
[21. 32.]]
'''
print(tf.matmul(v1, v2).eval(session=sess))
'''[[19. 22.]
[43. 50.]]'''
sess.close()
3、tf.reduce_mean函数对整个矩阵做平均而不改变计算结果的意义。
v1 = tf.constant([[1.0, 2.0], [3.0, 4.0]])
print(sess.run(tf.reduce_mean(v1)))
# 输出:2.5
4、tf.nn.softmax_cross_entropy_with_logits函数,将交叉熵和softmax回归封装,实现使用了softmax回归之后的交叉熵损失函数
# y_是预测值,y是真实值
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)
#如果只有一个正确答案的分类问题,可以使用tf.nn.sparse_softmax_cross_entropy_with_logits函数来进一步加速计算过程
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y_, logits=y)
5、tf.greater和tf.where可以实现选择操作。
loss = tf.reduce_sum(tf.where(tf.greater(v1, v2),
(v1-v2)*a, (v1-v2)*b))
tf.greater的输入是两个张量,会比较两个输入张量中每一个元素的大小,并返回比较结果。当tf.greater的输入张量维度不一样时,Tensorflow会进行类似Numpy广播操作(broadcasting)的处理。tf.where函数有三个参数。第一个是选择条件的一句,当选择条件为True时,tf.where函数会选择第二个参数中的值,否则选择第三个参数的值。
import tensorflow as tf
v1 = tf.constant([[1.0, 2.0], [3.0, 4.0]])
v2 = tf.constant([[5.0, 6.0], [7.0, 8.0]])
sess = tf.InteractiveSession()
print(tf.greater(v1, v2).eval())
'''[[False False]
[False False]]'''
print(tf.where(tf.greater(v1, v2), v1, v2).eval())
'''[[5. 6.]
[7. 8.]]'''
sess.close()
实例:实现一个拥有两个输入节点、一个输出节点,没有隐藏层的神经网络。
import tensorflow as tf
from numpy.random import RandomState
#定义训练数据batch的大小
batch_size = 8
#两个输入节点
x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input")
#回归问题一般只有一个输出节点
y_ = tf.placeholder(tf.float32, shape=(None, 1), name="y-input")
#定义了一个单层的神经网络前向传播的过程,这里是简单的加权求和
w1 = tf.Variable(tf.random_normal((2, 1), stddev=1, seed=1))
y = tf.matmul(x, w1)
#定义预测多了和预测少了的成本
loss_less = 10
loss_more = 1
loss = tf.reduce_sum(tf.where(tf.greater(y, y_),
(y-y_)*loss_more,
(y_-y)*loss_less))
train_step = tf.train.AdamOptimizer(0.001).minimize(loss)
#生成模拟数据集
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size, 2)
#加入不可预测的噪音,体现损失函数的意义,噪音为-0.05~0.05的随机数
Y = [[x1+x2+rdm.rand()/10.0-0.05] for (x1, x2) in X]
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
#初始化变量
sess.run(init_op)
print(sess.run(w1))
'''
w1=[[-0.8113182]
[ 1.4845988]]
'''
#设定训练的轮数
STEPS = 5000
for i in range(STEPS):
#每次选取batch_size个样本进行训练
start = (i * batch_size) % dataset_size
end = min(start + batch_size, dataset_size)
#通过选取的样本训练神经网络并更新参数
sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
print(sess.run(w1))
'''
w1=[[1.019347 ]
[1.0428089]]
'''
6、tf.train.exponential_decay函数实现了指数衰减学习率,可以设置参数staircase选择不同的衰减方式,默认为False,这时学习率随着迭代轮数变化趋势是一个连续曲线下降,若为True则为阶梯状下降趋势。train.exponential_decay它实现了以下功能
decayed_learning_rate = learning_rate * decay_rate ** (global_step / decay_step)
'''
decayed_learning_rate 每一轮优化时使用的学习率
learning_rate 初始学习率
decay_rate 衰减系数
decay_step 衰减速度(代表完整的使用一边训练数据所需要的迭代轮数)
'''
实例:设定初始学习率为0.1,设置staircase=True,因此没训练100轮后学习率乘以0.96。
global_step = tf.Variable(0)
#通过exponential_decay函数生成学习率
learning_rate = tf.train.exponential_decay(0.1, global_step, 100, 0.96, staircase=True)
#使用指数衰减的学习率,在minimize函数中传入global_step将自动更新
#global_step参数,从而使得学习率也得到相应更新
learning_step = tf.train.GradientDescentOptimizer(learning_rate).
minimize(...my loss..., global_step=global_step)
7、tf.contrib.layers.l2_regularizer函数,计算一个给定参数的L2正则化项的值。tf.contrib.layers.l1_regularizer函数,计算一个给定参数的L2正则化项的值。
import tensorflow as tf
weights = tf.constant([[1.0, -2.0],[-3.0, 4.0]])
with tf.Session() as sess:
print(sess.run(tf.contrib.layers.l1_regularizer(.5)(weights)))
print(sess.run(tf.contrib.layers.l2_regularizer(.5)(weights)))
#输出5.0 7.5
8、collection可以在一个计算图中(tf.Graph)中保存一组实体(比如张量)。以下结合代码给出一个通过集合计算一个5层神经网络带L2正则化的损失函数的计算方法
import tensorflow as tf
#获取一层神经网络边上的权重,并将这个权重L2正则化损失加入名称为“losses”的集合中
def get_weight(shape, mylambda):
#生成一个变量
var = tf.Variable(tf.random_normal(shape), dtype = tf.float32)
#add_to_collection函数将这个新生成变量的L2正则化损失项计入集合
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(mylambda)(var))
#返回生成的变量
return var
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.folat32, shape=(None, 1))
batch_size = 8
#定义了每一层网络中节点的个数
layer_dimension = [2, 10, 10, 10, 1]
#神经网络的层数
n_layers = len(layer_dimension)
#这个变量维护前向传播时最深层的节点,开始的时候就是输入层
cur_layer = x
#当前层的节点个数
in_dimension = layer_dimension[0]
#通过一个循环来生成5层全连接的神经网络结构
for i in range(1, n_layers):
# layer_dimension[i]为下一层的节点个数
out_dimension = layer_dimension[i]
# 生成当前层中权重的变量,并将这个变量的L2正则化损失加入计算图上的集合
weight = get_weight([in_dimension, out_dimension], 0.001)
bias = tf.Variable(tf.constant(0.1, shape=[out_dimension]))
#使用reLU函数
cur_layer = tf.nn.relu(tf.matmul(cur_layer, weight) + bias)
#进入下一层之前将下一层的节点个数更新为当前层节点个数
in_dimension = layer_dimension[i]
#在定义神经网络前向传播的同时已经将所有的L2正则项加入图上的集合
#这里只需要计算刻画模型在训练数据上边线的损失函数
mse_loss = tf.reduce_mean(tf.square(y_ - cur_layer))
#将均方误差损失将入损失集合
tf.add_to_collection('losses', mse_loss)
9、滑动平均模型, 使用tf.train.ExponentialMovingAverage来实现滑动平均模型。在初始化ExponentialMovingAverage
import tensorflow as tf
#定义一个变量用于计算滑动平均,这个变量的初始值为0。注意这里手动指定了变量类型
#为tf.float32,因为所有需要计算滑动平均的变量的变量必须是实数型
v1 = tf.Variable(0, dtype=tf.float32)
#这里step变量模拟神经网络中迭代的轮数,可以用于动态控制衰减率
step = tf.Variable(0, trainable=False)
#定义一个滑动平均的类class,初始化时给定了衰减率(0.99)和控制衰减率的变量step
ema = tf.train.ExponentialMovingAverage(0.99, step)
#这个列表中的变量都会被更新
maintain_averages_op = ema.apply([v1])
with tf.Session() as sess:
#初始化所有变量
init_op = tf.global_variables_initializer()
sess.run(init_op)
#通过ema.average(v1)获取滑动平均之后变量的取值。在初始化之后变量v1的值和v1的滑动平均值都为0
print(sess.run([v1, ema.average(v1)]))
#更新变量v1的值为5
sess.run(tf.assign(v1, 5))
#更新v1的滑动平均值。衰减率为min{0.99, (1+step)/(10+step)}=0.1}=0.1
#所以v1的滑动平均会被更新为0.1x0 + 0.9x5 = 4.5
sess.run(maintain_average_op)
print(sess.run([v1, ema.average(v1)]))
#更新变量step的值为10000
sess.run(tf.assign(step, 10000))
#更新变量v1的值为10
sess.run(tf.assign(v1, 10))
#更新v1的滑动平均值。衰减率为min{0.99, (1+step)/(10+step)}=0.999}=0.99
#所以v1的滑动平均会被更新为0.99x4.5 + 0.01x10 = 4.555
sess.run(maintain_average_op)
print(sess.run([v1, ema.average(v1)]))
#再次更新滑动平均值,得到的新的滑动平均值为0.99x4.555+0.01x10=4.60945
sess.run(maintain_average_op)
print(sess.run([v1, ema.average(v1)]))