Тензорный поток вычисляет перекрестную энтропию только с одинарной точностью?

1

Я пытаюсь полностью понять вычисление перекрестной энтропии в TensorFlow. В следующем фрагменте кода с помощью numpy я генерирую случайные двойные данные x двойной точности, преобразую их в logits для двоичной классификации (т. logits Только один логит на точку данных), отображаю их через сигмоид в sig, вычисляю перекрестную энтропию ce и затем средняя перекрестная энтропия mce. Аналогичные вычисления в TensorFlow приведены ниже. Мой вопрос:

Почему я получаю несоответствие между моей средней перекрестной энтропией mce (вычисленной с двойной точностью в numpy) и tf.losses.sigmoid_cross_entropy?

Я не знаю, где я забыл указать для TensorFlow для вычисления с двойной точностью. Кроме того, если я использую tf.nn.reduce_mean, см. Вычисление mcetf2 для вычисленной перекрестной энтропии для каждой точки данных, то я получу свой результат с нулевыми значениями. Откуда берется несоответствие? Спасибо!

import numpy as np
import tensorflow as tf

#%%

# Number of data pionts nx and dimension dx
nx = 10
dx = 4

# Input data
x = np.random.rand(nx,dx)

#%% Numpy

# Transform to logits for binary classification with sigmoid
matrix = np.random.rand(dx,1)
logits = np.matmul(x,matrix)
print('Logits dimensions: %s' % str(logits.shape))

# Sigmoid
def sigmoid(x):
    return 1. / (1. + np.exp(-x))
sig = sigmoid(logits)
print('Sigmoid dimensions: %s' % str(sig.shape))

# Discrete probabilities
p = np.random.randint(2,size=nx)[:,np.newaxis]
print('Probability dimensions: %s'% str(p.shape))

# Cross entropy for each data point
ce = p*np.log(1/sig)+(1-p)*np.log(1/(1-sig))

# Mean cross entropy
mce = np.mean(ce)
print('MCE with np: %.16f' % mce)

#%% Tensorflow

xp = tf.placeholder(dtype=tf.float64,shape=[None,dx])
pp = tf.placeholder(dtype=tf.float64,shape=[None,1])

model = xp
c1 = tf.constant(matrix,dtype=tf.float64)
model = tf.matmul(xp,c1)
sigtf = tf.nn.sigmoid(model)
cetf = tf.nn.sigmoid_cross_entropy_with_logits(labels=pp,logits=model)
mcetf = tf.losses.sigmoid_cross_entropy(pp,model)
mcetf2 = tf.reduce_mean(cetf)

sess = tf.Session()
feed = {xp:x,pp:p}
print('Error in logits: %.16f' % np.max(np.abs(sess.run(model,feed)-logits)))
print('Error in sigmoid: %.16f' % np.max(np.abs(sess.run(sigtf,feed)-sig)))
print('Error in CE: %.16f' % np.max(np.abs(sess.run(cetf,feed)-ce)))
print('Error in MCE: %.16f' % np.abs(sess.run(mcetf,feed)-mce))
print('Error in MCE2: %.16f' % np.abs(sess.run(mcetf2,feed)-mce))
sess.close()

Размеры логитов: (10, 1)

Размер сигмовидной кишки: (10, 1)

Вероятностные размеры: (10, 1)

MCE с np: 0,7413128316195762

Ошибка в логах: 0.0000000000000000

Ошибка в сигмоиде: 0,0000000000000000

Ошибка в CE: 0.0000000000000009

Ошибка в MCE: 0,0000000297816550

Ошибка в MCE2: 0,0000000000000001

Теги:
tensorflow
cross-entropy

1 ответ

1
Лучший ответ

использование (32-битного) числа с float будет жестко compute_weighted_loss() функции compute_weighted_loss() используемой sigmoid_cross_entropy в Tensorflow

в качестве второстепенной точки зрения ваш код для вычисления ce не очень численно стабилен, но здесь он ни на что не повлияет. Я бы реализовал это как:

ce = p * -np.log(sig) + (1-p) * -np.log1p(-sig)

использование log1p является основным изменением. использование 1 - sig потеряет всю точность, так как sig приближается к нулю

  • 0
    о, круто, большое спасибо, это сводило меня с ума!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню