Весы сегментации изображения Tensorflow не обновляются - PullRequest
0 голосов
/ 04 июня 2018

Я строю простую сеть сегментации изображений, основанную на архитектуре кодера / декодера в TensorFlow, и в настоящее время модель работает, но весы не обновляются.Входные данные - это мой собственный набор данных: изображения, преобразованные в массивы фигуры [-1,200,200,1] с метками маски пиксель-бу-пиксель формы [-1,40000,3].

Код для моей функции модели здесь

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% и не может тренироваться.Если у кого-то есть какие-либо предложения, они будут очень признательны.

1 Ответ

0 голосов
/ 04 июня 2018

В начале вопроса вы говорите:

модель работает, но весы не обновляются.

Затем в конце вы говорите:

показатель точности остается около отметки 35% и не может обучаться

Это две разные ситуации.В первом случае весовые коэффициенты вообще не обновляются, тогда как во втором случае они обновляются, но их обновление не дает какого-либо улучшения с точки зрения точности.Сначала вам нужно проверить, в каком случае вы.

ПОСТОЯННЫЕ ВЕСЫ

Если веса остаются постоянными во время тренировки, вы можете экспериментировать исчезновение градиента .Ваша сеть имеет функцию активации в качестве релю, поэтому может случиться так, что почти все линейные выходы (то есть Z = W*x + b) являются отрицательными, а у реле есть градиент, равный 0 для отрицательных входов, поэтому обучение не распространяется обратно через слои к каждому весу.Вы можете попробовать другую функцию активации или, что более распространено в CNN, добавить уровень нормализации партии после каждого слоя.

ПОСТОЯННАЯ ТОЧНОСТЬ

Существует несколько причин.

  1. Ваша сеть может находиться в глобальном оптимуме, поэтому не имеет значения, что вы делаете, если вы не расширите свой набор данных, вы не достигнете лучшей точности

  2. Ваша сеть может находиться в локальном оптимуме.Даже если это маловероятно из-за случайной инициализации веса, вы должны попытаться реализовать мини-пакет и / или перетасовать свой набор данных на каждой итерации.

  3. Ваша сеть проста и не может понять основные отношениямежду входами и выходами.

  4. Ваша сеть слишком сложна.В этом случае вам следует поэкспериментировать с переобучением, если вы оставите в своей сети обучение для большого числа эпох.

Надеюсь, это поможет!

...