30天从入门到精通TensorFlow1.x 第三天,tf.variable_scope()共享或重用变量

news2024/12/23 14:02:24

tf.variable_scope()共享或重用变量

文章目录

  • 一、接前一天
  • 二、`tf.variable_scope()`共享或重用变量
    • 1. 背景
    • 2. 目的
    • 3. `tf.variable_scope()`基本参数
    • 3. `tf.variable_scope()`作用
      • (1).命名空间
      • (2).共享变量
      • (3).控制变量重复定义
  • 三、解释前天遗留问题以及文章最后抛出的问题
    • 1. 解释前先明白共享的含义
    • 2. 还有什么是作用域的重用策略
    • 3. 解释之前的问题,为什么在同一作用域下同时使用 tf.Variable() 和 tf.get_variable() ,不设置reuse不开启共享变量,tf.get_variable() 可以继承同名的tf.Variable()变量。将reuse=True开启共享变量反而会报错
    • 4. 为什么 tf.Variable() 和 tf.get_variable()创建的变量不共享
    • 5. 解释 `这个当前作用域也有说法,等下说`
    • 6. 重点注意:

一、接前一天

总结:到这里为止,基本掌握如何通过常量、操作、占位符、变量来定义张量。今天在学习一个重要函数
tf.variable_scope()共享重用变量
一般获取已经定义的变量有利于复用,如果没有使用tf.variable_scope()就会抛出异常。

今天来一起讨论下该函数

二、tf.variable_scope()共享或重用变量

1. 背景

当我们使用 TensorFlow 构建神经网络时,通常会涉及到很多的变量。这些变量需要在训练期间不断地更新,同时在推理(inference)过程中也需要被重复使用。因此,在 TensorFlow 中,我们需要对变量进行管理控制,使之易于调用共享可视化

2. 目的

tf.variable_scope() 是一个用于定义变量的作用域的函数。它可以将同一种类型的变量放在同一个作用域下,方便进行管理调用。每个变量都有相应的名称,以及所属的作用域的名称。

通过 tf.variable_scope() 函数,我们可以实现以下几个目的:

  1. 为变量命名提供更高级别的结构化管理:在 TensorFlow 的计算图中使用的所有变量都将被分配到一个作用域(scope)中,这样可以更好地组织计算图,并且可以更容易地调试可视化
  2. 共享变量:在 TensorFlow 中,如果两个变量具有相同的名称和作用域,则它们将指向同一个变量。
  3. 控制变量的可访问性:通过设置 reuse 参数,我们可以控制变量是否可以被重复使用或者共享

3. tf.variable_scope()基本参数

#来看下源码
  def __init__(self,
               name_or_scope,
               default_name=None,
               values=None,
               initializer=None,
               regularizer=None,
               caching_device=None,
               partitioner=None,
               custom_getter=None,
               reuse=None,
               dtype=None,
               use_resource=None,
               constraint=None,
               auxiliary_name_scope=True):

这里重点标记几个参数:

  1. name_or_scope:作用域的名称或者作用域本身,是必填参数
  2. default_name:默认的名称,如果没有指定具体的名称,则使用此名称。
  3. values列表字典类型的参数,其中每个元素对应一个变量
  4. reuse:重用标志,表示是否共享变量。
  5. initializer:变量的初始化方式。默认值为None。如果不指定initializer,则会采用默认的随机初始化方式。具体的初始化方式可以在定义变量时进行设置。

3. tf.variable_scope()作用

(1).命名空间

假设现在有一个深度神经网络模型,模型中包含多个卷积层和全连接层。为了方便管理和调试,我们可以使用variable_scope来给每个变量添加前缀,按照功能或者含义进行分组

with tf.variable_scope('conv_1'):
  weight = tf.get_variable('weight', shape=[3, 3, 3, 32], initializer=tf.truncated_normal_initializer(stddev=0.1))
  bias = tf.get_variable('bias', shape=[32], initializer=tf.constant_initializer(0.0))

