Sự khác biệt giữa tf.placeholder và tf.Variable là gì?


290

Tôi là người mới sử dụng TensorFlow. Tôi bối rối về sự khác biệt giữa tf.placeholdertf.Variable. Theo quan điểm của tôi, tf.placeholderđược sử dụng cho dữ liệu đầu vào và tf.Variableđược sử dụng để lưu trữ trạng thái của dữ liệu. Đây là tất cả những gì tôi biết.

Ai đó có thể giải thích cho tôi chi tiết hơn về sự khác biệt của họ? Đặc biệt, khi nào nên sử dụng tf.Variablevà khi nào nên sử dụng tf.placeholder?


7
Theo trực giác, bạn sẽ muốn độ dốc liên quan đến Variables, nhưng không phải placeholders (có giá trị phải luôn được cung cấp).
Yibo Yang

Một khóa học như cs231n.stanford.edu có thể giúp những người bối rối. Tôi rất thích nó! Rõ ràng là có những người khác
Nathan

Câu trả lời:


175

Nói tóm lại, bạn sử dụng tf.Variablecho các biến có thể huấn luyện như trọng số (W) và độ lệch (B) cho mô hình của bạn.

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 được sử dụng để nuôi các ví dụ đào tạo thực tế.

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

Đây là cách bạn nuôi các ví dụ đào tạo trong quá trình đào tạo:

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)

Bạn tf.variablessẽ được đào tạo (sửa đổi) như là kết quả của khóa đào tạo này.

Xem thêm tại https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.html . (Ví dụ được lấy từ trang web.)


2
Điều gì xảy ra nếu tôi muốn xử lý trước hình ảnh của mình trước khi cho nó vào? (ví dụ: hủy bỏ độ tương phản). Bây giờ tôi có cần một biến cho điều này không? Nếu vậy, nó có bất kỳ ý nghĩa bộ nhớ hoặc tốc độ?
Bastiaan

1
Bất kỳ quá trình tiền xử lý nào bạn thực hiện sẽ đến trước khi đưa dữ liệu vào biểu đồ Tensorflow (tức là mạng), do đó công việc không yêu cầu về mặt kỹ thuật bất kỳ công cụ mã nào từ Tensorflow. Ví dụ: một biến sẽ không cần thiết 1. vì đó là dữ liệu đầu vào, được truyền qua tf.placeholder (không phải biến) trong biểu đồ và 2. Quá trình tiền xử lý xảy ra trước khi nó được nạp vào một trình giữ chỗ cho truyền hiện tại qua mạng .
PaulG

Chỉ muốn lưu ý rằng tôi đánh giá cao câu trả lời này. Thực tế là có rất upvotes rất ít về câu trả lời này hơn về vấn đề chỉ là đi để hiển thị như thế nào ngay lập tức-sự hài lòng mọi người có thể được, và làm thế nào thẻ sành điệu thích tensorflowdeep learningAIđang có.
Nathan

70

Sự khác biệt là với tf.Variablebạn phải cung cấp một giá trị ban đầu khi bạn khai báo nó. Với tf.placeholderbạn không phải cung cấp một giá trị ban đầu và bạn có thể chỉ định nó trong thời gian chạy với feed_dictđối số bên trongSession.run


63
-1. Trong khi sự thật, điều này bỏ lỡ điểm. Sự khác biệt quan trọng hơn là vai trò của họ trong TensorFlow. Các biến được đào tạo theo thời gian, giữ chỗ là dữ liệu đầu vào không thay đổi khi mô hình của bạn đào tạo (như hình ảnh đầu vào và nhãn lớp cho những hình ảnh đó). Giống như câu trả lời của Sung Kim nói, bạn sử dụng các biến cho trọng số và độ lệch trong mô hình của mình (mặc dù không giới hạn ở điều đó - để chuyển kiểu, bạn tối ưu hóa hình ảnh theo thời gian).
Chris Anderson

@ChrisAnderson chúng ta có thể nói rằng minh họa này là sai không?! youtu.be/MotG3XI2qSs?t=136
N0rA

@ChrisAnderson Tại sao nó lại được sử dụng cho mục đích gì, nếu sự khác biệt chỉ là một nhu cầu ban đầu?
Goldname

