pytorch对TIMIT数据集的预处理(不需要kaldi,Windows系统)

使用pytorch,在Windows系统下处理语音信号(附代码)

这篇博客以TIMIT数据集为例,在Windows系统下,使用pytorch自带的语音处理库,将语音文件处理成pytroch模型能直接加载训练的文件。


前言

  • 语言信号处理好麻烦,github上好多ASR项目,Windows系统都运行不了,还要安装kalid,好麻烦,还好pytorch有自带的语音处理库。
  • 处理好的数据已上传,可以直接加载到pytorch模型。

一、引入库

import os
import torch
import torchaudio
from collections import Counter, OrderedDict,defaultdict
from torch.utils.data import DataLoader
from nltk.tokenize import TweetTokenizer
import numpy as np

二、构建词汇表

语音识别,根据语音信号,得到一句话,词汇表用于将这句话变成一串数字
例如: I hate you -> 12 9 35

  • 使用PTB的训练文件生成词汇表,代码如下(示例):
class OrderedCounter(Counter, OrderedDict): #这样定义的字典类型变量,会将输入的句子里的新单词添加到字典中,并记录该单词的出现次数
    """Counter that remembers the order elements are first encountered"""
    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

    def __reduce__(self):
        return self.__class__, (OrderedDict(self),)
    
def create_vocab(split):
    tokenizer = TweetTokenizer(preserve_case=False) #分词,不区分大小写
    w2c = OrderedCounter()          
    w2i = dict()
    i2w = dict()
    special_tokens = ['<pad>', '<unk>', '<sos>', '<eos>']
    for st in special_tokens:
        i2w[len(w2i)] = st
        w2i[st] = len(w2i)
    with open(split, 'r') as file:
        for i, line in enumerate(file):
            words = tokenizer.tokenize(line)
            w2c.update(words)                     #这段程序将文件中出现过的所有单词加载到字典类型变量w2c中,并存储了他们出现的次数
        for w, c in w2c.items():
            if c > 3 and w not in special_tokens: #依次为出现次数大于3,且不是那4种特殊信号的单词分配序号
                i2w[len(w2i)] = w                
                w2i[w] = len(w2i)                #w2i格式为'cat':50这种,i2w为50:'cat'这种
    return w2i,i2w
w2i,_ = create_vocab('ptb.train.txt')

得到的词汇表w2i如图所示,每个单词都有对应的数字。
具体可以参考这篇文献:Pytorch加载txt格式的数据集文件
在这里插入图片描述

三、处理TIMIT数据集

TIMIT数据集的各个文件夹以及文件名的详细介绍,参考这篇博客,解释的很清楚:语音识别数据集-TIMIT数据集-中文超详细解析

代码如下:

path = os.getcwd() #获取当前文件地址
train_path = path + '\\data\\TRAIN' #得到训练集和测试集的地址
test_path = path + '\\data\\TEST'

num = 0
for i in os.listdir(train_path): #这个和TIMIT数据集的组成有关,参考上面提到的TIMIT那篇博客
    for j in os.listdir(train_path + str('\\') +i):
        for k in os.listdir(train_path + str('\\') + i + str('\\') + j):
            path = train_path + str('\\') + i + str('\\') + j + str('\\') + k
            if '.WAV' in path:  #加载训练集的每一个音频文件(WAV)
                waveform,sample_rate = torchaudio.load('data\\TRAIN' + str('\\') + i + str('\\') + j + str('\\') + k) #得到音频文件的波形和采样率(都是16khz)
                specgram = torchaudio.transforms.MelSpectrogram()(waveform) #得到MFCC频谱信号波形
                with open('data\\TRAIN' + str('\\') + i + str('\\') + j + str('\\') + k[:-4]+ '.TXT', "r") as f:
                    data = f.read() #读出数据集里语音转换后的txt文件
                    data = data.split() #下面是因为,txt存储是这样的 0  4555 i hate you.我们只需要 i hate you 其余全部去掉 
                    data_e = data[-1][:-1]#取出最后一个字母‘you.’ 并且删除'.' 只保留'you'
                    data = data[2:-1]#不要0 4555 和 you.
                    data.append(data_e)#将'you'加上,这样句子就从‘0 4555 i hate you.’变成'i hate you' 
                    length = len(data) #句子的长度
                    target = [w2i.get(w, w2i['<unk>']) for w in data]#根据词汇表,将句子转换为数字
                    target = torch.from_numpy(np.asarray(target))
                state = {'waveform':waveform,'txt':data,'length':length,'specgram':specgram,'target':target,'sample_rate':sample_rate}
                torch.save(state,'train_data/'+str(num)+ '.cfg')
                num = num + 1
        