with tf.variable_scope('conv_2'):
  weight = tf.get_variable('weight', shape=[3, 3, 32, 64], initializer=tf.truncated_normal_initializer(stddev=0.1))
  bias = tf.get_variable('bias', shape=[64], initializer=tf.constant_initializer(0.0))

with tf.variable_scope('fc_1'):
  weight = tf.get_variable('weight', shape=[7 * 7 * 64, 1024], initializer=tf.truncated_normal_initializer(stddev=0.1))
  bias = tf.get_variable('bias', shape=[1024], initializer=tf.constant_initializer(0.0))

with tf.variable_scope('fc_2'):
  weight = tf.get_variable('weight', shape=[1024, 10], initializer=tf.truncated_normal_initializer(stddev=0.1))
  bias = tf.get_variable('bias', shape=[10], initializer=tf.constant_initializer(0.0))

(2).共享变量

假设现在有两个模型AB,这两个模型需要共享某些变量。为了节省内存和方便调试,我们可以使用variable_scope来共享变量,

def model_A(input_data):
  with tf.variable_scope('shared', reuse=tf.AUTO_REUSE):
    weight = tf.get_variable('weight', shape=[input_dim, hidden_dim], initializer=tf.truncated_normal_initializer(stddev=0.1))
    bias = tf.get_variable('bias', shape=[hidden_dim], initializer=tf.constant_initializer(0.0))
  ...

def model_B(input_data):
  with tf.variable_scope('shared', reuse=tf.AUTO_REUSE):
    weight = tf.get_variable('weight')
    bias = tf.get_variable('bias')
  ...

使用了相同的variable_scope ‘shared’ 来定义和共享模型A和B中的权重和偏置。通过设置reuse参数为tf.AUTO_REUSE,我们可以让模型B共享模型A的变量。这样可以节省内存,同时让模型更加可靠和易于理解。

(3).控制变量重复定义

假设现在有一个函数f(x)需要多次调用,其中包含一个变量v。我们希望在第一次调用时定义变量v,在后续调用时共享这个变量v。为了避免重复定义变量,我们可以使用variable_scope控制变量是否可重用

def f(x):
  with tf.variable_scope('v', reuse=tf.AUTO_REUSE):
    v = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(0.0))
  return x * v

x_1 = tf.constant(1.0)
y_1 = f(x_1)

x_2 = tf.constant(2.0)
y_2 = f(x_2)

在这里插入图片描述

在比如结合tf.get_variable使用:

import tensorflow as tf

with tf.variable_scope("my_scope"):
    a = tf.Variable([1, 2], name="var_a")
    b = tf.get_variable(name="var_b", shape=[2])
    c = tf.constant([3, 4], name="const_c")

with tf.variable_scope("my_scope", reuse=True):
    d = tf.Variable([5, 6], name="var_d")
    e = tf.get_variable(name="var_b")

print(a.name)
print(b.name)
print(c.name)
print(d.name)
print(e.name)

在这里插入图片描述可以看到:当我们开起了 reuse=True功能:说明开启了重复使用变量的功能。注意:这里说的是变量
当我们定义一个新的变量时候,如果,在同一个 variable_scope下已经有了同名的变量,就会抛出ValueError异常。(这里肯定有人说 可以使用 get_variable函数啊,这个等会说)。但是在某种情况下需要共享变量,也就是多个操作共用一个变量。这是就可以设置为True

如果将reuse参数设置为True,则在当前作用域这个当前作用域也有说法,等下说)下查找已经存在同名变量,并返回这个变量。如果没有找到,则抛出异常。如果将reuse参数设置为None或False,则在当前作用域下创建该变量。

注意!!!:reuse参数只对当前variable_scope下的变量起作用,如果遇到嵌套的variable_scope,则每个variable_scope都可以单独控制reuse参数的取值。如果想在不同的作用域下共享变量,则需要将reuse参数设置为True,并且使用tf.variable_scope()的嵌套语法来指定每个变量作用域。

三、解释前天遗留问题以及文章最后抛出的问题

1. 解释前先明白共享的含义

