深度学习项目三: 自动语音识别---采用的是WAVENet网络结构(含数据和所需源码)并讲了空洞卷积+一维卷积

自动语音识别

目录

自动语音识别

介绍几个前导知识:

了解数据集

代码实现+讲解


首先我们看一下WaveNet的网络结构:

         我大概描述一下这个网络的结构: 首先输入数据,这里我们输入的是音频的mfcc特征(不懂没关系,等会说) , 接着进行一个一维的空洞卷积,然后进入到残差块中,残差块是这样的结构:将进来的数据再进行一次空洞卷积,分两路,一路是用tanh()做激活函数,一路是用sigmoid做激活函数,最后又将两路合并,合并完成后,我们在经过一个一维的空洞卷积,这里得到的输出,我们又会进行两路处理,一路是进入下一次的残差块,一路是往右边发展,经过一个relu激活,一个一维空洞卷积,一个relu,一个一维空洞卷积,再接着softmax ,最后得到输出。。说道这里,大概好多人都有点晕。不要紧,接着往下看。一步一步解开谜团。

介绍几个前导知识:

概念一:空洞卷积是什么?

       很可惜,csdn放不了动图。。。。

            如上图,这是一个二维的3x3的空洞卷积(这里只看深蓝色的框) ,深蓝色和深蓝色框之间间隔了一个浅蓝色的框,这个浅蓝色的框就是空出来的,空洞的名字就是从这里来的,也就是卷积的时候,卷积的范围变大了,但是对于部分像素,我们不参与计算(这个图中就是5x5格子中浅蓝色的那些) 。 这里你可以把这个空洞卷积想象成咱们的正常卷积,如果是正常的卷积,这个卷积核就是5x5的。只不顾部分权重是零而已。  水平有限,只能说道这里。。

概念二:一维卷积

      我们在图像处理中经常采用的都是二维卷积,对于一维卷积感觉好默认。下面就简要的说明一下

假设我们有一个待卷积序列(左边) 。 有一个1x5的卷积核。 如果我们的步长为1,则卷积的过程是:

了解数据集

数据源:下载数据集    这里如果下载不来,可以评论练习我

     首先我们先了解数据:    .wav文件是音频, .wav.trn是音频所对应的文本文件。。总共有13388条数据

代码实现+讲解

1:加载所需的模块:

from keras.models import Model
from keras.layers import Input, Activation, Conv1D, Lambda, Add, Multiply, BatchNormalization
from keras.optimizers import Adam, SGD
from keras import backend as K
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import random
import pickle
import glob
from tqdm import tqdm
from python_speech_features import mfcc
import scipy.io.wavfile as wav
import librosa
from IPython.display import Audio

2:读取文本文件,去掉一些换行符号等。。最后将每个文本中的中文保存到texts列表中,接着将每个音频的路径保存到paths中。见下面代码。注意看注释

# 读取语音所对应的文本数据
text_paths = glob.glob('data/*.trn')
total = len(text_paths)   # 统计文本的个数
print(total)

with open(text_paths[0], 'r', encoding='utf8') as fr:
    lines = fr.readlines()
    print(lines)    # 查看第一条文本的内容


# 提取文本标注和语音文件路径,保留中文并去掉空格
texts = []   # 放置文本
paths = []   # 存的是每个对应音频的路径
for path in text_paths:
    with open(path, 'r', encoding='utf8') as fr:
        lines = fr.readlines()
        line = lines[0].strip('\n').replace(' ', '')   # 因为我们原始数据中还包含有拼音,我们要将其去除掉
        texts.append(line)
        paths.append(path.rstrip('.trn'))   # 去掉.trn就是音频文件

print(paths[0], texts[0])   # 文本所在路径 以及所对应的文本

3:处理音频文件, 首先我们删除音频开始和结束部分中的静音部分。然后将计算各个音频所对应的的mfcc特征。这里mfcc你就可以理解为是一段很短音频的数字描述。 

# MFCC特征保留13维,定义加载语音文件并去掉两端静音的函数, 以及可视化语音文件的函数
mfcc_dim = 13


def load_and_trim(path):
    # 去掉两端的静音
    audio, sr = librosa.load(path)   # 加载音频
    energy = librosa.feature.rmse(audio)   # 计算能量
    frames = np.nonzero(energy >= np.max(energy) / 5)   # 如果能量大则保留 说明这段不是两端的静音
    indices = librosa.core.frames_to_samples(frames)[1]
    audio = audio[indices[0]:indices[-1]] if indices.size else audio[0:0]

    return audio, sr    # 去掉两端静音的音频和采样频率


