1. tf.nn.l2_loss
l2正则化, 如果正则的对象是矩阵,也相当于把矩阵展开做正则,并不是数学书矩阵的L2范数的计算
另外此函数 是 1/2*分量平方相加, 并没有计算平方根,估计是为了求导的方便,严格来说是最小均方误差的计算。
l = [[2, 2, 2], [2, 2, 2], [2, 2, 2]]
W = tf.get_variable(initializer=tf.constant(value=np.array(l), dtype=tf.float32), name='W')
l2 = tf.nn.l2_loss(W)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(l2))
这个结果不上图,计算结果为:18
2. tf.nn.batch_noralization
理论: https://www.cnblogs.com/zhengmingli/p/8031690.html
# Layer 2 with BN, using Tensorflows built-in BN function
w2_BN = tf.Variable(w2_initial)
z2_BN = tf.matmul(l1_BN,w2_BN)
batch_mean2, batch_var2 = tf.nn.moments(z2_BN,[0])
scale2 = tf.Variable(tf.ones([100]))
beta2 = tf.Variable(tf.zeros([100]))
BN2 = tf.nn.batch_normalization(z2_BN,batch_mean2,batch_var2,beta2,scale2,epsilon)
l2_BN = tf.nn.sigmoid(BN2)
作者:黑猿大叔
链接:https://www.jianshu.com/p/b2d2f3c7bfc7
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
该函数的api:
tf.nn.batch_normalization(
x,
mean,
variance,
offset,
scale,
variance_epsilon,
name=None
)
参数含义如下
x: 输入的张量
mean: 均值张量, 一般以x的第0维做均值
variance: 方差张量,同以x的0维
可调用
fc_mean, fc_var = tf.nn.moments(x_, axes=[0])
来计算x的均值
offset: 偏移量,
scale: 缩放量
variance_epsilon: 一个浮点数,避免除0,一般设为0.001
name: 略.
实际上 normaliazation 与以下代码是等效的
# Layer 1 with BN
w1_BN = tf.Variable(w1_initial)
# Note that pre-batch normalization bias is ommitted. The effect of this bias would be
# eliminated when subtracting the batch mean. Instead, the role of the bias is performed
# by the new beta variable. See Section 3.2 of the BN2015 paper.
z1_BN = tf.matmul(x,w1_BN)
# Calculate batch mean and variance
batch_mean1, batch_var1 = tf.nn.moments(z1_BN,[0])
# Apply the initial batch normalizing transform
z1_hat = (z1_BN - batch_mean1) / tf.sqrt(batch_var1 + epsilon)
# Create two new parameters, scale and beta (shift)
scale1 = tf.Variable(tf.ones([100]))
beta1 = tf.Variable(tf.zeros([100]))
# Scale and shift to obtain the final output of the batch normalization
# this value is fed into the activation function (here a sigmoid)
BN1 = scale1 * z1_hat + beta1
l1_BN = tf.nn.sigmoid(BN1)
作者:黑猿大叔
链接:https://www.jianshu.com/p/b2d2f3c7bfc7
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
3. tf.nn.max_pool
tf.nn.max_pool(value, ksize, strides, padding, name=None)
参数是四个,和卷积很类似:
第一个参数value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch, height, width, channels]这样的shape
第二个参数ksize:池化窗口的大小,取一个四维向量,一般是[1, height, width, 1],因为我们不想在batch和channels上做池化,所以这两个维度设为了1
第三个参数strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride,stride, 1]
第四个参数padding:和卷积类似,可以取'VALID' 或者'SAME'
返回一个Tensor,类型不变,shape仍然是[batch, height, width, channels]这种形式
a = tf.constant([
[[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0],
[8.0, 7.0, 6.0, 5.0],
[4.0, 3.0, 2.0, 1.0]],
[[4.0, 3.0, 2.0, 1.0],
[8.0, 7.0, 6.0, 5.0],
[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0]]
])
a = tf.reshape(a, [1, 4, 4, 2])
pooling = tf.nn.max_pool(a, [1, 2, 2, 1], [1, 1, 1, 1], padding='VALID')
with tf.Session() as sess:
print("image:")
image = sess.run(a)
print(image)
print("reslut:")
result = sess.run(pooling)
print(result)
4. tf.reshape
tf.reshape(tensor,shape,name=None)
函数的作用是将tensor变换为参数shape形式,其中的shape为一个列表形式,特殊的是列表可以实现逆序的遍历,即list(-1).-1所代表的含义是我们不用亲自去指定这一维的大小,函数会自动进行计算,但是列表中只能存在一个-1。(如果存在多个-1,就是一个存在多解的方程)
下面就说一下reshape是如何进行矩阵的变换的,其简单的流程就是:
将矩阵t变换为一维矩阵,然后再对矩阵的形式进行更改就好了,具体的流程如下:
>>>import numpy as np
>>>a= np.array([1,2,3,4,5,6,7,8])
>>>a
array([1,2,3,4,5,6,7,8])
>>>d = a.reshape((2,4))
>>>d
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>>f = a.reshape((2,2,2))
>>>f
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
>>>image = np.array([[[1,2,3], [4,5,6]], [[1,1,1], [1,1,1]]])
>>>image.shape
(2,2,3)
>>>image.reshape((-1,6))
array([[1, 2, 3, 4, 5, 6],
[1, 1, 1, 1, 1, 1]])
注意:形状发生变化的原则时数组元素的个数是不能发生改变的
如 一共有8个数, 则所有维度乘积必须要为 8
注: tf.reshape的规则 与 numpy中 reshape的规则相同,故此处用 numpy做示范
5. tf.concat
tf.concat(values, axis, name="concat"):
把一个list中的多个张量 按照某个维度连接成一个长的张量
如果 list中的第 i 个张量的shape 是 values[i].shape = [D0, D1, ... Daxis(i), ...Dn]
则连接后的张量 形状为 [D0, D1, ... Raxis, ...Dn]
且存在如下关系:
Raxis = sum(Daxis(i))
即这些张量沿着 第 axis
维 连接起来。 注意, 所有张量, 除了待匹配的维度 axis
可以不相等 , 其它的的维度必须相等。
例如
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0) # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 1) # [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]
# tensor t3 with shape [2, 3]
# tensor t4 with shape [2, 3]
tf.shape(tf.concat([t3, t4], 0)) # [4, 3]
tf.shape(tf.concat([t3, t4], 1)) # [2, 6]
与python中的索引方式相同,axis
也可以为负数,代表的是第 axis + rank(values)
维, 例如
t1 = [[[1, 2], [2, 3]], [[4, 4], [5, 3]]]
t2 = [[[7, 4], [8, 4]], [[2, 10], [15, 11]]]
tf.concat([t1, t2], -1)
结果为:
[[[ 1, 2, 7, 4],
[ 2, 3, 8, 4]],
[[ 4, 4, 2, 10],
[ 5, 3, 15, 11]]]
如果想在一个新的维度做连接 如:
tf.concat([tf.expand_dims(t, axis) for t in tensors], axis)
可以用如下函数
tf.stack(tensors, axis=axis)
参数:
values: 一个Tensor
的list,或一个单个的 Tensor
.
axis:连接的维度
name: 略.
返回: 连接后的张量
6. tf.nn.xw_plus_b((x, weights) + biases.)
相当于 matmul(x, weights) + biases.
7. tf.nn.argmax(input, axis=None, name=None, dimension=None)
一般用axis
指定维度
x=tf.constant([[1.,2.,6],[6.,2.,6]])
xShape=tf.shape(x)
z1=tf.arg_max(x,1)#沿axis=1操作
with tf.Session() as sess:
xShapeValue,d1=sess.run([xShape,z1])
print('shape=%s'%(xShapeValue))
print(d1)
# 输出
# shape= [2 3]
# [2 0]
8. tf.nn.softmax(logits, axis=None, name=None, dim=None)
softmax激活函数 等同于
softmax = tf.exp(logits) / tf.reduce_sum(tf.exp(logits), axis)
Args:
logits: 张量y
axis: softmax的维度 默认-1
name: 略
dim: axis
的别名 不推荐使用
Returns:
一个 Tensor
. 与logits
形状相同.
import tensorflow as tf
A = [1.0,2.0,3.0,4.0,5.0,6.0]
with tf.Session() as sess:
print sess.run(tf.nn.softmax(A))
#[ 0.00426978 0.01160646 0.03154963 0.08576079 0.23312201 0.63369131]
9. tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
除去name参数用以指定该操作的name,与方法有关的一共两个参数:
第一个参数logits
:就是神经网络最后一层的输出,如果有batch的话,它的大小就是[batchsize,num_classes]
,单样本的话,大小就是num_classes
第二个参数labels
:实际的标签,大小同上
具体的执行流程大概分为两步:
第一步是先对网络最后一层的输出做一个softmax,这一步通常是求取输出属于某一类的概率,对于单样本而言,输出就是一个num_classes
大小的向量[Y1,Y2,Y3...]
其中Y1,Y2,Y3...
分别代表了是属于该类的概率
softmax的公式是:
第二步是softmax的输出向量[Y1,Y2,Y3...]
和样本的实际标签做一个交叉熵,公式如下:
yi指代实际的标签中第i个的值(用mnist数据举例,如果是3,那么标签是[0,0,0,1,0,0,0,0,0,0],除了第4个值为1,其他全为0)
就是softmax的输出向量[Y1,Y2,Y3...]````中,第i个元素的值
越准确,结果的值越小(别忘了前面还有负号),最后求一个平均,得到我们想要的loss
注意!!!这个函数的返回值并不是一个数,而是一个向量,如果要求交叉熵,我们要再做一步tf.reduce_sum
操作,就是对向量里面所有元素求和,最后才得到 cross entropy ,如果求loss,则要做一步tf.reduce_mean
操作,对向量求均值!
# our NN's output
logits = tf.constant([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]])
# step1:do softmax
y = tf.nn.softmax(logits)
# true label
y_ = tf.constant([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0]])
# step2:do cross_entropy
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
# do cross_entropy just one step
cross_entropy2 = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_)) # dont forget tf.reduce_sum()!!
with tf.Session() as sess:
softmax = sess.run(y)
c_e = sess.run(cross_entropy)
c_e2 = sess.run(cross_entropy2)
print("step1:softmax result=")
print(softmax)
print("step2:cross_entropy result=")
print(c_e)
print("Function(softmax_cross_entropy_with_logits) result=")
print(c_e2)
# step1:softmax result=
# [[0.09003057 0.24472848 0.66524094]
# [0.09003057 0.24472848 0.66524094]
# [0.09003057 0.24472848 0.66524094]]
# step2:cross_entropy result=
# 1.222818
# Function(softmax_cross_entropy_with_logits) result=
# 1.2228179
计算损失通常用如下代码
losses = tf.nn.softmax_cross_entropy_with_logits(labels=self.input_y, logits=self.scores)
self.loss = tf.reduce_mean(losses) + l2_reg_lambda * l2_loss
l2_reg_lambda
是l2正则的系数
l2_loss
是正则损失
10. 计算梯度
optimizer = tf.train.AdamOptimizer(learning_rate=lr)
grads_and_vars = optimizer.compute_gradients(self.model.loss)
train_op = optimizer.apply_gradients(grads_and_vars,global_step=None,name=None)
lr
学习率
self.model.loss
loss函数 compute_gradients(loss)
求loss的梯度
apply_gradients
把梯度“应用”(Apply)到变量上面去。其实就是按照梯度下降的方式加到上面去。这是minimize()函数的第二个步骤。 返回一个应用的操作。
参数:
grads_and_vars: compute_gradients()函数返回的(gradient, variable)对的列表
global_step: 计步的自增变量
name: 可选,名字