1
@Goldname Đó không phải là "nghĩa là" được sử dụng cho - đó là những gì có thể và không thể. Chúng là những đối tượng hoàn toàn khác nhau. Chúng không thể thay thế cho nhau và sự khác biệt không chỉ là "người ta cần một giá trị ban đầu".
Chris Anderson

61

Vì các tính toán của Tenor hợp thành các biểu đồ nên tốt hơn là giải thích hai biểu đồ theo biểu đồ.

Lấy ví dụ hồi quy tuyến tính đơn giản

WX+B=Y

nơi Wvà đại diện Bcho các trọng số và thiên vị và Xcho các đầu vào Ycủa các quan sát và cho các đầu ra của các quan sát.

Rõ ràng XYcó cùng bản chất (biến số biểu hiện) khác với biến số WB(biến tiềm ẩn). XYlà các giá trị của các mẫu (các quan sát) và do đó cần phải điền vào một vị trí , trong khi WBlà các trọng số và độ lệch, Biến (các giá trị trước ảnh hưởng đến sau) trong biểu đồ cần được huấn luyện bằng các cặp XYcặp khác nhau . Chúng tôi đặt các mẫu khác nhau cho các Placeholder để huấn luyện các Biến .

Chúng ta chỉ cần lưu hoặc khôi phục các Biến (tại các điểm kiểm tra) để lưu hoặc xây dựng lại biểu đồ bằng mã.

Giữ chỗ chủ yếu là chủ sở hữu cho các bộ dữ liệu khác nhau (ví dụ dữ liệu đào tạo hoặc dữ liệu thử nghiệm). Tuy nhiên, Biến được đào tạo trong quy trình đào tạo cho các nhiệm vụ cụ thể, nghĩa là để dự đoán kết quả của đầu vào hoặc ánh xạ đầu vào tới các nhãn mong muốn. Chúng vẫn giữ nguyên cho đến khi bạn đào tạo lại hoặc tinh chỉnh mô hình bằng cách sử dụng các mẫu khác nhau hoặc giống nhau để điền vào Trình giữ chỗ thường xuyên thông qua lệnh. Ví dụ:

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

Giữ chỗ cũng được thông qua dưới dạng tham số để đặt mô hình.

Nếu bạn thay đổi trình giữ chỗ (thêm, xóa, thay đổi hình dạng, v.v.) của một mô hình ở giữa đào tạo, bạn vẫn có thể tải lại điểm kiểm tra mà không cần sửa đổi gì khác. Nhưng nếu các biến của mô hình đã lưu bị thay đổi, bạn nên điều chỉnh điểm kiểm tra phù hợp để tải lại và tiếp tục đào tạo (tất cả các biến được xác định trong biểu đồ sẽ có sẵn trong điểm kiểm tra).

Tóm lại, nếu các giá trị là từ các mẫu (các quan sát bạn đã có), bạn tạo một trình giữ chỗ một cách an toàn để giữ chúng, trong khi nếu bạn cần một tham số để đào tạo khai thác Biến (chỉ cần đặt, đặt Biến cho các giá trị bạn muốn để tự động sử dụng TF).

Trong một số mô hình thú vị, như mô hình chuyển kiểu , các pix đầu vào sẽ được tối ưu hóa và các biến mô hình được gọi là thông thường được cố định, sau đó chúng ta nên tạo đầu vào (thường được khởi tạo ngẫu nhiên) như một biến như được thực hiện trong liên kết đó.

Để biết thêm thông tin xin vui lòng suy ra tài liệu đơn giản và minh họa này .


38

TL; DR

Biến

  • Để biết thông số cần học
  • Giá trị có thể được bắt nguồn từ đào tạo
  • Giá trị ban đầu là bắt buộc (thường là ngẫu nhiên)

Giữ chỗ

  • Lưu trữ được phân bổ cho dữ liệu (chẳng hạn như dữ liệu pixel hình ảnh trong nguồn cấp dữ liệu)
  • Các giá trị ban đầu không bắt buộc (nhưng có thể được đặt, xem tf.placeholder_with_default)

34

Sự khác biệt rõ ràng nhất giữa tf.Variabletf.placeholder là ở chỗ


bạn sử dụng các biến để giữ và cập nhật các tham số. Các biến là bộ đệm trong bộ nhớ có chứa tenxơ. Chúng phải được khởi tạo rõ ràng và có thể được lưu vào đĩa trong và sau khi đào tạo. Sau này bạn có thể khôi phục các giá trị đã lưu để thực hiện hoặc phân tích mô hình.

Khởi tạo các biến được thực hiện với sess.run(tf.global_variables_initializer()). Ngoài ra, trong khi tạo một biến, bạn cần chuyển một Tenor làm giá trị ban đầu của nó cho hàm Variable()tạo và khi bạn tạo một biến bạn luôn biết hình dạng của nó.


Mặt khác, bạn không thể cập nhật trình giữ chỗ. Chúng cũng không nên được khởi tạo, nhưng vì chúng là một lời hứa sẽ có một tenxơ, bạn cần cung cấp giá trị cho chúng sess.run(<op>, {a: <some_val>}). Và cuối cùng, so với một biến, trình giữ chỗ có thể không biết hình dạng. Bạn có thể cung cấp các phần của kích thước hoặc không cung cấp gì cả.


Có sự khác biệt khác:

Điều thú vị là không chỉ người giữ chỗ có thể được cho ăn. Bạn có thể cung cấp giá trị cho Biến và thậm chí là hằng số.


14

Thêm vào câu trả lời của người khác, họ cũng giải thích rất rõ trong hướng dẫn này của MNIST trên trang web của Tensoflow:

Chúng tôi mô tả các hoạt động tương tác này bằng cách thao tác các biến tượng trưng. Hãy tạo một:

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

xkhông phải là một giá trị cụ thể. Đó là một trình giữ chỗ, một giá trị mà chúng tôi sẽ nhập khi chúng tôi yêu cầu TensorFlow chạy tính toán. Chúng tôi muốn có thể nhập bất kỳ số lượng hình ảnh MNIST nào, mỗi hình ảnh được làm phẳng thành một vectơ 784 chiều. Chúng tôi biểu thị điều này dưới dạng một tenxơ 2 chiều của các số có dấu phẩy động, với hình dạng [Không có, 784]. (Ở đây Không có nghĩa là kích thước có thể có độ dài bất kỳ.)

Chúng tôi cũng cần các trọng số và thành kiến ​​cho mô hình của chúng tôi. Chúng ta có thể tưởng tượng đối xử với những thứ này như đầu vào bổ sung, nhưng TensorFlow có cách thậm chí còn tốt hơn để xử lý nó : Variable. A Variablelà một tenxơ có thể sửa đổi, nằm trong biểu đồ các hoạt động tương tác của TensorFlow. Nó có thể được sử dụng và thậm chí sửa đổi bằng cách tính toán. Đối với các ứng dụng học máy, người ta thường có các tham số mô hình là Variables.

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

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

Chúng tôi tạo ra các Variables này bằng cách đưa ra tf.Variablegiá trị ban đầu của Variable: trong trường hợp này, chúng tôi khởi tạo cả hai Wbnhư các tenxơ đầy số không. Vì chúng ta sẽ học Wb, ban đầu chúng không quan trọng lắm.


Hi, cảm ơn bạn cho câu trả lời của bạn! Trong ví dụ bạn đưa ra, chúng ta có xhình dạng [batch size, features], chúng ta có các trọng số đi từ đầu vào đến lớp kích thước đầu tiên [features, hidden units]và các độ lệch [hidden units]. Vì vậy, câu hỏi của tôi là: làm thế nào để chúng tôi nhân chúng lại với nhau? Nếu chúng ta làm tf.matmul(x, w)thì chúng ta sẽ có được [batch size, hidden units]và chúng ta không thể blàm được, vì nó có hình dạng[hidden units]
Euler_Salter

1
M.Gorner giải thích tất cả những điều này trong các bài trình chiếu của mình "Tìm hiểu về TensorFlow và học sâu, không cần bằng tiến sĩ". tốt hơn tôi có thể làm ở đây trong bình luận này. Vì vậy, vui lòng cho phép tôi tham khảo slide này: docs.google.com/presentation/d/
Kẻ