TensorFlow中,变量共享是指多个TensorFlow节点之间使用相同的变量。当多个TensorFlow节点共享相同的变量时,它们可以共同学习这个变量,并且每个节点对变量做出的更新都会影响到其他节点

使用tf.get_variable()函数创建变量时,可以通过将reuse参数设置为True来启用变量共享。如果在同一作用域内调用tf.get_variable()多次,每次使用相同的名称和形状,则将返回现有的变量,而不是每次都创建一个新的变量

在深度学习模型中,通常需要在不同的层之间共享变量,以便提高模型训练的效率和精度。例如,在卷积神经网络(CNN)中,卷积层的权重可以在整个模型中共享,以提高模型的可训练性和泛化能力。

总结一句话一荣俱荣,一损俱损共享变量意味着多个节点共用相同的变量,因此任何一个对该变量的操作都会影响到其他节点。如果其中一个节点更新了变量的值,则所有使用相同变量的节点的输出也会随之改变。

2. 还有什么是作用域的重用策略

作用域的重用策略是指在创建一个新的变量作用域时,当前作用域下是否可以重用已经存在的变量

在 TensorFlow 中,每个变量都会有一个唯一的名称,这个名称包含了所有定义该变量的作用域变量名。当使用 tf.Variable()tf.get_variable() 创建变量时,需要指定变量的名称,如果名称相同则会在创建变量时发生命名空间冲突。

为了避免这种冲突,TensorFlow 提供了作用域(tf.variable_scope())来隔离变量的命名空间,并且可以设置作用域的重用策略。具体来说,作用域的重用策略有以下三种:

  1. None:默认值,表示在创建作用域时不强制设置重用策略,由上下文环境自动确定是否可以重用变量。
  2. tf.AUTO_REUSE:表示在创建作用域时尝试重用已经存在的变量,如果不存在则创建新的变量
  3. True:表示强制重用已经存在的变量,如果不存在则抛出异常。
    在 TensorFlow 2.x 中,作用域的重用策略默认为 tf.compat.v1.AUTO_REUSE,即尝试重用已经存在的变量。而在 TensorFlow 1.x 中,默认的重用策略是 None,表示不强制设置重用策略,由上下文环境自动确定是否可以重用变量。

作用域的重用策略是在创建新作用域时设置的,可以使用 tf.variable_scope() 函数的 reuse 参数来指定

3. 解释之前的问题,为什么在同一作用域下同时使用 tf.Variable() 和 tf.get_variable() ,不设置reuse不开启共享变量,tf.get_variable() 可以继承同名的tf.Variable()变量。将reuse=True开启共享变量反而会报错

tf.get_variable()继承同名的tf.Variable()变量不等同于共享变量,它创建的是一个新变量。当您在同一作用域内同时使用tf.Variable()tf.get_variable()函数来创建同名的变量时,这两个变量是不同的,它们的状态也是不同的,因此不能称之为共享变量

因此:这也是为什么在同一作用域下同时使用 tf.Variable() 和 tf.get_variable() ,不设置reuse不开启共享变量,tf.get_variable() 可以继承同名的tf.Variable()变量。将reuse=True开启共享变量反而会报错。还有就是上边 (这里肯定有人说 可以使用 get_variable函数啊)这句话的解释。因为reuse=True开启共享变量也就意味着同一个作用域下,的变量共享,然而事实是 这两者创建的变量并不是共享的。因此才会报错。

4. 为什么 tf.Variable() 和 tf.get_variable()创建的变量不共享

  1. 使用tf.Variable()函数创建变量,则每次调用该函数都会创建一个新的变量。而如果您使用tf.get_variable()函数创建变量,则会尝试重用具有相同名称的现有变量

  2. 如果未启用变量共享,则tf.Variable()tf.get_variable()可以创建同名的变量。但是,如果您想要启用变量共享,则必须在使用tf.get_variable()函数时将reuse参数设置为True,并且在使用相同名称的变量时,仅限于在同一作用域内进行共享。如果没有设置reuse=True,则不能在同一作用域内使用tf.get_variable()和tf.Variable()来创建具有相同名称的变量。

