我正在尝试为Tensorflow构建一个有点复杂的输入管道。 该数据集由257天的图像组成,每天有大约5000张图像(图像大约每8秒拍摄一次并按时间顺序排列)。 它们以jpeg编码。我需要能够在每天内按顺序(暂时)访问它们。但是,我还需要能够创建洗牌批次(在几天内和一天内随机化)。此外,一个样本可能包含2或3个连续图像,分别带有最后一个图像的标签。另外,我应该能够在一个样本中的图像之间添加步幅或填充(例如,我有一个由2个图像组成的样本,相隔16秒而不是8个)
我的第一个方法是用解码的图像和标签(由23个float32组成)创建TFRecord文件。当然,这会使内存需求大约增加600GB。
现在我为每天创建了TFRecord文件(257)。它们将图像的路径及其标签(path,label1 .. label23)编码。在一个TFRecord文件中,日期按顺序编码,从上午6:30:00到下午18:00:00左右。
下面您将看到我当前的(简化)解决方案。我正在使用数据读取器(TFRecordReader)和队列运行器。我设法按顺序(当不使用batch_shuffle时)和随机(当使用batch_shuffle时)加载批量图像及其各自的标签。
但是我遇到以下问题:
问题:
我如何阅读每个样本两个连续图像?我应该只调用两次tfreader.read函数吗?是否可以保证读取下一张图像(按时间顺序保存在tfrecords文件中,如上所述)或者是否会因多个队列运行器而出现问题?最后我想要批次(Tensor(image_06:30:00,image_06:30:08),Tensor(image_06:30:08的标签))
如何确保tf.train.string_input_producer随机切换输入列表中的不同TFRecord文件?在创建样本时保留图像的顺序。例如,当我想为一个样本读取2个图像时,应该从同一天读取(相同的tfrecords文件)
如何添加大于1的步幅?基本上我想在一个样本中包含每个第二或第三个图像。例如:(Tensor(image_06:30:00,image_06:30:16),Tensor(image_06:30:16的标签))而不是image_06:30:08
如何处理超出内存使用量的问题?我应该在使用时解码图像,而不是使用解码的图像张量创建大样本,然后将它们放入队列中?所以基本上我创建的批量样本只包含图像和标签的路径。然后我在训练/评估时解码图像
当前解决方案(简化,不编译!):
IMAGE_HEIGHT=1566
IMAGE_WIDTH=1566
IMAGE_CHANNELS=3
def decode_single_tfrecord(filename_queue,feature_dict,name):
tfreader = tf.TFRecordReader()
key,serialized_value = tfreader.read(filename_queue,name=name)
features = tf.parse_single_example(serialized_value,features=feature_dict)
return key,features
def get_example(decoded_features,feature_list,img_path_key='image_path'):
labels = list()
for feature in feature_list:
labels.append(decoded_features[feature])
label_tensor = tf.stack(labels)
image_path = decoded_features[img_path_key]
with tf.name_scope('decode_image',[image_path],None):
image_file = tf.read_file(image_path)
image_file = tf.image.decode_jpeg(image_file,channels=IMAGE_CHANNELS)
image_tensor = tf.reshape(image_file,(IMAGE_HEIGHT,IMAGE_WIDTH,IMAGE_CHANNELS))
return image_tensor,label_tensor
#############################
#Encodes the label key in the tfrecord file
feature_list=['VF','IRR0','IRR1','IRR2','IRR3','IRR4','IRR5','IRR6','IRR7','IRR8','IRR9',/
'IRR10','MPC0','MPC1','MPC2','MPC3','MPC4','MPC5','MPC6','MPC7','MPC8','MPC9','MPC10']
features={}
for f in feature_list:
features[f] = tf.FixedLenFeature([], tf.float32)
#Path to image in tfrecord file
features['image_path'] = tf.FixedLenFeature([], tf.string)
#GRAPH#######################
filename_queue = tf.train.string_input_producer(["paths to tfrecords"])
tf_key,decoded_f = decode_single_tfrecord(filename_queue,features, name="tf_records_reader")
image,label = get_example(decoded_f,feature_list)
#simply calls tf.train.shuffle_batch([image,label],..)
imageBatch,labelBatch = create_shuffled_data_batch(image,label,)
init_op = tf.group(tf.global_variables_initializer(),tf.local_variables_initializer())
with tf.Session() as sess:
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range(100):
f,l = sess.run([imageBatch,labelBatch])
coord.request_stop()
coord.join(threads)