• 语音增强——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的创建和使用
    (十三)Java算法:基数排序(详细图解)
    Linux系统编程—socket网络编程
    Spring源码分析(十五)循环依赖2:源码分析
    python打开.npy文件的常见报错及解决
    orb-slam2 从单目开始的简单学习(8):LocalMapping
    Halcon一维码识别实例
    JavaSE学习----(八)常用类之String类
    虚拟数字人直播软件实现带货功能,成为新一代直播风口!
  • 原文地址:https://blog.csdn.net/qq_42233059/article/details/126780515