gpt4 book ai didi

python - 在 slim 的tensorflow和tf记录批处理中微调inceptionv3的问题

转载 作者:太空宇宙 更新时间:2023-11-03 13:56:30 25 4
gpt4 key购买 nike

我正在尝试使用苗条的tensorflow库微调inceptionv3模型。
在编写代码时,我无法理解某些事情。我尝试阅读源代码(没有适当的文档),并弄清了几件事,并且能够对其进行微调并保存检查点。这是我遵循的步骤
 1.我为训练数据创建了一个tf.record,这很好,现在我正在使用以下代码读取数据。

import tensorflow as tf
import tensorflow.contrib.slim.nets as nets
import tensorflow.contrib.slim as slim
import matplotlib.pyplot as plt
import numpy as np

# get the data and labels here

data_path = '/home/sfarkya/nvidia_challenge/datasets/detrac/train1.tfrecords'

# Training setting
num_epochs = 100
initial_learning_rate = 0.0002
learning_rate_decay_factor = 0.7
num_epochs_before_decay = 5
num_classes = 5980

# load the checkpoint
model_path = '/home/sfarkya/nvidia_challenge/datasets/detrac/inception_v3.ckpt'

# log directory
log_dir = '/home/sfarkya/nvidia_challenge/datasets/detrac/fine_tuned_model'

with tf.Session() as sess:
feature = {'train/image': tf.FixedLenFeature([], tf.string),
'train/label': tf.FixedLenFeature([], tf.int64)}

# Create a list of filenames and pass it to a queue
filename_queue = tf.train.string_input_producer([data_path], num_epochs=1)

# Define a reader and read the next record
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)

# Decode the record read by the reader
features = tf.parse_single_example(serialized_example, features=feature)

# Convert the image data from string back to the numbers
image = tf.decode_raw(features['train/image'], tf.float32)

# Cast label data into int32
label = tf.cast(features['train/label'], tf.int32)

# Reshape image data into the original shape
image = tf.reshape(image, [128, 128, 3])

# Creates batches by randomly shuffling tensors
images, labels = tf.train.shuffle_batch([image, label], batch_size=64, capacity=128, num_threads=2,
min_after_dequeue=64)


现在,我使用苗条微调模型,这是代码。

  init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)

# Create a coordinator and run all QueueRunner objects
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)

# load model

# load the inception model from the slim library - we are using inception v3
#inputL = tf.placeholder(tf.float32, (64, 128, 128, 3))

img, lbl = sess.run([images, labels])
one_hot_labels = slim.one_hot_encoding(lbl, num_classes)

with slim.arg_scope(slim.nets.inception.inception_v3_arg_scope()):
logits, inceptionv3 = nets.inception.inception_v3(inputs=img, num_classes=5980, is_training=True,
dropout_keep_prob=.6)

# Restore convolutional layers:

variables_to_restore = slim.get_variables_to_restore(exclude=['InceptionV3/Logits', 'InceptionV3/AuxLogits'])
init_fn = slim.assign_from_checkpoint_fn(model_path, variables_to_restore)

# loss function
loss = tf.losses.softmax_cross_entropy(onehot_labels=one_hot_labels, logits = logits)
total_loss = tf.losses.get_total_loss()

# train operation
train_op = slim.learning.create_train_op(total_loss + loss, optimizer= tf.train.AdamOptimizer(learning_rate=1e-4))

print('Im here')
# Start training.
slim.learning.train(train_op, log_dir, init_fn=init_fn, save_interval_secs=20, number_of_steps= 10)


现在,我对代码有几个疑问,我完全无法弄清楚。一旦代码到达slim.learning.train,我什么都看不到,但是正在训练,我可以在日志中看到。现在,
1.如何给代码赋予新纪元?现在它正在逐步运行,每个步骤的batch_size = 64。
2.如何确保在代码tf.train.shuffle_batch中我没有重复图像,而是在整个数据集中进行训练?
3.在训练过程中如何打印损失值?

最佳答案

这是您问题的答案。