num = 0
for i in os.listdir(test_path):
    for j in os.listdir(test_path + str('\\') +i):
        for k in os.listdir(test_path + str('\\') + i + str('\\') + j):
            path = test_path + str('\\') + i + str('\\') + j + str('\\') + k
            if '.WAV' in path:
                waveform,sample_rate = torchaudio.load('data\\TEST' + str('\\') + i + str('\\') + j + str('\\') + k)
                specgram = torchaudio.transforms.MelSpectrogram()(waveform)
                with open('data\\TEST' + str('\\') + i + str('\\') + j + str('\\') + k[:-4]+ '.TXT', "r") as f:
                    data = f.read()
                    data = data.split()
                    data_e = data[-1][:-1]
                    data = data[2:-1]
                    data.append(data_e)
                    length = len(data)
                    target = [w2i.get(w, w2i['<unk>']) for w in data]
                    target = torch.from_numpy(np.asarray(target))
                state = {'waveform':waveform,'txt':data,'length':length,'specgram':specgram,'target':target,'sample_rate':sample_rate}
                torch.save(state,'test_data/'+str(num)+ '.cfg')
                num = num + 1
  • 对TMIT数据集处理,得到的训练集文件0.cfg-4619.cfg存放在train_data文件夹内; 得到的测试集文件0.cfg-1679.cfg存放在train_data文件夹内;
  • 生成cfg文件含有六个属性
    • waveform : 波形
    • txt : 对应的文字
    • target : 经过词汇表转换txt后的数字
    • length : txt长度
    • specgram: MFCC波形,一般使用MFCC做ASR,语音识别之特征参数提取(一)
    • sample_rate:采样率
      如图所示:
      在这里插入图片描述

四、加载为能被批处理的tensor变量

data = defaultdict(dict)
for i in range(4620): #处理训练集和测试集
    train_data = torch.load('train_data/'+str(i)+'.cfg')
    inp = train_data['specgram']
    if inp.size()[2] <= 256:       #统一输入input的长度,短的填0,长的截断
        zero = torch.zeros(1,128,256-inp.size()[2])
        inp = torch.cat((inp,zero),dim=2)
    else:
        inp = inp[:,:,:256]
    data[i]['input'] = inp.squeeze(0)
    txt = train_data['txt']
    length = train_data['length']
    if length <= 15:     #统一标签label的长度,短的填<pad>,长的截断
        txt.extend(['<pad>'] * (15-length))
    else:
        txt = txt[:15]
    target = [w2i.get(w, w2i['<unk>']) for w in txt]
    target = torch.from_numpy(np.asarray(target))
    data[i]['target'] = target
train_data_loader = DataLoader(
                dataset= data,
                batch_size= 64,#批处理大小
                shuffle=True #是否打乱排序
            )


data = defaultdict(dict)
for i in range(1680):
    test_data = torch.load('test_data/'+str(i)+'.cfg')
    inp = test_data['specgram']
    if inp.size()[2] <= 256:
        zero = torch.zeros(1,128,256-inp.size()[2])
        inp = torch.cat((inp,zero),dim=2)
    else:
        inp = inp[:,:,:256]
    data[i]['input'] = inp.squeeze(0)
    txt = test_data['txt']
    length = test_data['length']
    if length <= 15:
        txt.extend(['<pad>'] * (15-length))
    else:
        txt = txt[:15]
    target = [w2i.get(w, w2i['<unk>']) for w in txt]
    target = torch.from_numpy(np.asarray(target))
    data[i]['target'] = target
test_data_loader = DataLoader(
                dataset= data,
                batch_size= 64,#批处理大小
                shuffle=True #是否打乱排序
            )

这样就得到了训练集和测试集的批处理的迭代器,输入为MFCC波形(input),输出为一串数字(target)(可通过词汇表w2i翻译)
如图所示:
在这里插入图片描述

总结

这篇博客以TIMIT数据集为例,在Windows系统下,使用pytorch自带的语音处理库,将语音文件处理成pytroch模型能直接加载训练的文件。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值