Python 3.x Tensorflow:使用带有自定义估计器的CSV文件队列和;输入“fn”;作用
我花了很长时间(很多小时)寻找问题的正确答案,但没有结果,所以我来了。我想我遗漏了一些明显的东西,但我不知道 问题:使用队列读取CSV文件,并使用输入对估计器进行训练,而每次都不重新加载图形(这非常慢)Python 3.x Tensorflow:使用带有自定义估计器的CSV文件队列和;输入“fn”;作用,python-3.x,csv,machine-learning,tensorflow,Python 3.x,Csv,Machine Learning,Tensorflow,我花了很长时间(很多小时)寻找问题的正确答案,但没有结果,所以我来了。我想我遗漏了一些明显的东西,但我不知道 问题:使用队列读取CSV文件,并使用输入对估计器进行训练,而每次都不重新加载图形(这非常慢) 我创建了一个自定义模型,该模型为我提供了一个模型函数,用于创建我自己的估计器: tf.estimator.Estimator(model_fn=model_fn, params=model_params) batch_size = 4 shuffle_size = 10000 feature
我创建了一个自定义模型,该模型为我提供了一个模型函数,用于创建我自己的估计器:
tf.estimator.Estimator(model_fn=model_fn, params=model_params)
batch_size = 4
shuffle_size = 10000
features, labels = input_fn()
with tf.Session() as sess:
f_data, l_data = sess.run([features, labels])
print(f_data, l_data)
之后,我需要读取一个非常大的CSV文件(无法在内存中加载),因此我决定使用队列(似乎是最好的解决方案):
我认为这个代码是可以的
然后,主代码:
with tf.Session() as sess:
tf.logging.set_verbosity(tf.logging.INFO)
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
# Return a Tensor of 1000 features/labels
def get_inputs():
print("input call !")
xs = []
ys = []
for i in range(1000):
x, y = sess.run([features, label])
xs.append(x)
ys.append(y)
return tf.constant(np.asarray(xs), dtype=tf.float32), tf.constant(np.asarray(ys))
estimator.train(input_fn=get_inputs,
steps=100)
coord.request_stop()
coord.join(threads)
正如你所看到的,这里有很多丑陋的东西 我想要的:我想要训练功能在每个步骤中使用新的一批功能。但在这里,它在100个步骤中使用了同一批1000个特性,因为get_inputs函数只是在我们开始训练时调用的。有没有一个简单的方法可以做到这一点 我尝试使用step=1循环estimator.train,但每次都会重新加载图形,速度会非常慢 我不知道现在该怎么办,也不知道这是否可能
谢谢你帮助我 简短版本:将CSV文件转换为
tfrecords
,然后使用tf.contrib.data.TFRecordDataset
。长版:见代码见问题/公认答案(为方便起见,复制如下)
查看API。我想您最好将CSV转换为TfRecord文件并使用TfRecordDataset。这里有一个完整的教程 步骤1:将csv数据转换为tfrecords数据。下面是示例代码
import tensorflow as tf
def read_csv(filename):
with open(filename, 'r') as f:
out = [line.rstrip().split(',') for line in f.readlines()]
return out
csv = read_csv('data.csv')
with tf.python_io.TFRecordWriter("data.tfrecords") as writer:
for row in csv:
features, label = row[:-1], row[-1]
features = [float(f) for f in features]
label = int(label)
example = tf.train.Example()
example.features.feature[
"features"].float_list.value.extend(features)
example.features.feature[
"label"].int64_list.value.append(label)
writer.write(example.SerializeToString())
这假设最后一列中的标签是整数,前面的列中有浮点特征。这只需要运行一次
第2步:编写数据集并解码这些记录文件
def parse_function(example_proto):
features = {
'features': tf.FixedLenFeature((n_features,), tf.float32),
'label': tf.FixedLenFeature((), tf.int64)
}
parsed_features = tf.parse_single_example(example_proto, features)
return parsed_features['features'], parsed_features['label']
def input_fn():
dataset = tf.contrib.data.TFRecordDataset(['data.tfrecords'])
dataset = dataset.map(parse_function)
dataset = dataset.shuffle(shuffle_size)
dataset = dataset.repeat() # repeat indefinitely
dataset = dataset.batch(batch_size)
print(dataset.output_shapes)
features, label = dataset.make_one_shot_iterator().get_next()
return features, label
测试(独立于估计器):
用于tf.estimator.estimator:
estimator.train(input_fn, max_steps=1e7)
如果您担心没有调用
tf.train.start\u queue\u runner
,请尝试以下操作:
class ThreadStartHook(tf.train.SessionRunHook):
def after_create_session(self, session, coord):
self.coord = coord
self.threads = tf.train.start_queue_runners(coord=coord, sess=session)
def end(self, session):
self.coord.request_stop()
self.coord.join(self.threads)
estimator.train(input_fn, [ThreadStartHook()])
刚开始的时候我也有类似的想法,但我觉得没必要这样做。嗨,谢谢你的回答。我已经看到了你的帖子,但是这个解决方案需要将CSV转换为TFRecord,我想知道我们是否不能避免使用队列和批处理功能。你可以。。。但我相当肯定这就是数据集在幕后所做的一切。您可以在训练时直接从csv读取并解析字符串数据,但速度会慢一些。据我所知,TFR记录的唯一缺点是它们会占用额外的空间。这真的令人担忧吗?如果你正在加载图像,你可以将路径保存在tfrecords中,然后像平常一样从文件中读取。不,在TFrecord中复制并不重要,这只是为了我个人的知识(因为我在这个问题上浪费了很多时间哈哈)。你有没有想过不用转换就从CSV开始呢?对于您的解决方案,所有数据集都不会加载到内存中?只是当前批次,对吗?我明天会试试这个。这肯定是个办法,但我很怀疑这是不是最好的办法。我花了很长时间尝试制作一个数据管道,它以我想要的方式工作,直到我意识到在更大的团队中有更聪明的人做得更好,并考虑具有更多通用性的边缘案例:)。此外,还有比数据更有趣的问题。看,你赢了。我也很厌倦这个。再次感谢:)好的!我认为这个代码解决了这个问题。但是另一个出现了。。。(否则就不好玩了是的)。“传递的张量(“稀疏\软最大\交叉\熵\损失/值:0”,shape=(),dtype=float32)应具有与当前图形相等的图形属性”。我现在会调查这个错误。好的,我更了解。。。事实上,我们需要在tf.train.batch之后调用“start\u queue\u runners”,实习生队列将不会启动!(已测试并批准)
class ThreadStartHook(tf.train.SessionRunHook):
def after_create_session(self, session, coord):
self.coord = coord
self.threads = tf.train.start_queue_runners(coord=coord, sess=session)
def end(self, session):
self.coord.request_stop()
self.coord.join(self.threads)
estimator.train(input_fn, [ThreadStartHook()])