def visualize(index):
    # 可视化
    path = paths[index]  # 获取某个音频
    text = texts[index]  # 获得所对应的文字
    print('Audio Text:', text)

    audio, sr = load_and_trim(path)
    plt.figure(figsize=(12, 3))
    plt.plot(np.arange(len(audio)), audio)
    plt.title('Raw Audio Signal')
    plt.xlabel('Time')
    plt.ylabel('Audio Amplitude')  # 音频高度
    plt.show()

    feature = mfcc(audio, sr, numcep=mfcc_dim, nfft=551)   # 计算mfcc特征
    print('Shape of MFCC:', feature.shape)

    fig = plt.figure(figsize=(12, 5))
    ax = fig.add_subplot(111)
    im = ax.imshow(feature, cmap=plt.cm.jet, aspect='auto')
    plt.title('Normalized MFCC')
    plt.ylabel('Time')
    plt.xlabel('MFCC Coefficient')
    plt.colorbar(im, cax=make_axes_locatable(ax).append_axes('right', size='5%', pad=0.05))
    ax.set_xticks(np.arange(0, 13, 2), minor=False);
    plt.show()

    return path


Audio(visualize(0))   # 只是用ipython时,让其显示在notebook中,不想在ipython中显示,直接visualize(0)就行了,我们只看一下第一节音频的特征


# 获取全部语音文件对应的MFCC特征
features = []    # 存取所有音频的mfcc特征
for i in tqdm(range(total)):
    path = paths[i]
    audio, sr = load_and_trim(path)    # 加载全部的语音
    features.append(mfcc(audio, sr, numcep=mfcc_dim, nfft=551))  # nfft每个多少采一下
    # 记住,这里的features是 [ []    ]
print(len(features), features[0].shape)  # 输出13388, (444, 13)
# 也就是说有13388段音频,,  (444, 13) 代表的是将第一段音频被分为444个小段,每个小段有13个mfcc特征

   这里我多啰嗦一句,我们数据集中一段音频可以切分成好多段短的音频,所以一段音频最后结构就变成了:[切分的段数, 13维特征]

 4:我们对mfcc特征进行归一化, 并将音频所对应的文字与数字进行映射,因为电脑不认识汉字,只认识数字

# 将MFCC特征进行归一化
samples = random.sample(features, 100)  # 这里是随机选了100段音频,将它们拼接起来,求均值,和方差。
samples = np.vstack(samples)

mfcc_mean = np.mean(samples, axis=0)
mfcc_std = np.std(samples, axis=0)
print(mfcc_mean)
print(mfcc_std)

# 运用上面的均值和方差对整体音频进行处理
features = [(feature - mfcc_mean) / (mfcc_std + 1e-14) for feature in features]


# 建立字典,共2883个不同的字
chars = {}
for text in texts:
    for c in text:
        chars[c] = chars.get(c, 0) + 1

chars = sorted(chars.items(), key=lambda x: x[1], reverse=True)
chars = [char[0] for char in chars]
print(len(chars), chars[:100])   # 输出2883  则有2993个汉字

char2id = {c: i for i, c in enumerate(chars)}
id2char = {i: c for i, c in enumerate(chars)}

5: 准备输入数据和输出数据(标签,也就是对应的汉字),我们在模型训练的时候,采用generator函数生成批数据往模型中送,代码如下:

# total是所有音频的个数,也可以说是所有文本的条数。
# 划分训练数据和测试数据 定义产生批数据的函数
data_index = np.arange(total)
np.random.shuffle(data_index)   # 将索引打乱
train_size = int(0.9 * total)   # 训练数据占90%
test_size = total - train_size
train_index = data_index[:train_size]   # 切分出来训练数据的索引
test_index = data_index[train_size:]   # 切分出来测试数据的索引

X_train = [features[i] for i in train_index]   # 取出训练音频的mfcc特征
Y_train = [texts[i] for i in train_index]    # 取出训练的标签,也就是所对应的文本
X_test = [features[i] for i in test_index]   # 同理 取测试
Y_test = [texts[i] for i in test_index]   # 同理 取测试

batch_size = 16


