我正在基于这个用于噪声抑制的代码构建模型。原版实现的问题在于它一次性加载所有数据,这在训练数据非常大时并不是一个好主意;我在链接代码中标记为training.h5
的输入文件超过30 GB。
我决定改用tf.data
接口,这应该能让我处理大型数据集;我的问题在于我不知道如何正确调整TFRecordDataset
以满足模型API的要求。
如果你查看model.fit(x_train, [y_train, vad_train]
,它本质上需要以下内容:
- x_train,形状为
[nb_sequences, window, 42]
- y_train,形状为
[nb_sequences, window, 22]
- vad_train,形状为
[nb_sequences, window, 1]
window
通常是固定的(在代码中为2000
),所以唯一变量nb_sequences
取决于你的数据集大小。然而,使用tf.data
时,我们不提供x
和y
,而只提供x
(参见模型API文档)。
将tfrecord保存到文件
为了使代码可重现,我使用以下代码创建了输入文件:
writer = tf.io.TFRecordWriter(path='example.tfrecord')for record in data: feature = {} feature['X'] = tf.train.Feature(float_list=tf.train.FloatList(value=record[:42])) feature['y'] = tf.train.Feature(float_list=tf.train.FloatList(value=record[42:64])) feature['vad'] = tf.train.Feature(float_list=tf.train.FloatList(value=[record[64]])) example = tf.train.Example(features=tf.train.Features(feature=feature)) serialized = example.SerializeToString() writer.write(serialized)writer.close()
data
是我们的训练数据,形状为[10000, 65]
。我的example.tfrecord
文件可以在这里找到。它大小为3 MB,实际上它会超过30 GB。
你可能会注意到,在链接的代码中,numpy数组的形状是[x, 87]
,而我的则是[x, 65]
。这没问题——剩余部分在任何地方都没有使用。
使用tf.data.TFRecordDataset加载数据集
我想使用tf.data
按需加载数据,并进行一些预取,没有必要将所有数据都保存在内存中。我的尝试如下:
我的数据集现在具有以下形状:
<MapDataset shapes: ((42,), ((22,), (1,))), types: (tf.float32, (tf.float32, tf.float32))>
我以为这是模型API所期望的(剧透:并不是)。
model.fit(dataset.batch(10))
会产生以下错误:
ValueError: Error when checking input: expected main_input to have 3 dimensions, but got array with shape (None, 42)
这是有道理的,我这里没有window
参数。同时,看起来它并没有得到Model(inputs=main_input, outputs=[denoise_output, vad_output])
所期望的正确形状。
如何修改load_dataset
以符合tf.data
所需的模型API格式?
回答: