Keras имеет гораздо лучшие градиенты, рассчитанные, чем родной TF, при использовании мини-партии SGD

Я не уверен, является ли это ошибкой в ​​некоторой функции TF, или у Keras есть только несколько умных способов справиться с этой задачей. Я прототипировал простую модель логистической регрессии с Keras и пытался написать точно такую ​​же модель с TF, чтобы воспроизвести результат. Тем не менее, есть кое-что необъяснимое для меня, что Keras всегда рассчитывает намного лучшие градиенты, чем TF, когда я использую мини-пакет SGD.

tensorflow == 1.2.1

Keras == 2.0.8

GPU: Tesla P40

Версия Keras:

def custom_objective(y_true, y_pred):
    loss = tf.reduce_mean(-(y_true*tf.log(y_pred)+((1.0-y_true)*tf.log(1.0-y_pred))))
    return loss
model = Sequential()
model.add(Dense(1,input_dim=2440000, activation='sigmoid', bias_initializer='zeros', kernel_initializer='zeros'))
sgd = tf.train.GradientDescentOptimizer(0.5)
model.compile(loss=custom_objective, optimizer=sgd)
model.fit_generator(generator, steps_per_epoch=1, epochs=1, callbacks=[ival], max_queue_size=10, workers=1, use_multiprocessing=False, initial_epoch=0)

Версия TF:

def linear(x, n_input, n_output, name=None):
    with tf.variable_scope(name or 'fc'):
        W = tf.get_variable(
            name = "W",
            # shape = [n_input, n_output],
            dtype=tf.float32,
            # initializer=tf.contrib.layers.xavier_initializer())
            initializer=tf.zeros(shape=[n_input,n_output]))
        b = tf.get_variable(
            name='bias',
            shape=[n_output],
            dtype=tf.float32,
            initializer=tf.constant_initializer(0.0))
        if not isinstance(x, tf.SparseTensor):
            h = tf.nn.bias_add(
                tf.matmul(x, W),
                b,
                name='h')
        else:
            h = tf.nn.bias_add(
                tf.sparse_tensor_dense_matmul(x, W),
                b,
                name='h')
    return h, W, b

tf.reset_default_graph()
X_shape = tf.placeholder(tf.int64, shape=[2], name="X_shape")
X_indices = tf.placeholder(tf.int64, name="X_indices")
X_values = tf.placeholder(tf.float32, shape=[None], name="X_values")
y = tf.placeholder(dtype=tf.float32, name="y")
H = tf.SparseTensor(indices=X_indices, values=X_values, dense_shape=X_shape)
logit, w, b = linear(H, 2440000, 1, name="output_layer")
y_pred = tf.nn.sigmoid(logit)
train_error = -(y*tf.log(y_pred) + ((1.0 - y) * tf.log(1.0-y_pred)))
loss = tf.reduce_mean(train_error)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.5)
gvs = optimizer.compute_gradients(loss,[w,b])
train_op = optimizer.apply_gradients(gvs)
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True), graph=tf.get_default_graph())
sess.run(tf.global_variables_initializer())

TL; DR Keras имеет лучшие рассчитанные / обновленные градиенты, чем TF.

Обе версии реализуют ванильную логистическую регрессию, с тем же собственным оптимизатором TF, той же самой определенной кросс-энтропией и тем же генератором данных(за исключением того, что Keras принимает плотную матрицу и TF принимает разреженную matrix.tocoo()), одинаковую скорость обучения, тот же нулевой инициализатор для и ш и б. Простое исчисление может показать, что если первая партия содержит все ОТРИЦАТЕЛЬНЫЕ примеры, градиент для b в первом обновлении должен быть точно 0,5.

Если в партии очень мало примеров (например, 1-9), обе версии дают точный градиент 0,5 для b. Когда размер выборки становится больше 9, Keras начинает получать лучшие градиенты, рассчитанные как для b, так и для w. Например, при размере выборки 10 Keras вычисляет 0,50000006 для b, а TF дает 0,49999988. С размером выборки 12, Keras дает 0,49999994, но TF дает 0,50000012. Хотя оба дают неправильный градиент, Keras всегда лучше, не говоря уже о градиентах весов. Кроме того, попытка бросить урон float16, 32 или 64 не сделает градиент таким же хорошим, как у Кераса.

Накопленные различия после 100 партий тренировок делают модель TF хуже, чем Keras, с точки зрения AUC.

На данном этапе я не уверен, где мне следует искать, поэтому я прибегаю к сообществу, чтобы помочь мне с этим "необъяснимым" явлением. Любое предложение будет высоко ценится.

Оскар

0 ответов

Другие вопросы по тегам