首页 文章

不构建模型时占位符和变量之间是否存在差异?

提问于
浏览
9

我试图理解TensorFlow中占位符和变量之间的区别:

X = tf.placeholder("float")
W = tf.Variable(rng.randn(), name="weight")

我还阅读了下面的Stack Overflow问题 . 当他们是模型的输入时,我理解它们之间的区别 .

InvalidArgumentError:您必须为占位符张量占位符提供值

但是,一般来说,如果我们没有 Build 模型, tf.placeholder()tf.Variable() 之间是否还有区别?

2 回答

  • 4

    占位符

    占位符用于将外部数据馈送到Tensorflow计算(图表外部的东西) . 这是一些文档:(https://www.tensorflow.org/versions/r0.10/how_tos/reading_data/#feeding

    TensorFlow的进给机制允许您将数据注入计算图中的任何Tensor . 因此,python计算可以将数据直接馈送到图中 .

    我个人会从占位符到标准输入的阅读进行类比 .

    x = raw_input()
    X = tf.placeholder("float")
    

    从标准输入读取时,需要从外部源“注入数据” . 与占位符相同 . 它允许您“注入”计算图外部的数据 .

    如果您正在训练学习算法,那么占位符的明确用例就是提供您的训练数据 . 训练数据不存储在计算图中 . 你打算如何将其纳入图表?通过占位符注入它 . 一个占位符基本上是你告诉图表“我还没有这个 . 但是当我要求你跑的时候我会帮你的 . ”

    变量

    变量用于在图表中存储状态 . 它需要一个初始值 . 一个用例可以表示神经网络的权重或类似的东西 . 这是文档:(https://www.tensorflow.org/api_docs/python/tf/Variable

    变量在调用run()的过程中维护图中的状态 . 您可以通过构造Variable类的实例将变量添加到图形中 . Variable()构造函数需要变量的初始值,该值可以是任何类型和形状的Tensor . 初始值定义变量的类型和形状 . 构造完成后,变量的类型和形状是固定的 . 可以使用其中一种assign方法更改该值 .

    我个人会在Tensorflow变量之间进行类比,并将Python中的变量分配给任何不依赖于外部内容的变量 . 例如,

    # Tensorflow:
    W = tf.Variable(rng.randn(), name="weight")
    
    # Standard python:
    w = 5
    w = "hello"
    w = [1, 2, 3, 4, 5]
    

    W 表示计算的某种结果 . 就像你必须在Python中初始化所有变量一样(你不能只运行命令 x ,你必须说 x = ...something... ),你必须初始化Tensorflow中的所有变量对象 .

    变量与占位符

    在我看来, tf.Variabletf.placeholder 之间并没有多大关系 . 如果需要存储状态,请使用 Variable . 如果需要输入外部数据,请使用 placeholder .

    如果您没有构建模型,如果要插入未定义图形的外部数据,则仍应使用 tf.placeholder . 如果您没有构建模型,如果要在运行图形时存储某种计算结果,则仍需要 tf.Variable .

    为什么两者兼而有之?

    我不是Tensorflow的专家,所以我只能猜测为什么设计都有 .

    占位符和变量之间的一个很大区别是占位符可以具有可变大小,但在构造图形时必须指定 tf.Variable 的形状 .

    可变大小的占位符感觉:也许我现在只想输入大小为5的培训批次,但也许我想稍后增加批量大小 . 也许我提前不知道我将获得多少训练样例 .

    可变大小的变量没有意义: tf.Variable 保存模型的学习参数,参数的数量不应改变 . 此外,Tensorflow扩展到分布式计算 . 如果你的形状在整个计算过程中发生了变化,那么在1000台计算机中保持正确分布是非常困难的 .

    通常,您构建模型并且所有参数都是提前知道的,因此 tf.Variable 可能用于表示 . tf.placeholder 可能适用于模型(或计算图)之外的所有其他内容,因此可以更灵活 .

  • 21

    tf.Variabletf.placeholder之间最明显的区别是


    您使用变量来保存和更新参数 . 变量是包含张量的内存缓冲区 . 必须明确初始化它们并且可以在训练期间和之后保存到磁盘 . 您可以稍后恢复已保存的值以锻炼或分析模型 .

    使用 sess.run(tf.global_variables_initializer()) 完成变量的初始化 . 同时在创建变量时,您需要将Tensor作为其初始值传递给Variable()构造函数,并且在创建变量时,您始终知道其形状 .


    另一方面,您无法更新占位符 . 它们也不应该被初始化,但是因为它们是承诺有张量,你需要将它们提供给它们 sess.run(<op>, {a: <some_val>}) . 最后,与变量相比,占位符可能不知道形状 . 您既可以提供部分尺寸,也可以不提供任何尺寸 .


    There other differences:

    有趣的是,不仅可以喂养占位符 . 您可以将值提供给变量甚至是常量 .

相关问题