我对新数据集API(tensorflow 1.4rc1)有疑问.我有一个不平衡的数据集与标签0和1.我的目标是在预处理过程中创建平衡的迷你批次.
假设我有两个过滤的数据集:
ds_pos = dataset.filter(lambda l, x, y, z: tf.reshape(tf.equal(l, 1), []))
ds_neg = dataset.filter(lambda l, x, y, z: tf.reshape(tf.equal(l, 0), [])).repeat()
Run Code Online (Sandbox Code Playgroud)
有没有办法组合这两个数据集,使得结果数据集如下所示ds = [0, 1, 0, 1, 0, 1]:
像这样的东西:
dataset = tf.data.Dataset.zip((ds_pos, ds_neg))
dataset = dataset.apply(...)
# dataset looks like [0, 1, 0, 1, 0, 1, ...]
dataset = dataset.batch(20)
Run Code Online (Sandbox Code Playgroud)
我目前的做法是:
def _concat(x, y):
return tf.cond(tf.random_uniform(()) > 0.5, lambda: x, lambda: y)
dataset = tf.data.Dataset.zip((ds_pos, ds_neg))
dataset = dataset.map(_concat)
Run Code Online (Sandbox Code Playgroud)
但我觉得有一种更优雅的方式.
提前致谢!
TensorFlow 1.4将TF数据集移动到core(tf.data.Dataset),doc/tutorial建议tf.estimator用于训练模型.
但是,正如本页末尾所建议的那样,必须在input_fn函数内实例化数据集对象及其迭代器.这意味着每次调用都将重新开始数据集的迭代estimator.train(input_fn, steps).因此,调用步骤<在纪元中的样本数量,将导致在数据集的子集上训练模型.
因此我的问题.是否可以使用Estimator + Dataset实现类似的功能:
for i in range(num_epochs):
# Train for some steps
estimator.train(input_fn=train_input_fn, steps=valid_freq)
validation_iterator.
# Evaluate on the validation set (steps=None, we evaluate on the full validation set)
estimator.evaluate(input_fn=valid_input_fn)
Run Code Online (Sandbox Code Playgroud)
没有在每次调用时从头开始训练样本迭代estimator.train(input_fn=train_input_fn, steps=valid_freq)?
例如,与此处不同,实例化数据集及其迭代器input_fn?我尝试过,但它不工作,因为那么输入(从数据集迭代器)和模型(从估计model_fn)是不一样的图的一部分.
谢谢
相关的GitHub问题
TF Map功能支持并行调用.我看到没有改进传递num_parallel_calls给地图.使用num_parallel_calls=1和num_parallel_calls=10,性能运行时间没有改善.这是一个简单的代码
import time
def test_two_custom_function_parallelism(num_parallel_calls=1, batch=False,
batch_size=1, repeat=1, num_iterations=10):
tf.reset_default_graph()
start = time.time()
dataset_x = tf.data.Dataset.range(1000).map(lambda x: tf.py_func(
squarer, [x], [tf.int64]),
num_parallel_calls=num_parallel_calls).repeat(repeat)
if batch:
dataset_x = dataset_x.batch(batch_size)
dataset_y = tf.data.Dataset.range(1000).map(lambda x: tf.py_func(
squarer, [x], [tf.int64]), num_parallel_calls=num_parallel_calls).repeat(repeat)
if batch:
dataset_y = dataset_x.batch(batch_size)
X = dataset_x.make_one_shot_iterator().get_next()
Y = dataset_x.make_one_shot_iterator().get_next()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
i = 0
while True:
try:
res = sess.run([X, Y])
i += 1
if i == num_iterations:
break
except tf.errors.OutOfRangeError …Run Code Online (Sandbox Code Playgroud) 我通过读取TFRecords来创建数据集,我映射了值,我想过滤数据集中的特定值,但由于结果是带有张量的dict,我无法获得张量的实际值或检查它用tf.cond()/ tf.equal.我怎样才能做到这一点?
def mapping_func(serialized_example):
feature = { 'label': tf.FixedLenFeature([1], tf.string) }
features = tf.parse_single_example(serialized_example, features=feature)
return features
def filter_func(features):
# this doesn't work
#result = features['label'] == 'some_label_value'
# neither this
result = tf.reshape(tf.equal(features['label'], 'some_label_value'), [])
return result
def main():
file_names = ["/var/data/file1.tfrecord", "/var/data/file2.tfrecord"]
dataset = tf.contrib.data.TFRecordDataset(file_names)
dataset = dataset.map(mapping_func)
dataset = dataset.shuffle(buffer_size=10000)
dataset = dataset.filter(filter_func)
dataset = dataset.repeat()
iterator = dataset.make_one_shot_iterator()
sample = iterator.get_next()
Run Code Online (Sandbox Code Playgroud) 我发现Dataset.map()功能非常适合设置管道以预先处理图像/音频数据,然后再送入网络进行培训,但我遇到的一个问题是在预处理之前访问原始数据以发送到tensorboard作为摘要.
例如,假设我有一个加载音频数据的功能,做一些帧,制作频谱图,然后返回.
import tensorflow as tf
def load_audio_examples(label, path):
# loads audio, converts to spectorgram
pcm = ... # this is what I'd like to put into tf.summmary.audio() !
# creates one-hot encoded labels, etc
return labels, examples
# create dataset
training = tf.data.Dataset.from_tensor_slices((
tf.constant(labels),
tf.constant(paths)
))
training = training.map(load_audio_examples, num_parallel_calls=4)
# create ops for training
train_step = # ...
accuracy = # ...
# create iterator
iterator = training.repeat().make_one_shot_iterator()
next_element = iterator.get_next()
# ready session
sess = tf.InteractiveSession()
tf.global_variables_initializer().run() …Run Code Online (Sandbox Code Playgroud) python tensorflow tensorboard tensorflow-serving tensorflow-datasets
我正在使用自定义tf.Estimator对象来训练神经网络。问题在于培训后事件文件的大小-太大了。我已经通过使用解决了将一部分数据集保存为常量的问题tf.Dataset.from_generator()。但是,尺寸仍然很大,开始时tensorboard我收到消息
W0225 10:38:07.443567 140693578311424 tf_logging.py:120] Found more than one metagraph event per run. Overwriting the metagraph with the newest event.
因此,我想我正在此事件文件中创建并保存许多不同的图形。是否可以关闭此保存或仅保存第一份副本?
众所周知,我找到了删除所有默认日志的唯一方法,方法是删除带有
list(map(os.remove, glob.glob(os.path.join(runtime_params['model_dir'], 'events.out.tfevents*'))))
Run Code Online (Sandbox Code Playgroud)
但是,这对我来说是一个不好的解决方案,因为我希望保留摘要,最好保留图表的一个副本。
从文档中,我可以看到
估算器自动将以下内容写入磁盘:
python tensorflow tensorboard tensorflow-datasets tensorflow-estimator
我正在使用 tensorflow 2.0.0-beta1 和 python 3.7
首先考虑以下 tensor.numpy() 正常工作的代码:
import tensorflow as tf
import numpy as np
np.save('data.npy',np.ones(1024))
def func(mystr):
return np.load(mystr.numpy())
mystring = tf.constant('data.npy')
print(func(mystring))
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常并输出[1. 1. 1. ... 1. 1. 1.].
现在考虑以下 tensor.numpy() 不起作用的代码。
import tensorflow as tf
import numpy as np
np.save('data.npy',np.ones(1024))
def func(mystr):
return np.load(mystr.numpy())
mystring = tf.constant('data.npy')
data = tf.data.Dataset.from_tensor_slices([mystring])
data.map(func,1)
Run Code Online (Sandbox Code Playgroud)
上面的代码给出了以下错误 AttributeError: 'Tensor' object has no attribute 'numpy'
我无法弄清楚为什么 tensor.numpy() 在 tf.data.Dataset.map() 的情况下不起作用
编辑
以下段落阐明了我的目的:
我有一个数据集文件夹,其中包含数百万个数据对(图像、时间序列)。整个数据集不适合内存,所以我使用 tf.data.Dataset.map(func)。在 func() 函数中,我想加载一个包含时间序列的 numpy 文件并加载图像。为了加载图像,tensorflow 中有内置函数,如 …
当使用 TensorFlowtf.data.experimental.sample_from_datasets从两个非常不平衡的数据集中进行同等采样时,我最终收到了DirectedInterleave selected an exhausted input: 0警告。基于此 GitHub 问题,当其中的一个数据集sample_from_datasets已耗尽示例时,似乎会发生这种情况,并且需要对已经看到的示例进行采样。
耗尽的数据集是否仍然产生样本(从而保持所需的平衡训练比率),或者数据集是否没有采样,因此训练再次变得不平衡?如果是后者,是否有一种方法可以产生所需的平衡训练比率sample_from_datasets?
注意:正在使用 TensorFlow 2 Beta
在 TensorFlow 1.X 中,您可以使用占位符动态更改批次大小。例如
dataset.batch(batch_size=tf.placeholder())
查看完整示例
你如何在 TensorFlow 2.0 中做到这一点?
我已经尝试了以下但它不起作用。
import numpy as np
import tensorflow as tf
def new_gen_function():
for i in range(100):
yield np.ones(2).astype(np.float32)
batch_size = tf.Variable(5, trainable=False, dtype=tf.int64)
train_ds = tf.data.Dataset.from_generator(new_gen_function, output_types=(tf.float32)).batch(
batch_size=batch_size)
for data in train_ds:
print(data.shape[0])
batch_size.assign(10)
print(batch_size)
Run Code Online (Sandbox Code Playgroud)
输出
5
<tf.Variable 'Variable:0' shape=() dtype=int64, numpy=10>
5
<tf.Variable 'Variable:0' shape=() dtype=int64, numpy=10>
5
<tf.Variable 'Variable:0' shape=() dtype=int64, numpy=10>
5
...
...
Run Code Online (Sandbox Code Playgroud)
我正在使用 Gradient 磁带使用自定义训练循环训练模型。我怎样才能做到这一点?
我理解Dataset API是一种迭代器,它不会将整个数据集加载到内存中,因此无法找到数据集的大小.我正在谈论存储在文本文件或tfRecord文件中的大型数据语料库.通常使用tf.data.TextLineDataset或类似的东西来读取这些文件.找到使用的数据集加载大小是微不足道的tf.data.Dataset.from_tensor_slices.
我问数据集大小的原因如下:假设我的数据集大小为1000个元素.批量大小= 50个元素.然后训练步骤/批次(假设1个纪元)= 20.在这20个步骤中,我想将我的学习率从0.1到0.01指数衰减为
tf.train.exponential_decay(
learning_rate = 0.1,
global_step = global_step,
decay_steps = 20,
decay_rate = 0.1,
staircase=False,
name=None
)
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我有"和"想要设置decay_steps = number of steps/batches per epoch = num_elements/batch_size.仅当预先知道数据集中的元素数量时,才能计算此值.
另一个原因预先知道尺寸是将数据拆分为使用训练集和测试集tf.data.Dataset.take(),tf.data.Dataset.skip()方法.
PS:我不是在寻找蛮力方法,例如迭代整个数据集并更新计数器来计算元素数量或放置非常大的批量大小,然后查找结果数据集的大小等.