11

Tensorflow sử dụng ba loại container để lưu trữ / thực hiện quy trình

  1. Hằng số: Hằng giữ dữ liệu điển hình.

  2. biến: Giá trị dữ liệu sẽ được thay đổi, với các hàm tương ứng như cost_function ..

  3. giữ chỗ: Dữ liệu đào tạo / kiểm tra sẽ được chuyển vào biểu đồ.


10

Đoạn trích ví dụ:

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})

Như tên nói, giữ chỗ là một lời hứa sẽ cung cấp một giá trị sau đó tức là

Biến chỉ đơn giản là các tham số đào tạo ( W(ma trận), b(thiên vị) giống như các biến thông thường bạn sử dụng trong lập trình hàng ngày, mà huấn luyện viên cập nhật / sửa đổi trên mỗi lần chạy / bước.

Mặc dù trình giữ chỗ không yêu cầu bất kỳ giá trị ban đầu nào, nhưng khi bạn tạo xyTF không cấp phát bất kỳ bộ nhớ nào, thay vào đó sau này khi bạn cung cấp cho trình giữ chỗ trong việc sess.run()sử dụng feed_dict, TensorFlow sẽ phân bổ bộ nhớ có kích thước phù hợp cho chúng ( xy) - điều này không bị ràng buộc- Ness cho phép chúng tôi cung cấp bất kỳ kích thước và hình dạng của dữ liệu.


Tóm lại :

Biến - là một tham số bạn muốn huấn luyện viên (tức là GradientDescentOptimizer) cập nhật sau mỗi bước.

Bản giới thiệu giữ chỗ -

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

Chấp hành:

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

dẫn đến đầu ra

7.5
[ 3.  7.]

Trong trường hợp đầu tiên 3 và 4.5 sẽ được chuyển đến abtương ứng, sau đó đến adder_node xuất hiện 7. Trong trường hợp thứ hai có một danh sách nguồn cấp dữ liệu, bước đầu tiên 1 và 2 sẽ được thêm vào, 3 và 4 tiếp theo ( ab).


Đọc có liên quan:


7

Biến

Biến TensorFlow là cách tốt nhất để biểu thị trạng thái chia sẻ, liên tục được thao tác bởi chương trình của bạn. Các biến được thao tác thông qua lớp tf.Variable. Trong nội bộ, một tf.Variable lưu trữ một tenor liên tục. Các hoạt động cụ thể cho phép bạn đọc và sửa đổi các giá trị của tenxơ này. Những sửa đổi này có thể nhìn thấy trên nhiều tf.Sairs, vì vậy nhiều công nhân có thể thấy các giá trị giống nhau cho một tf.Variable. Các biến phải được khởi tạo trước khi sử dụng.

Thí dụ:

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

Điều này tạo ra một biểu đồ tính toán. Các biến (x và y) có thể được khởi tạo và hàm (f) được đánh giá trong phiên kéo căng như sau:

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

Giữ chỗ

Giữ chỗ là một nút (giống như một biến) có giá trị có thể được khởi tạo trong tương lai. Các nút này về cơ bản xuất giá trị được gán cho chúng trong thời gian chạy. Một nút giữ chỗ có thể được chỉ định bằng cách sử dụng lớp tf.placeholder () mà bạn có thể cung cấp các đối số như loại biến và / hoặc hình dạng của nó. Giữ chỗ được sử dụng rộng rãi để đại diện cho tập dữ liệu đào tạo trong mô hình học máy khi tập dữ liệu đào tạo liên tục thay đổi.

Thí dụ:

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

Lưu ý: 'Không' cho kích thước có nghĩa là 'mọi kích thước'.

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.]]

Người giới thiệu:

  1. https://www.tensorflow.org/guide/variabled
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly: Học máy thực hành với Scikit-Learn & Tensorflow

6

