Пользовательская функция потерь keras не возвращает градиента даже без argmax - PullRequest
0 голосов
/ 26 марта 2019

Я хочу выполнить некоторую постобработку на y_pred, прежде чем вычислять потери по keras, поэтому я решил использовать пользовательскую функцию потерь keras.сначала я использовал argmax.Я знаю, что для argmax градиента нет, поэтому я заменил его комбинацией других функций, таких как map_fn, redu_min и sum.но все равно получил ошибку

Операция имеет None для градиента.Пожалуйста, убедитесь, что все ваши операции имеют определенный градиент (то есть являются дифференцируемыми).Обычные операции без градиента: K.argmax, K.round, K.eval.

В чем проблема?если проблема все еще использует какую-то определенную функцию (какую функцию), и что эквивалентно им, которые имеют градиентиспользование регистра Tensorflow Gradient, изменение функции потери кераса или любое другое решение?

def my_loss(y_true, y_pred):
  global ind_Batch
  def aaa(x):
    return tf.reduce_min(tf.where(tf.equal(x[0],x[1])))
  def aaa2(xx):
    ww=tf.keras.backend.max(y_pred[ind_Batch,xx,:,:],axis=1)
    return tf.map_fn(aaa,(y_pred[ind_Batch,xx,:,:],ww),dtype=tf.int64)
  def fun_true_false(var,status,mask_):
    delta = tf.SparseTensor(tf.where(mask_), tf.fill((1,tf.count_nonzero(mask_)),status)[0], (384,384)) #assign
    return var+ tf.sparse_tensor_to_dense(delta)
  def my_fun_contour(contour_index):
    ind_F=tf.constant(0)
    def condition(ind_F,num_feature,f):
      return tf.less(ind_F,num_feature+1)
    def body(ind_F,num_feature,f):
      mask=tf.equal(contours,ind_F) #bool mask
      mask_=tf.cast(mask,tf.int32) #int mask
      new_mask=(mask_*argmax_var) #remove unnecessary classes
      #target_class=tf.math.argmax([tf.count_nonzero(tf.equal(new_mask,ind)) for ind in range(1,6)], output_type=tf.dtypes.int32)#find major class
      list_items=[tf.count_nonzero(tf.equal(new_mask,ind)) for ind in range(1,6)]
      target_class=tf.cast(tf.where(tf.equal(list_items,tf.keras.backend.max(list_items)))[0][0],tf.int32)
      for ind in range(6):
        f[ind]=tf.where(tf.equal(ind,target_class+1),fun_true_false(f[ind],1.0,mask_),fun_true_false(f[ind],0.0,mask_))
      return [tf.add(ind_F,1),num_feature,f]
    num_feature=tf.math.reduce_max(tf.math.reduce_max(contours,axis=[1]),axis=0)
    f=[] #a list for appending dimention
    for ind in range(6):
      f.append(np.zeros((384,384),dtype=np.float32))
    res = tf.while_loop(condition,body,[ind_F,num_feature,f])
    mm=tf.transpose(tf.stack(res[-1]),perm=[1,2,0]) #stack f and transpose it to 1,2,0
    return mm
  predict_var=[] #a list for appending batches
  for ind_B in range(Batch_size):
    ind_Batch=ind_B
    argmax_var=tf.cast(tf.map_fn(aaa2,tf.range(384),dtype=tf.int64),tf.int32)
    predict_label=tf.cast(tf.greater(argmax_var,0),tf.int32) 
    contours=tf.contrib.image.connected_components(predict_label)
    predict_var.append(my_fun_contour(ind_B))
  y_pred_=tf.stack(predict_var)
  return bce_jaccard_loss(y_true,y_pred_)

Опишите мою проблему: я работаю над сегментацией.этот код найдет каждый объект (связанный компонент с помощью tf.contrib.image.connected_components), а затем вычислит основной класс в объекте и, наконец, расширит основной класс на весь объект.рис ниже.modifying y_predict спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...