十八.TensorFlow之scope命名方式

部署运行你感兴趣的模型镜像

TensorFlow之scope命名方式

scope 能让你命名变量的时候轻松很多. 同时也会在 reusing variable 代码中常常见到. 所以今天我们会来讨论下 tensorflow 当中的两种定义 scope 的方式. 最后并附加一个 RNN 运用 reuse variable 的例子.


在 Tensorflow 当中有两种途径生成变量 variable, 一种是 tf.get_variable(), 另一种是 tf.Variable(). 如果在 tf.name_scope() 的框架下使用这两种方式, 结果会如下.

import tensorflow as tf

with tf.name_scope("a_name_scope"):
    initializer = tf.constant_initializer(value=1)
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    var21 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)
    var22 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)


with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print(var1.name)        # var1:0
    print(sess.run(var1))   # [ 1.]
    print(var2.name)        # a_name_scope/var2:0
    print(sess.run(var2))   # [ 2.]
    print(var21.name)       # a_name_scope/var2_1:0
    print(sess.run(var21))  # [ 2.0999999]
    print(var22.name)       # a_name_scope/var2_2:0
    print(sess.run(var22))  # [ 2.20000005]

可以看出使用 tf.Variable() 定义的时候, 虽然 name 都一样, 但是为了不重复变量名, Tensorflow 输出的变量名并不是一样的. 所以, 本质上 var2var21var22 并不是一样的变量. 而另一方面, 使用tf.get_variable()定义的变量不会被tf.name_scope()当中的名字所影响.

如果想要达到重复利用变量的效果, 我们就要使用 tf.variable_scope(), 并搭配 tf.get_variable() 这种方式产生和提取变量. 不像 tf.Variable() 每次都会产生新的变量, tf.get_variable() 如果遇到了同样名字的变量时, 它会单纯的提取这个同样名字的变量(避免产生新变量). 而在重复使用的时候, 一定要在代码中强调 scope.reuse_variables(), 否则系统将会报错, 以为你只是单纯的不小心重复使用到了一个变量.

with tf.variable_scope("a_variable_scope") as scope:
    initializer = tf.constant_initializer(value=3)
    var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer)
    scope.reuse_variables()
    var3_reuse = tf.get_variable(name='var3',)
    var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    var4_reuse = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var3.name)            # a_variable_scope/var3:0
    print(sess.run(var3))       # [ 3.]
    print(var3_reuse.name)      # a_variable_scope/var3:0
    print(sess.run(var3_reuse)) # [ 3.]
    print(var4.name)            # a_variable_scope/var4:0
    print(sess.run(var4))       # [ 4.]
    print(var4_reuse.name)      # a_variable_scope/var4_1:0
    print(sess.run(var4_reuse)) # [ 4.]

RNN 例子的代码在这里, 整个 RNN 的结构已经在这里定义好了. 在 training RNN 和 test RNN 的时候, RNN 的 time_steps 会有不同的取值, 这将会影响到整个 RNN 的结构, 所以导致在 test 的时候, 不能单纯地使用 training 时建立的那个 RNN. 但是 training RNN 和 test RNN 又必须是有同样的 weights biases 的参数. 所以, 这时, 就是使用 reuse variable 的好时机.

首先定义training 和 test 的不同参数.

class TrainConfig:
    batch_size = 20
    time_steps = 20
    input_size = 10
    output_size = 2
    cell_size = 11
    learning_rate = 0.01


class TestConfig(TrainConfig):
    time_steps = 1
    
train_config = TrainConfig()
test_config = TestConfig()

然后让 train_rnn 和 test_rnn 在同一个 tf.variable_scope('rnn') 之下. 并且定义 scope.reuse_variables(), 使我们能把 train_rnn 的所有 weights, biases 参数全部绑定到 test_rnn 中. 这样, 不管两者的 time_steps 有多不同, 结构有多不同, train_rnn W, b 参数更新成什么样, test_rnn 的参数也更新成什么样.

with tf.variable_scope('rnn') as scope:
    sess = tf.Session()
    train_rnn = RNN(train_config)
    scope.reuse_variables()
    test_rnn = RNN(test_config)
    sess.run(tf.global_variables_initializer())

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

