Как реализовать tf.nn.sigmoid_cross_entropy_with_logits

В настоящее время я изучаю тензорный поток и столкнулся с проблемой с tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits). В описании функции сказано, что и метки, и логиты должны быть одного типа. У меня есть функция ниже, которую я использую для классификации изображений MNIST. Ниже приведены ключевые разделы моего кода.

X=tf.placeholder(tf.float32,shape=(None,n_inputs),name="X")
y=tf.placeholder(tf.int32,shape=(None),name="y")

def neuron_layer(X,W,b,n_neurons,name,activation=None):
    with tf.name_scope(name):
        n_inputs=int(X.get_shape()[1])
        stddev=2/np.sqrt(n_inputs)
        z=tf.matmul(X,W)+b
        if activation=="sigmoid":
            return tf.math.sigmoid(z)
        else:
            return z
with tf.name_scope("dnn"):
    hidden1=neuron_layer(X,W1,b1,n_hidden1,"hidden",activation="sigmoid")
       logits=neuron_layer(hidden1,W2,b2,n_outputs,"outputs",activation="sigmoid")
with tf.name_scope("loss"):
    xentropy=tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits)
loss=tf.reduce_mean(xentropy,name="loss")

Я получаю сообщение об ошибке: ввод «y» в «Mul» Op имеет тип int32, который не соответствует типу float32 аргумента «x».

если я изменю y=tf.placeholder(tf.float32,shape=(None),name="y"). Я получаю сообщение об ошибке. Значение, переданное параметру «цели», имеет DataType float32, которого нет в списке допустимых значений: int32, int64. Однако логиты могут быть только с плавающей запятой32 или с плавающей запятой64. Пожалуйста, помогите мне решить проблему. Спасибо


person onexpeters    schedule 06.08.2019    source источник
comment
Поскольку вы используете данные классификации изображений MNIST, вы должны использовать tf.nn.softmax_cross_entropy_with_logits, так как для каждого прогноза существует только одна правильная метка (см. раздел Multi-Label vs Multi-Label Classification дополнительную информацию см. по ссылке). Также у вашего последнего слоя не должно быть активации, так как он интегрирован в tf.nn.sigmoid_cross_entropy_with_logits и tf.nn.softmax_cross_entropy_with_logits для оптимизации.   -  person KrisR89    schedule 06.08.2019
comment
Спасибо. Это было так полезно   -  person onexpeters    schedule 06.08.2019


Ответы (1)


Как упоминалось в комментариях, tf.nn.sigmoid_cross_entropy_with_logits — неправильная функция. В вашем случае вы должны использовать вместо этого tf.nn.softmax_cross_entropy_with_logits (на самом деле это дает предупреждение об устаревании, поэтому tf.nn.softmax_cross_entropy_with_logits_v2 является правильным). Также обратите внимание, как также упоминалось в комментариях, что смысл этих двух функций в том, что они имеют встроенную сигмоиду (или softmax, соответственно), поэтому ваша модель не должна иметь никакой функции активации на последнем уровне.

Что касается проблемы: я только что попробовал это с версией tensorflow 1.14.0. Там проблема все еще возникает, если y имеет тип int32. Однако он работает гладко, если оба, y и labels, имеют тип float32.

Немного нелогично, что tf.nn.sigmoid_cross_entropy_with_logits сам не выполняет это приведение, в то время как tf.nn.softmax_cross_entropy_with_logits не имеет ничего против того, чтобы y был int32.

person sebrockm    schedule 06.08.2019