Python 使用调整后的CNN教程对图像进行分类-系统会混淆输出
对不起,这是一个很长的 我80%确信问题在于我不完全理解Python 使用调整后的CNN教程对图像进行分类-系统会混淆输出,python,tensorflow,Python,Tensorflow,对不起,这是一个很长的 我80%确信问题在于我不完全理解tensorflow如何使用tf.train.batch函数对数据进行排队 我正在尝试改编一个tensorflow教程来对大量图像进行分类 教程可在此处找到: 我已经构建了一些模块,可以用cifar10使用的相同格式对原始数据进行编码。我用它来构建培训和评估数据,该计划能够评估到高度的准确性。精度取决于我输入的图像集的质量。为了简单起见,我使用32x32的黄色或蓝色单色瓷砖(分别为0类和1类)对其进行了培训。方便的是,网络能够以100%的准
tensorflow
如何使用tf.train.batch
函数对数据进行排队
我正在尝试改编一个tensorflow
教程来对大量图像进行分类
教程可在此处找到:
我已经构建了一些模块,可以用cifar10使用的相同格式对原始数据进行编码。我用它来构建培训和评估数据,该计划能够评估到高度的准确性。精度取决于我输入的图像集的质量。为了简单起见,我使用32x32的黄色或蓝色单色瓷砖(分别为0类和1类)对其进行了培训。方便的是,网络能够以100%的准确度识别它是被给予黄色还是蓝色瓷砖
我还能够调整cifar10_eval.py
以输出预测,而不是准确率。这允许我输入未分类的数据,并将预测输出为列表。为此,我交换了声明:
top\u k\u op=tf.nn.in\u top\k(logits,labels,1)
用于:
output_2=tf.argmax(logits,1)
我在eval_once函数调用中添加了一个变量和一个布尔值,以允许它访问“output_2”的定义,并根据我是否处于求值模式或是否预测新数据,在这和“top_k_op”之间切换
到目前为止还不错。这种方法适用于少量的输入数据,但一旦我想要输出128个以上的分类,它就会失败。批次大小并非巧合
理论上,二进制文件中的第一项(3073字节)应该对应于列表中的第一项,该列表是在我预测新数据时生成的。这种情况发生在最多128幅图像的输入上,但当我尝试对更多图像进行分类时,数据会变得混乱。事实上,有些预测完全失败了
发生这种情况有几个原因。本教程的设计目的并不是关注数据的读取或处理顺序,而是关注单个图像与其标签对应的顺序。最初数据丢失是随机的(!),但我通过删除多线程(threads=1而不是16)成功地删除了随机元素,并阻止了它洗牌文件名
filename\u queue=tf.train.string\u input\u producer(文件名,shuffle=False)
string_input_producer有一个隐藏/可选参数,用于洗牌文件名。对于模型评估,我已如上所述将其设置为false
然而。。。。在评估大于单个批次的数据时,我仍然会遇到混乱的数据丢失问题
有人知道为什么会发生这种情况,并且对如何修复它有什么想法吗
理论上,我可以重新设计代码来重建图形,并一次对128幅图像进行评估。然而,我想对数百万张图像进行分类,并觉得在尝试每批打开一个新的graph实例时会遇到麻烦
PS,我已经完成了我的家庭作业:
我已经通过运行一个程序验证了我的初始数据到二进制转换的工作原理,该程序可以读取cifar10样式的文件并将其解释为一大块图像。我已经在原始的cifar10二进制文件和我自己的二进制文件上运行了这段代码,并且能够完美地重建它们
当我对未分类的数据进行编码时,我会添加一个零的类别标签,以确保教程可以读取该文件。但是,我要确保这个标签在文件读取阶段被丢弃,因此在生成预测列表时不会使用
我已经验证了输出预测,将列表直接打印到屏幕上作为python输出,还使用它组装了一个PNG图像,可以与原始输入进行比较。这种验证对于小批量非常有效,并且在大批量中开始崩溃
我还对本帖中未讨论的教程进行了一些修改。这些都是简单的修改,例如将类别数更改为2而不是10。我相信这不是问题所在
PPS,这里是修改后的脚本中的一些函数的副本。我没有粘贴所有内容,因为这个问题已经很大了:
从cifar10\u评估:
def eval_once(saver, summary_writer, top_k_op, output_2, summary_op, mapping=False):
"""Run Eval once.
Args:
saver: Saver.
summary_writer: Summary writer.
top_k_op: Top K op.
summary_op: Summary op.
"""
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
if ckpt and ckpt.model_checkpoint_path:
# Restores from checkpoint
saver.restore(sess, ckpt.model_checkpoint_path)
# Assuming model_checkpoint_path looks something like:
# /my-favorite-path/cifar10_train/model.ckpt-0,
# extract global_step from it.
global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
else:
print('No checkpoint file found')
return
# Start the queue runners.
coord = tf.train.Coordinator()
try:
threads = []
for qr in tf.get_collection(tf.GraphKeys.QUEUE_RUNNERS):
threads.extend(qr.create_threads(sess, coord=coord, daemon=True,
start=True))
num_iter = int(math.ceil(FLAGS.num_examples / FLAGS.batch_size))
true_count = 0 # Counts the number of correct predictions.
total_sample_count = num_iter * FLAGS.batch_size
step = 0
output=[]
if mapping: # if in mapping mode generate a map, if in default mode (variable set to False by default) then tally predictions instead.
while step < num_iter and not coord.should_stop():
step += 1
hold = sess.run(output_2)
print(hold)
for i in range (len(hold)):
output.append(hold[i])
return(output)
从cifar10\u输入:
def inputs(mapping, data_dir, batch_size):
"""Construct input for CIFAR evaluation using the Reader ops.
Args:
mapping: bool, indicating if one should use the raw or pre-classified eval data set.
data_dir: Path to the CIFAR-10 data directory.
batch_size: Number of images per batch.
Returns:
images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
labels: Labels. 1D tensor of [batch_size] size.
"""
filelist = os.listdir(data_dir)
filenames = []
if mapping:
# from Raw_Image_Processor import file_name
for f in filelist:
if f.startswith("raw_batch"):
filenames.append(os.path.join(data_dir, f))
num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
else:
for f in filelist:
if f.startswith("eval_batch"):
filenames.append(os.path.join(data_dir, f))
num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_EVAL
for f in filenames:
if not tf.gfile.Exists(f):
raise ValueError('Failed to find file: ' + f)
# Create a queue that produces the filenames to read.
filename_queue = tf.train.string_input_producer(filenames, shuffle=False)
# Read examples from files in the filename queue.
read_input = read_cifar10(filename_queue)
reshaped_image = tf.cast(read_input.uint8image, tf.float32)
height = IMAGE_SIZE
width = IMAGE_SIZE
# Image processing for evaluation.
# Crop the central [height, width] of the image.
resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image,
height, width)
# Subtract off the mean and divide by the variance of the pixels.
float_image = tf.image.per_image_standardization(resized_image)
# Set the shapes of tensors.
float_image.set_shape([height, width, 3])
read_input.label.set_shape([1])
# Ensure that the random shuffling has good mixing properties.
min_fraction_of_examples_in_queue = 0.4
min_queue_examples = int(num_examples_per_epoch *
min_fraction_of_examples_in_queue)
# Generate a batch of images and labels by building up a queue of examples.
return _generate_image_and_label_batch(float_image, read_input.label,
min_queue_examples, batch_size,
shuffle=False)
def _generate_image_and_label_batch(image, label, min_queue_examples,
batch_size, shuffle):
"""Construct a queued batch of images and labels.
Args:
image: 3-D Tensor of [height, width, 3] of type.float32.
label: 1-D Tensor of type.int32
min_queue_examples: int32, minimum number of samples to retain
in the queue that provides of batches of examples.
batch_size: Number of images per batch.
shuffle: boolean indicating whether to use a shuffling queue.
Returns:
images: Images. 4D tensor of [batch_size, height, width, 3] size.
labels: Labels. 1D tensor of [batch_size] size.
"""
# Create a queue that shuffles the examples, and then
# read 'batch_size' images + labels from the example queue.
num_preprocess_threads = 16
if shuffle:
images, label_batch = tf.train.shuffle_batch(
[image, label],
batch_size=batch_size,
num_threads=num_preprocess_threads,
capacity=min_queue_examples + 3 * batch_size,
min_after_dequeue=min_queue_examples)
else:
images, label_batch = tf.train.batch(
[image, label],
batch_size=batch_size,
num_threads=1,
capacity=1,
enqueue_many = False)
# Display the training images in the visualizer.
tf.summary.image('images', images)
return images, tf.reshape(label_batch, [batch_size])
编辑:
下面的注释给出了部分解决方案。信息丢失取决于批大小,因此增加批大小(仅在映射模式下)是一种有效的修复方法
但是,我仍然不确定当超过批量大小时,它为什么会丢失和/或扰乱信息。可能批次是按某种非顺序进行的。我不需要它来推进项目,但如果有人能解释这是如何发生的或为什么发生的,我将不胜感激
编辑2:
它回来了!我已经将批量大小设置为相当于一个二进制文件(在我的例子中,大约是10000个图像)。在这个批处理中,数据不会丢失或混乱,但当我尝试处理多个文件(大约30个)时,它会稍微混合批处理,而不是以FIFO的方式输出它们
图片可能是您了解情况的最简单方式:
这是岩石表面的重建图像,从中分类器已被训练以识别三个类别。正如你所看到的,重建基本上是平滑的。但是,在图像顶部附近有两个干净的分隔符,其中一批(或3批)已按非时间顺序输出。这些症状应该出现在图像的底部,而不是顶部附近。我无法重现这些症状,但可能我在寻找错误的症状。我(正如您所提到的)在cfar10\u input.py的第131行设置
num\u threads=1
,并关闭文件名洗牌,每次运行python3 cifar10\u eval.py--eval\u interval\u secs=0时,我都会得到完全相同的损失--