TensorFlow学习笔记(二):变量的创建和初始化

一、Tensorflow中的变量

·  上节我说,在tensorflow中,所有的操作或者变量都是一个个节点,其实这对于变量的描述不够精确。其实官方的说法是这样的:Tensorflow中的变量是一个个有着特定形状和数据类型的张量(tensor)。
·  这里普及一下张量的概念。我是这么理解的:张量可以看做是一个特殊的向量:零阶张量的元素是标量(例如,0就是一个零阶张量),一阶张量的元素是零阶张量(例如,[0,0]就是一个一阶张量),二阶张量的元素是一阶张量(例如,[ [0,0], [1,1] ]就是一个二阶张量),以此类推。 所以张量的物理意义很明显:零阶是标量,一阶是矢量,二阶是矩阵,三阶是立体结构由矩阵拼接起来,四阶以后就比较抽象了,这里就不说了,因为我说不出来了
·  可以看到,在tensorflow中所有的变量都是张量节点,这意味着在tensorflow中的计算均是很复杂的张量计算,尤其矩阵计算。因此,大家应该知道为什么tensorflow能很愉快地做机器学习了吧。
·  值得一提的是:张量必须进行初始化操作后才合法,创建张量的操作只是规定了它的结构和初始化的方法。

二、创建变量

2.1 环境准备

import tensorflow as tf

2.2 Creating variables

·  在Tensorflow中,变量是一个类:tf.Variable,因此我们创建变量就是在用这个类的构造函数,其构造函数有三个入参:其一是张量的形状(shapes),其二是张量内部的数据类型(默认是float32),其三是此张量在图中的名称。

#######################################
######## Defining Variables ###########
#######################################
# Create three variables with some default values.
weights = tf.Variable(tf.random_normal([2, 3], stddev=0.1),
                      name="weights")
biases = tf.Variable(tf.zeros([3]), name="biases")
#biases_0 = tf.assign(biases, tf.ones([3]))
custom_variable = tf.Variable(tf.zeros([3]), name="custom")

# Get all the variables' tensors and store them in a list.
all_variables_list = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)
  • 可见虽然官方上说,定义变量时,指定是张量的shapes。但是上面构造的时候,不仅定义了张量的shapes,也给出了给张量赋值的具体方法:如上面的 正太分布赋值 和 全零赋值。
  • 创建完变量后,所有的变量都会储存在一个列表里,可以用tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)取出来。
  • 关于tf.assign操作放在2.5节讲

·  注意:也可以用tf.get_variable(…)来创建变量,据说这种方法更好一点,但是我还是喜欢更加直观的tf.Variable,这里给出这种方法的官方说明:tf.get_variable

2.3 Initialization

·  在其他操作运行之前,所有的变量都应该被初始化。我们可以这样比喻:变量的创建是在组装汽车,不同的变量组成了不同的汽车组件,而变量的初始化是汽车的启动器,只有启动器执行了,这些组件才有用。
·  初始化操作可以有三种:给特定的某个变量执行初始化,给全局所有变量执行初始化以及用另一个变量给当前变量初始化。

  • Initializing Specific Variables
    ·  使用tf.variables_initializer给特定的变量初始化。
# "variable_list_custom" is the list of variables that we want to initialize.
variable_list_custom = [weights, custom_variable]

# The initializer
init_custom_op = tf.variables_initializer(var_list=variable_list_custom)
  • Global variable initialization
    ·  使用tf.global_variables_initializer()给所有的变量进行并行的初始化。其实这个操作就是给所有保存全部变量的列表进行tf.variables_initializer
# Method-1
# Add an op to initialize the variables.
init_all_op = tf.global_variables_initializer()

# Method-2
init_all_op = tf.variables_initializer(var_list=all_variables_list)
  • Initialization of a variables using other existing variables
# Create another variable with the same value as 'weights'.
WeightsNew = tf.Variable(weights.read_value(), name="WeightsNew")

# Now, the variable must be initialized.
init_WeightsNew_op = tf.variables_initializer(var_list=[WeightsNew])