<think>我们正在处理的问题:在Visual Studio中,尝试右键点击`CustomObjectScope`并选择“转到定义”时,提示“无法导航到插入点下面的符号”。同时,我们发现`CustomObjectScope`类并不在`Tensorflow.Keras.Saving`命名空间下。 根据之前的讨论,我们尝试了多种解决方案,但问题仍未解决。现在,结合站内引用的一些信息,我们重新分析问题。 站内引用中提到了几个关键点: 1. 引用[1]:项目中的命名冲突可能导致导入失败。需要检查是否有与TensorFlow内部模块冲突的文件或库。 2. 引用[2]:提供了解决导入问题的一些方法,包括安装`types-tensorflow`和使用条件导入。 3. 引用[3]:用户在使用`tensorflow.keras`时遇到导入问题,转而直接使用`keras`模块。 4. 引用[4]:展示了导入`tensorflow.keras.models`时出现的错误,提示无法从`typing`导入`OrderedDict`。 5. 引用[5]:指出在TensorFlow 2.0中,推荐使用`import tensorflow as tf`然后从`tf`中导入`keras`。 但是,我们的问题不是导入错误,而是在VS中无法导航到定义。因此,我们需要考虑VS特定的问题。 结合问题,我们可能面临以下情况: - `CustomObjectScope`类可能已经移动到了不同的命名空间。 - 智能感知无法正确解析符号,因为程序集可能没有包含该符号,或者存在版本不匹配。 根据TensorFlow.NET的文档(假设我们使用的是TensorFlow.NET库),在0.15版本中,`CustomObjectScope`位于`Tensorflow.Keras.Saving`命名空间。但用户提示不在该命名空间下,因此我们需要考虑: 1. 版本差异:可能用户使用的版本中,这个类被移动或删除了。 2. 实际代码中,我们可能使用了错误的命名空间。 解决方案: 步骤1:确认当前安装的TensorFlow.NET版本 在VS中,打开NuGet包管理器,查看项目安装的TensorFlow.NET和TensorFlow.Keras的版本。 步骤2:查阅对应版本的API文档 访问TensorFlow.NET的GitHub仓库或文档,查找对应版本的`CustomObjectScope`类的位置。 步骤3:尝试使用其他方式定位符号 在代码中,尝试使用完全限定名来查看是否可以跳转: ```csharp var scope = new Tensorflow.Keras.Saving.CustomObjectScope(); ``` 或者,如果版本不同,可能需要使用: ```csharp var scope = new Tensorflow.Keras.Utils.CustomObjectScope(); // 例如,在0.14版本中可能在Utils命名空间 ``` 步骤4:检查程序集元数据 如果转到定义仍然失败,我们可以使用对象浏览器(在VS中,视图->对象浏览器)来搜索`CustomObjectScope`,查看它到底在哪个程序集和哪个命名空间下。 步骤5:考虑升级或降级版本 如果发现版本不匹配,考虑升级或降级TensorFlow.NET到合适的版本。例如,如果文档显示该类在0.15.0版本中存在于`Tensorflow.Keras.Saving`,而我们使用的是0.15.0,那么可能是其他问题。如果使用更高版本(比如0.16.0)且该类被移除,则需要调整代码。 步骤6:如果该类确实不存在,寻找替代方案 查阅文档,看是否有替代`CustomObjectScope`的方式。例如,在较新的版本中,可能使用不同的方式来实现相同的功能。 步骤7:清理和重建 执行清理解决方案、清除NuGet缓存、删除bin/obj文件夹,然后重新生成。 步骤8:检查项目引用 确保项目正确引用了TensorFlow.Keras程序集,并且该程序集确实包含`CustomObjectScope`类。 步骤9:使用反编译工具 如果以上步骤都失败,可以使用反编译工具(如ILSpy)打开程序集,直接查看其中是否存在`CustomObjectScope`以及它的命名空间。 根据站内引用[3]和[5],在Python的TensorFlow中,使用`tensorflow.keras`是推荐的方式,但在.NET中,我们使用的是TensorFlow.NET,其API可能与Python不同。 在TensorFlow.NET的0.15.0版本中,我们可以在源码中看到: https://github.com/SciSharp/TensorFlow.NET/blob/v0.15.0/src/TensorFlowNET.Keras/Saving/CustomObjectScope.cs 所以,如果我们的版本是0.15.0,那么该类应该在`Tensorflow.Keras.Saving`命名空间下。 因此,我们重点检查版本和程序集是否正确加载。 具体步骤: 1. 在解决方案资源管理器中,展开项目的“依赖项”->“程序集”,找到`TensorFlow.Keras`程序集,展开并尝试在`Tensorflow.Keras.Saving`命名空间下找到`CustomObjectScope`类。如果存在,直接双击它,看是否能打开元数据视图。 2. 如果不存在,则可能程序集版本不对。检查NuGet包管理器,确认安装的版本。 3. 如果程序集版本正确,但仍然没有,则可能是NuGet包损坏。尝试卸载并重新安装TensorFlow.Keras包。 4. 如果重新安装后问题依旧,考虑升级到最新版本(如果最新版本中该类还在)或者回退到已知包含该类的版本。 5. 如果该类已经被移除或移动,我们需要调整代码。可以查看该库的发布说明或提交历史,确定变化。 6. 如果项目中有多个项目引用,可能存在版本冲突,确保所有相关项目使用相同版本的TensorFlow.NET和TensorFlow.Keras。 7. 如果使用对象浏览器可以在程序集中看到该类,但在代码中无法跳转,可能是智能感知的问题。尝试关闭VS,删除解决方案目录下的`.vs`文件夹(隐藏文件夹),然后重新打开解决方案。 8. 在代码中,尝试使用`global::`前缀来避免可能的命名冲突: ```csharp var scope = new global::Tensorflow.Keras.Saving.CustomObjectScope(); ``` 9. 如果以上都不行,可以尝试在代码中通过反射来检查类型是否存在,以确认不是编译时问题而是IDE的问题: ```csharp var type = Type.GetType("Tensorflow.Keras.Saving.CustomObjectScope, TensorFlow.Keras"); Console.WriteLine(type?.FullName ?? "Not found"); ``` 如果反射能找到,那么说明程序集正确,只是IDE的智能感知有问题。我们可以继续使用,或者等待VS更新。 如果反射也找不到,那么就是程序集确实不包含这个类,需要检查版本。 根据这些步骤,我们逐步排查。 由于用户提到“CustomObjectScope类不在Tensorflow.Keras.Saving命名空间下”,可能是版本升级导致的变化。例如,在TensorFlow.NET的0.16.0版本中,我们注意到一些API发生了变化。因此,请确认使用的版本。 总结: 请按照以下顺序操作: 1. 确认版本:检查项目中的TensorFlow.NET和TensorFlow.Keras的NuGet包版本。 2. 如果版本是0.15.0,则应该在`Tensorflow.Keras.Saving`命名空间下有此类。如果版本高于0.15.0,请查看发行说明或源码,确认是否移动或删除了该类。 3. 重新安装NuGet包。 4. 清理解决方案并重建。 5. 使用对象浏览器或反编译工具验证程序集内容。 6. 如果类存在但无法导航,重置VS智能感知缓存(删除.ipcache文件夹)。 7. 如果类不存在,考虑降级到0.15.0或升级到包含该类的其他版本,或者使用替代方法。 如果用户确认版本是0.15.0,但仍然找不到,那么很可能是程序集没有正确加载或损坏。重新安装并清理是必要的。 相关问题: 1. 如何检查Visual Studio中引用的程序集版本? 2.TensorFlow.NET中,如何查找特定类的命名空间? 3. 当智能感知无法导航到定义时,如何手动验证类的存在? 4. 如何处理因版本升级导致的API变化? </think> ### 解决 "无法导航到 CustomObjectScope 定义" 问题 根据您的问题描述和站内引用分析,以下是针对 VS 中无法导航到 `CustomObjectScope` 定义的综合解决方案: --- ### 核心问题分析 1. **命名空间迁移问题**:TensorFlow API 版本更新导致 `CustomObjectScope` 可能已迁移到新命名空间[^3][^5] 2. **程序集冲突**:项目中可能存在多个 TensorFlow/Keras 版本冲突[^1] 3. **元数据缺失**:VS 智能感知所需的类型元数据未正确生成[^4] 4. **版本不匹配**:TensorFlow 与 Keras 版本不兼容[^3] --- ### 分步解决方案 #### 第一步:验证实际命名空间位置 ```csharp // 尝试在代码中使用以下导入语句 using Tensorflow.Keras.Utils; // 新版本可能在此命名空间 using Tensorflow.Keras.Saving; // 旧版本位置 // 或直接使用全局命名空间 var scope = new global::Tensorflow.Keras.Utils.CustomObjectScope(); ``` 1. 在对象浏览器中搜索 `CustomObjectScope` (视图 → 对象浏览器) 2. 在解决方案资源管理器中展开 `TensorFlow.Keras` 程序集节点 #### 第二步:解决程序集冲突[^1] 1. 检查项目中的冲突文件: - 删除或重命名项目中任何名为 `tensorflow.*.cs` 的文件 - 检查是否存在多个版本的 Keras 包引用 2. 统一 NuGet 包版本(.csproj 文件): ```xml <ItemGroup> <PackageReference Include="TensorFlow.Keras" Version="0.150.0" /> <PackageReference Include="TensorFlow.NET" Version="0.150.0" /> </ItemGroup> ``` #### 第三步:重建类型元数据[^4] 1. 清理解决方案: ```powershell 生成 → 清理解决方案 ``` 2. 删除缓存文件: - 关闭 VS - 删除项目目录下的 `bin` 和 `obj` 文件夹 - 删除解决方案目录下的 `.vs` 隐藏文件夹 3. 重建项目: ```powershell 生成 → 重新生成解决方案 ``` #### 第四步:版本兼容性处理[^5] ```csharp // 尝试使用推荐的 TensorFlow 2.x 导入方式 using Tensorflow; using static Tensorflow.KerasApi; // 通过 KerasApi 访问 // 使用示例 keras.utils.CustomObjectScope(); // 注意命名空间变化 ``` 1. 检查 TensorFlow 版本兼容性: ```powershell # 包管理器控制台 Get-Package | Where-Object {$_.Id -like "TensorFlow*"} ``` 2. 升级到兼容版本: ```powershell Update-Package TensorFlow.NET -Version 0.150.0 Update-Package TensorFlow.Keras -Version 0.150.0 ``` #### 第五步:备选导航方法 1. 使用元数据视图: - 右键 `CustomObjectScope` → 查看定义 - 在元数据窗口中检查实际命名空间 2. 反编译验证: - 使用 [ILSpy](https://github.com/icsharpcode/ILSpy) 打开 `TensorFlow.Keras.dll` - 搜索 `CustomObjectScope` 类位置 #### 第六步:替代实现方案 如果类确实不存在: ```csharp // 创建自定义实现(简化示例) public class CustomObjectScope : IDisposable { public void Register<T>(string name, T obj) where T : class { // 注册自定义对象逻辑 } public void Dispose() { // 清理资源 } } ``` --- ### 验证流程图 ```mermaid graph TD A[问题:无法导航到定义] --> B{检查命名空间} B -->|Tensorflow.Keras.Utils| C[更新导入] B -->|不存在| D[检查程序集冲突] D --> E[统一NuGet版本] E --> F[清理并重建] F --> G{问题解决?} G -->|否| H[使用元数据视图] H --> I[反编译验证] I --> J[创建自定义实现] G -->|是| K[完成] ``` --- ### 相关问题 1. 如何检测和解决 Visual Studio 中的程序集引用冲突?[^1] 2. 当 NuGet 包损坏时,有哪些可靠的恢复方法?[^4] 3. 如何在没有源代码的情况下验证 .NET 程序集中的类结构?[^2] 4. TensorFlow 不同版本间的 API 变化如何追踪和适配?[^5] 5. 如何创建 Visual Studio 智能感知友好的自定义类型元数据? [^1]: 项目中存在命名冲突可能导致导入失败,需检查冲突文件 : 使用 ILSpy 等工具可反编译程序集验证类型存在性 : TensorFlow 2.x 推荐使用 `from tensorflow import keras` 导入方式 [^4]: 清理解决方案和删除缓存可解决元数据损坏问题 : TensorFlow.keras 是 TensorFlow 2.0 的推荐使用方式
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码哥kylin

你的鼓励拿去给我儿子买好吃的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值