关于从 tfrecords 读取数据时的形状
About shapes when reading data from tfrecords
我要从 tfrecords 读取 'image'(2000) 和 'landmarks'(388)。
这是代码的一部分。
filename_queue = tf.train.string_input_producer([savepath])
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example, features={'label': tf.FixedLenFeature([], tf.string), 'img_raw':tf.FixedLenFeature([], tf.string), })
image = tf.decode_raw(features['img_raw'], tf.uint8)
image = tf.reshape(image, [224, 224, 3])
image = tf.cast(image, tf.float32)
label = tf.decode_raw(features['label'], tf.float64) # problem is here
label = tf.cast(label, tf.float32)
label = tf.reshape(label, [388])
错误是
InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 291 values, but the requested shape has 388.
当我将 'float64' 更改为 'float32' 时:
label = tf.decode_raw(features['label'], tf.float32) # problem is here
#Error: InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 582 values, but the requested shape has 388
或 'float16':
label = tf.decode_raw(features['label'], tf.float16) # problem is here
#Error: InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 1164 values, but the requested shape has 388
下面是我制作 tfrecords 的方法:(为了简单起见,我简化了一些代码)
writer = tf.python_io.TFRecordWriter(savepath)
for i in range(number_of_images):
img = Image.open(ImagePath[i]) # load one image from path
landmark = landmark_read_from_csv[i] # shape of landmark_read_from_csv is (number_of_images, 388)
example = tf.train.Example(features=tf.train.Features(feature={
"label": tf.train.Feature(bytes_list=tf.train.BytesList(value=[landmark.tobytes()])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img.tobytes()]))}))
writer.write(example.SerializeToString())
writer.close()
我有 3 个问题:
- 为什么更改数据类型后形状会发生变化?
- 如何选择合适的数据类型? (因为有时我可以使用 'tf.float64' 成功解码图像,但有时 'tf.uint8' 使用不同的数据集)
- 创建tfrecords的代码有问题吗?
我最近遇到了一个非常相似的问题,根据我的个人经验,我非常有信心能够推断出您所问内容的答案,即使我不是 100% 确定。
列表项的形状发生变化,因为不同的数据类型在编码为 byte
列表时具有不同的长度,并且由于 float16
的长度是 float32
的一半相同的字节列表可以读取为 n float32
个值的序列,也可以读取为 float16
个值的两倍。换句话说,当您更改数据类型时,您尝试解码的 byte
列表不会改变,但改变的是您对该数组列表所做的分区。
您应该检查用于生成 tfrecord
文件的数据的数据类型,并在读取时使用相同的数据类型解码 byte_list(您可以使用 .dtype 属性检查 numpy 数组的数据类型)。
None 我能看到,但我可能错了。
我要从 tfrecords 读取 'image'(2000) 和 'landmarks'(388)。
这是代码的一部分。
filename_queue = tf.train.string_input_producer([savepath])
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example, features={'label': tf.FixedLenFeature([], tf.string), 'img_raw':tf.FixedLenFeature([], tf.string), })
image = tf.decode_raw(features['img_raw'], tf.uint8)
image = tf.reshape(image, [224, 224, 3])
image = tf.cast(image, tf.float32)
label = tf.decode_raw(features['label'], tf.float64) # problem is here
label = tf.cast(label, tf.float32)
label = tf.reshape(label, [388])
错误是
InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 291 values, but the requested shape has 388.
当我将 'float64' 更改为 'float32' 时:
label = tf.decode_raw(features['label'], tf.float32) # problem is here
#Error: InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 582 values, but the requested shape has 388
或 'float16':
label = tf.decode_raw(features['label'], tf.float16) # problem is here
#Error: InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 1164 values, but the requested shape has 388
下面是我制作 tfrecords 的方法:(为了简单起见,我简化了一些代码)
writer = tf.python_io.TFRecordWriter(savepath)
for i in range(number_of_images):
img = Image.open(ImagePath[i]) # load one image from path
landmark = landmark_read_from_csv[i] # shape of landmark_read_from_csv is (number_of_images, 388)
example = tf.train.Example(features=tf.train.Features(feature={
"label": tf.train.Feature(bytes_list=tf.train.BytesList(value=[landmark.tobytes()])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img.tobytes()]))}))
writer.write(example.SerializeToString())
writer.close()
我有 3 个问题:
- 为什么更改数据类型后形状会发生变化?
- 如何选择合适的数据类型? (因为有时我可以使用 'tf.float64' 成功解码图像,但有时 'tf.uint8' 使用不同的数据集)
- 创建tfrecords的代码有问题吗?
我最近遇到了一个非常相似的问题,根据我的个人经验,我非常有信心能够推断出您所问内容的答案,即使我不是 100% 确定。
列表项的形状发生变化,因为不同的数据类型在编码为
byte
列表时具有不同的长度,并且由于float16
的长度是float32
的一半相同的字节列表可以读取为 nfloat32
个值的序列,也可以读取为float16
个值的两倍。换句话说,当您更改数据类型时,您尝试解码的byte
列表不会改变,但改变的是您对该数组列表所做的分区。您应该检查用于生成
tfrecord
文件的数据的数据类型,并在读取时使用相同的数据类型解码 byte_list(您可以使用 .dtype 属性检查 numpy 数组的数据类型)。None 我能看到,但我可能错了。