Hãy nghĩ về Variabletenorflow như một biến thông thường mà chúng ta sử dụng trong các ngôn ngữ lập trình. Chúng tôi khởi tạo các biến, chúng tôi cũng có thể sửa đổi nó. Trong khi đó placeholderkhông yêu cầu giá trị ban đầu. Trình giữ chỗ chỉ đơn giản là phân bổ khối bộ nhớ để sử dụng trong tương lai. Sau đó, chúng ta có thể sử dụng feed_dictđể đưa dữ liệu vào placeholder. Theo mặc định, placeholdercó hình dạng không giới hạn, cho phép bạn cung cấp các thang đo có hình dạng khác nhau trong một phiên. Bạn có thể tạo hình dạng bị ràng buộc bằng cách chuyển đối số tùy chọn -shape, như tôi đã làm dưới đây.

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}))

Trong khi thực hiện tác vụ Machine Learning, hầu hết thời gian chúng tôi không biết về số lượng hàng nhưng (giả sử) chúng tôi biết số lượng tính năng hoặc cột. Trong trường hợp đó, chúng tôi có thể sử dụng Không có.

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

Bây giờ, trong thời gian chạy, chúng ta có thể cung cấp bất kỳ ma trận nào với 4 cột và bất kỳ số lượng hàng nào.

Ngoài ra, Placeholder được sử dụng cho dữ liệu đầu vào (chúng là loại biến mà chúng tôi sử dụng để cung cấp cho mô hình của chúng tôi), trong đó Biến là các tham số như trọng số mà chúng tôi đào tạo theo thời gian.


4

Giữ chỗ:

  1. Một trình giữ chỗ chỉ đơn giản là một biến mà chúng ta sẽ gán dữ liệu vào một ngày sau đó. Nó cho phép chúng tôi tạo các hoạt động của chúng tôi và xây dựng biểu đồ tính toán của chúng tôi mà không cần dữ liệu. Trong thuật ngữ TensorFlow, sau đó chúng tôi cung cấp dữ liệu vào biểu đồ thông qua các trình giữ chỗ này.

  2. Các giá trị ban đầu không bắt buộc nhưng có thể có các giá trị mặc định với tf.placeholder_with_default)

  3. Chúng tôi phải cung cấp giá trị trong thời gian chạy như:

    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

Biến đổi :

  1. Biến TensorFlow là cách tốt nhất để biểu thị trạng thái chia sẻ, liên tục được thao tác bởi chương trình của bạn.
  2. Các biến được thao tác thông qua lớp tf.Variable. Một tf.Variable đại diện cho một tenxơ có giá trị có thể được thay đổi bằng cách chạy ops trên nó.

Thí dụ : tf.Variable("Welcome to tensorflow!!!")


3

Trả lời tương thích Tensorflow 2.0 : Khái niệm về Placeholder, tf.placeholdersẽ không có sẵn Tensorflow 2.x (>= 2.0)theo mặc định, vì Chế độ thực thi mặc định là Thực thi háo hức.

Tuy nhiên, chúng ta có thể sử dụng chúng nếu được sử dụng trong Graph Mode( Disable Eager Execution).

Lệnh tương đương cho TF Placeholder trong phiên bản 2.x là tf.compat.v1.placeholder.

Lệnh tương đương cho biến TF trong phiên bản 2.x là tf.Variablevà nếu bạn muốn di chuyển mã từ 1.x sang 2.x, lệnh tương đương là

tf.compat.v2.Variable.

Vui lòng tham khảo Trang Tensorflow này để biết thêm thông tin về Tensorflow Phiên bản 2.0.

Vui lòng tham khảo Hướng dẫn di chuyển để biết thêm thông tin về di chuyển từ các phiên bản 1.x sang 2.x.


2

Hãy nghĩ về một đồ thị tính toán . Trong biểu đồ như vậy, chúng ta cần một nút đầu vào để truyền dữ liệu của mình vào biểu đồ, các nút đó phải được xác định là Placeholder trong tenorflow .

Đừng nghĩ như một chương trình chung trong Python. Bạn có thể viết chương trình Python và thực hiện tất cả những thứ mà các chàng trai đã giải thích trong các câu trả lời khác chỉ bằng Biến, nhưng đối với các biểu đồ tính toán trong tenorflow, để đưa dữ liệu của bạn vào biểu đồ, bạn cần xác định những cái gật đầu đó là Placeholder.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.