【问题标题】:Tensorflow Image Segmentation weights not updatingTensorflow 图像分割权重未更新
【发布时间】:2018-11-14 01:24:58
【问题描述】:

我正在构建一个简单的图像分割网络,基于 TensorFlow 中的编码器/解码器架构,目前该模型似乎可以运行,但它没有更新权重。输入是我自己的数据集:图像转换为形状为 [-1,200,200,1] 的 numpy 数组,带有形状为 [-1,40000,3] 的像素-bu-像素掩码标签。

我的模型函数的代码在这里

def model(features, labels, mode):

    inpt = tf.reshape(features["x"], [-1,200,200,1])

    #encoder
    x = tf.layers.conv2d(
        inputs = inpt,
        filters = 16,
        kernel_size = [2,2],
        padding = 'same',
        activation = tf.nn.relu)  
    x = tf.layers.max_pooling2d(inputs = x, pool_size = [2,2], strides = 2)

    x = tf.layers.conv2d(
        inputs = x,
        filters = 32,
        kernel_size = [2,2],
        padding = 'same',
        activation = tf.nn.relu)
    x = tf.layers.max_pooling2d(inputs = x, pool_size = [2,2], strides = 2)

    x = tf.layers.conv2d(
        inputs = x,
        filters = 64,
        kernel_size = [2,2],
        padding = 'same',
        activation = tf.nn.relu)
    x = tf.layers.max_pooling2d(inputs = x, pool_size = [2,2], strides = 2)

    #decoder
    x = tf.keras.layers.UpSampling2D(size = (2,2))(x)
    x = tf.layers.conv2d(
        inputs = x,
        filters = 64,
        kernel_size = [2,2],
        padding = 'same',
        activation = tf.nn.relu)

    x = tf.keras.layers.UpSampling2D(size = (2,2))(x)
    x = tf.layers.conv2d(
        inputs = x,
        filters = 32,
        kernel_size = [2,2],
        padding = 'same',
        activation = tf.nn.relu)

    x = tf.keras.layers.UpSampling2D(size = (2,2))(x)   
    x = tf.layers.conv2d(
        inputs = x,
        filters = 16,
        kernel_size = [2,2],
        padding = 'same',
        activation = tf.nn.relu)

    x = tf.layers.conv2d(
        inputs = x,
        filters = 3,
        kernel_size = [1,1],
        padding = 'valid',
        activation = tf.nn.relu)

    logits = tf.reshape(x, [-1,3])

    predictions = {
        "classes": tf.argmax(input = logits, axis = 1),
        "probabilities": tf.nn.softmax(logits, name = "softmax_tensor")
    }

    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(mode = mode, predictions = predictions)

    labels = tf.reshape(labels, [-1,3])

    loss = tf.losses.softmax_cross_entropy(onehot_labels = labels, logits = logits)

    if mode == tf.estimator.ModeKeys.TRAIN:
        optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.0001)
        train_op = optimizer.minimize(
            loss = loss,
            global_step = tf.train.get_global_step())
        return tf.estimator.EstimatorSpec(mode = mode, loss = loss, train_op = train_op)


    eval_metric_ops = {
        "accuracy": tf.metrics.accuracy(
            labels = tf.argmax(labels, axis = 1), predictions = predictions["classes"])
    }
    return tf.estimator.EstimatorSpec(
        mode = mode, loss = loss, eval_metric_ops = eval_metric_ops)

然后我按如下方式调用模型:

classifier = tf.estimator.Estimator(model_fn = model, model_dir = '.')

tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(
    tensors = tensors_to_log, every_n_iter = 50)

train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x = {"x": train},
    y = train_label,
    batch_size = 1,
    num_epochs = 5,
    shuffle = True)

classifier.train(
    input_fn = train_input_fn,
    steps = None)

模型正在运行,但准确度得分保持在 35% 左右,无法训练。如果有人有任何建议,他们将不胜感激。

【问题讨论】:

  • 我会使用 tf.layers.conv2d_transpose 而不是 tf.keras.layers.UpSampling2D,以免混合 Keras 和 Tensorflow 层。
  • 我的理解是它们的表现不同。我想使用最近邻上采样,我相信 Keras 会使用它,因为转置卷积层会在上采样图像中添加伪影,从而混淆输出。

标签: python tensorflow machine-learning computer-vision


【解决方案1】:

在问题的开头你说:

模型似乎在运行,但它没有更新权重。

然后,最后你说:

准确度分数保持在 35% 左右,无法训练

这是两种不同的情况。在第一种情况下,权重根本不会更新,而在第二种情况下,权重会更新,但它们的更新在准确性方面没有任何改进。您首先需要检查您是哪种情况。

恒定重量

如果在训练期间权重保持不变,您可能正在试验gradient vanishing。您的网络将 relu 作为激活函数,因此可能几乎所有线性输出(即Z = W*x + b)都是负的,并且对于负输入,relu 的梯度等于 0,因此学习不会通过层反向传播到每个权重。您可以尝试不同的激活函数,或者在 CNN 中更常见,在每个 conv 层之后添加一个 Batch 归一化层。

恒定精度

有几个原因。

  1. 您的网络可能处于全局最优状态,因此无论您做什么都没关系,如果您不扩展数据集,您将无法达到更好的准确度

  2. 您的网络可能处于局部最优状态。即使由于权重的随机初始化而不太可能,您也应该尝试在每次迭代时实现小批量和/或打乱您的数据集。

  3. 您的网络过于简单,无法理解输入和输出之间的底层关系。

  4. 您的网络太复杂了。在这种情况下,如果您将网络训练留给大量 epoch,则应该尝试过拟合。

希望对你有帮助!

【讨论】:

  • 嗨,@Neb,感谢您的回答。你说的很对,这是两种截然不同的情况。我去看看是哪一个。不过,关于你对这两种情况的回答,我已经在 Keras 中实现了相同的网络,并且它在我拥有的数据上表现良好,所以我认为我的代码中可能存在语法错误。
  • 嗨@JosephBullock。请注意,使用不同的框架,您可能会遇到略有不同的结果(这里不是这种情况)。如果我无论如何都帮助了你,你能给我点个赞吗?谢谢!
猜你喜欢
  • 2020-10-25
  • 1970-01-01
  • 2016-07-23
  • 2018-10-19
  • 2020-04-18
  • 2017-04-06
  • 1970-01-01
  • 2022-10-17
  • 2021-03-26
相关资源
最近更新 更多