【问题标题】:Deep Learning implementation in Tensorflow or Keras give drastic different resultsTensorflow 或 Keras 中的深度学习实现给出了截然不同的结果
【发布时间】:2018-09-08 16:02:30
【问题描述】:

上下文:我正在使用全卷积网络来执行图像分割。通常,输入是 RGB 图像shape = [512, 256],目标是定义注释区域的 2 通道二进制掩码(第 2 通道与第 1 通道相反)。

问题:我使用 Tensorflow 和 Keras 实现了相同的 CNN。但是 TensorFlow 模型并没有开始学习。实际上,loss 甚至会随着 epoch 的数量而增长!这个 TensorFlow 实现有什么问题阻止它学习?

设置: 数据集分为 3 个子集:训练 (78%)、测试 (8%) 和验证 (14%) 集,它们通过 8 张图像批量输入网络。这些图表显示了每个子集的loss 的演变。这些图像显示了两个不同图像在 10 个 epoch 后的 prediction


Tensorflow 实施和结果

import tensorflow as tf

tf.reset_default_graph()
x = inputs = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 3])
targets = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 2])

for d in range(4):
    x = tf.layers.conv2d(x, filters=np.exp2(d+4), kernel_size=[3,3], strides=[1,1], padding="SAME", activation=tf.nn.relu)
    x = tf.layers.max_pooling2d(x, strides=[2,2], pool_size=[2,2], padding="SAME")
    
x = tf.layers.conv2d(x, filters=2, kernel_size=[1,1])
logits = tf.image.resize_images(x, [shape[1], shape[0]], align_corners=True)
prediction = tf.nn.softmax(logits)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=targets, logits=logits))
optimizer = tf.train.RMSPropOptimizer(learning_rate=0.001).minimize(loss)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

def run(mode, x_batch, y_batch):
    if mode == 'TRAIN':
        return sess.run([loss, optimizer], feed_dict={inputs: x_batch, targets: y_batch})
    else:
        return sess.run([loss, prediction], feed_dict={inputs: x_batch, targets: y_batch})


Keras 实施和结果

import keras as ke

ke.backend.clear_session()
x = inputs = ke.layers.Input(shape=[shape[1], shape[0], 3])

for d in range(4):
    x = ke.layers.Conv2D(int(np.exp2(d+4)), [3,3], padding="SAME", activation="relu")(x)
    x = ke.layers.MaxPool2D(padding="SAME")(x)

x = ke.layers.Conv2D(2, [1,1], padding="SAME")(x)
logits = ke.layers.Lambda(lambda x: ke.backend.tf.image.resize_images(x, [shape[1], shape[0]], align_corners=True))(x)
prediction = ke.layers.Activation('softmax')(logits)

model = ke.models.Model(inputs=inputs, outputs=prediction)
model.compile(optimizer="rmsprop", loss="categorical_crossentropy")

def run(mode, x_batch, y_batch):
    if mode == 'TRAIN':
        loss = model.train_on_batch(x=x_batch, y=y_batch)
        return loss, None
    else:
        loss = model.evaluate(x=x_batch, y=y_batch, batch_size=None, verbose=0)
        prediction = model.predict(x=x_batch, batch_size=None)
        return loss, prediction


两者之间一定有区别,但我对文档的理解让我无处可去。我真的很想知道区别在哪里。提前致谢!

【问题讨论】:

  • 我不明白那些情节是什么。但我发现你的 2 个版本之间的唯一差异是 TF 使用相同的填充来池化层,这是不寻常的,可能是错误的来源。
  • 谢谢,但这并没有什么不同。我用更多细节完成了这个问题,并在 TF 和 K 中使用“相同”的填充给出了结果。
  • 您可以尝试使用tf.reduce_sum 来支付费用吗?
  • 感谢您的建议,但没有帮助...

标签: python tensorflow deep-learning keras


【解决方案1】:

答案在 softmax 的 Keras 实现中,他们减去了一个意想不到的 max

def softmax(x, axis=-1):
    # when x is a 2 dimensional tensor
    e = K.exp(x - K.max(x, axis=axis, keepdims=True))
    s = K.sum(e, axis=axis, keepdims=True)
    return e / s

这里是使用max hack 更新的 Tensorflow 实现以及相关的良好结果

import tensorflow as tf

tf.reset_default_graph()
x = inputs = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 3])
targets = tf.placeholder(tf.float32, shape=[None, shape[1], shape[0], 2])

for d in range(4):
    x = tf.layers.conv2d(x, filters=np.exp2(d+4), kernel_size=[3,3], strides=[1,1], padding="SAME", activation=tf.nn.relu)
    x = tf.layers.max_pooling2d(x, strides=[2,2], pool_size=[2,2], padding="SAME")

x = tf.layers.conv2d(x, filters=2, kernel_size=[1,1])
logits = tf.image.resize_images(x, [shape[1], shape[0]], align_corners=True)
# The misterious hack took from Keras
logits = logits - tf.expand_dims(tf.reduce_max(logits, axis=-1), -1)
prediction = tf.nn.softmax(logits)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=targets, logits=logits))
optimizer = tf.train.RMSPropOptimizer(learning_rate=0.001).minimize(loss)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

def run(mode, x_batch, y_batch):
    if mode == 'TRAIN':
        return sess.run([loss, optimizer], feed_dict={inputs: x_batch, targets: y_batch})
    else:
        return sess.run([loss, prediction], feed_dict={inputs: x_batch, targets: y_batch})

非常感谢 Simon 在 Keras 实现中指出这一点 :-)

【讨论】:

    猜你喜欢
    • 2019-02-05
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    相关资源
    最近更新 更多