2.4 Run the Session

·  可以通过,Variable.eval()得到里面的值。如果没有进行初始化,则会报错。

with tf.Session() as sess:
    sess.run(init_custom_op)
    print(weights.eval())
    print(custom_variable.eval())
    #以上操作没有初始化biases,所以会报错
#     print(sess.run(biases))
    sess.run(init_weightsNew_op)
    print(weightsNew.eval())
    sess.run(init_all_op)
    print(biases.eval())

输出结果为:

[[ 0.1077401  -0.16742168  0.06057863]
 [-0.27632776  0.1984974   0.03617979]]
[0. 0. 0.]
[[ 0.1077401  -0.16742168  0.06057863]
 [-0.27632776  0.1984974   0.03617979]]
[0. 0. 0.]

注意:如果重复运行sess.run(init_custom_op),weights的值是不同的,可见变量的值确实是在初始化的时候被赋予的。

2.5 tf.assign

`  这个操作有时候也会使用,用于给变量赋值。注意:在tensorflow中所有的操作(op),只有在run之后才会生效。

  • 运行
with tf.Session() as sess:
    sess.run(init_all_op)
    print(biases.eval())
    sess.run(tf.assign(biases,tf.ones([3])))
    #相当于运行如下操作
    #sess.run(biases_0)
    print(biases.eval())
  • 得到
[0. 0. 0.]
[1. 1. 1.]

三、图示

如果运行如下代码,再用tensorboard打开,就可以很清晰的看到我们定义的变量,以及作用在变量上的操作了。

# coding: utf-8
import tensorflow as tf
import os,sys
tf.app.flags.DEFINE_string('f', '', 'kernel')
tf.app.flags.DEFINE_string('log_dir1', os.path.dirname(os.path.abspath(__file__)) + '/logs','logsDire')
FLAGS = tf.app.flags.FLAGS

weights = tf.Variable(tf.random_normal([2, 3], stddev=0.1), name = "weights")
biases = tf.Variable(tf.zeros([3]),name = "biases")
biases_0 = tf.assign(biases, tf.ones([3]),name="assign_biases")
custom_variable = tf.Variable(tf.zeros([3]),name="custom")

init_all_op = tf.global_variables_initializer()

with tf.Session() as sess:
    writer = tf.summary.FileWriter(os.path.expanduser(FLAGS.log_dir1),sess.graph)
    sess.run(init_all_op)
    print(weights.eval())
    print(custom_variable.eval())
    #print(weightsNew.eval())
    sess.run(biases_0)
    print(biases.eval())

可以看到:
在这里插入图片描述
·  我来稍微解释一下吧:可以看到,在图里面保存的是我们定义的name属性的节点,不过是什么操作在图例都是节点,比较明显的就是:init操作,正太分布的操作以及那个赋值操作。尤其看到那个assign赋值节点,这个也是可以有name的。

  • 三种不同的线
    1. 灰色实线: Dataflow edge,表示操作之间的数据流流动,在本例中表示把正态分布的数据流传递给变量。 Edge showing the data flow between operations. Edges flow upwards unless arrowheads specify otherwise.
    2. 灰色虚线: Control dependency edge,表示操作之间控制依赖。本例中表示,变量操作的使用依赖于初始化操作。Edge showing the control dependency between operations.
    3. 橘色实线: Reference edge,表示操作节点如果运行了,可以改变被指向张量的值。本例中表示,assgin操作如果被运行,则可以改变biases的值。Edge showing that the outgoing operation node can mutate the incoming tensor.
  • 三种节点的形状
    1. 矩形: 表示名称空间,一种颜色代表一种名称空间 ,名称空间是可扩展的,说明其内部会有很多的操作
    2. 椭圆形: 表示操作节点
    3. 圆形: 表示常量节点
    这里给出weights和random_normal的内部结构图。

在这里插入图片描述
·  这就可以很清楚的看到,我们是如何定义一个张量结构的:先构建了一个2x3形状的常量,然后初始化后给weights赋值。仔细想一下也没有大不了的嘛!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值