您不能将纪元直接赋予slim.learning.train。相反,您将批次数作为参数。它称为number_of_steps。它用于在line 709上设置名为should_stop_op的操作。我假设您知道如何将纪元数转换为批次。
我不认为shuffle_batch函数会重复图像,因为它内部使用了RandomShuffleQueue。根据this answerRandomShuffleQueue使用后台线程将元素排入队列:


size(queue) < capacity时:


向队列添加元素




它使元素出队:


number of elements dequeued < batch_size


等待直到size(queue) >= min_after_dequeue + 1元素。
从队列中均匀地随机选择一个元素,将其从队列中删除,然后将其添加为输出批次。



因此,我认为重复元素的可能性很小,因为在dequeuing操作中,所选元素将从队列中删除。因此,它是采样而无需更换。

是否会为每个时期创建一个新的队列?

输入到tf.train.shuffle_batch的张量是imagelabel,它们最终来自filename_queue。如果该队列无限期地产生TFRecord文件名,那么我认为shuffle_batch不会创建新队列。您也可以创建玩具代码,例如this,以了解shuffle_batch的工作方式。

接下来,如何训练整个数据集?在您的代码中,以下行获取TFRecord文件名的列表。

filename_queue = tf.train.string_input_producer([data_path], num_epochs=1)


如果 filename_queue涵盖了您拥有的所有TFRecords,那么您肯定在训练整个数据集。现在,如何重新整理整个数据集是另一个问题。正如@mrry提到的 here一样,尚无支持(尚未使用AFAIK)对内存不足的数据集进行混洗。因此,最好的方法是准备数据集中的许多分片,以使每个分片包含约1024个示例。将TFRecord文件名列表按以下顺序随机排列:

filename_queue = tf.train.string_input_producer([data_path], shuffle=True, capacity=1000)


请注意,我删除了 num_epochs = 1参数并设置了 shuffle=True。这样,它将无限期地产生TFRecord文件名的改组列表。现在,在每个文件上,如果使用 tf.train.shuffle_batch,则将获得接近均匀的混排。基本上,随着每个分片中的示例数趋于1,您的混洗将变得越来越统一。我不想设置 num_epochs,而是使用前面提到的 number_of_steps参数终止训练。


要打印损失值,您可能只需编辑 training.py并引入 logging.info('total loss = %f', total_loss)。我不知道有没有更简单的方法。无需更改代码的另一种方法是在Tensorboard中查看摘要。


关于如何在Tensorboard中查看摘要的文章非常有用,包括此答案末尾的链接。通常,您需要执行以下操作。


创建 summary对象。
将感兴趣的变量写入 summary
合并所有单独的摘要。
创建一个 summary操作。
创建一个摘要文件编写器。
在整个训练过程中,以所需的频率写下摘要。


现在,如果您使用 slim.learning.train,则步骤5和6已自动为您完成。

对于前4个步骤,您可以检查文件 train_image_classifier.py。 472行显示了如何创建 summaries对象。第490、512和536行将相关变量写入 summaries。第549行合并所有摘要,第553行创建op。您可以将此操作传递给 slim.learning.train,还可以指定要编写摘要的频率。我认为,除非要进行特定的调试,否则不要在摘要中写任何内容,包括损失,total_loss,准确性和学习率。如果您编写直方图,那么对于ResNet-50之类的网络,张量板文件可能需要数十小时才能加载(我的张量板文件曾经是28 GB,要花12个小时才能加载6天的进度!)。顺便说一句,您实际上可以使用 train_image_classifier.py文件进行微调,您将跳过上面的大多数步骤。但是,我喜欢这样做,因为您可以学到很多东西。

有关如何在浏览器中查看进度的信息,请参见 launching tensorboard部分。

附加说明:


除了最小化 total_loss + loss,您可以执行以下操作:

loss = tf.losses.softmax_cross_entropy(onehot_labels=one_hot_labels, logits = logits)
tf.losses.add_loss(loss)
total_loss = tf.losses.get_total_loss()
train_op = slim.learning.create_train_op(total_loss, optimizer=tf.train.AdamOptimizer(learning_rate=1e-4))

我在学习Tensorflow时发现 this帖子非常有用。

关于python - 在 slim 的tensorflow和tf记录批处理中微调inceptionv3的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49564318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com