Использование слоя softmax внутри самой целевой функции

Это будет долго и сложно описывать, поэтому заранее приношу свои извинения.

У меня есть обычная сеть типа 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 используются таким образом.

Я делаю что-то неправильно? Любая помощь будет оценена по достоинству.


person eurotomania    schedule 26.02.2016    source источник


Ответы (1)


Извините .. Я понял, что проблема в том, что функция tf.argmax явно не имеет определенного градиента.

person eurotomania    schedule 26.02.2016