这看起来像是架构上的问题。首先,您正在动态生成数据,尽管这是一种常用的技术,但并不总是最合理的选择。这是因为:
它的缺点之一
Dataset.from_generator()
正在重新整理结果数据集
对于大小为n的无序缓冲区,需要加载n个示例。这个
将在管道中创建周期性暂停(大n)或
最好将数据转换为numpy数组,然后将numpy数组存储在磁盘上用作数据集,如下所示:
def array_to_tfrecords(X, y, output_file):
feature = {
'X': tf.train.Feature(float_list=tf.train.FloatList(value=X.flatten())),
'y': tf.train.Feature(float_list=tf.train.FloatList(value=y.flatten()))
}
example = tf.train.Example(features=tf.train.Features(feature=feature))
serialized = example.SerializeToString()
writer = tf.python_io.TFRecordWriter(output_file)
writer.write(serialized)
writer.close()
这将需要
Dataset.from_generator
组件不在问题中。然后可以使用以下命令读取数据:
def read_tfrecords(file_names=("file1.tfrecord", "file2.tfrecord", "file3.tfrecord"),
buffer_size=10000,
batch_size=100):
dataset = tf.contrib.data.TFRecordDataset(file_names)
dataset = dataset.map(parse_proto)
dataset = dataset.shuffle(buffer_size)
dataset = dataset.repeat()
dataset = dataset.batch(batch_size)
return tf.contrib.data.Iterator.from_structure(dataset.output_types, dataset.output_shapes)
这将确保您的数据被彻底洗牌,并提供更好的结果。
另外,我相信您会从一些数据预处理中受益。首先,尝试将数据集中的所有文件转换为标准化的WAVE表单,然后将该数据保存到TFRecord。目前,您正在将它们转换为WAVE并使用librosa标准化采样率,但这并不能标准化通道。相反,请尝试使用如下函数:
from pydub import AudioSegment
def convert(path):
#open file (supports all ffmpeg supported filetypes)
audio = AudioSegment.from_file(path, path.split('.')[-1].lower())
#set to mono
audio = audio.set_channels(1)
#set to 44.1 KHz
audio = audio.set_frame_rate(44100)
#save as wav
audio.export(path, format="wav")
最后,您可能会发现,将声音文件作为浮点读取不符合您的最佳利益。你应该考虑尝试以下方法:
import scipy.io.wavfile as wave
import python_speech_features as psf
def getSpectrogram(path, winlen=0.025, winstep=0.01, NFFT=512):
#open wav file
(rate,sig) = wave.read(path)
#get frames
winfunc=lambda x:np.ones((x,))
frames = psf.sigproc.framesig(sig, winlen*rate, winstep*rate, winfunc)
#Magnitude Spectrogram
magspec = np.rot90(psf.sigproc.magspec(frames, NFFT))
#noise reduction (mean substract)
magspec -= magspec.mean(axis=0)
#normalize values between 0 and 1
magspec -= magspec.min(axis=0)
magspec /= magspec.max(axis=0)
#show spec dimensions
print magspec.shape
return magspec
然后应用如下函数:
#convert file if you need to
convert(filepath)
#get spectrogram
spec = getSpectrogram(filepath)
这将把WAVE文件中的数据解析成图像,然后您就可以用处理任何图像分类问题的方法来处理这些图像。