InceptionV4 и V2 дают более низкую точность для "набора данных цветов", чем InceptionV1

Я использую следующий код для обучения набора данных цветов на InceptionV1. Этот код предоставляется здесь

import os

from datasets import flowers
from nets import inception
from preprocessing import inception_preprocessing

slim = tf.contrib.slim
image_size = inception.inception_v1.default_image_size


def get_init_fn():
    """Returns a function run by the chief worker to warm-start the training."""
    checkpoint_exclude_scopes=["InceptionV1/Logits", "InceptionV1/AuxLogits"]

exclusions = [scope.strip() for scope in checkpoint_exclude_scopes]

variables_to_restore = []
for var in slim.get_model_variables():
    excluded = False
    for exclusion in exclusions:
        if var.op.name.startswith(exclusion):
            excluded = True
            break
    if not excluded:
        variables_to_restore.append(var)

return slim.assign_from_checkpoint_fn(
  os.path.join(checkpoints_dir, 'inception_v1.ckpt'),
  variables_to_restore)


train_dir = '/tmp/inception_finetuned/'

with tf.Graph().as_default():
    tf.logging.set_verbosity(tf.logging.INFO)

dataset = flowers.get_split('train', flowers_data_dir)
images, _, labels = load_batch(dataset, height=image_size, width=image_size)

# Create the model, use the default arg scope to configure the batch norm parameters.
with slim.arg_scope(inception.inception_v1_arg_scope()):
    logits, _ = inception.inception_v1(images, num_classes=dataset.num_classes, is_training=True)

# Specify the loss function:
one_hot_labels = slim.one_hot_encoding(labels, dataset.num_classes)
slim.losses.softmax_cross_entropy(logits, one_hot_labels)
total_loss = slim.losses.get_total_loss()

# Create some summaries to visualize the training process:
tf.scalar_summary('losses/Total Loss', total_loss)

# Specify the optimizer and create the train op:
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_op = slim.learning.create_train_op(total_loss, optimizer)

# Run the training:
final_loss = slim.learning.train(
    train_op,
    logdir=train_dir,
    init_fn=get_init_fn(),
    number_of_steps=2)



print('Finished training. Last batch loss %f' % final_loss)

Я оценил модель, используя следующий код и получил точность 58,34%

import numpy as np
import tensorflow as tf
from datasets import flowers
from nets import inception

slim = tf.contrib.slim

image_size = inception.inception_v1.default_image_size
batch_size = 3

with tf.Graph().as_default():
    tf.logging.set_verbosity(tf.logging.INFO)

    dataset = flowers.get_split('train', flowers_data_dir)
    images, images_raw, labels = load_batch(dataset, height=image_size, width=image_size)

# Create the model, use the default arg scope to configure the batch norm parameters.
with slim.arg_scope(inception.inception_v1_arg_scope()):
    logits, _ = inception.inception_v1(images, num_classes=dataset.num_classes, is_training=True)
    predictions = tf.argmax(logits, 1)


checkpoint_path = tf.train.latest_checkpoint(train_dir)
init_fn = slim.assign_from_checkpoint_fn(
  checkpoint_path,
  slim.get_variables_to_restore())

names_to_values, names_to_updates = slim.metrics.aggregate_metric_map({
    'eval/Accuracy': slim.metrics.streaming_accuracy(predictions, labels),
    'eval/Recall@5': slim.metrics.streaming_recall_at_k(logits, labels, 5),
})

# Define the streaming summaries to write:
for metric_name, metric_value in names_to_values.items():
    tf.summary.scalar(metric_name, metric_value)

print('Running evaluation Loop...')
# Load the most recent checkpoint of variables saved
checkpoint_path = tf.train.latest_checkpoint(train_dir)
# Evaluates the model at the given checkpoint path
metric_values = slim.evaluation.evaluate_once(
    master='',
    checkpoint_path=checkpoint_path,
    logdir=train_dir,
    num_evals=100,
    eval_op=list(names_to_updates.values()),
    final_op=list(names_to_values.values()),
    summary_op=tf.summary.merge_all())

names_to_values = dict(zip(names_to_values.keys(), metric_values))
for name in names_to_values:
    print('%s: %f' % (name, names_to_values[name]))

Помимо настройки контрольных точек и каталогов обучения, я только заменил "V1" в коде на "V2" и "V4" и обучил модель.

Во-первых, потери при обучении остаются постоянными как для "V2", так и для "V4", около 4% для всех 100 итераций. Во-вторых, точность оценки составляет около 25% для V2 и V4.

Я новичок в TF, так что я определенно что-то упускаю, что я делаю не так?

1 ответ

Есть много вещей, которые могут пойти не так при тонкой настройке довольно большой сверточной сети, такой как Inception V3. Вот несколько советов, которые вы могли бы изучить, чтобы улучшить свою модель:

  • Код обучения, который вы разместили выше, исключает InceptionV1/Logits а также InceptionV1/AuxLogits от загрузки в tf.Graph, Эти тензоры являются полностью связанными слоями сверху сверточного основания. По сути, это позволяет вам тренироваться самостоятельно InceptionV1/Logits а также InceptionV1/AuxLogits, Этот код, однако, не "замораживает" сверточную основу, что означает, что сверточные фильтры являются обучаемыми. Это плохая идея, потому что большие градиенты, вытекающие из случайно инициализированных полностью связанных слоев, могут разрушить изученные веса в сверточной основе. Это имеет более катастрофический эффект для больших сетей, что может объяснить, почему V2 и V4 работали хуже, чем V1. Вы можете прочитать больше о тонкой настройке сетей здесь.
  • Скорость обучения 0,01 кажется исключительно высокой для тонкой настройки сети. Обычно предварительно обученные модели изучают фильтры более низкого уровня, такие как обнаружение линий и краев, поэтому вам не нужно сильно изменять их вес. Скорость обучения <=0,001 будет достаточно.
  • Однако из того, что вы описали, модель, кажется, не сходится, потому что она застряла на 0,04 в течение 100 итераций, что предполагает увеличение скорости обучения. Я все еще не уверен в этом. Возможно, код является лишь примером и не должен быть адаптирован к другим моделям.

У Tensorflow есть более документированный раздел о тонкой настройке различных моделей здесь. Он также использует slim которая является более удобной и краткой оболочкой Tensorflow. Возможно, вы можете попробовать. Удачи.

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