tf.placeholderとtf.Variableの違いは何ですか?


290

私はTensorFlowの初心者です。私はとの違いについて混乱しているtf.placeholdertf.Variable。私の見解でtf.placeholderは、入力データにtf.Variable使用され、データの状態を格納するために使用されます。私が知っているのはこれだけです。

誰かが違いについてもっと詳しく説明してくれませんか?特に、いつtf.Variable使用するtf.placeholderか、いつ使用するか?


7
直感的には、Variables に関する勾配は必要ですが、 placeholdersは必要ありません(その値は常に提供される必要があります)。
Yibo Yang

cs231n.stanford.eduのようなコースは、混乱している人を助けることができます。私はそれがとても好きでした!明らかに他にもあります
ネイサン

回答:


175

つまり、tf.Variableモデルの重み(W)やバイアス(B)などのトレーニング可能な変数に使用します。

weights = tf.Variable(
    tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
                    stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))), name='weights')

biases = tf.Variable(tf.zeros([hidden1_units]), name='biases')

tf.placeholder 実際のトレーニング例をフィードするために使用されます。

images_placeholder = tf.placeholder(tf.float32, shape=(batch_size, IMAGE_PIXELS))
labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))

これは、トレーニング中にトレーニング例をフィードする方法です。

for step in xrange(FLAGS.max_steps):
    feed_dict = {
       images_placeholder: images_feed,
       labels_placeholder: labels_feed,
     }
    _, loss_value = sess.run([train_op, loss], feed_dict=feed_dict)

あなたは、tf.variablesこのトレーニングの結果として、訓練を受けた(修正)されます。

詳しくは、https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.htmlをご覧ください。(例はWebページから取得されます。)


2
画像を取り込む前に前処理したい場合はどうすればよいですか?(例:コントラストを再調整)。これに変数が必要ですか?もしそうなら、それは何かメモリや速度の影響がありますか?
Bastiaan

1
データをTensorflowグラフ(ネットワーク)に送る前に、行う前処理が行われるため、Tensorflowのコードツールを技術的に必要としません。たとえば、変数は不要です。1。グラフのtf.placeholders(変数ではない)を介して渡される入力データであり、2。ネットワークを介して現在のパスのプレースホルダーにロードされる前に前処理が行われます。 。
PaulG 2017

私がこの答えにどれだけ感謝しているかを書きたかっただけです。この回答に対する賛成票が質問よりもはるかに少ないという事実は、人々がどのように即座に満足することができるか、およびトレンドのタグがtensorflowand deep learningおよびlikeであるかを示すだけAIです。
ネイサン

70

違いは、tf.Variable宣言時に初期値を指定する必要があることです。tf.placeholderあなたは初期値を提供する必要はありません、あなたがして、実行時にそれを指定することができfeed_dict、引数の内部Session.run


63
-1。これは事実ですが、要点を逃しています。より重要な違いは、TensorFlow内での役割です。変数は時間の経過とともにトレーニングされます。プレースホルダーは、モデルがトレーニングしても変化しない入力データです(入力画像やそれらの画像のクラスラベルなど)。Sung Kimの回答が言うように、モデルの重みとバイアスには変数を使用します(ただし、それに限定されるわけではありません-スタイルの転送では、時間の経過とともに画像を最適化します)。
クリスアンダーソン、

@ChrisAndersonこのイラストは間違っていると言えるでしょうか?! youtu.be/MotG3XI2qSs?t=136
N0rA

@ChrisAnderson違いが1つだけの初期値が必要な場合、なぜそれが何のために使用されることを意味するのかが重要なのですか?
ゴールドネーム

1
@Goldname使用することが「意味」があるのではなく、可能なことと不可能なことです。それらは完全に異なるオブジェクトです。それらは交換可能ではなく、その違いは「初期値が必要」という以上のものです。
クリスアンダーソン

61

Tensorの計算はグラフで構成されているため、グラフで 2つを解釈することをお勧めします。

単純な線形回帰を例にとります

WX+B=Y

where WBは、重みとバイアス、およびX観測の入力とY観測の出力を表します。

明らかXYの異なる同じ性質(顕在変数)であるWB(潜在変数)。XYはサンプル(観測)の値であり、したがって、塗りつぶす場所が必要です。一方W、およびBは、重みとバイアスです。変数(前の値は後者に影響します)は、異なるペアXYペアを使用してトレーニングする必要があります。変数をトレーニングするために、さまざまなサンプルをプレースホルダーに配置します。

