第一个##################
import tensorflow as tf
import numpy as np
#version is 0.5
a = np.ones([100],dtype=np.float32)
x = tf.placeholder(dtype=tf.float32,shape = [100])
w = tf.Variable(tf.ones([100,100]))
out = tf.mul(x,w)
sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)
def f():
return tf.mul(x,w)
for i in range(1000000):
sess.run(f(),feed_dict={x:a})
print i
for i in range(1000000):
sess.run(out,feed_dict={x:a})
print i
上面的代码,两个for循环都是运行得出out,但是第一个for循环会不断的建立新的计算节点并计算,即tf.mul(x,w),导致内存不断消耗,而第二个for循环则只会建立一一个计算节点,之后的调用仅仅计算,而不新建。
因此,除非符合我们的意图,否则不要使用以下形式建立计算节点
for i in range(1000000):
sess.run(f(),feed_dict={x:a})
print i
第二个######################
if [False]:
跟
if True:
是一样的。
===================================================
而
if False:
跟
if None:
是一样的。
================batch_normalization=============================
tf里面有两个相关的实现,分别是
tensorflow.contrib.layers.batch_norm()和
tensorflow.layers.batch_normalization()
但tensorflow.layers.batch_normalization()似乎是以奇怪的方式在运作。
例如
import tensorflow as tf
from tensorflow.contrib.layers import batch_norm
a = tf.get_variable('a',[1,2],dtype=tf.float32,initializer=tf.random_uniform_initializer(-10.,10.))
b = tf.get_variable('b',[1,2],dtype=tf.float32,initializer=tf.random_uniform_initializer(-10.,10.))
c = batch_norm(a)
cc = tf.layers.batch_normalization(b)
with tf.Session() as sess:
tf.global_variables_initializer().run()
for i in range(1):
print sess.run(c)
print sess.run(cc)
结果是
[[ 0. 0.]]
[[-0.82290715 7.70175266]]
按理说,第一个结果是对的,因为对于batch=1的数据,输出0均值,1方差的结果是全部等于0。但第二个结果就很奇怪了。
再把batch数改成5,结果是:
[[ 0.66675264 -0.31775036]
[ 0.55268157 0.8353436 ]
[-0.31323212 1.0280273 ]
[ 0.91457742 -1.76017237]
[-1.82077944 0.2145521 ]]
[[-1.72455609 -7.3269577 ]
[ 1.20964813 -6.78956413]
[-7.1524272 -5.85298967]
[ 9.05802536 5.26228619]
[ 9.85200882 7.94727564]]
仍然是第一个方法的结果比较正常。
原来,两个方法都有一个参数:training。batch_norm()方法默认training为true,而batch_normalization()默认training为false。当training为true时,会使用样本的均值和方差进行正规化,而当training为false时,会使用累积的mean的均值和方差进行正规化。
===========================梯度=================================
计算梯度主要有tf.gradients()和 tf.train.AdamOptimizer(0.01).compute_gradients(),其中tf.gradients()中有个参数是grad_ys,
他的作用是:当计算图有多个输出单元(例如输出是[1,2]),会对各个单元对应于每个变量的梯度求和,用文档的话说就是:sum(dy/dx)。有的时候我们需要对不同的输出单元取不同的权重,而grad_ys就是这个权重参数。
但是呢,明显的我们只要用权重参数乘以输出单元,应该能得到一样的梯度,也就是说,这个grad_ys参数并不是必要的,是不是这样呢?试了才知道
import numpy as np
import tensorflow as tf
import math
from tensorflow.contrib import layers
a = tf.constant([[2.,2.]])
aa = tf.get_variable(name='aa',shape=[1,2],dtype=tf.float32,initializer=tf.constant_initializer(2))
b = tf.constant([[2.,3.],[4.,5.]])
c = tf.matmul(aa,b)
with tf.Session() as sess:
tf.global_variables_initializer().run()
print sess.run(tf.gradients(c, aa))
print sess.run(tf.gradients(c,aa,[a]))
print sess.run(tf.gradients(c*a, aa, ))
print sess.run(tf.train.AdamOptimizer(0.01).compute_gradients(a*c))
print sess.run(tf.train.AdamOptimizer(0.01).compute_gradients(c))
结果是
[array([[ 5., 9.]], dtype=float32)]
[array([[ 10., 18.]], dtype=float32)]
[array([[ 10., 18.]], dtype=float32)]
[(array([[ 10., 18.]], dtype=float32), array([[ 2., 2.]], dtype=float32))]
[(array([[ 5., 9.]], dtype=float32), array([[ 2., 2.]], dtype=float32))]
所以答案是: 是的