Я хочу выполнить некоторую постобработку на 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), а затем вычислит основной класс в объекте и, наконец, расширит основной класс на весь объект.рис ниже. спасибо.