TensorFlowの初心者です。私はtf.placeholder
とtf.Variable
の違いについて混乱しています。私の考えでは、tf.placeholder
は入力データに使用され、tf.Variable
はデータの状態を格納するために使用されます。これが私が知っていることのすべてです。
違いについてもっと詳しく説明してもらえますか。特に、いつtf.Variable
を使うのか、そしていつtf.placeholder
を使うのですか?
つまり、モデルの重み(W)やバイアス(B)などの学習可能な変数にはtf.Variable
を使用します。
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ページから取られています。)
違いは、tf.Variable
では、宣言時に初期値を指定する必要があるということです。 tf.placeholder
を使用すると、初期値を指定する必要はなく、実行時にfeed_dict
内のSession.run
引数を使用して指定できます。
Tensorの計算は graphs で構成されるため、2つのグラフを解釈する方が適切です。
たとえば、単純な線形回帰WX + B = Y(WとBは重みとバイアスを表し、Xは観測値の入力を表し、Yは観測値の出力を表す)を考えます。明らかにXとYは同じ性質(マニフェスト変数)であり、WとB(潜在変数)の性質とは異なります。 XとYはサンプル(観測)の値であるため、を埋める場所が必要です、WとBは重みとバイアスです- 変数(前の値は後の値に影響します)、異なるXとYのペアを使用してトレーニングする必要があるグラフ内。 Placeholdersに異なるサンプルを配置して、Variablesをトレーニングします。
グラフを保存または再構築するには、変数をsaveまたはrestoreすることだけが必要です。 プレースホルダーは、主にさまざまなデータセット(トレーニングデータやテストデータなど)のホルダーですが、変数はトレーニングプロセスでトレーニングされ、同じままです(結果を予測するため)後でモデルを再トレーニングするまで、サンプルの入力と出力[ラベル]を入力またはマッピングします(異なるサンプルまたは同じサンプルを使用して、プレースホルダーにディクショナリーを挿入することがよくあります。たとえば、session.run(a_graph, dict={a_placeholder_name: sample_values})
、プレースホルダーは、モデルを設定するためのパラメーターとしても渡されます)。
トレーニングの途中でモデルのプレースホルダーを変更(形状の追加または削除または変更など)した場合でも、他の変更なしでチェックポイントをリロードできます。ただし、保存されたモデルの変数が変更された場合、それに応じてチェックポイントを調整してリロードし、トレーニングを続行する必要があります(グラフで定義されたすべての変数はチェックポイントで使用可能になります)。
まとめると、値がサンプル(既にある観測)からのものである場合、それらを保持するプレースホルダーを安全に作成します。一方、トレーニングするパラメーターが必要な場合は、Variable(単純に設定、設定TFを使用して自動的に取得する値の変数)。
詳細については、これを推測してください シンプルでわかりやすいドキュメント 。
TL; DR
変数
プレースホルダー
tf.placeholder_with_default
を参照)tf.Variable と tf.placeholder の最も明らかな違いは、
変数を使用してパラメータを保持および更新します。変数はテンソルを含むメモリ内バッファです。これらは明示的に初期化する必要があり、トレーニング中およびトレーニング後にディスクに保存できます。後で保存した値を復元して、モデルを実行または分析することができます。
変数の初期化はsess.run(tf.global_variables_initializer())
で行われます。また、変数を作成する際には、Tensorを初期値としてVariable()
コンストラクタに渡す必要があります。また、変数を作成するときは、常にその形状を知っている必要があります。
一方、プレースホルダを更新することはできません。それらも初期化されるべきではありませんが、それらはテンソルを持つことが約束されているので、あなたはそれらに値を与える必要がありますsess.run(<op>, {a: <some_val>})
。そして最後に、変数と比較して、プレースホルダーは形状を知らないかもしれません。寸法の一部を指定することも、何も指定しないこともできます。
他にも違いがあります:
興味深いのは、プレースホルダーだけをフィードできるわけではないということです。値を変数に、さらには定数にも渡すことができます。
他の人の答えに加えて、彼らはまたそれをTensoflowウェブサイトのこの MNISTチュートリアル でとてもよく説明しています。
記号変数を操作することによって、これらの相互作用操作を説明します。作成しましょう。
x = tf.placeholder(tf.float32, [None, 784])
、
x
は特定の値ではありません。これはプレースホルダーで、TensorFlowに計算の実行を依頼するときに入力します。それぞれが784次元のベクトルに平坦化された、任意の数のMNIST画像を入力できるようにしたいです。これを浮動小数点数の2次元テンソルとして、形状[None、784]で表します。 (ここで「なし」とは、ディメンションの長さを問わないことを意味します。)モデルには重みとバイアスも必要です。これらを追加の入力のように扱うことを想像できますが、TensorFlowにはそれを処理するためのさらに優れた方法があります:
Variable
。Variable
は、TensorFlowの対話型操作のグラフに含まれる変更可能なテンソルです。それは使用することができ、計算によっても修正することができます。機械学習アプリケーションの場合、一般にモデルパラメータはVariable
sです。
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
tf.Variable
にVariable
の初期値を指定して、これらのVariable
を作成します。この場合、W
とb
の両方をゼロでいっぱいのテンソルとして初期化します。私たちはW
とb
を学ぶつもりなので、それらが最初に何であるかはあまり重要ではありません。
スニペットの例:
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
(matrix)、b
(bias)です。トレーナーは各実行/ステップで更新/変更します)。
placeholder は初期値を必要としませんが、x
とy
TFを作成したときはメモリを割り当てず、代わりにfeed_dict
を使用してsess.run()
にプレースホルダを入力すると、TensorFlowは適切なサイズを割り当てます。彼らのためのメモリ(x
とy
) - この制約のない性質は、私たちがどんなサイズと形状のデータでも供給することを可能にします。
一言で言えば :
変数 - は、各ステップの後にトレーナー(つまりGradientDescentOptimizer)に更新させたいパラメーターです。
プレースホルダー demo -
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がそれぞれa
とb
に渡され、次にadder_node出力7に渡されます。2番目のケースでは、最初のステップ1と2が追加され、次に3と4が追加されます(a
とb
)。
関連する読み:
変数
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.]]
参考文献:
テンソルフローにおけるVariable
は、プログラミング言語で使用される通常の変数と考えてください。変数を初期化します。後で変更することもできます。 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列と任意の数の行を持つ任意の行列を入力できます。
また、プレースホルダーは入力データに使用されます(これらは、モデルのフィードに使用される一種の変数です)。ここで、変数は、時間の経過とともにトレーニングする重みなどのパラメーターです。
プレースホルダー:
プレースホルダーは、後でデータを割り当てる変数です。データを必要とせずに、操作を作成して計算グラフを作成することができます。 TensorFlowの用語では、これらのプレースホルダーを介してデータをグラフに送ります。
初期値は必須ではありませんが、tf.placeholder_with_default)
を使用してデフォルト値を設定できます。
実行時に次のように値を提供する必要があります。
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
変数:
例:tf.Variable("Welcome to tensorflow!!!")
Tensorflowはプロセスを保存/実行するために3種類のコンテナを使用します
定数:定数は典型的なデータを保持します。
変数:データ値はcost_functionなどのそれぞれの関数で変更されます。
プレースホルダー:トレーニング/テストデータがグラフに渡されます。
計算グラフを考える 。このようなグラフでは、データをグラフに渡すための入力ノードが必要です。これらのノードは tensorflow のプレースホルダーとして定義する必要があります。
Pythonの一般的なプログラムとして考えないでください。 Pythonプログラムを書いて、他の答えで説明したことをすべて変数だけで実行できますが、テンソルフローの計算グラフの場合は、データをグラフにフィードするために、それらのノードをプレースホルダーとして定義する必要があります。