为了实现变量共享,所以有了 tf.get_variable()这个函数,当然前提是配合 tf.variable_scope()使用,官方给出了一个例子,注意 reuse=tf.AUTO_REUSE:
def foo():
with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
v = tf.get_variable("v", [1])
return v
v1 = foo() # Creates v.
v2 = foo() # Gets the same, existing v.
一般情况下,get_variable 和 variable_scope 是结合使用的,用来共享变量。
另外注意到还有另外的创建变量的方式 tf.Variable(),如果使用 tf.Variable()创建变量,如果名字一样,tf会自动命名别名进行区分,具体可以测试下:
def foo1():
with tf.name_scope('foo1'):
v = tf.Variable('v1',[1])
v2 = tf.Variable('v1',[1])
return v,v2
a,b = foo1()
print(a.name)
foo1/Variable:0
print(b.name)
foo1/Variable_1:0
引用知乎的一个总结:`tf.variable_scope`和`tf.get_variable`必须要搭配使用(全局scope除外),为share提供支持;`tf.Variable`可以单独使用,也可以搭配`tf.name_scope`使用,给变量分类命名,模块化;`tf.Variable`和`tf.variable_scope`搭配使用不伦不类,不是设计者的初衷。
计算一个数的平方,例如:
with tf.Session() as sess:
sess.run(tf.square(tf.constant([1,2,3])))
output: array([1, 4, 9], dtype=int32)
可以理解为降维操作,最好是通过例子来看
'''
输入是一个2*2*3的矩阵
array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]], dtype=int32)
分别设置axis=0/1/2
'''
with tf.Session() as sess:
sess.run(tf.reduce_sum(tf.constant([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]),0))
#输出 2*3矩阵,最外层2个合并,即 np.array([1,2,3]) + np.array([7,8,9]) np.array([4,5,6]) + np.array([10,11,12]):
array([[ 8, 10, 12],
[14, 16, 18]], dtype=int32)
with tf.Session() as sess:
sess.run(tf.reduce_sum(tf.constant([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]),1))
#输出, 2*3矩阵,np.array([1,2,3])+np.array([4,5,6])
array([[ 5, 7, 9],
[17, 19, 21]], dtype=int32)
with tf.Session() as sess:
sess.run(tf.reduce_sum(tf.constant([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]),2))
#输出
array([[ 6, 15],
[24, 33]], dtype=int32)
def add_layer(inputs, in_size, out_size, activation_function=None):
weights = tf.Variable(tf.random_normal([in_size, out_size]))
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
Wx_plus_b = tf.matmul(inputs, weights) + biases
.........
.........
h1 = addlayer(xs,1,20)
.........
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(1000):
_,summary = sess.run([train_step, merged], feed_dict={xs:x_data, ys:y_data})
.......
问题来了,既然 sess一直不停的循环调用 add_layer 函数,那么函数里面的变量 每次都初始化吗?答案当然是否定的。那怎么做到的?使用了变量 tf.Variable()初始化变量,之后就不会重复初始化。如果不使用 tf.Variable 情况就不一样了
在练习写 tensor mnist的时候,如果用tensorflow.examples.tutorials.mnist.input_data.read_data_sets()的话,配next_batch(100)是没有问题的,训练数据也很快。但是程序一致提示:
好吧,那就修改下,搞了半天,使用tf.keras.datasets.mnist.load_data进行数据读取,返回的是(x_train, y_train), (x_test, y_test),其中 x_train 是[None, 28, 28]我们用的是机器学习中softmax多分类,需要的数据是[None, 784]的,需要转换,就用到了 tf.reshape(),所以记录下。tf.reshape(x, [-1, 784]),这里主要是如果不确定第一维是多少,可以设置成-1。还发现了一个严重的问题,就是用我这段代码跑的话,很耗时,并且是每一个 batch 时间都会成倍增长,原因就是错用了 eval(),每次循环都另建了一个 graph??目前没找到原因,把代码贴出来,有知道的可以告诉我,谢谢了
import tensorflow as tf
import argparse
import tensorflow.train as tr
import numpy as np
class Config:
def __init__(self, flags):
self.FLAGS = flags
class MnistMethod:
def __init__(self):
self.x = tf.placeholder(tf.float32, name='in_x')
self.y_ = tf.placeholder(tf.int64, name='in_y')
self.w = tf.Variable(tf.random_normal([784, 10]), trainable=True, name='W')
self.b = tf.Variable(tf.random_normal([10]), trainable=True, name='b')
self.softmaxfoo()
def softmaxfoo(self):
#pdb.set_trace()
with tf.name_scope('calculation'):
y = tf.matmul(self.x, self.w) + self.b
#self.y_pred_cls = tf.argmax(tf.nn.softmax(y), 1)
with tf.name_scope('loss'):
self.cross_entropy = tf.losses.sparse_softmax_cross_entropy(self.y_, y)
tf.summary.scalar('loss', self.cross_entropy)
with tf.name_scope('opt'):
self.train_step = tf.train.GradientDescentOptimizer(0.1, name='learn_rate'). \
minimize(self.cross_entropy, var_list=tf.trainable_variables())
self.merged = tf.summary.merge_all()
def cnn(self):
pass
def train_input_fn(features, labels, batch_size):
"""An input function for training"""
# Convert the inputs to a Dataset.
dataset = tf.data.Dataset.from_tensor_slices((features, labels))
# Shuffle, repeat, and batch the examples.
dataset = dataset.shuffle(1000).repeat().batch(batch_size)
# Build the Iterator, and return the read end of the pipeline.
return dataset.make_one_shot_iterator().get_next()
def train(mnist, model):
with tf.Session() as sess:
saver = tr.Saver()
writer = tf.summary.FileWriter('./log', sess.graph)
sess.run(tf.global_variables_initializer())
features, labels = mnist
train_loops = 5000
for i in range(train_loops):
batch_xs, batch_ys = train_input_fn(features, labels, 100)
batch_xs = np.array(tf.reshape(batch_xs, [-1, 784]).eval())
batch_ys = np.array(batch_ys.eval())
if i == train_loops - 1:
sess.run(model.train_step, feed_dict={model.x: batch_xs, model.y_: batch_ys})
saver.save(sess, 'model/model.ckpt')
else:
summary, _ = sess.run([model.merged, model.train_step],
feed_dict={model.x: batch_xs, model.y_: batch_ys})
writer.add_summary(summary, i)
def test(model):
with tf.Session() as sess:
tf.train.Saver().restore(sess=sess, save_path='model/model.ckpt')
mnist = input_data.read_data_sets(FLAGS.data_dir)
test_xs, test_ys = mnist.test.next_batch(100)
pre = sess.run(model.y_pred_cls, feed_dict={model.x: test_xs})
correct_pred = tf.equal(pre, test_ys)
acc = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'--data_dir',
type=str,
default='./mnist',
help='Directory for storing input data')
parser.add_argument(
'--type',
type=str,
default='train',
help='input train or test'
)
FLAGS, _ = parser.parse_known_args()
myconfig = Config(FLAGS)
mymodel = MnistMethod()
train_data, test_data = tf.keras.datasets.mnist.load_data(myconfig.FLAGS.data_dir)
if FLAGS.type == 'train':
train(train_data, mymodel)
else:
test(test_data)
进行矩阵的乘法
a = [[1, 0], [0, 1]]
b = [[4, 1], [2, 2]]
np.dot(a, b)
array([[4, 1],
[2, 2]])
7)最近在看 tensorflow 书籍,看到其中一个例子,是通过管道进行读取,接口更新太快,书上的已经要淘汰了,这里记录下
#书上的例子
def test_queue():
with tf.Session() as sess:
filename = ['cifar/ABC/A.jpg', 'cifar/ABC/B.jpg', 'cifar/ABC/C.jpg']
filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=5)
reader = tf.WholeFileReader()
_, value = reader.read(filename_queue)
tf.local_variables_initializer().run()
theads = tf.train.start_queue_runners(sess=sess)
i = 0
while True:
i += 1
image_data = sess.run(value)
with open('cifar/ABC/test_%d.jpg' % i, 'wb') as f:
f.write(image_data)
#新的接口使用了 data.dataset
def test_queue1():
def _read_image(name):
image_string = tf.read_file(name)
return image_string
with tf.Session() as sess:
filename = ['cifar/ABC/A.jpg', 'cifar/ABC/B.jpg', 'cifar/ABC/C.jpg']
image_list = tf.data.Dataset.from_tensor_slices(filename).repeat(5)
image = image_list.map(_read_image)
iter = image.make_one_shot_iterator()
one_element = iter.get_next()
for i in range(15):
image_data = sess.run(one_element)
with open('cifar/ABC/test_%d.jpg' % i, 'wb') as f:
f.write(image_data)