Tensorflow笔记之变量管理

在前面已经讲了Tensorflow常用的五种优化方法,其中在结构设计上使用激活函数和多层隐藏层。在优化过程中使用指数衰减来设置学习率,加入正则化的损失函数以及滑动平均模型,有效的提高了神经网络模型的正确率。下面学习变量管理:

        在上一篇博文中,将计算神经网络前向传播结果的过程抽象成了一个函数。通过这种方式在训练和测试过程中可以统一调用这个函数来获得模型的前向传播结果,函数帝国一如下:

definference(input_tensor,avg_class,weights1,biases1,weights2,biases2):

从定义来看,这个函数包含了神经网络的所有参数。但是当神经网络更复杂、参数更多时,就需要一个更好的方式来传递和管理神经网络的参数。Tensorflow提供了通过变量名称来创建或者获取一个变量的机制,由tf.get_variable和tf.variable_scope函数实现。

前面通过tf.Variable函数创建变量,除此之外,还可以通过tf.get_variable函数创建或者获取变量。下面给出两个的使用样例,效果相同。

v=tf.get_variable("v",shape=[1],initializer=tf.constant_initializer(1.0))
v=tf.Variable(tf.constant(1.0,shape=[1]),name="v")

下面是Tensorflow的7种不同的初始化函数

Tensorflow中的变量初始化函数
初始化函数功能主要参数
tf.constant_initializer将变量初始化为给定常量常量的取值
tf.constant_normal_initializer将变量初始化为满足正态分布的随机值正太分布的均值和标准差
tf.truncated_normal_initializer将变量初始化为满足正态分布的随机值,如果随机值出来的偏离平均值超过2个标准差,那么这个数将被重新随机正态分布的均值和标准差
tf.random_uniform_initializer将变量初始化为满足平均分布的随机值最大最小值
tf.uniform_unit_scaling_initializer将变量初始化为满足平均分布但不影响输出数量级的随机值factor(产生随机值时乘的系数)
tf.zeros_initializer将变量设置为全0变量维度
tf.ones_initializer将变量设置为全1变量维度

如果需要通过tf.get_variable获取一个已经创建的变量,需要通过tf.variable_scope函数来生成一个上下文管理器,并明确指定在这个上下文管理器中,tf.get_variable将直接获取已经生成的变量,如下代码所示:

#在名字为foo的命名空间内创建名字为v的变量
with tf.variable_scope("foo"):
     v=tf.get_variable("v",[1],initializer=tf.constant_initializer(1.0))
#因为命名空间foo中已经存在名字为v的变量,所以下面代码会报错
with tf.variable_scope("foo"):
     v=tf.get_variable("v",[1])
#在生成上下文管理器时,将参数reuse设置为True。这样tf.get_variable函数将直接获取已经声明的变量
with tf.variable_scope("foo",reuse=True):
     v1=tf.get_variable("v",[1])
     print v==v1 #输出为True,代表v,v1代表相同的Tensorflow中的变量
#将参数reuse设置为True时,tf.variable_scope将只能获取已经创建过的变量。因为在命名空间bar中还没创建变量v,所以以下代码会报错
with tf.variable_scope("bar",reuse=True):
     v=tf.get_variable("v",[1])

关于tf.variable_scope函数嵌套时,reuse参数的取值是如何确定的

with tf.variable_scope("root")
  #可以通过tf.get_variable_scope().reuse函数来获取上下文管理器中reuse参数的取值
  print tf.get_variable_scope().reuse  #输出False,即最外层reuse是False
  with tf.variable_scope("foo",reuse=True): #新建一个嵌套上下文的管理器,并指定reuse为True
       print tf.get_variable_scope().reuse   #输出为True
       with tf.variable_scope("bar"):       #新建一个嵌套的上下文管理器,但不指定reuse,这是                                          #                                            #reuse的取值回合外面一层保持一致。
      print tf.get_variable_scope().reuse     #输出为True
  print tf.get_variable_scope().reuse       #输出为False,退出reuse设置为True的上下文之后,又
                                            #回到了False.

reuse为True时,tf.get_variable函数会直接获取已经创建的变量。如果变量不存在,将报错

reuse为False时,tf.get_variable函数会创建新的变量,若变量已经存在,则报错。

同时tf.variable_scope函数生成的上下文管理器也会创建一个Tensorflow中的命名空间,在命名空间内创建的变量名称都会带上这个命名空间作为前缀。下面代码是通过tf.variable_scope来管理变量的名称

v1=tf.get_variable("v",[1])
print v1.name      #输出v:0.“v”为变量的名称,“:0”表示这个变量时生成变量这个运算的第一个结果。
with tf.variable_scope("foo"):
     v2=tf.get_variable("v",[1])
     print v2.name #输出foo/v:0.在tf.variable_scope中创建的变量,名称前面会加入名称空间的名称, 
                   #并通过/来分隔命名空间的名称和变量的名称
with tf.variable_scope("foo"):
     with tf.variable_scope("bar"):
          v3=tf.get_variable("v",[1])
          print v3.name   #输出foo/bar/v:0.命名空间可以嵌套,同时变量的名称也会加入所有命名空间
                           #的名称做前缀
     v4=tf.get_variable("v1",[1])
     print v4.name   #输出foo/v1:0.当命名空间退出之后,变量名称也就不会在被加入前缀了
#创建一个名称为空的命名空间,并设置reuse=True
with tf.variable_scope("",reuse=True):
     v5=tf.get_variable("foo/bar/v",[1]) #可以直接通过带命名空间名称的变量名来获取
                                          #其他命名空间下的变量,比如这里通过指定名称foo/bar/v
                                          #来获取在命名空间foo/bar/中创建的变量
      print v5==v3                        #输出True
      v6=tf.get_variable("foo/v1",[1])
      print v6==v4                        #输出为True

通过tf.variable_scope和tf.get_variable函数,对前向传播结果的函数做了一些改进,代码如下:

def inference(input_tensor,reuse=False)
  #定义第一层神经网络的变量和前向传播过程
   with tf.variable_scope('layer1',reuse=reuse):
        #根据传进来的reuse来判断是创建新变量还是使用已经创建好的。在第一次构造网络时
        #需要创建新的变量,以后每次调用这个函数都直接使用reuse=True就不需要每次将变量传进来
       weights=tf.get_variable("weights",[INPUT_NODE,LAYER1_NODE],
               initializer=tf.truncated_normal_initializer(stddev=0.1))
       biases=tf.get_variable("biases",

          [LAYER1_NODE],initializer=tf.constant_initializer(0.0))
     layer1=tf.nn.relu(tf.matmul(input_tensor,weights)+biases)
#类似地定义第二层神经网络的变量和前向传播过程
with tf.variable_scope('layer2',reuse=reuse):
     weights=tf.get_variable("weights",[LAYER1_NODE,OUTPUT_NODE],
             initializer=tf.truncated_normal_initializer(stddev=0.1))
     biases=tf.get_variable("biases",[OUTPUT_NODE],
            tf.constant_initializer(0.0))
     layer2=tf.matmul(layer1,weights)+biases
#返回最后前向传播结果
   return layer2
x=tf.placeholder(tf.float32,[None,INPUT_NODE],name='x-input')
y=inference(x)

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值