コードを使用してグラフを保存または再構築するには、変数を(チェックポイントで)保存または復元するだけです。

プレースホルダーは、主にさまざまなデータセット(トレーニングデータやテストデータなど)のホルダーです。ただし、変数は特定のタスクのトレーニングプロセスでトレーニングされます。つまり、入力の結果を予測したり、入力を目的のラベルにマップしたりします。さまざまなサンプルまたは同じサンプルを使用してモデルを再トレーニングまたは微調整して、dictを通じてプレースホルダーに入力するまで、これらは同じままです。例えば:

 session.run(a_graph, dict = {a_placeholder_name : sample_values}) 

プレースホルダーは、モデルを設定するためのパラメーターとしても渡されます。

トレーニングの途中でモデルのプレースホルダーを変更(追加、削除、形状変更など)した場合でも、他の変更を行わずにチェックポイントを再ロードできます。ただし、保存されたモデルの変数が変更された場合は、それに応じてチェックポイントを調整し、モデルをリロードしてトレーニングを続行する必要があります(グラフで定義されたすべての変数がチェックポイントで使用可能である必要があります)。

あなたは安全にあなたがハーネスを訓練するパラメータが必要な場合は一方で、プレースホルダは、それらを保持するために作るの値はサンプルからであれば(観測あなたが既に持っている)、要約すると変数(簡単に言えば、設定変数の必要な値のためにTFを自動的に使用するため)。

スタイル転送モデルなどのいくつかの興味深いモデルでは、入力pixが最適化され、通常呼び出されるモデル変数が固定されているため、そのリンクに実装されている変数として入力(通常はランダムに初期化)を作成する必要があります。

詳細については、このシンプルで説明的なdocを推測してください。


38

TL; DR

変数

  • 学習するパラメータについて
  • 値はトレーニングから導出できます
  • 初期値が必要です(多くの場合ランダム)

プレースホルダー

  • データ用に割り当てられたストレージ(フィード中の画像ピクセルデータなど)
  • 初期値は必要ありません(ただし、設定できます。を参照tf.placeholder_with_default

34

間の最も明白な違いtf.Variabletf.placeholderはということです


変数を使用してパラメーターを保持および更新します。変数は、テンソルを含むメモリ内バッファーです。これらは明示的に初期化する必要があり、トレーニング中およびトレーニング後にディスクに保存できます。保存した値を後で復元して、モデルを実行または分析できます。

変数の初期化はで行われsess.run(tf.global_variables_initializer())ます。また、変数を作成するときに、Tensorを初期値としてVariable()コンストラクターに渡す必要があります。変数を作成するときは、常にその形状を知っています。


一方、プレースホルダーを更新することはできません。それらも初期化されるべきではありませんが、それらはテンソルを持つことが約束されているため、それらに値をフィードする必要がありますsess.run(<op>, {a: <some_val>})。そして最後に、変数と比較して、プレースホルダーは形状を知らない可能性があります。ディメンションの一部を提供することも、何も提供しないこともできます。


他にも違いがあります:

興味深いのは、プレースホルダーだけがフィードできるということです。値を変数、さらには定数に渡すことができます。


14

他の回答に加えて、Tensoflow WebサイトのこのMNISTチュートリアルでも非常によく説明しています。

シンボリック変数を操作することにより、これらの相互作用する操作について説明します。作成しましょう:

x = tf.placeholder(tf.float32, [None, 784])

x特定の値ではありません。これはプレースホルダーであり、TensorFlowに計算の実行を依頼するときに入力する値です。任意の数のMNIST画像を入力できるようにしたいと思います。それぞれの画像は、784次元のベクトルに平坦化されます。これを、形状を伴う浮動小数点数の2次元テンソルとして表します[なし、784]。(ここでNoneは、次元が任意の長さであることを意味します。)

また、モデルの重みとバイアスも必要です。これらを追加の入力のように扱うことを想像できますが、TensorFlowにはそれを処理するためのさらに良い方法がありますVariable。A Variableは、相互作用する操作のTensorFlowのグラフに存在する変更可能なテンソルです。計算で使用したり、修正することもできます。機械学習アプリケーションの場合、通常、モデルパラメーターはVariablesです。

W = tf.Variable(tf.zeros([784, 10]))

b = tf.Variable(tf.zeros([10]))

我々は、これらの作成Variable与えることでSをtf.Variable初期値をVariable:このケースでは、我々は両方の初期化Wbゼロのフルテンソルとして。私たちが学ぼうとしているためWb、それは非常に多く、彼らが最初にあるかは重要ではありません。


こんにちはあなたの答えをありがとう!あなたが与える例では、私たちxは形状を持っており[batch size, features]、入力から最初のサイズのレイヤーへの重み[features, hidden units]とバイアスを持っています[hidden units]。だから私の質問は:どのようにそれらを一緒に乗算するのですか?私たちがしなければtf.matmul(x, w)、我々が得るつもりです[batch size, hidden units]し、私たちがすることはできませんb、それは形があるので、それへ[hidden units]
Euler_Salter

1
M.Gornerは、スライドショー「Ph.DなしでTensorFlowとディープラーニングを学ぶ」でこれらすべてを説明しています。このコメントで私がこれまで行うことができたよりも優れています。:だから、私はこのスライドを参照することを可能にしてください docs.google.com/presentation/d/...
tagoma

11

Tensorflowは3種類のコンテナを使用してプロセスを保存/実行します

  1. 定数:定数は一般的なデータを保持します。

  2. variables:データ値は、cost_functionなどのそれぞれの関数で変更されます。

  3. プレースホルダー:トレーニング/テストのデータがグラフに渡されます。


10

スニペットの例:

import numpy as np
import tensorflow as tf

### Model parameters ###
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)

