deeplearning4j - 使用RNN / LSTM进行音频信号处理

时间:2017-05-06 21:44:42

标签: java machine-learning audio-processing deeplearning4j

我正在尝试使用deeplearning4j训练RNN进行数字(音频)信号处理。 我们的想法是拥有2个.wav文件:一个是录音,第二个是相同的录音但是经过处理(例如使用低通滤波器)。 RNN的输入是第一个(未处理的)录音,输出是第二个(已处理的)录音。

我已经使用了dl4j示例中的GravesLSTMCharModellingExample,并且大部分都使用了CharacterIterator类来接受音频数据而不是文本。

我使用dl4j处理音频的第一个项目基本上与GravesLSTMCharModellingExample做同样的事情,但生成音频而不是文本,使用11025Hz 8位单声道音频,这有效(对于一些非常有趣的结果)。因此,在这种情况下使用音频的基础知识似乎有效。

所以第2步是为音频处理而不是音频生成进行调整。

不幸的是,我没有取得多大成功。 它似乎能做的最好的就是输出一个非常嘈杂的输入版本。

作为一个“健全性检查”,我已经测试了输入和输出使用相同的音频文件,我希望它能够快速收敛到只需复制输入的模型。但它并没有。再次,经过长时间的训练,它似乎能够做的就是产生一个噪音更大的输入版本。

我猜的最相关的代码是DataSetIterator.next()方法(改编自示例的CharacterIterator类),现在看起来像这样:

public DataSet next(int num) {
    if (exampleStartOffsets.size() == 0)
        throw new NoSuchElementException();

    int currMinibatchSize = Math.min(num, exampleStartOffsets.size());
    // Allocate space:
    // Note the order here:
    // dimension 0 = number of examples in minibatch
    // dimension 1 = size of each vector (i.e., number of characters)
    // dimension 2 = length of each time series/example
    // Why 'f' order here? See http://deeplearning4j.org/usingrnns.html#data
    // section "Alternative: Implementing a custom DataSetIterator"
    INDArray input = Nd4j.create(new int[] { currMinibatchSize, columns, exampleLength }, 'f');
    INDArray labels = Nd4j.create(new int[] { currMinibatchSize, columns, exampleLength }, 'f');

    for (int i = 0; i < currMinibatchSize; i++) {
        int startIdx = exampleStartOffsets.removeFirst();
        int endIdx = startIdx + exampleLength;

        for (int j = startIdx, c = 0; j < endIdx; j++, c++) {
            // inputIndices/idealIndices are audio samples converted to indices.
            // With 8-bit audio, this translates to values between 0-255.
            input.putScalar(new int[] { i, inputIndices[j], c }, 1.0);
            labels.putScalar(new int[] { i, idealIndices[j], c }, 1.0);
        }
    }

    return new DataSet(input, labels);
}

所以也许我对LSTM应该做的事情有一个基本的误解。 我发布的代码中是否有任何明显错误? 是否有一个明显的原因,为什么同一文件的训练不一定能快速收敛到只复制输入的模型? (更不用说甚至试图在实际做某事的信号处理上进行训练?)

我看过Using RNN to recover sine wave from noisy signal这似乎是一个类似的问题(但是使用了不同的ML框架),但是没有得到答案。

感谢任何反馈!

3 个答案:

答案 0 :(得分:0)

你好我认为在数据集的逻辑中尝试使用long类型而不是整数

module.exports.userLogin = function (req,res) {
    console.log('----------Login----------');
    if(req.method == 'POST') {
        User
        .findOne({un:req.body.username})
        .exec( (err, user) =>  {
            if(!user) {
                return res.status(404).send({"message" : "no user"});
            }
            else {
                console.log(user, req.body);
                if(user.pw === req.body.password) {
                    return res.status(200).json(user);
                } else {
                    //always failed
                    return res.status(402).send({"message": "invalid credentials"});
                }
            }
        });
    }
};

替换为

mongoose connected to mongodb://localhost/loc8r
OPTIONS /api/login 200 4.553 ms - 4
----------Login----------
{ _id: 591ddbd91c343acac0114ab5,
  un: 'root',
  pw: 'pass',
  createdOn: 2017-05-19T18:01:58.729Z,
  gender: true } { username: 'root', password: 'pass' }
POST /api/login 402 35.329 ms - 33

答案 1 :(得分:0)

如果您听到输入的失真版本,那么您就走对了。

问题可能是你的网络自由参数不能很好地概括在少数例子上。确保你有更多的样本,至少 50_000 个彼此不重叠(不是来自同一个 wav 文件)并尝试使用网络参数,例如尝试将每层上的节点减少 10-15% 并尝试使用较低的学习率。

答案 2 :(得分:0)

此类问题最常见的问题是训练数据。

  1. 确保您有足够的可用训练数据。如果没有,您可以使用 audiomentations 之类的库来扩充您的训练集。
  2. 训练数据的多样性。您可以向训练集添加的扰动越多越好。
  3. 超参数优化 - 神经网络通常需要大量参数调整才能达到高于平均水平的性能。 Parameter optimization in deeplearning4j
  4. 这是基于过去经验的建议。它可能超出范围,但 autoencoder 架构通常会为这些处理用例创造奇迹。 (音频、图片等)