def batch_generator(x, y, batch_size=batch_size):
    # 主要是产生批数据
    offset = 0
    while True:
        offset += batch_size

        if offset == batch_size or offset >= len(x):    # 当偏移量大于x的长度时,将序号进行打乱。再进行训练
            data_index = np.arange(len(x))
            np.random.shuffle(data_index)
            x = [x[i] for i in data_index]   # [ [[13维],[13维],[13维],[13维],[13维]...], [], []...]
            y = [y[i] for i in data_index]   # [ [              汉字                  ], [], []...]
            offset = batch_size

        X_data = x[offset - batch_size: offset]     # 取出一批语音所对应的mfcc值
        Y_data = y[offset - batch_size: offset]     # 取出语音所对应的汉字

        X_maxlen = max([X_data[i].shape[0] for i in range(batch_size)])   # 不同的语音段切分多少段不一定。这里获取切分最长的长度
        Y_maxlen = max([len(Y_data[i]) for i in range(batch_size)])    # 语音对应的汉字也是不固定的,这里获取汉字最多的长度

        X_batch = np.zeros([batch_size, X_maxlen, mfcc_dim])       # 输入的维度
        Y_batch = np.ones([batch_size, Y_maxlen]) * len(char2id)   # 输出的维度
        X_length = np.zeros([batch_size, 1], dtype='int32')     # 输入的批量数  这是为了算ctc损失所需要的
        Y_length = np.zeros([batch_size, 1], dtype='int32')     # 输出的批量数  这是为了算ctc损失所需要的

        for i in range(batch_size):
            X_length[i, 0] = X_data[i].shape[0]    # 将每一条语音切分的长度复制给X_length   这里再强调一下,这只是为了算ctc损失
            X_batch[i, :X_length[i, 0], :] = X_data[i]   # 将每条数据放入到X_batch  这是我们最终构造的输入

            Y_length[i, 0] = len(Y_data[i])   # 将每条语音所对应的汉字所具有的长度复制为Y_length 这里再强调一下,这只是为了算ctc损失
            Y_batch[i, :Y_length[i, 0]] = [char2id[c] for c in Y_data[i]]   # 将每条汉字转为id  放进Y_batch  这是我们最终构造的标签

        inputs = {'X': X_batch, 'Y': Y_batch, 'X_length': X_length, 'Y_length': Y_length}
        outputs = {'ctc': np.zeros([batch_size])}   # ctc损失

        yield (inputs, outputs)

6:定义wavenet网络。这里对应着最前面的那个图看

# 定义训练参数和模型结构并开始训练
epochs = 50
num_blocks = 3
filters = 128    # 128个卷积核

X = Input(shape=(None, mfcc_dim,), dtype='float32', name='X')   # 输入的音频的那个
Y = Input(shape=(None,), dtype='float32', name='Y')   # 输入的是所对应的汉字
X_length = Input(shape=(1,), dtype='int32', name='X_length')
Y_length = Input(shape=(1,), dtype='int32', name='Y_length')


def conv1d(inputs, filters, kernel_size, dilation_rate):
    # causal指定是因果空洞卷积   dilation_rate指的空洞数
    return Conv1D(filters=filters, kernel_size=kernel_size, strides=1, padding='causal', activation=None,
                  dilation_rate=dilation_rate)(inputs)


def batchnorm(inputs):
    return BatchNormalization()(inputs)


def activation(inputs, activation):
    return Activation(activation)(inputs)


def res_block(inputs, filters, kernel_size, dilation_rate):
    hf = activation(batchnorm(conv1d(inputs, filters, kernel_size, dilation_rate)), 'tanh')
    hg = activation(batchnorm(conv1d(inputs, filters, kernel_size, dilation_rate)), 'sigmoid')
    h0 = Multiply()([hf, hg])

    ha = activation(batchnorm(conv1d(h0, filters, 1, 1)), 'tanh')
    hs = activation(batchnorm(conv1d(h0, filters, 1, 1)), 'tanh')

    return Add()([ha, inputs]), hs


h0 = activation(batchnorm(conv1d(X, filters, 1, 1)), 'tanh')
shortcut = []
for i in range(num_blocks):
    for r in [1, 2, 4, 8, 16]:
        h0, s = res_block(h0, filters, 7, r)
        shortcut.append(s)

h1 = activation(Add()(shortcut), 'relu')
h1 = activation(batchnorm(conv1d(h1, filters, 1, 1)), 'relu')
Y_pred = activation(batchnorm(conv1d(h1, len(char2id) + 1, 1, 1)), 'softmax')
sub_model = Model(inputs=X, outputs=Y_pred)

