Як призначити значення змінній TensorFlow?


79

Я намагаюся призначити нове значення змінній tensorflow у python.

import tensorflow as tf
import numpy as np

x = tf.Variable(0)
init = tf.initialize_all_variables()
sess = tf.InteractiveSession()
sess.run(init)

print(x.eval())

x.assign(1)
print(x.eval())

Але результат, який я отримую, є

0
0

Отже, значення не змінилося. Чого мені не вистачає?

Відповіді:


124

В TF1, оператор x.assign(1)практично не присвоїть значення 1для x, а створює tf.Operationщо ви повинні явно запустити , щоб оновити змінну * Виклик. Operation.run()Або Session.run()може бути використаний для запуску операції:

assign_op = x.assign(1)
sess.run(assign_op)  # or `assign_op.op.run()`
print(x.eval())
# ==> 1

(* Насправді він повертає a tf.Tensor, що відповідає оновленому значенню змінної, щоб полегшити ланцюгове призначення.)

Однак у TF2 x.assign(1)тепер буде присвоюватися значення охоче:

x.assign(1)
print(x.numpy())
# ==> 1

Дякую! assign_op.run () видає помилку: AttributeError: "Tensor" об'єкт не має атрибута "run". Але sess.run (assign_op) працює абсолютно нормально.
abora

У цьому прикладі дані, які Variable xзберігаються в пам'яті до assignзапуску операції / змінного тензора, перезаписуються, або створений новий тензор, що зберігає оновлене значення?
dannygoldstein

3
Поточна реалізація assign()замінює існуюче значення.
mrry

1
Чи є спосіб присвоїти нове значення а, Variableне створюючи жодних додаткових операцій на графіку? Здається, кожна змінна вже має операцію Assign, створену для неї, але викликає my_var.assign()або tf.assign()створює нову операцію замість використання існуючої.
Натан

Не думаю, що це тут актуально, але ви можете вказати assignтакий параметр тензору, як математична операція. І таким чином створити лічильник , який оновлюється кожного разу , коли правонаступник операція обчислюється: op = t.assign(tf.add(t, 1)).
Еліель Ван Хойман,

40

Ви також можете присвоїти нове значення в tf.Variableбез додавання операції до графіку: tf.Variable.load(value, session). Ця функція також може заощадити додавання заповнювачів під час присвоєння значення поза графіком, і це корисно на випадок, якщо графік завершено.

import tensorflow as tf
x = tf.Variable(0)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(x))  # Prints 0.
x.load(1, sess)
print(sess.run(x))  # Prints 1.

Оновлення: це скасовано в TF2, оскільки наполегливе виконання виконується за замовчуванням, а графіки більше не відображаються в інтерфейсі API, що відповідає користувачу .


2
Застереження: ви не можете завантажити його масивом, що має іншу форму, ніж форма початкового значення змінної!
Rajarshee Mitra

1
Variable.load (з tensorflow.python.ops.variables) застаріла і буде вилучена в наступній версії. Інструкції з оновлення: Віддайте перевагу Variable.assign, яка має еквівалентну поведінку в 2.X. Не знаю, як змінити значення змінної в Tensorflow 2.0, не додаючи опції до графіка
Жоао

15

Перш за все, ви можете призначати значення змінним / константам, просто подаючи значення в них так само, як це робите із заповнювачами. Отже, це цілком законно робити:

import tensorflow as tf
x = tf.Variable(0)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(x, feed_dict={x: 3})

Щодо вашої плутанини з оператором tf.assign () . У TF нічого не виконується перед тим, як запустити його всередині сеансу. Тому завжди потрібно робити щось подібне: op_name = tf.some_function_that_create_op(params)а потім усередині сеансу, який ви запускаєте sess.run(op_name). На прикладі assign ви зробите щось подібне:

import tensorflow as tf
x = tf.Variable(0)
y = tf.assign(x, 1)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(x)
    print sess.run(y)
    print sess.run(x)

@RobinDinse, це так. У наведеному вище прикладі ви отримуєте 0,1,1 як свій станд.
Rajarshee Mitra

4
Зверніть увагу, що подача значення через feed_dictне постійно призначає це значення змінній, а лише для цього конкретного виклику запуску.
Робін Дінсе,

@RobinDinse, як я можу назавжди призначити це значення? Якщо ви можете, побачити моє запитання тут stackoverflow.com/questions/53141762 / ...
volperossa

3

Крім того, слід зазначити, що якщо ви використовуєте your_tensor.assign(), тоді tf.global_variables_initializerне потрібно викликати явно, оскільки операція присвоєння робить це за вас у фоновому режимі.

Приклад:

In [212]: w = tf.Variable(12)
In [213]: w_new = w.assign(34)

In [214]: with tf.Session() as sess:
     ...:     sess.run(w_new)
     ...:     print(w_new.eval())

# output
34 

Однак це не ініціалізує всі змінні, а ініціалізує лише змінну, з якою assignбуло виконано.


1

Я відповів на подібне запитання тут . Я шукав у багатьох місцях, які завжди створювали одну і ту ж проблему. В основному, я не хотів призначати значення вагам, а просто міняти ваги. Коротка версія наведеної вище відповіді:

tf.keras.backend.set_value(tf_var, numpy_weights)


0

Ось повний робочий приклад:

import numpy as np
import tensorflow as tf

w= tf.Variable(0, dtype=tf.float32) #good practice to set the type of the variable
cost = 10 + 5*w + w*w
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)

init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)

print(session.run(w))

session.run(train)
print(session.run(w)) # runs one step of gradient descent

for i in range(10000):
  session.run(train)

print(session.run(w))

Зверніть увагу, що результат буде:

0.0
-0.049999997
-2.499994

Це означає, що на самому початку змінна становила 0, як було визначено, тоді лише після одного кроку градієнта пристойним змінна становила -0,049999997, а після ще 10 000 кроків ми досягаємо -2,499994 (на основі нашої функції витрат).

Примітка: Ви спочатку використовували інтерактивний сеанс. Інтерактивний сеанс корисний, коли кілька різних сеансів потрібно було запускати в одному сценарії. Однак я використовував неінтерактивний сеанс для простоти.


0

Використовуйте найсвіжіший режим виконання Tensorflow.

import tensorflow as tf
tf.enable_eager_execution()
my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3])
print(my_int_variable)

-1

Отже, у мене був інший випадок, коли мені потрібно було призначити значення перед запуском сеансу, отже це був найпростіший спосіб зробити це:

other_variable = tf.get_variable("other_variable", dtype=tf.int32,
  initializer=tf.constant([23, 42]))

тут я створюю змінну, а також присвоюю їй значення одночасно


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.