• 语音增强——DNN(深度神经网络)频谱映射


    内容来自B站视频:https://www.bilibili.com/video/BV1Vo4y1D7jJ/?spm_id_from=333.788&vd_source=77c874a500ef21df351103560dada737

    输出层得到的是干净语音的频谱

     M开头的是男性说话人,F开头的是女性说话人

     

     

    get_scp.py程序如下:

    1. import os
    2. import numpy as np
    3. base_path="TIMIT/TEST/"
    4. with open("test.scp","wt",encoding='utf-8') as f:
    5. # base_path="TIMIT/TRAIN/"
    6. # with open("train.scp","wt",encoding='utf-8') as f:
    7. for root,dirs,files in os.walk(base_path):
    8. for file in files:
    9. file_name = os.path.join(root,file)
    10. if file_name.endswith(".WAV"):
    11. print(file_name)
    12. f.write("%s\n"%file_name)

    Psignal和Pnoise是能量,Asignal和Anoise是幅值 

     

     librosa读取数据会把语音归一化到[-1,1]之间,因此我们不用librosa,我们使用soundfile,直接读取原始数据

    程序如下:

    1. import os
    2. import numpy as np
    3. import random
    4. import scipy.io.wavfile as wav
    5. import librosa
    6. import soundfile as sf
    7. from numpy.linalg import norm
    8. def signal_by_db(speech,noise,snr):
    9. speech = speech.astype(np.int16)
    10. noise = noise.astype(np.int16)
    11. len_speech = speech.shape[0] # 得到语音的长度
    12. len_noise = noise.shape[0] # 得到噪声的长度,噪声的长度要远大于语音的长度
    13. start = random.randint(0,len_noise-len_speech) # 返回0~len_noise-len_speech之间的任意整数
    14. end = start+len_speech
    15. add_noise = noise[start:end] # 从噪声信号截取一段与语言信号长度一样的噪声段出来
    16. add_noise = add_noise / norm(add_noise) * norm(speech) / (10.0 ** (0.05 * snr))
    17. mix = speech + add_noise
    18. return mix
    19. if __name__=="__main__":
    20. noise_path = "D:\\深度学习数据集\\NOISEX"
    21. noises = ['babble', 'buccaneer1', 'destroyerengine', 'factory2', 'volvo', 'white']
    22. clean_wavs = np.loadtxt('scp/train.scp', dtype='str').tolist()
    23. clean_path = "D:\\TIMIT"
    24. path_noisy = "D:\\深度学习数据集\\DNN-Mapping\\nosiy"
    25. snrs = [-5, 0, 5, 10, 15, 20]
    26. with open('scp/train_DNN_enh.scp', 'wt') as f:
    27. for noise in noises:
    28. print(noise)
    29. noise_file = os.path.join(noise_path, noise + '.wav')
    30. noise_data, fs = sf.read(noise_file, dtype='int16')
    31. for clean_wav in clean_wavs:
    32. clean_file = os.path.join(clean_path, clean_wav)
    33. clean_data, fs = sf.read(clean_file, dtype='int16')
    34. for snr in snrs:
    35. noisy_file = os.path.join(path_noisy, noise, str(snr), clean_wav)
    36. noisy_path, _ = os.path.split(noisy_file)
    37. os.makedirs(noisy_path, exist_ok=True) # 文件路径不存在则创建路径
    38. mix = signal_by_db(clean_data, noise_data, snr)
    39. noisy_data = np.asarray(mix, dtype=np.int16)
    40. sf.write(noisy_file, noisy_data, fs) # 把噪声数据写入该路径(noisy_file)下
    41. f.write('%s %s \n' %(noisy_file, clean_file))

     

     

     拼帧操作:

    假设语音信号有14帧,用5帧预测一帧(中间帧),最终因此只能预测10帧【2~11】

    expend=左边扩展帧=右边扩展帧=3,因此本程序用3+3+1=7帧预测一帧

    tensor.unfold的dimension表示,沿着哪一个维度进行取帧的,本程序令dimension=0,表示沿着时间的维度取帧,size表示取几帧,step表示移动步长

     

    为什么不直接把结果进行MSE,而要进行 BatchNorm1d后在MSE?

    原因如下:若不进行BatchNorm1d,数值取值范围很大,用神经网络映射一个取值范围很大的数时,收敛很慢,所以为了提高收敛速度,必须加入BatchNorm1d

    测试阶段:

     

     

     

     

     

     

  • 相关阅读:
    (新)Spring Security如何实现跨域
    基于NSGAII多目标遗传优化的WSN无线传感器网络最优覆盖率matlab仿真
    ABP - 缓存模块(2)
    Webix JavaScript UI-9.24.0 Crack
    Pr 入门系列之十:添加图形和标题
    【Oculus Interaction SDK】(七)使用射线进行交互(物体 & UI)
    Python 接口测试之接口关键字封装
    java——mybatis——Mybatis的缓存——Mybatis中的一级缓存——默认情况下,MyBatis 只开启一级缓存...
    基于Jenkins实现的CI/CD方案
    Python 潮流周刊第 44 期(摘要)+ 赠书 5 本《明解Python算法与数据结构》
  • 原文地址:https://blog.csdn.net/qq_42233059/article/details/126780515