分离歌曲中的人声和背景音乐(tensorflow)

本文介绍如何利用RNN网络分离音频中的人声和背景音乐。通过MIR-1K数据集,将音频从时域转换到频域,采用神经网络进行训练,最终实现人声和背景音乐的分离。训练过程包括数据准备、模型构建、训练框架及测试代码的详细步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有没有好奇歌星们清唱的声音怎么样?这一讲,我们将歌曲的人声和背景音乐分离出来,使用的网络是RNN。接下来一一讲解怎么实现。

下载数据集

搞机器学习,首先想到的是怎么获取训练的数据,网上有开放的数据集MIR-1k,下载地址如下:
http://mirlab.org/dataset/public/MIR-1K.rar
下载完数据,解压到dataset/下,结构如下图所示
在这里插入图片描述
数据集里有很多文件夹,其他的我们不管,我们只用到Wavfile和UndividedWavfile文件夹下的文件。简单介绍一下数据集,打开Wavfile文件夹
在这里插入图片描述
里面有1000个音频文件,随便播放一个,请忽略里面五音不全的唱功(这里还是对得向该数据集的制作者致敬,感谢你们的付出),注意听会发现,有一个声道的数据是纯背景音乐,另一个声道的数据是纯人声。有了这个特性,我们就可以很好的利用了,后面详解代码再说。UndividedWavfile文件夹下也是类似的音频文件,只是数量只有110个,正好我们可以使用Wavfile文件夹下的数据做训练集,用UndividedWavfile文件夹下的数据做测试集。

思路

有了数据集,接下来还的有思路,俗称套路。首先,我们现在做的是音频的项目, 做音频的项目,首先就得想到将时域转到频域,再做分析。

而神经网络的套路也基本是下面的几步:

  1. 创建占位符、变量
  2. 设置学习率和batch size等参数
  3. 构建神经网络
  4. 设置损失函数
  5. 设置优化器
  6. 创建会话
  7. 利用神经网络开始训练数据,一般都是mini-batch的方法

具体到我们的这个项目,我们应该做以下事情

  1. 导入需要训练的数据集文件路径,存到列表中即可
  2. 导入训练集数据,每一个训练集文件都是一个双声道的音频文件,其中,第一个声道存的是背景音乐,第二个声道存的是纯人声;我们需要三组数据,第一组是将双声道转成单声道的数据,即让背景音乐和人声混合在一起 第二组数据是纯背景音乐,第三组数据是纯人声数据
  3. 通过上一步获取的数据都是时域的,我们要通过短时傅里叶变换将声音数据转到频域
  4. 初始化网络模型
  5. 获取mini-batch数据,开始进行迭代训练

train主框架

有了套路,就开始撸代码,先来看看训练train部分的代码,代码在train.py文件里

#可以通过命令设置的参数:
#dataset_dir : 数据集路径
#model_dir : 模型保存的文件夹
#model_filename : 模型保存的文件名
#dataset_sr : 数据集音频文件的采样率
#learning_rate : 学习率
#batch_size : 小批量训练数据的长度
#sample_frames : 每次训练获取多少帧数据
#iterations : 训练迭代次数
#dropout_rate : dropout率
def parse_arguments(argv):
    parser = argparse.ArgumentParser()
 
    parser.add_argument('--dataset_train_dir', type=str, help='数据集训练数据路径', default='./dataset/MIR-1K/Wavfile')
    parser.add_argument('--dataset_validate_dir', type=str, help='数据集验证数据路径', default='./dataset/MIR-1K/UndividedWavfile')
    parser.add_argument('--model_dir', type=str, help='模型保存的文件夹', default='model')
    parser.add_argument('--model_filename', type=str, help='模型保存的文件名', default='svmrnn.ckpt')
    parser.add_argument('--dataset_sr', type=int, help='数据集音频文件的采样率', default=16000)
    parser.add_argument('--learning_rate', type=float, help='学习率', default=0.0001)
    parser.add_argument('--batch_size', type=int, help='小批量训练数据的长度', default=64)
    parser.add_argument('--sample_frames', type=int, help='每次训练获取多少帧数据', default=10)
    parser.add_argument('--iterations', type=int, help='训练迭代次数', default=30000)
    parser.add_argument('--dropout_rate', type=float, help='dropout率', default=0.95)
 
    return parser.parse_args(argv)
 
if __name__ == '__main__':
    main(parse_arguments(sys.argv[1:]))

上面一些参数都有注释,比较简单就不再解释了,来看main函数做了什么

#训练模型,需要做以下事情
#1. 导入需要训练的数据集文件路径,存到列表中即可
#2. 导入训练集数据,每一个训练集文件都是一个双声道的音频文件,
#   其中,第一个声道存的是背景音乐,第二个声道存的是纯人声,
#   我们需要三组数据,第一组是将双声道转成单声道的数据,即让背景音乐和人声混合在一起
#   第二组数据是纯背景音乐,第三组数据是纯人声数据
#3. 通过上一步获取的数据都是时域的,我们要通过短时傅里叶变换将声音数据转到频域
#4. 初始化网络模型
#5. 获取mini-batch数据,开始进行迭代训练
 
def main(args):
 
    #先看数据集数据是否存在
    if not os.path.exists(args.dataset_train_dir) or not os.path.exists(args.dataset_validate_dir):
        raise NameError('数据集路径"./dataset/MIR-1K/Wavfile"或"./dataset/MIR-1K/UndividedWavfile"不存在!')
 
    # 1. 导入需要训练的数据集文件路径,存到列表中即可
    train_file_list = load_file(args.dataset_train_dir)
    valid_file_list = load_file(args.dataset_validate_dir)

上面做的很简单,将我们要训练和验证的文件路径导入到相应的列表里就可以了。然后设置一些参数

# 数据集的采样率
mir1k_sr = args.dataset_sr
# 用于短时傅里叶变换,窗口大小
n_fft = 1024
# 步幅;帧移对应卷积中的stride;
hop_length = n_fft // 4
 
# Model parameters
# 学习率
learning_rate = args.learning_rate
 
# 用于创建rnn节点数
num_hidden_units = [1024, 1024, 1024, 1024, 1024]
# batch 长度
batch_size = args.batch_size
# 获取多少帧数据
sample_frames = args.sample_frames
# 训练迭代次数
iterations = args.iterations
# dropout
dropout_rate = args.dropout_rate
 
# 模型保存路径
model_dir = args.model_dir
model_filename = args.model_filename

接着,我们就需要读取音频文件了,音频文件里保存的是时域的数据,读取文件后,使用快速傅里叶变换将它们转到频域中

#导入训练数据集的wav数据,
#wavs_mono_train存的是单声道,wavs_music_train 存的是背景音乐,wavs_voice_train 存的是纯人声
wavs_mono_train, wavs_music_train, wavs_voice_train = load_wavs(filenames = train_file_list, sr = mir1k_sr)
# 通过短时傅里叶变换将声音转到频域
stfts_mono_train, stfts_music_train, stfts_voice_train = wavs_to_specs(
    wavs_mono=wavs_mono_train, wavs_music=wavs_music_train, wavs_voice=wavs_voice_train, n_fft=n_fft,
    hop_length=hop_length)
 
# 跟上面一样,只不过这里是测试集的数据
wavs_mono_valid, wavs_music_valid, wavs_voice_valid = load_wavs(filenames=valid_file_list, sr=mir1k_sr)
stfts_mono_valid, stfts_music_valid, stfts_voice_valid = wavs_to_specs(
    wavs_mono=wavs_mono_valid, wavs_music=wavs_music_valid, wavs_voice=wavs_voice_valid
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值