### Model input and output ###
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)

### loss ###
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares

### optimizer ###
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

### training data ###
x_train = [1,2,3,4]
y_train = [0,-1,-2,-3]

### training loop ###
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init) # reset values to wrong
for i in range(1000):
  sess.run(train, {x:x_train, y:y_train})

名前が言うように、プレースホルダーは後で値を提供するという約束です

変数は、日常のプログラミングで使用する通常の変数と同じトレーニングパラメータ(W(行列)、b(バイアス)であり、トレーナーが各実行/ステップで更新/変更します。

一方でプレースホルダは任意の初期値を必要としない、あなたはそれを作成したときxyあなたが、プレースホルダを養うときTFではなく、後に、任意のメモリが割り当てられていないsess.run()使用してfeed_dictTensorFlowは、それら(のために適切なサイズのメモリを割り当てます、xy) -このunconstrained-をnessを使用すると、あらゆるサイズと形状のデータをフィードできます。


一言で言えば

変数 -トレーナー(GradientDescentOptimizerなど)が各ステップの後に更新するパラメーターです。

プレースホルダーデモ-

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b  # + provides a shortcut for tf.add(a, b)

実行:

print(sess.run(adder_node, {a: 3, b:4.5}))
print(sess.run(adder_node, {a: [1,3], b: [2, 4]}))

結果として

7.5
[ 3.  7.]

最初のケースでは3と4.5に渡されるab、それぞれ、及び第2のケースでは7をouputting adder_nodeにフィードリストがあると、最初のステップ1及び2は、次の3及び図4に示すように、追加(であろうab)。


関連する読み取り:


7

変数

TensorFlow変数は、プログラムによって操作される共有された永続的な状態を表す最良の方法です。変数はtf.Variableクラスを介して操作されます。内部的には、tf.Variableは永続的なテンソルを格納します。特定の操作により、このテンソルの値を読み取って変更できます。これらの変更は複数のtf.Sessionsにわたって可視であるため、複数のワーカーがtf.Variableの同じ値を見ることができます。変数は使用する前に初期化する必要があります。

例:

x = tf.Variable(3, name="x")
y = tf.Variable(4, name="y")
f = x*x*y + y + 2

これにより、計算グラフが作成されます。変数(xおよびy)は初期化でき、関数(f)はテンソルフローセッションで次のように評価されます。

with tf.Session() as sess:
     x.initializer.run()
     y.initializer.run()
     result = f.eval()
print(result)
42

プレースホルダー

プレースホルダーは、将来その値を初期化できるノード(変数と同じ)です。これらのノードは基本的に、実行時にそれらに割り当てられた値を出力します。プレースホルダーノードは、変数のタイプやその形状などの引数を指定できるtf.placeholder()クラスを使用して割り当てることができます。プレースホルダーは、トレーニングデータセットが変化し続けるため、機械学習モデルでトレーニングデータセットを表すために広く使用されています。

例:

A = tf.placeholder(tf.float32, shape=(None, 3))
B = A + 5

注:ディメンションの「なし」は「任意のサイズ」を意味します。

with tf.Session as sess:
    B_val_1 = B.eval(feed_dict={A: [[1, 2, 3]]})
    B_val_2 = B.eval(feed_dict={A: [[4, 5, 6], [7, 8, 9]]})

print(B_val_1)
[[6. 7. 8.]]
print(B_val_2)
[[9. 10. 11.]
 [12. 13. 14.]]

参照:

  1. https://www.tensorflow.org/guide/variables
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly:Scikit-Learn&Tensorflowによる実践的な機械学習

6

Variabletensorflowでは、プログラミング言語で使用する通常の変数と考えてください。変数を初期化します。後で変更することもできます。一方placeholder、初期値は必要ありません。プレースホルダーは、将来使用するためにメモリブロックを割り当てるだけです。後で、を使用feed_dictしてデータをにフィードできますplaceholder。デフォルトでplaceholderは、形状に制約がありません。これにより、セッションでさまざまな形状のテンソルをフィードできます。以下で行ったように、オプションの引数-shapeを渡すことで、制約された形状を作成できます。

x = tf.placeholder(tf.float32,(3,4))
y =  x + 2

sess = tf.Session()
print(sess.run(y)) # will cause an error

s = np.random.rand(3,4)
print(sess.run(y, feed_dict={x:s}))

機械学習タスクを実行している間、ほとんどの場合、行の数はわかりませんが、(仮定しましょう)フィーチャまたは列の数は知っています。その場合は、Noneを使用できます。

x = tf.placeholder(tf.float32, shape=(None,4))

これで、実行時に、4つの列と任意の数の行を持つ任意の行列をフィードできます。

また、プレースホルダーは入力データに使用されます(これらは、モデルへのフィードに使用する一種の変数です)。ここで、変数は、時間とともにトレーニングする重みなどのパラメーターです。


4

プレースホルダー:

  1. プレースホルダーは、後でデータを割り当てる変数です。データを必要とせずに、操作を作成して計算グラフを作成できます。TensorFlowの用語では、これらのプレースホルダーを通じてデータをグラフに送ります。

  2. 初期値は必須ではありませんが、デフォルト値を持つことができます tf.placeholder_with_default)

  3. 次のように実行時に値を提供する必要があります。

    a = tf.placeholder(tf.int16) // initialize placeholder value
    b = tf.placeholder(tf.int16) // initialize placeholder value
    
    use it using session like :
    
    sess.run(add, feed_dict={a: 2, b: 3}) // this value we have to assign at runtime

