0

我正在使用以下代码在 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”,并训练了模型。

首先,对于所有 100 次迭代,“V2”和“V4”的训练损失始终保持在 4% 左右。其次,“V2”和“V4”的评估准确率都在 25% 左右

我是 TF 的新手,所以这里肯定缺少一些东西,我做错了什么?

4

1 回答 1

1

在微调 Inception V3 等相当大的卷积网络时,可能会出现很多问题。以下是您可以考虑改进模型的一些建议:

  • 您在上面发布的培训代码不包括InceptionV1/LogitsandInceptionV1/AuxLogits被加载到tf.Graph. 这些张量是卷积基础之上的全连接层。从本质上讲,这使您可以训练自己的InceptionV1/LogitsInceptionV1/AuxLogits. 但是,此代码不会“冻结”卷积基数,这意味着卷积滤波器是可训练的。这是一个坏主意,因为从随机初始化的全连接层流出的大梯度可能会破坏卷积基中的学习权重。这对更大的网络具有更大的灾难性影响,这可以解释为什么 V2 和 V4 的表现比 V1 差。您可以在此处阅读有关微调网络的更多信息。
  • 对于微调网络,0.01 的学习率似乎异常高。通常,预先训练的模型会学习较低级别的过滤器,例如线条和边缘检测,因此您不想过多地改变它们的权重。<=0.001 的学习率就足够了。
  • 但是,根据您的描述,该模型似乎没有收敛,因为它在 100 次迭代中停留在 0.04,这表明需要提高学习率。我仍然不确定这一点。也许代码只是一个示例,不应该适用于其他模型。

Tensorflow 在此处有更多关于微调不同模型的文档部分。它还使用slim了对 Tensorflow 更友好、更简洁的封装。也许你可以试一试。祝你好运。

于 2017-03-24T07:04:10.910 回答