TensorFlow中tfrecord存储浮点数数组的精度陷阱与正确实现
本文探讨在TensorFlow中使用tfrecord存储浮点数数组时遇到的精度丢失问题。通过对比tobytes()二进制存储与直接序列化,揭示了二进制转换导致的精度损失,并提供了正确的代码实现,包括如何保存和读取浮点数组,确保数据完整性。
项目迁移背景与问题发现
近期,为了将脑部肿瘤分割项目从Caffe迁移至TensorFlow框架,我开始尝试新的技术栈。
在将数据存入Tfrecord文件的过程中,我遇到了模型不收敛以及精度无法提升的问题。
经过排查,根本原因在于数据存入tfrecord时使用了tobytes()函数将其转换为二进制格式。浮点数以二进制形式存储时,确实存在精度丢失的风险。
起初,面对精度不高的现象,我首先怀疑是精度丢失所致。在与他人交流时,对方认为不可能发生精度丢失,并建议我输出数据验证。当我实际输出查看后,发现数值看似未变,便暂时放弃了这一方向,转而寻找其他原因。然而,在多次尝试无果后,我重新审视了二进制转换这一环节,最终确认确实是转换为二进制导致了精度丢失。这个过程耗费了大量精力,甚至让我一度想要放弃。
此次经历带来的教训是:在与他人交流技术方案时,应保持理性。虽然可以参考他人的建议,但不能完全放弃自己的判断,因为没有人比你自己更了解你的项目细节。
tfrecord存储浮点数数组的正确实现
接下来,我将介绍如何将浮点数数组正确存入tfrecord文件中。如有疑问,欢迎在评论区留言讨论。
import tensorflow as tf
import numpy as np
def _floats_feature(value):
#这里的value=后面没有括号
#千万不要写成return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))
return tf.train.Feature(float_list=tf.train.FloatList(value=value))
# data you would like to save, dtype=float32
#这里我生成了一个浮点数数组,来假定作为我的数据
data = np.random.randn(shape=(5, 5))
#这里一定要铺平,不然存不进去
data = data.flatten()
# open tfrecord file
writer = tf.python_io.TFRecordWriter(train_data_path)
# make train example
example = tf.train.Example(features=tf.train.Features(
feature={'data': _floats_feature(data)}))
# write on the file
writer.write(example.SerializeToString())
以上是数据的存储过程。在下一步读取数据时,务必注意将展平后的数据重新reshape为原始形状,以恢复数据结构。
# open tfrecorder reader
reader = tf.TFRecordReader()
# read file
_, serialized_example = reader.read(filename_queue)
# read data
features = tf.parse_single_example(serialized_example,
features={'data': tf.VarLenFeature(tf.float32)})
# make it dense tensor
data = tf.sparse_tensor_to_dense(features['data'], default_value=0)
# reshape
data = tf.reshape(data, [5,5])
return tf.train.batch(data, batch_size, num_threads, capacity)
以上关于TensorFlow中tfrecord实现存储浮点数数组的内容到此结束,希望能为读者提供参考,并欢迎大家支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