変数:

  1. TensorFlow変数は、プログラムによって操作される共有された永続的な状態を表す最良の方法です。
  2. 変数はtf.Variableクラスを介して操作されます。tf.Variableは、その上でopsを実行することによって値を変更できるテンソルを表します。

例: tf.Variable("Welcome to tensorflow!!!")


3

Tensorflow 2.0互換性のある回答:デフォルトの実行モードはEager Executionであるため、プレースホルダーの概念はデフォルトではtf.placeholder使用できませんTensorflow 2.x (>= 2.0)

ただし、Graph ModeDisable Eager Execution)で使用すれば使用できます。

バージョン2.xのTFプレースホルダーと同等のコマンドはtf.compat.v1.placeholderです。

バージョン2.xのTF変数tf.Variableの同等のコマンドは次のとおりです。コードを1.xから2.xに移行する場合、同等のコマンドは

tf.compat.v2.Variable

Tensorflowバージョン2.0の詳細については、このTensorflowページを参照してください。

バージョン1.xから2.xへの移行の詳細については、移行ガイドを参照してください。


2

計算グラフについて考えてください。このようなグラフでは、データをグラフに渡すために入力ノードが必要です。これらのノードは、tensorflowでプレースホルダーとして定義する必要があります。

Pythonの一般的なプログラムとは考えないでください。Pythonプログラムを作成して、変数によって他の回答で説明されているすべてのことを行うことができますが、テンソルフローの計算グラフの場合、データをグラフにフィードするには、それらのノードをプレースホルダーとして定義する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.