私はTensorFlowの初心者です。私はとの違いについて混乱しているtf.placeholder
とtf.Variable
。私の見解でtf.placeholder
は、入力データにtf.Variable
使用され、データの状態を格納するために使用されます。私が知っているのはこれだけです。
誰かが違いについてもっと詳しく説明してくれませんか?特に、いつtf.Variable
使用するtf.placeholder
か、いつ使用するか?
私はTensorFlowの初心者です。私はとの違いについて混乱しているtf.placeholder
とtf.Variable
。私の見解でtf.placeholder
は、入力データにtf.Variable
使用され、データの状態を格納するために使用されます。私が知っているのはこれだけです。
誰かが違いについてもっと詳しく説明してくれませんか?特に、いつtf.Variable
使用するtf.placeholder
か、いつ使用するか?
回答:
つまり、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ページから取得されます。)
tensorflow
and deep learning
およびlikeであるかを示すだけAI
です。
違いは、tf.Variable
宣言時に初期値を指定する必要があることです。tf.placeholder
あなたは初期値を提供する必要はありません、あなたがして、実行時にそれを指定することができfeed_dict
、引数の内部Session.run
Tensorの計算はグラフで構成されているため、グラフで 2つを解釈することをお勧めします。
単純な線形回帰を例にとります
WX+B=Y
where W
とB
は、重みとバイアス、およびX
観測の入力とY
観測の出力を表します。
明らかX
とY
の異なる同じ性質(顕在変数)であるW
とB
(潜在変数)。X
とY
はサンプル(観測)の値であり、したがって、塗りつぶす場所が必要です。一方W
、およびB
は、重みとバイアスです。変数(前の値は後者に影響します)は、異なるペアX
とY
ペアを使用してトレーニングする必要があります。変数をトレーニングするために、さまざまなサンプルをプレースホルダーに配置します。
コードを使用してグラフを保存または再構築するには、変数を(チェックポイントで)保存または復元するだけです。
プレースホルダーは、主にさまざまなデータセット(トレーニングデータやテストデータなど)のホルダーです。ただし、変数は特定のタスクのトレーニングプロセスでトレーニングされます。つまり、入力の結果を予測したり、入力を目的のラベルにマップしたりします。さまざまなサンプルまたは同じサンプルを使用してモデルを再トレーニングまたは微調整して、dictを通じてプレースホルダーに入力するまで、これらは同じままです。例えば:
session.run(a_graph, dict = {a_placeholder_name : sample_values})
プレースホルダーは、モデルを設定するためのパラメーターとしても渡されます。
トレーニングの途中でモデルのプレースホルダーを変更(追加、削除、形状変更など)した場合でも、他の変更を行わずにチェックポイントを再ロードできます。ただし、保存されたモデルの変数が変更された場合は、それに応じてチェックポイントを調整し、モデルをリロードしてトレーニングを続行する必要があります(グラフで定義されたすべての変数がチェックポイントで使用可能である必要があります)。
あなたは安全にあなたがハーネスを訓練するパラメータが必要な場合は一方で、プレースホルダは、それらを保持するために作るの値はサンプルからであれば(観測あなたが既に持っている)、要約すると変数(簡単に言えば、設定変数の必要な値のためにTFを自動的に使用するため)。
スタイル転送モデルなどのいくつかの興味深いモデルでは、入力pixが最適化され、通常呼び出されるモデル変数が固定されているため、そのリンクに実装されている変数として入力(通常はランダムに初期化)を作成する必要があります。
詳細については、このシンプルで説明的なdocを推測してください。
間の最も明白な違いtf.Variableとtf.placeholderはということです
変数を使用してパラメーターを保持および更新します。変数は、テンソルを含むメモリ内バッファーです。これらは明示的に初期化する必要があり、トレーニング中およびトレーニング後にディスクに保存できます。保存した値を後で復元して、モデルを実行または分析できます。
変数の初期化はで行われsess.run(tf.global_variables_initializer())
ます。また、変数を作成するときに、Tensorを初期値としてVariable()
コンストラクターに渡す必要があります。変数を作成するときは、常にその形状を知っています。
一方、プレースホルダーを更新することはできません。それらも初期化されるべきではありませんが、それらはテンソルを持つことが約束されているため、それらに値をフィードする必要がありますsess.run(<op>, {a: <some_val>})
。そして最後に、変数と比較して、プレースホルダーは形状を知らない可能性があります。ディメンションの一部を提供することも、何も提供しないこともできます。
他にも違いがあります:
興味深いのは、プレースホルダーだけがフィードできるということです。値を変数、さらには定数に渡すことができます。
他の回答に加えて、Tensoflow WebサイトのこのMNISTチュートリアルでも非常によく説明しています。
シンボリック変数を操作することにより、これらの相互作用する操作について説明します。作成しましょう:
x = tf.placeholder(tf.float32, [None, 784])
、
x
特定の値ではありません。これはプレースホルダーであり、TensorFlowに計算の実行を依頼するときに入力する値です。任意の数のMNIST画像を入力できるようにしたいと思います。それぞれの画像は、784次元のベクトルに平坦化されます。これを、形状を伴う浮動小数点数の2次元テンソルとして表します[なし、784]。(ここでNoneは、次元が任意の長さであることを意味します。)また、モデルの重みとバイアスも必要です。これらを追加の入力のように扱うことを想像できますが、TensorFlowにはそれを処理するためのさらに良い方法があります
Variable
。AVariable
は、相互作用する操作のTensorFlowのグラフに存在する変更可能なテンソルです。計算で使用したり、修正することもできます。機械学習アプリケーションの場合、通常、モデルパラメーターはVariable
sです。
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
我々は、これらの作成
Variable
与えることでSをtf.Variable
初期値をVariable
:このケースでは、我々は両方の初期化W
とb
ゼロのフルテンソルとして。私たちが学ぼうとしているためW
とb
、それは非常に多く、彼らが最初にあるかは重要ではありません。
x
は形状を持っており[batch size, features]
、入力から最初のサイズのレイヤーへの重み[features, hidden units]
とバイアスを持っています[hidden units]
。だから私の質問は:どのようにそれらを一緒に乗算するのですか?私たちがしなければtf.matmul(x, w)
、我々が得るつもりです[batch size, hidden units]
し、私たちがすることはできませんb
、それは形があるので、それへ[hidden units]
スニペットの例:
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
(バイアス)であり、トレーナーが各実行/ステップで更新/変更します。
一方でプレースホルダは任意の初期値を必要としない、あなたはそれを作成したときx
とy
あなたが、プレースホルダを養うときTFではなく、後に、任意のメモリが割り当てられていないsess.run()
使用してfeed_dict
TensorFlowは、それら(のために適切なサイズのメモリを割り当てます、x
とy
) -この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に渡されるa
とb
、それぞれ、及び第2のケースでは7をouputting adder_nodeにフィードリストがあると、最初のステップ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
tensorflowでは、プログラミング言語で使用する通常の変数と考えてください。変数を初期化します。後で変更することもできます。一方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 2.0互換性のある回答:デフォルトの実行モードはEager Executionであるため、プレースホルダーの概念はデフォルトではtf.placeholder
使用できませんTensorflow 2.x (>= 2.0)
。
ただし、Graph Mode
(Disable 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ページを参照してください。
Variable
s に関する勾配は必要ですが、placeholder
sは必要ありません(その値は常に提供される必要があります)。