Использование пакетной нормы при восстановлении модели?

У меня есть небольшая проблема, связанная с использованием пакетной нормы при восстановлении модели в тензорном потоке.

Ниже моя норма партии, которая отсюда:

def _batch_normalization(self, input_tensor, is_training, batch_norm_epsilon, decay=0.999):
    """batch normalization for dense nets.

    Args:
        input_tensor: `tensor`, the input tensor which needed normalized.
        is_training: `bool`, if true than update the mean/variance using moving average,
                             else using the store mean/variance.
        batch_norm_epsilon: `float`, param for batch normalization.
        decay: `float`, param for update move average, default is 0.999.

    Returns:
        normalized params.
    """
    # actually batch normalization is according to the channels dimension.
    input_shape_channels = int(input_tensor.get_shape()[-1])

    # scala and beta using in the the formula like that: scala * (x - E(x))/sqrt(var(x)) + beta
    scale = tf.Variable(tf.ones([input_shape_channels]))
    beta = tf.Variable(tf.zeros([input_shape_channels]))

    # global mean and var are the mean and var that after moving averaged.
    global_mean = tf.Variable(tf.zeros([input_shape_channels]), trainable=False)
    global_var = tf.Variable(tf.ones([input_shape_channels]), trainable=False)

    # if training, then update the mean and var, else using the trained mean/var directly.
    if is_training:
        # batch norm in the channel axis.
        axis = list(range(len(input_tensor.get_shape()) - 1))
        batch_mean, batch_var = tf.nn.moments(input_tensor, axes=axis)

        # update the mean and var.
        train_mean = tf.assign(global_mean, global_mean * decay + batch_mean * (1 - decay))
        train_var = tf.assign(global_var, global_var * decay + batch_var * (1 - decay))
        with tf.control_dependencies([train_mean, train_var]):
            return tf.nn.batch_normalization(input_tensor,
                                             batch_mean, batch_var, beta, scale, batch_norm_epsilon)
    else:
        return tf.nn.batch_normalization(input_tensor,
                                         global_mean, global_var, beta, scale, batch_norm_epsilon)

Я тренирую модель и сохраняю ее, используя tf.train.Saver(), Ниже приведен тестовый код:

def inference(self, images_for_predict):
    """load the pre-trained model and do the inference.

    Args:
        images_for_predict: `tensor`, images for predict using the pre-trained model.

    Returns:
        the predict labels.
    """

    tf.reset_default_graph()
    images, labels, _, _, prediction, accuracy, saver = self._build_graph(1, False)

    predictions = []
    correct = 0
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        # saver = tf.train.import_meta_graph('./models/dense_nets_model/dense_nets.ckpt.meta')
        # saver.restore(sess, tf.train.latest_checkpoint('./models/dense_nets_model/'))
        saver.restore(sess, './models/dense_nets_model/dense_nets.ckpt')
        for i in range(100):
            pred, corr = sess.run([tf.argmax(prediction, 1), accuracy],
                                  feed_dict={
                                      images: [images_for_predict.images[i]],
                                      labels: [images_for_predict.labels[i]]})
            correct += corr
            predictions.append(pred[0])
    print("PREDICTIONS:", predictions)
    print("ACCURACY:", correct / 100)

Но прогнозируемый результат всегда очень плох, вот так:

('PREDICTIONS:', [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

('ACCURACY:', 0.080000000000000002)

Несколько советов: images_for_predict = mnist.test и self._build_graph Метод имеет два параметра: batch_size а также is_training,

Кто-нибудь может мне помочь?

2 ответа

Перепробовав множество методов, я решил эту проблему, вот что я сделал.

Во-первых, благодаря @gdelab, я использовал tf.layers.batch_normalization вместо этого, так моя функция пакетной нормы так:

def _batch_normalization(self, input_tensor, is_training):
    return tf.layers.batch_normalization(input_tensor, training=is_training)

Парам is_training такой заполнитель: is_training = tf.placeholder(tf.bool)

при построении графика не забудьте добавить этот код в свой оптимизатор:

extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(extra_update_ops):
    train_step = tf.train.AdamOptimizer(self.learning_rate).minimize(cross_entropy)

поскольку tf.layers.batch_normalization добавляет для обновления среднее, а дисперсия не добавляется автоматически как зависимости от операции поезда - поэтому, если вы не сделаете ничего лишнего, они никогда не запустятся.

Итак, начните тренировать сеть, после окончания обучения сохраните модель, используя следующий код:

saver = tf.train.Saver(var_list=tf.global_variables())
savepath = saver.save(sess, 'here_is_your_personal_model_path')

Обратите внимание, что var_list=tf.global_variables() param, убедитесь, что тензор потока сохраняет все параметры, включая глобальное среднее /var, которое установлено не обучаемым.

когда восстановите и протестируете модель, сделайте так:

# build the graph like training:
images, labels, _, _, prediction, accuracy, saver = self._build_graph(1, False)
saver = tf.train.Saver()
saver.restore(sess, 'here_is_your_personal_model_path')

И теперь можно проверить его / ее модель, надеюсь, что это поможет вам, спасибо!

Видя, как вы реализуете пакетную норму, когда вы загружаете вашу модель, вам нужно сохранить график, построенный с images, labels, _, _, prediction, accuracy, saver = self._build_graph(1, False) и загрузите значения веса для чекпойнта, но НЕ мета-графика. я думаю что saver.restore(sess, './models/dense_nets_model/dense_nets.ckpt') теперь также восстанавливает мета-график (извините, если я ошибаюсь), поэтому вам нужно восстановить только часть данных.

В противном случае вы просто используете график для обучения, в котором среднее значение и дисперсия, используемые в норме партии, являются теми, которые получены из партии. Но когда вы тестируете, пакет имеет размер 1, поэтому нормализация по среднему значению и дисперсии пакета всегда приводит ваши данные к 0, следовательно, постоянный вывод.

В любом случае, я бы предложил использовать tf.layers.batch_normalization вместо этого с is_training заполнитель, который вам нужно будет передать в вашу сеть...

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