原理

  1. TensorFlow中的变量是指在程序运行时可以进行修改的张量,它们通常用于存储模型参数和其他状态信息。在TensorFlow中,tf.Variable()tf.get_variable()都可以用来创建变量。

  2. tf.Variable()函数是通过调用TensorFlow的ops来创建一个变量节点,这个节点包含了一个初始值,并且允许在训练过程中更新这个值每次调用tf.Variable()函数都会创建一个新的变量

  3. tf.get_variable()函数则是首先检查当前上下文中是否已经存在名字为指定名称的变量,如果已经存在,则返回现有变量;否则,就使用给定的名称和形状创建一个新的变量。因此,tf.get_variable()函数可以用于实现变量共享,并且在同一作用域内调用tf.get_variable()多次不会创建新的变量

  4. 当在同一作用域下同时使用tf.Variable()tf.get_variable()函数来创建同名的变量时,由于tf.Variable()创建的变量和tf.get_variable()创建的变量并不是同一个变量因此不能共享。但是,如果您想要启用变量共享,则必须在使用tf.get_variable()函数时将reuse参数设置为True,并且在使用相同名称的变量时,仅限于在同一作用域内进行共享

5. 解释 这个当前作用域也有说法,等下说

在TensorFlow中,如果在一个variable_scope定义了一个变量,那么这个变量的名称就会被加上该variable_scope前缀

例如:

with tf.variable_scope('my_scope'):
    x = tf.Variable(1.0, name='x')

在这里插入图片描述

我们在变量作用域’my_scope’下定义了一个名称为’x’的变量,实际的变量名'my_scope/x'

此时如果:我们再次尝试使用tf.get_variable()函数来获取名称为'x'的变量并且不指定reuse=True参数,那么TensorFlow就会抛出一个ValueError异常,因为它会认为要创建一个新的变量,而已经存在同名的变量了。

with tf.variable_scope('my_scope'):
    # 以下代码会抛出ValueError异常
    y = tf.get_variable('x', shape=[2, 2], initializer=tf.constant_initializer(0.0))

6. 重点注意:

  1. 变量共享通常通过tf.get_variable()函数reuse参数来实现,而tf.Variable()函数则用于创建不需要共享的独立变量
  2. 同一个作用域下,不要同时出现tf.get_variable()tf.Variable()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/601469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软考A计划-电子商务设计师-电子商务相关技术与应用基础知识

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&am…

cesium 相机相关

1 相机的初始位置 /*** The default rectangle the camera will view on creation.* type Rectangle*/ Camera.DEFAULT_VIEW_RECTANGLE Rectangle.fromDegrees(-95.0,-20.0,-70.0,90.0 );// set default view rectangleCameraPosition3D(this,Camera.DEFAULT_VIEW_RECTANGLE,…

Async 使用详解

Spring Boot异步调用Async 在实际开发中,有时候为了及时处理请求和进行响应,我们可能会多任务同时执行,或者先处理主任务,也就是异步调用,异步调用的实现有很多,例如多线程、定时任务、消息队列等&#xf…

若依框架快速搭建(二)

目录 数据库设计功能模块设计XXX信息管理xxx查询xxx添加xxx删除xxx修改xxx导出 功能模块实现运行数据库自动代码生成在IDEA中找到RuoYi-generator,修改配置运行前后端项目,在网页中找到代码生成模块导入表后点击确定,序号前打勾,再…

Mac - 光标特效 By CursorEffect2

目录 一.引言 二.安装 CursorEffect2 三.使用 CursorEffect2 四.使用效果 五.内存消耗 六.一键关闭 七.总结 一.引言 在自己搭建的 Hexo 博客上可以定义鼠标点击的特效,如图点击后可以产生彩色的斑点。 于是想着除了浏览 Hexo 博客外,能不能别的也…

【笔试强训编程题】Day1.(组队竞赛100449)和(删除公共字符69390)

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:笔试强训编程题 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!! 文章目录…

【CSS3系列】第一章 · CSS3新增的三种基本属性

写在前面 Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正&#xff0…

FineBI6.0基础学习第一课 数据门户