7:定义损失函数,并进行模型的训练。注意这里的损失使用的ctc损失。这就是我们前面为什么要传x_length, y_length原因

def calc_ctc_loss(args):
    y, yp, ypl, yl = args
    return K.ctc_batch_cost(y, yp, ypl, yl)


ctc_loss = Lambda(calc_ctc_loss, output_shape=(1,), name='ctc')([Y, Y_pred, X_length, Y_length])
model = Model(inputs=[X, Y, X_length, Y_length], outputs=ctc_loss)
optimizer = SGD(lr=0.02, momentum=0.9, nesterov=True, clipnorm=5)
model.compile(loss={'ctc': lambda ctc_true, ctc_pred: ctc_pred}, optimizer=optimizer)

checkpointer = ModelCheckpoint(filepath='asr.h5', verbose=0)
lr_decay = ReduceLROnPlateau(monitor='loss', factor=0.2, patience=1, min_lr=0.000)

history = model.fit_generator(
    generator=batch_generator(X_train, Y_train),
    steps_per_epoch=len(X_train) // batch_size,
    epochs=epochs,
    validation_data=batch_generator(X_test, Y_test),
    validation_steps=len(X_test) // batch_size,
    callbacks=[checkpointer, lr_decay])


# 保存模型和字典
sub_model.save('asr.h5')
with open('dictionary.pkl', 'wb') as fw:
    pickle.dump([char2id, id2char, mfcc_mean, mfcc_std], fw)

 最终的损失:

           训练集的损失已经降到非常低了,但是测试集损失还在45左右。。最终就维持在这个状态。这是因为我们的训练数据太小的缘故。。

 模型训练就到这里,我们调用一下模型,随机选取一段语音进行测试:

# -*- coding: utf-8 -*-

from keras.models import load_model
from keras import backend as K
import numpy as np
import librosa
from python_speech_features import mfcc
import pickle
import glob

wavs = glob.glob('data/*.wav')
with open('dictionary.pkl', 'rb') as fr:
    [char2id, id2char, mfcc_mean, mfcc_std] = pickle.load(fr)

mfcc_dim = 13
model = load_model('asr.h5')

index = np.random.randint(len(wavs))
print(wavs[index])

audio, sr = librosa.load(wavs[index])
energy = librosa.feature.rmse(audio)
frames = np.nonzero(energy >= np.max(energy) / 5)
indices = librosa.core.frames_to_samples(frames)[1]
audio = audio[indices[0]:indices[-1]] if indices.size else audio[0:0]
X_data = mfcc(audio, sr, numcep=mfcc_dim, nfft=551)
X_data = (X_data - mfcc_mean) / (mfcc_std + 1e-14)
print(X_data.shape)

with open(wavs[index] + '.trn', 'r', encoding='utf8') as fr:
    label = fr.readlines()[0]
    print(label)

pred = model.predict(np.expand_dims(X_data, axis=0))
pred_ids = K.eval(K.ctc_decode(pred, [X_data.shape[0]], greedy=False, beam_width=10, top_paths=1)[0][0])
pred_ids = pred_ids.flatten().tolist()
print(''.join([id2char[i] for i in pred_ids]))

   最终输出结果:

准确率很高,这是一条训练数据,所以拟合的比较好,因为我们训练集的损失已将快降到零了。。如果抽到测试集,就不一定这么好了。 

