Tensorflow - градиенты для любой переменной не предусмотрены
Я экспериментирую с кодом на Jupyter и продолжаю застрять здесь. На самом деле все работает нормально, если я удаляю строку, начинающуюся с "optimizer =...", и все ссылки на эту строку. Но если я вставлю эту строку в код, это выдаст ошибку.
Я не вставляю здесь все остальные функции, чтобы сохранить размер кода на удобочитаемом уровне. Я надеюсь, что кто-то более опытный может сразу увидеть, в чем здесь проблема.
Обратите внимание, что в входном слое, в 2 скрытых слоях и в выходных слоях имеется 5, 4, 3 и 2 единицы.
КОД:
tf.reset_default_graph()
num_units_in_layers = [5,4,3,2]
X = tf.placeholder(shape=[5, 3], dtype=tf.float32)
Y = tf.placeholder(shape=[2, 3], dtype=tf.float32)
parameters = initialize_layer_parameters(num_units_in_layers)
init = tf.global_variables_initializer()
my_sess = tf.Session()
my_sess.run(init)
ZL = forward_propagation_with_relu(X, num_units_in_layers, parameters, my_sess)
#my_sess.run(parameters) # Do I need to run this? Or is it obsolete?
cost = compute_cost(ZL, Y, my_sess, parameters, batch_size=3, lambd=0.05)
optimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)
_ , minibatch_cost = my_sess.run([optimizer, cost],
feed_dict={X: minibatch_X,
Y: minibatch_Y})
print(minibatch_cost)
my_sess.close()
ОШИБКА:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-321-135b9fc18268> in <module>()
16 cost = compute_cost(ZL, Y, my_sess, parameters, 3, 0.05)
17
---> 18 optimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)
19 _ , minibatch_cost = my_sess.run([optimizer, cost],
20 feed_dict={X: minibatch_X,
~/.local/lib/python3.5/site-packages/tensorflow/python/training/optimizer.py in minimize(self, loss, global_step, var_list, gate_gradients, aggregation_method, colocate_gradients_with_ops, name, grad_loss)
362 "No gradients provided for any variable, check your graph for ops"
363 " that do not support gradients, between variables %s and loss %s." %
--> 364 ([str(v) for _, v in grads_and_vars], loss))
365
366 return self.apply_gradients(grads_and_vars, global_step=global_step,
ValueError: No gradients provided for any variable, check your graph for ops that do not support gradients, between variables ["<tf.Variable 'weights/W1:0' shape=(4, 5) dtype=float32_ref>", "<tf.Variable 'biases/b1:0' shape=(4, 1) dtype=float32_ref>", "<tf.Variable 'weights/W2:0' shape=(3, 4) dtype=float32_ref>", "<tf.Variable 'biases/b2:0' shape=(3, 1) dtype=float32_ref>", "<tf.Variable 'weights/W3:0' shape=(2, 3) dtype=float32_ref>", "<tf.Variable 'biases/b3:0' shape=(2, 1) dtype=float32_ref>"] and loss Tensor("Add_3:0", shape=(), dtype=float32).
Обратите внимание, что если я бегу
print(tf.trainable_variables())
как раз перед строкой "optimizer =..." я на самом деле вижу свои обучаемые переменные.
hts/W1:0' shape=(4, 5) dtype=float32_ref>, <tf.Variable 'biases/b1:0' shape=(4, 1) dtype=float32_ref>, <tf.Variable 'weights/W2:0' shape=(3, 4) dtype=float32_ref>, <tf.Variable 'biases/b2:0' shape=(3, 1) dtype=float32_ref>, <tf.Variable 'weights/W3:0' shape=(2, 3) dtype=float32_ref>, <tf.Variable 'biases/b3:0' shape=(2, 1) dtype=float32_ref>]
Кто-нибудь есть идеи о том, в чем может быть проблема?
РЕДАКТИРОВАНИЕ И ДОБАВЛЕНИЕ НЕКОТОРОЙ БОЛЬШЕ ИНФОРМАЦИИ: Если вы хотите посмотреть, как я создаю и инициализирую свои параметры, вот код. Может быть, что-то не так с этой частью, но я не вижу, что..
def get_nn_parameter(variable_scope, variable_name, dim1, dim2):
with tf.variable_scope(variable_scope, reuse=tf.AUTO_REUSE):
v = tf.get_variable(variable_name,
[dim1, dim2],
trainable=True,
initializer = tf.contrib.layers.xavier_initializer())
return v
def initialize_layer_parameters(num_units_in_layers):
parameters = {}
L = len(num_units_in_layers)
for i in range (1, L):
temp_weight = get_nn_parameter("weights",
"W"+str(i),
num_units_in_layers[i],
num_units_in_layers[i-1])
parameters.update({"W" + str(i) : temp_weight})
temp_bias = get_nn_parameter("biases",
"b"+str(i),
num_units_in_layers[i],
1)
parameters.update({"b" + str(i) : temp_bias})
return parameters
#ДОПОЛНЕНИЕ
Я получил это работает. Вместо того, чтобы писать отдельный ответ, я добавляю правильную версию своего кода здесь.
(Ответ Дэвида ниже очень помог.)
Я просто удалил my_sess в качестве параметра моей функции compute_cost. (Я не мог заставить это работать раньше, но, по-видимому, это вообще не нужно.) И я также переупорядочил утверждения в своей основной функции для вызова вещей в правильном порядке.
Вот рабочая версия моей функции стоимости и как я ее называю:
def compute_cost(ZL, Y, parameters, mb_size, lambd):
logits = tf.transpose(ZL)
labels = tf.transpose(Y)
cost_unregularized = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits = logits, labels = labels))
#Since the dict parameters includes both W and b, it needs to be divided with 2 to find L
L = len(parameters) // 2
list_sum_weights = []
for i in range (0, L):
list_sum_weights.append(tf.nn.l2_loss(parameters.get("W"+str(i+1))))
regularization_effect = tf.multiply((lambd / mb_size), tf.add_n(list_sum_weights))
cost = tf.add(cost_unregularized, regularization_effect)
return cost
А вот основная функция, где я вызываю функцию compute_cost (..):
tf.reset_default_graph()
num_units_in_layers = [5,4,3,2]
X = tf.placeholder(shape=[5, 3], dtype=tf.float32)
Y = tf.placeholder(shape=[2, 3], dtype=tf.float32)
parameters = initialize_layer_parameters(num_units_in_layers)
my_sess = tf.Session()
ZL = forward_propagation_with_relu(X, num_units_in_layers, parameters)
cost = compute_cost(ZL, Y, parameters, 3, 0.05)
optimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)
init = tf.global_variables_initializer()
my_sess.run(init)
_ , minibatch_cost = my_sess.run([optimizer, cost],
feed_dict={X: [[-1.,4.,-7.],[2.,6.,2.],[3.,3.,9.],[8.,4.,4.],[5.,3.,5.]],
Y: [[0.6, 0., 0.3], [0.4, 0., 0.7]]})
print(minibatch_cost)
my_sess.close()
1 ответ
Я на 99,9% уверен, что вы создаете свою функцию затрат неправильно.
cost = compute_cost(ZL, Y, my_sess, parameters, batch_size=3, lambd=0.05)
Ваша функция стоимости должна быть тензорной. Вы передаете свой сеанс в функцию стоимости, которая выглядит так, как будто она на самом деле пытается запустить сеанс тензорного потока, который сильно ошибочен.
Затем позже вы передаете результат compute_cost
к вашему минимизатору.
Это распространенное недоразумение о тензорном потоке.
Tensorflow - это декларативная парадигма программирования, которая означает, что вы сначала объявляете все операции, которые хотите выполнить, а затем передаете данные и запускаете их.
Рефакторинг вашего кода, чтобы строго следовать этой лучшей практике:
(1) Создать build_graph()
функция, в эту функцию должны быть помещены все ваши математические операции. Вы должны определить свою функцию стоимости и все уровни сети. Вернуть optimize.minimize()
обучающая операция (и любые другие ОП, которые вы можете вернуть, например, точность).
(2) Теперь создайте сеанс.
(3) После этого момента не создавайте больше операций или переменных тензорного потока, если вам кажется, что вам нужно что-то делать неправильно.
(4) Вызовите sess.run для вашего train_op и передайте данные заполнителя через feed_dict
,
Вот простой пример того, как структурировать ваш код:
В общем, есть очень хорошие примеры, представленные aymericdamien, я настоятельно рекомендую просмотреть их, чтобы изучить основы тензорного потока.