PC端门户使用示例 首先,以管理员身份登录FineBI系统,安装数据门户,安装步骤见官网 新建一个数据门户

SouapUI接口测试之创建性能测试

SouapUI也是一个能生动的体现一个系统(项目)性能状态的工具,本篇就来说说如何在SouapUI工具下创建性能测试 一、创建测试用例 由于在《SouapUI接口测试之使用Excel进行参数化》篇已经创建好了测试用例,本篇就不讲解如何创建测试…

SpringCloudAlibaba:服务网关之Gateway学习

目录 一、网关简介 (一)为什么要用网关 (二)网关解决了什么问题 (三)常用的网关 二、Gateway简介 (一)核心概念 (二)工作原理 三、Gateway快速入门 &…

linuxOPS基础_用户与组管理

linux用户与组概念 为什么需要了解用户和组 服务器要添加多账户的作用 ​ 针对不同用户分配不同的权限,不同权限可以限制用户可以访问到的系统资源 ​ 提高系统的安全性 ​ 帮助系统管理员对使用系统的用户进行跟踪 用户和组的关系 理论上Linux系统中的每个用户…

2023年6月实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】

首先,来看下效果图 在线体验地址:https://geojson.hxkj.vip,并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据&#xff0…

日本原装Yokogawa AQ6317B横河AQ6317C光谱分析仪

Yokogawa AQ6317B光谱分析仪,50 GHz ​Yokogawa AQ6317B 光谱分析仪 (OSA) 是一款先进的光谱分析仪,应用范围广泛,包括光源评估、光学设备损耗波长特性的测量以及 WDM(波分复用)系统的波形分析。在 Yokogawa 购买产品…

第十七篇、基于Arduino uno,获取cp2d12红外测距传感器的原始值和距离值——结果导向

0、结果 说明:先来看看串口调试助手显示的结果,第一个值是原始的模拟电压值,第二个值是距离值,如果是你想要的,可以接着往下看。 1、外观 说明:虽然红外测距传感器形态各异,但是原理和代码都是…

java中实现对象属性复制的工具类

在 Java 中,有多个工具类可用于实现对象属性的复制,使得属性值从一个对象复制到另一个对象。以下是几个常用的工具类: Apache Commons BeanUtils: Apache Commons BeanUtils 提供了 BeanUtils 类,可以方便地进行属性…

一文简介Linux固件子系统的实现机制

一、Linux固件子系统概述 固件是硬件设备自身执行的一段程序。固件一般存放在设备flash内。而出于成本和便利性的考虑,通常是先将硬件设备的运行程序打包为一个特定格式的固件文件,存储到终端系统内,通过终端系统给硬件设备进行升级。Linux内…

java面向对象学习

一、Java类及类的成员 1.类是对一类事物的描述,是抽象的、概念上的定义 2.对象是实际存在的该类事物的每个个体,因而也称为实例 3.属性:对应类中的成员变量 4.行为:对应类中的方法 权限修饰符号:public、protected…

玄派玄智星笔记本U盘重装电脑系统详细步骤教学

玄派玄智星笔记本U盘重装电脑系统详细步骤教学。有用户使用玄派玄智星笔记本的时候,电脑系统出现了故障,导致自己无法启动电脑了。这个情况需要使用U盘去进行系统的重装,那么具体要怎么去进行重装呢?来看看以下的操作方法吧。 准备…

移动端布局之流式布局1(百分比布局):流式布局基础、案例:京东移动端首页1

移动端布局之流式布局1 流式布局(百分比布局)基础案例:京东移动端首页搭建相关文件夹结构设置视口标签以及引入初始化样式normalize.css引入我们的css初始化文件与首页css body设置index.css app布局和app内容填充index.htmlindex.css 搜索模…

小说App源码分享,从零开始搭建小说阅读平台

作为一名小说阅读爱好者或者创业者,你是否也曾经想要搭建自己的小说阅读平台?然而,开发一款小说App通常需要大量的人力、物力和时间成本,怎样才能让它变得更加容易?今天,我将与大家分享如何从零开始&#x…