1 简介1 1.1 自动语音识别:更好的沟通之桥 1 1.1.1 人类之间的交流 2 1.1.2 人机交流 2 1.2 语音识别系统的基本结构 4 1.3 全书结构 6 1.3.1 第一部分:传统声学模型6 1.3.2 第二部分:深度神经网络6 1.3.3 第部分:语音识别中的DNN-HMM 混合系统7 1.3.4 第四部分:深度神经网络中的特征表示学习 7 1.3.5 第五部分:高级的深度模型 7 第一部分传统声学模型9 2 混合高斯模型10 2.1 随机变量10 2.2 高斯分布和混合高斯随机变量11 2.3 参数估计13 2.4 采用混合高斯分布对语音特征建模 15 3 隐马尔可夫模型及其变体17 3.1 介绍17 3.2 马尔可夫链19 3.3 序列与模型 20 3.3.1 隐马尔可夫模型的性质21 3.3.2 隐马尔可夫模型的仿真22 3.3.3 隐马尔可夫模型似然度的计算22 3.3.4 计算似然度的高效算法24 3.3.5 前向与后向递归式的证明25 3.4 期望zui大化算法及其在学习HMM 参数中的应用 26 3.4.1 期望zui大化算法介绍 26 3.4.2 使用EM 算法来学习HMM 参数——Baum-Welch 算法 28 3.5 用于解码HMM 状态序列的维特比算法32 3.5.1 动态规划和维特比算法32 3.5.2 用于解码HMM 状态的动态规划算法33 3.6 隐马尔可夫模型和生成语音识别模型的变体35 3.6.1 用于语音识别的GMM-HMM 模型 36 3.6.2 基于轨迹和隐藏动态模型的语音建模和识别37 3.6.3 使用生成模型HMM 及其变体解决语音识别问题 38 第二部分深度神经网络41 4 深度神经网络42 4.1 深度神经网络框架42 4.2 使用误差反向传播来进行参数训练 45 4.2.1 训练准则 45 4.2.2 训练算法46 4.3 实际应用50 4.3.1 数据预处理51 4.3.2 模型初始化52 4.3.3 权重衰减52 4.3.4 丢弃法 53 4.3.5 批量块大小的选择55 4.3.6 取样随机化56 4.3.7 惯性系数 57 4.3.8 学习率和停止准则58 4.3.9 网络结构59 4.3.10 可复现性与可重启性 59 5 高级模型初始化技术61 5.1 受限玻尔兹曼机61 5.1.1 受限玻尔兹曼机的属性63 5.1.2 受限玻尔兹曼机参数学习66 5.2 深度置信网络预训练 69 5.3 降噪自动编码器预训练71 5.4 鉴别性预训练74 5.5 混合预训练75 5.6 采用丢弃法的预训练 75 第部分语音识别中的深度神经网络–隐马尔可夫混合模型77 6 深度神经网络–隐马尔可夫模型混合系统78 6.1 DNN-HMM 混合系统 78 6.1.1 结构78 6.1.2 用CD-DNN-HMM 解码80 6.1.3 CD-DNN-HMM 训练过程81 6.1.4 上下文窗口的影响83 6.2 CD-DNN-HMM 的关键模块及分析 85 6.2.1 进行比较和分析的数据集和实验85 6.2.2 对单音素或者音素的状态进行建模 87 6.2.3 越深越好88 6.2.4 利用相邻的语音帧89 6.2.5 预训练 90 6.2.6 训练数据的标注质量的影响 90 6.2.7 调整转移概率 91 6.3 基于KL 距离的隐马尔可夫模型91 7 训练和解码的加速93 7.1 训练加速93 7.1.1 使用多GPU 流水线反向传播94 7.1.2 异步随机梯度下降97 7.1.3 增广拉格朗日算法及乘子方向交替算法100 7.1.4 减小模型规模 101 7.1.5 其他方法102 7.2 加速解码103 7.2.1 并行计算103 7.2.2 稀疏网络105 7.2.3 低秩近似107 7.2.4 用大尺寸DNN 训练小尺寸DNN108 7.2.5 多帧DNN 109 8 深度神经网络序列鉴别性训练111 8.1 序列鉴别性训练准则 111 8.1.1 zui大相互信息 112 8.1.2 增强型MMI 113 8.1.3 zui小音素错误/状态级zui小贝叶斯风险114 8.1.4 统一的公式115 8.2 具体实现中的考量116 8.2.1 词图产生116 8.2.2 词图补偿117 8.2.3 帧平滑 119 8.2.4 学习率调整119 8.2.5 训练准则选择 120 8.2.6 其他考量120 8.3 噪声对比估计 121 8.3.1 将概率密度估计问题转换为二分类设计问题121 8.3.2 拓展到未归一化的模型123 8.3.3 在深度学习网络训练中应用噪声对比估计算法 124 第四部分深度神经网络中的特征表示学习127 9 深度神经网络中的特征表示学习128 9.1 特征和分类器的联合学习128 9.2 特征层级129 9.3 使用随意输入特征的灵活性 133 9.4 特征的鲁棒性 134 9.4.1 对说话人变化的鲁棒性134 9.4.2 对环境变化的鲁棒性 135 9.5 对环境的鲁棒性137 9.5.1 对噪声的鲁棒性138 9.5.2 对语速变化的鲁棒性 140 9.6 缺乏严重信号失真情况下的推广能力141 10 深度神经网络和混合高斯模型的融合144 10.1 在GMM-HMM 系统中使用由DNN 衍生的特征144 10.1.1 使用Tandem 和瓶颈特征的GMM-HMM 模型144 10.1.2 DNN-HMM 混合系统与采用深度特征的GMM-HMM 系统的比较147 10.2 识别结果融合技术149 10.2.1 识别错误票选降低技术(ROVER) 149 10.2.2 分段条件随机场(SCARF) 151 10.2.3 zui小贝叶斯风险词图融合153 10.3 帧级别的声学分数融合153 10.4 多流语音识别 154 11 深度神经网络的自适应技术157 11.1 深度神经网络中的自适应问题157 11.2 线性变换159 11.2.1 线性输入网络.159 11.2.2 线性输出网络 159 11.3 线性隐层网络 161 11.4 保守训练162 11.4.1 L2 正则项163 11.4.2 KL 距离正则项163 11.4.3 减少每个说话人的模型开销 165 11.5 子空间方法167 11.5.1 通过主成分分析构建子空间 167 11.5.2 噪声感知、说话人感知及设备感知训练168 11.5.3 张量172 11.6 DNN 说话人自适应的效果172 11.6.1 基于KL 距离的正则化方法 173 11.6.2 说话人感知训练174 第五部分先进的深度学习模型177 12 深度神经网络中的表征共享和迁移178 12.1 多任务和迁移学习178 12.1.1 多任务学习 178 12.1.2 迁移学习180 12.2 多语言和跨语言语音识别180 12.2.1 基于Tandem 或瓶颈特征的跨语言语音识别181 12.2.2 共享隐层的多语言深度神经网络182 12.2.3 跨语言模型迁移185 12.3 语音识别中深度神经网络的多目标学习188 12.3.1 使用多任务学习的鲁棒语音识别188 12.3.2 使用多任务学习改善音素识别189 12.3.3 同时识别音素和字素(graphemes) 190 12.4 使用视听信息的鲁棒语音识别 190 13 循环神经网络及相关模型192 13.1 介绍192 13.2 基本循环神经网络中的状态-空间公式194 13.3 沿时反向传播学习算法195 13.3.1 zui小化目标函数 196 13.3.2 误差项的递归计算196 13.3.3 循环神经网络权重的更新197 13.4 一种用于学习循环神经网络的原始对偶技术199 13.4.1 循环神经网络学习的难点199 13.4.2 回声状态(Echo-State)性质及其充分条件 199 13.4.3 将循环神经网络的学习转化为带约束的优化问题 200 13.4.4 一种用于学习RNN 的原始对偶方法201 13.5 结合长短时记忆单元(LSTM)的循环神经网络203 13.5.1 动机与应用203 13.5.2 长短时记忆单元的神经元架构204 13.5.3 LSTM-RNN 的训练205 13.6 循环神经网络的对比分析205 13.6.1 信息流方向的对比:自上而下还是自下而上 206 13.6.2 信息表征的对比:集中式还是分布式208 13.6.3 解释能力的对比:隐层推断还是端到端学习209 13.6.4 参数化方式的对比:吝啬参数集合还是大规模参数矩阵 209 13.6.5 模型学习方法的对比:变分推理还是梯度下降210 13.6.6 识别正确率的比较211 13.7 讨论212 14 计算型网络214 14.1 计算型网络214 14.2 前向计算215 14.3 模型训练 218 14.4 典型的计算节点222 14.4.1 无操作数的计算节点 223 14.4.2 一个操作数的计算节点223 14.4.3 两个操作数的计算节点228 14.4.4 用来计算统计量的计算节点类型235 14.5 卷积神经网络 236 14.6 循环连接 239 14.6.1 只在循环中一个接一个地处理样本240 14.6.2 同时处理多个句子242 14.6.3 创建任意的循环神经网络243 15 总结及未来研究方向245 15.1 路线图 245 15.1.1 语音识别中的深度神经网络启蒙245 15.1.2 深度神经网络训练和解码加速248 15.1.3 序列鉴别性训练248 15.1.4 特征处理249 15.1.5 自适应 250 15.1.6 多任务和迁移学习251 15.1.7 卷积神经网络 251 15.1.8 循环神经网络和长短时记忆神经网络251 15.1.9 其他深度模型 252 15.2 技术前沿和未来方向 252 15.2.1 技术前沿简析252 15.2.2 未来方向253
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

传道解惑也

打赏一下咯

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

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

打赏作者

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

抵扣说明:

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

余额充值