Python slim tensorflow和tf记录批次中微调接收v3的问题
我正在尝试使用slim tensorflow库微调inceptionv3模型。 在为它编写代码时,我无法理解某些事情。我试着阅读源代码(没有合适的文档),并想出了一些事情,我能够微调它并保存检查点。以下是我遵循的步骤 1.我为我的训练数据创建了一个tf.record,这很好,现在我正在使用下面的代码读取数据Python slim tensorflow和tf记录批次中微调接收v3的问题,python,tensorflow,deep-learning,tf-slim,tfrecord,Python,Tensorflow,Deep Learning,Tf Slim,Tfrecord,我正在尝试使用slim tensorflow库微调inceptionv3模型。 在为它编写代码时,我无法理解某些事情。我试着阅读源代码(没有合适的文档),并想出了一些事情,我能够微调它并保存检查点。以下是我遵循的步骤 1.我为我的训练数据创建了一个tf.record,这很好,现在我正在使用下面的代码读取数据 import tensorflow as tf import tensorflow.contrib.slim.nets as nets import tensorflow.contrib.s
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)
现在,我正在使用slim对模型进行微调,下面是代码
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.我如何给代码提供纪元数?现在,它正在一步一步地运行,每个步骤的批处理大小为64。2.如何确保在代码tf.train.shuffle\u batch中,我没有重复我的图像,而是在整个数据集上进行训练?
3.如何在培训过程中打印损失值?以下是您问题的答案
slim.learning.train
提供纪元。相反,您将批数作为参数。它被称为步数
。它用于设置名为“应停止”的操作。我假设您知道如何将历代数转换为批次shuffle\u batch
函数不会重复图像,因为它在内部使用。根据,randomsufflequeue
使用后台线程将元素排队,如下所示:
- 而
:大小(队列)
- 将元素添加到队列中
- 退出队列的
:元素数
- 等待
元素size(queue)>=min\u-after\u-dequeue+1
- 从队列中随机均匀地选择一个元素,将其从队列中删除,然后将其添加到输出批中
- 等待
出列操作中,所选元素从队列中移除。因此,它是抽样而不更换的
是否会为每个历元创建一个新队列?
输入到tf.train.shuffle\u batch
的张量是image
和label
,它们最终来自filename\u队列
。如果该队列无限期地生成TFRecord文件名,那么我认为shuffle\u batch
不会创建新的队列。您还可以创建一个玩具代码,如了解shuffle\u batch
的工作原理
接下来,如何对整个数据集进行训练?在代码中,下一行获取TFRecord文件名的列表
filename_queue = tf.train.string_input_producer([data_path], num_epochs=1)
如果filename\u queue
覆盖了您拥有的所有TFR记录,那么您肯定是在整个数据集上进行训练。现在,如何洗牌整个数据集是另一个问题。正如@mrry所提到的,目前还不支持(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\u batch
,您将得到一个近乎统一的洗牌。基本上,当每个碎片中的示例数趋于1时,您的洗牌将变得越来越一致。我不喜欢设置num_epochs
,而是使用前面提到的number_of_steps
参数终止训练
要打印损失值,您可能只需编辑并引入logging.info('total loss=%f',total_loss)
。我不知道有没有更简单的方法。另一种不改变代码的方法是在Tensorboard中查看摘要
关于如何在Tensorboard中查看摘要,有很多非常有用的文章,包括本答案末尾的链接。一般来说,你需要做以下事情
创建摘要
对象
将感兴趣的变量写入摘要
合并所有单独的摘要
创建一个摘要
op
创建摘要文件编写器
在整个培训过程中,以所需的频率编写总结
现在,如果您使用slim.learning.train
,步骤5和6已经自动完成
对于前4个步骤,您可以检查文件。第472行显示了如何创建摘要
对象。第490、512和536行将相关变量写入摘要中。第549行合并所有摘要,第553行创建一个op。您可以将此op传递给slim.learning.train
,还可以指定编写摘要的频率。在我看来,除了损失、总损失、准确性和学习率之外,不要在总结中写任何东西,除非你想做具体的调试。如果您编写直方图,那么对于ResNet-50这样的网络,tensorboard文件可能需要几十个小时才能加载(我的tensorboard文件曾经是28GB,加载6天的进度需要12个小时!)。顺便说一下,您实际上可以使用train\u image\u classifier.py
文件进行微调,您将跳过上面的大部分步骤。然而,我更喜欢这样,因为你可以学到很多东西
请参见有关如何在浏览器中查看进度的部分
附加备注:
- 您可以执行以下操作,而不是最小化总损失+损失
:
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))
我找到了p