Это будет долго и сложно описывать, поэтому заранее приношу свои извинения.
У меня есть обычная сеть типа CNN со стандартными слоями MLP поверх нее. На вершине MLP у меня также есть слой softmax, однако, в отличие от обычных сетей, он НЕ полностью связан с MLP ниже и состоит из подгрупп.
Для дальнейшего описания softmax это выглядит так:
Neur1A Neur2A ... NeurNA Neur1B Neur2B ... NeurNB Neur1C Neur2C ...NeurNC
Group A Group B Group C
Есть еще много групп. У каждой группы есть softmax, независимый от других групп. Так что это в некотором смысле несколько независимых классификаций (хотя на самом деле это не так).
Мне нужно, чтобы индекс активированного нейрона монотонно увеличивался между группами. Например, если у меня активирован Neuron5 в группе A, я хочу, чтобы активированный нейрон в группе B был> = 5. То же самое с Группой B, Группой C и т. Д.
Этот слой softmax, содержащий все нейроны для всех групп, на самом деле НЕ мой последний слой и, что интересно, промежуточный.
Чтобы добиться этой монотонности, я добавляю к своей функции потерь еще один член, который штрафует немонотонно активированные индексы нейронов. Вот часть кода:
Код для слоя softmax и его вывод:
def compute_image_estimate(layer2_input):
estimated_yps= tf.zeros([FLAGS.batch_size,0],dtype=tf.int64)
for pix in xrange(NUM_CLASSES):
pixrow= int( pix/width)
rowdata= image_pixels[:, pixrow*width:(pixrow+1)*width]
with tf.variable_scope('layer2_'+'_'+str(pix)) as scope:
weights = _variable_with_weight_decay('weights', shape=[layer2_input.get_shape()[1], width], stddev=0.04, wd=0.0000000)
biases = _variable_on_cpu('biases', [width], tf.constant_initializer(0.1))
y = tf.nn.softmax(tf.matmul(layer2_input,weights) + biases)
argyp=width-1-tf.argmax(y,1)
argyp= tf.reshape(argyp,[FLAGS.batch_size,1])
estimated_yps=tf.concat(1,[estimated_yps,argyp])
return estimated_yps
Оценочные_yps передаются в функцию, которая количественно определяет монотонность:
def compute_monotonicity(yp):
sm= tf.zeros([FLAGS.batch_size])
for curr_row in xrange(height):
for curr_col in xrange(width-1):
pix= curr_row *width + curr_col
sm=sm+alpha * tf.to_float(tf.square(tf.minimum(0,tf.to_int32(yp[:,pix]-yp[:,pix+1]))))
return sm
а функция потерь:
def loss(estimated_yp, SOME_OTHER_THINGS):
tf.add_to_collection('losses', SOME_OTHER_THINGS)
monotonicity_metric= tf.reduce_mean( compute_monotonocity(estimated_yp) )
tf.add_to_collection('losses', monotonicity_metric)
return tf.add_n(tf.get_collection('losses'), name='total_loss')
Теперь моя проблема в том, что когда я не использую НЕКОТОРЫЕ ВЕЩИ, которые являются обычными метриками, я получаю ValueError: No gradients provided for any variable
для метрики монотонности.
Похоже, что градиенты не определены, когда выходные данные слоя softmax используются таким образом.
Я делаю что-то неправильно? Любая помощь будет оценена по достоинству.