Почему Tensorflow Gradient Tape возвращает None, когда пытается найти градиент потерь по сравнению с вводом? - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть модель CNN, встроенная в keras, которая использует SVM в своем последнем слое. Я получаю прогноз этого SVM, вставляя входные данные в модель CNN, извлекая соответствующие функции, а затем помещая эти функции в мой SVM, чтобы получить выходной прогноз. Весь этот процесс у меня есть имена предиката_DNR_tensor в коде ниже. Это прекрасно работает, и я могу получить правильный прогноз. Сейчас я пытаюсь получить градиент квадрата потери шарнира этого прогноза от моего SVM по отношению к исходному вводу, см. Код. Однако при использовании Gradient Tape здесь это не работает, и функция просто возвращает None. Когда я использую его с выводимым прогнозом только модели CNN (без SVM), это нормально и дает мне градиент. Почему?

import tensorflow as tf
import tensorflow.keras.losses as losses


x = np.expand_dims(X_train[0,:,:,:],axis=0)
x = tf.convert_to_tensor(x)

with tf.GradientTape() as tape:
  tape.watch(x)

  ##
  y_pred = predict_DNR_tensor(x)/2 # dividing by 2 to normalise back into [0,1 range]
  y_pred = tf.convert_to_tensor(y_pred, dtype="float32")
  ##

  y_pred2 = CNN_model(x)

  y_true = np.expand_dims(y_train[0,:],axis=0)
  loss = losses.squared_hinge(y_true,y_pred)
  loss2 = losses.squared_hinge(y_true,y_pred2)

gradient = tape.gradient(loss,x)

используются следующие переменные:

y_true = array([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]], dtype=float32)  

y_pred = <tf.Tensor: id=84063, shape=(1, 10), dtype=float32, numpy=
array([[-0.51142603, -0.51385206, -0.5131374 , -0.52496594, -0.51574653,
         0.54295117, -0.5148362 , -0.51094234, -0.52781606, -0.53384954]],
      dtype=float32)>  

y_pred2 = <tf.Tensor: id=84105, shape=(1, 10), dtype=float32, numpy=
array([[9.1292924e-05, 6.4014189e-06, 1.2363887e-05, 2.6787011e-02,
        2.7567458e-07, 9.7225791e-01, 2.2164610e-04, 1.3467512e-06,
        5.6831568e-04, 5.3546366e-05]], dtype=float32)>


loss = <tf.Tensor: id=84125, shape=(1,), dtype=float32, numpy=array([0.22959474], dtype=float32)>

loss2 = <tf.Tensor: id=84384, shape=(1,), dtype=float32, numpy=array([0.9056972], dtype=float32)>

Когда я вычисляю градиент с использованием потерь, я получаю возвращенное значение Нет. Когда я вычисляю градиент, используя loss2, я получаю массив значений, как и ожидалось. Единственная разница между потерями и потерями2 - это y_pred и y_pred2. y_pred2, насколько я понимаю, это просто выходные прогнозы модели cnn, встроенной в keras. (Примечание: моя потеря не совсем корректна для этой функции, мне было просто интересно посмотреть, будет ли она выбрасывать градиент, если я использую выходные данные этой модели.)

y_pred, что меня действительно интересует в вызовах выходы SVM, используемые в качестве последнего уровня модели cnn. ie. он получает функции модели cnn для этого входного изображения и затем помещает эти функции в отдельную модель SVM, чтобы получить эти выходные данные.

y_pred и y_pred2 кажутся похожими по своим типам данных и формам, поскольку имеют разные значения. Почему y_pred не может получить градиент? И есть ли способ это исправить?

...