Python 深度学习(二)(3)

简介: Python 深度学习(二)

Python 深度学习(二)(2)https://developer.aliyun.com/article/1511969

基于字符的模型

在大多数情况下,语言建模是在单词级别进行的,其中分布是在一个固定词汇量为*|V|的词汇表上。在实际任务中,如语音识别中使用的语言模型,词汇表通常超过100,000*个单词。这个巨大的维度使得建模输出分布非常具有挑战性。此外,这些单词级别的模型在建模包含非单词字符串的文本数据时受到相当大的限制,比如多位数字或从未出现在训练数据中的单词(词汇外单词)。

可以克服这些问题的一类模型称为字符级语言模型[27]。这些模型对字符序列的分布建模,而不是单词,从而使您可以计算一个更小的词汇表上的概率。这里的词汇表包括文本语料库中所有可能的字符。然而,这些模型也有一个缺点。通过对字符序列而不是单词进行建模,我们需要对更长的序列进行建模,以在时间上捕获相同的信息。为了捕获这些长期依赖关系,让我们使用 LSTM RNN 语言模型。

本节的后续部分将详细介绍如何在 Tensorflow 中实现字符级 LSTM 以及如何在列夫·托尔斯泰的《战争与和平》上进行训练。这个 LSTM 将建模下一个字符的概率,给定先前看到的字符:P(c [t] | c [t-1] … c [t-n] )

因为完整文本太长,无法使用时间反向传播BPTT)训练网络,我们将使用一种批量变体,称为截断的 BPTT。在这种方法中,我们将训练数据分成固定序列长度的批次,并逐批次训练网络。由于批次将相互跟随,我们可以使用最后一批的最终状态作为下一批的初始状态。这样,我们可以利用状态中存储的信息,而无需对完整输入文本进行完整的反向传播。接下来,我们将描述如何读取这些批次并将其馈送到网络中。

预处理和读取数据

要训练一个好的语言模型,我们需要大量的数据。在我们的示例中,我们将了解基于列夫·托尔斯泰的《战争与和平》的英文译本的模型。这本书包含超过500,000个单词,使其成为我们小范例的完美候选者。由于它是公有领域的作品,因此《战争与和平》可以从古腾堡计划免费下载为纯文本。作为预处理的一部分,我们将删除古腾堡许可证、书籍信息和目录。接下来,我们将去除句子中间的换行符,并将允许的最大连续换行数减少到两个。

要将数据馈送到网络中,我们必须将其转换为数字格式。每个字符将与一个整数相关联。在我们的示例中,我们将从文本语料库中提取总共 98 个不同的字符。接下来,我们将提取输入和目标。对于每个输入字符,我们将预测下一个字符。由于我们使用截断的 BPTT 进行训练,我们将使所有批次相互跟随,以利用序列的连续性。将文本转换为索引列表并将其分成输入和目标批次的过程如下图所示:


将文本转换为长度为 5 的整数标签的输入和目标批次。请注意,批次彼此相继。

LSTM 网络

我们要训练的网络将是一个具有 512 个单元的两层 LSTM 网络。我们将使用截断的 BPTT 来训练这个网络,因此我们需要在批处理之间存储状态。

首先,我们需要为输入和目标定义占位符。输入和目标的第一维是批处理大小,即并行处理的示例数。第二维将沿着文本序列的维度。这些占位符接受包含字符索引的序列批次:

inputs = tf.placeholder(tf.int32, (batch_size, sequence_length))
targets = tf.placeholder(tf.int32, (batch_size, sequence_length))

要将字符馈送到网络,我们需要将它们转换成向量。我们将它们转换为独热编码,这意味着每个字符将被转换为一个长度等于数据集中不同字符数量的向量。这个向量将全为零,除了与其索引对应的单元,该单元将被设置为 1。在 TensorFlow 中,可以轻松完成以下代码行:

one_hot_inputs = tf.one_hot(inputs, depth=number_of_characters)

接下来,我们将定义我们的多层 LSTM 架构。首先,我们需要为每一层定义 LSTM 单元(lstm_sizes是每一层大小的列表,例如(512, 512),在我们的情况下):

cell_list = (tf.nn.rnn_cell.LSTMCell(lstm_size) for lstm_size in lstm_sizes)

然后,使用以下方法将这些单元包装在单个多层 RNN 单元中:

multi_cell_lstm = tf.nn.rnn_cell.MultiRNNCell(cell_list)

为了在批处理之间存储状态,我们需要获取网络的初始状态,并将其包装在要存储的变量中。请注意,出于计算原因,TensorFlow 会将 LSTM 状态存储在两个单独张量的元组中(来自长短期记忆部分的ch)。我们可以使用flatten方法展平这个嵌套数据结构,将每个张量包装在变量中,并使用pack_sequence``_as方法重新打包成原始结构:

initial_state = self.multi_cell_lstm.zero_state(batch_size, tf.float32)
# Convert to variables so that the state can be stored between batches
state_variables = tf.python.util.nest.pack_sequence_as(
    self.initial_state,
    (tf.Variable(var, trainable=False) 
     for var in tf.python.util.nest.flatten(initial_state)))

现在我们已经将初始状态定义为一个变量,我们可以开始通过时间展开网络。TensorFlow 提供了dynamic_rnn方法,根据输入的序列长度动态展开网络。该方法将返回一个包含表示 LSTM 输出和最终状态的张量的元组:

lstm_output, final_state = tf.nn.dynamic_rnn(
    cell=multi_cell_lstm, inputs=one_hot_inputs,    
    initial_state=state_variable)

接下来,我们需要将最终状态存储为下一批处理的初始状态。我们使用变量的assign方法将每个最终状态存储在正确的初始状态变量中。control_dependencies方法用于强制状态更新在返回 LSTM 输出之前运行:

store_states = (
    state_variable.assign(new_state)
    for (state_variable, new_state) in zip(
        tf.python.util.nest.flatten(self.state_variables),
        tf.python.util.nest.flatten(final_state)))
with tf.control_dependencies(store_states):
    lstm_output = tf.identity(lstm_output)

要从最终 LSTM 输出中获得 logit 输出,我们需要对输出应用线性变换,这样它就可以将batch size * sequence length * number of symbols作为其维度。在应用这个线性变换之前,我们需要将输出展平成大小为*number of outputs ** number of output features的矩阵:

output_flat = tf.reshape(lstm_output, (-1, lstm_sizes(-1)))

然后,我们可以定义并应用线性变换,使用权重矩阵W和偏差b来获得 logits,应用 softmax 函数,并将其重塑为一个尺寸为*batch size ** sequence length * number of characters的张量:

# Define output layer
logit_weights = tf.Variable(
    tf.truncated_normal((lstm_sizes(-1), number_of_characters), stddev=0.01))
logit_bias = tf.Variable(tf.zeros((number_of_characters)))
# Apply last layer transformation
logits_flat = tf.matmul(output_flat, self.logit_weights) + self.logit_bias
probabilities_flat = tf.nn.softmax(logits_flat)
# Reshape to original batch and sequence length
probabilities = tf.reshape(
    probabilities_flat, (batch_size, -1, number_of_characters))


LSTM 字符语言模型展开

训练

现在我们已经定义了网络的输入、目标和架构,让我们来定义如何训练它。训练的第一步是定义我们要最小化的损失函数。这个损失函数描述了在给定输入和目标的情况下输出错误序列的成本。因为我们是在考虑前面的字符来预测下一个字符,所以这是一个分类问题,我们将使用交叉熵损失。我们通过使用sparse_softmax_cross_ entropy_with_logits TensorFlow 函数来实现这一点。该函数将网络的 logits 输出(softmax 之前)和目标作为类标签,计算每个输出与其目标的交叉熵损失。为了减少整个序列和所有批次的损失,我们取所有损失的均值。

请注意,我们首先将目标扁平化为一个一维向量,以使它们与网络的扁平化 logits 输出兼容:

# Flatten the targets to be compatible with the flattened logits
targets_flat = tf.reshape(targets, (-1, ))
# Get the loss over all outputs
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(
     logits_flat, targets_flat)
# Reduce the loss to single value over all outputs
loss = tf.reduce_mean(loss)

现在我们已经定义了这个损失函数,可以在 TensorFlow 中定义训练操作,来优化我们的输入和目标批次的网络。为了执行优化,我们将使用 Adam 优化器;这有助于稳定梯度更新。Adam 优化器只是在更受控制的方式下执行梯度下降的特定方式 [28]。我们还会裁剪梯度,以防止梯度爆炸:

# Get all variables that need to be optimised
trainable_variables = tf.trainable_variables()
# Compute and clip the gradients
gradients = tf.gradients(loss, trainable_variables)
gradients, _ = tf.clip_by_global_norm(gradients, 5)
# Apply the gradients to those variables with the Adam optimisation algorithm.
optimizer = tf.train.AdamOptimizer(learning_rate=2e-3)
train_op = optimizer.apply_gradients(zip(gradients, trainable_variables))

已经定义了训练所需的所有 TensorFlow 操作,现在我们可以开始用小批量进行优化。如果data_feeder是一个生成器,返回连续的输入和目标批次,那么我们可以通过迭代地提供输入和目标批次来训练这些批次。我们每 100 个小批量重置一次初始状态,这样网络就能学习如何处理序列开头的初始状态。你可以使用 TensorFlow saver 来保存模型,以便稍后进行采样:

with tf.Session() as session:
    session.run(tf.initialize_all_variables())
    for i in range(minibatch_iterations):
        input_batch, target_batch = next(data_feeder)
        loss, _ = sess.run(
            (loss, train_op),
            feed_dict={ inputs: input_batch,targets: target_batch})
    # Reset initial state every 100 minibatches
        if i % 100 == 0 and i != 0:
            for state in tf.python.util.nest.flatten(
                    state_variables):
                session.run(state.initializer)

采样

一旦我们的模型训练完成,我们可能想要从该模型中对序列进行采样以生成文本。我们可以使用与训练模型相同的代码初始化我们的采样架构,但我们需要将batch_size设置为1sequence_length设置为None。这样,我们可以生成单个字符串并对不同长度的序列进行采样。然后,我们可以使用训练后保存的参数初始化模型的参数。为了开始采样,我们将一个初始字符串(prime_string)输入网络的状态。输入这个字符串后,我们可以根据 softmax 函数的输出分布对下一个字符进行采样。然后我们可以输入这个采样的字符并获取下一个字符的输出分布。这个过程可以继续进行一定数量的步骤,直到生成指定大小的字符串:

# Initialize state with priming string
for character in prime_string:
    character_idx = label_map(character)
    # Get output distribution of next character
    output_distribution = session.run(
        probabilities, 
        feed_dict={inputs: np.asarray(((character_idx)))})
# Start sampling for sample_length steps
for _ in range(sample_length):
    # Sample next character according to output distribution
    sample_label = np.random.choice(
        labels, size=(1), p=output_distribution(0, 0))
    output_sample += sample_label
    # Get output distribution of next character
    output_distribution = session.run(
       probabilities,
       feed_dict={inputs: np.asarray((label_map(character))))

示例训练

现在我们已经有了用于训练和采样的代码,我们可以对列夫·托尔斯泰的《战争与和平》进行网络训练,并在每个批次迭代之后对网络学到的内容进行采样。让我们用短语“她出生在年份”来激活网络,看看它在训练期间如何完成它。

经过 500 批次,我们得到了这个结果:“她出生在年份 sive 但 us eret tuke Toffhin e feale shoud pille saky doctonas laft the comssing hinder to gam the droved at ay vime”。网络已经学会了一些字符的分布,并且提出了一些看起来像是单词的东西。

经过 5,000 批次,网络掌握了许多不同的词语和名称:“她出生在 年份,他有许多的 Seffer Zsites。现在在 他的冠军-毁灭中,eccention,形成了一个 Veakov 的狼 也因为他是 congrary,他突然有了 首次没有回答。” 它仍然会创造出看起来合理的单词,比如“congrary”和“eccention”。

经过 50,000 批次,网络输出以下文本:“她出生在年份 1813。最后,天空可能会表现出莫斯科的房子 有一个绝佳的机会必须通过 Rostóvs’,所有的时间:坐退休,向他们展示 confure the sovereigns.” 网络似乎已经明白了一个年份是跟随我们激活字符串的一个非常合理的词。短字符串的词组似乎有意义,但是独立的句子还不具备意义。

经过 500,000 批次,我们停止了训练,网络输出了这个:“她出生在 年份 1806,当他在他的名字上表达了他的思想。公社不会牺牲他 :“这是什么?”娜塔莎问。“你还记得吗?” 我们可以看到,网络现在正在尝试构建句子,但这些句子彼此之间并不连贯。值得注意的是,在最后,它模拟了完整句子的小型对话,包括引号和标点符号。

尽管不完美,但 RNN 语言模型能够生成连贯的文本片段令人印象深刻。我们在此鼓励您尝试不同的架构,增加 LSTM 层的大小,将第三个 LSTM 层放入网络中,从互联网上下载更多文本数据,并查看您能够改进当前模型的程度。

到目前为止,我们讨论过的语言模型在许多不同的应用中被使用,从语音识别到创建能够与用户进行对话的智能聊天机器人。在接下来的部分中,我们将简要讨论深度学习语音识别模型,其中语言模型起着重要作用。

语音识别

在之前的章节中,我们看到了循环神经网络可以用来学习许多不同时间序列的模式。在本节中,我们将看看这些模型如何用于识别和理解语音的问题。我们将简要概述语音识别流水线,并提供如何在流水线的每个部分中使用神经网络的高层次视图。为了更多了解本节讨论的方法,我们希望您参考参考文献。

语音识别流水线

语音识别试图找到最有可能的单词序列的转录,考虑到提供的声学观察;这由以下表示:

转录 = argmax( P(单词 | 音频特征))

此概率函数通常由不同部分建模(请注意通常忽略归一化项 P(音频特征)):

P(单词 | 音频特征) = P(音频 特征 | 单词) * P(单词)

= P(音频特征 | 音素) * P(音素 | 单词) * P(单词)

注意

什么是音素?

音素是定义单词发音的基本声音单位。例如,单词“bat”由三个音素/b//ae//t/组成。每个音素都与特定的声音相关联。英语口语大约由 44 个音素组成。

这些概率函数中的每一个都将由识别系统的不同部分建模。典型的语音识别流水线接收音频信号并执行预处理和特征提取。然后使用这些特征在一个声学模型中,该模型尝试学习如何区分不同的声音和音素:P(音频特征 | 音素)。然后,这些音素将与发音词典的帮助匹配到字符或单词上:P(音素 | 单词)。从音频信号中提取的单词的概率然后与语言模型的概率相结合,P(单词)。然后通过一个解码搜索步骤找到最可能的序列,该步骤搜索最可能的序列(参见解码部分)。此语音识别流水线的高级概述如下图所示:


典型语音识别流水线概述

大型、实际应用的词汇语音识别流水线基于同样的流水线;然而,它们在每个步骤中使用了许多技巧和启发式方法来使问题可解。虽然这些细节超出了本节的范围,但有开源软件可用——Kaldi [29]——允许您使用先进的流水线训练语音识别系统。

在接下来的章节中,我们将简要描述标准流水线中的每个步骤以及深度学习如何帮助改善这些步骤。

语音作为输入数据

语音是一种通常传递信息的声音类型。它是通过介质(如空气)传播的振动。如果这些振动在 20 Hz 和 20 kHz 之间,则对人类是可听见的。这些振动可以被捕捉并转换成数字信号,以便在计算机上用于音频信号处理。它们通常由麦克风捕获,之后连续信号被离散采样。典型的采样率是 44.1 kHz,这意味着每秒对传入音频信号的幅度进行了 44100 次测量。请注意,这大约是最大人类听力频率的两倍。一个人说“hello world”的采样录音如下图所示:


一个人说“hello world”在时域的语音信号

预处理

在前述图像中的音频信号的录制持续了 1.2 秒。为了将音频数字化,它以每秒 44100 次(44.1 kHz)进行采样。这意味着对于这 1.2 秒的音频信号大约采集了 50000 个振幅样本。

即使是一个小例子,这些在时间维度上是很多点。为了减小输入数据的大小,在馈送到语音识别算法之前,这些音频信号通常被预处理以减少时间步数。一个典型的转换将信号转换为谱图,它表示信号中的频率随时间的变化,见下图。

这种频谱转换是通过将时间信号分成重叠窗口并对每个窗口进行傅立叶变换来完成的。傅立叶变换将信号随时间分解为组成信号的频率 [30]。得到的频率响应被压缩到固定的频率箱中。这个频率箱的数组也称为滤波器组。滤波器组是将信号分离到多个频率带中的一组滤波器。

假设前述的“hello world”录音被分成了 25 ms 的重叠窗口,并以 10 ms 的跨度。然后,利用窗口化傅立叶变换将得到的窗口转换为频率空间。这意味着每个时间步的振幅信息被转换为每个频率的振幅信息。最终的频率根据对数尺度(也称为 Mel 尺度)映射到 40 个频率箱中。得到的滤波器组谱图如下图所示。这个转换将时间维度从 50000 减少到 118 个样本,其中每个样本的大小为 40 个向量。


前图中语音信号的 Mel 频谱

特别是在较旧的语音识别系统中,这些 Mel-scale 滤波器组会通过去相关处理来消除线性依赖关系。通常,这是通过对滤波器组的对数进行离散 余弦变换 (DCT)来完成的。这个 DCT 是傅立叶变换的一种变体。这种信号转换也被称为梅尔频率倒谱系数 (MFCC)。

更近期,深度学习方法,如卷积神经网络,已学习了一些这些预处理步骤 [31], [32]。

声学模型

在语音识别中,我们希望将口语变成文本输出。这可以通过学习一个依赖时间的模型来实现,该模型接收一系列音频特征(如前一节所述),并输出可能的被说出的单词的序列分布。这个模型称为声学模型。

声学模型试图模拟一系列音频特征由一系列单词或音素生成的可能性:P (音频 特征 | 单词) = P (音频特征 | 音素) * P (音素 | 单词)

在深度学习变得流行之前,典型的语音识别声学模型将使用隐马尔可夫模型 (HMMs) 来模拟语音信号的时间变化性 [33], [34]。每个 HMM 状态发射一组高斯混合以模拟音频信号的频谱特征。发射的高斯混合构成高斯混合模型 (GMM),它们确定每个 HMM 状态在短时间段内的声学特征拟合程度。HMMs 被用来模拟数据的序列结构,而 GMMs 则模拟信号的局部结构。

HMM 假设连续帧在给定 HMM 的隐藏状态的情况下是独立的。由于这种强条件独立假设,声学特征通常是去相关的。

深信度网络

在语音识别中使用深度学习的第一步是用深度神经网络 (DNN) 替代 GMMs [35]。DNNs 将一组特征向量作为输入,并输出 HMM 状态的后验概率:P (HMM 状态 | 音频特征)

在这一步中使用的网络通常是在一组频谱特征上以一个通用模型进行预训练的。通常,深度信度网络 (DBN) 用于预训练这些网络。生成式预训练会创建多层逐渐复杂的特征检测器。一旦生成式预训练完成,网络会被判别性地微调以分类正确的 HMM 状态,基于声学特征。这些混合模型中的 HMMs 用于将由 DNNs 提供的段分类与完整标签序列的时间分类对齐。已经证明这些 DNN-HMM 模型比 GMM-HMM 模型具有更好的电话识别性能 [36]。

循环神经网络

本节描述了如何使用 RNN 模型来对序列数据进行建模。直接应用 RNN 在语音识别上的问题在于训练数据的标签需要与输入完全对齐。如果数据对齐不好,那么输入到输出的映射将包含太多噪音,网络无法学到任何东西。一些早期的尝试试图通过使用混合 RNN-HMM 模型来建模声学特征的序列上下文,其中 RNN 将模拟 HMM 模型的发射概率,很类似 DBNs 的使用 [37] 。

后来的实验尝试训练 LSTM(见 短期记忆一节)输出给定帧的音素后验概率 [38]。

语音识别的下一步将是摆脱需要对齐标记数据的必要性,并消除混合 HMM 模型的需要。

CTC

标准 RNN 目标函数独立定义了每个序列步骤,每个步骤输出自己独立的标签分类。这意味着训练数据必须与目标标签完全对齐。然而,可以制定一个全局目标函数,最大化完全正确标记的概率。其思想是将网络输出解释为给定完整输入序列的所有可能标记序列的条件概率分布。然后可以通过搜索给定输入序列的最可能标记来将网络用作分类器。

连接主义 时间分类 (CTC) 是一种优化函数,它定义了所有输出序列与所有输出对齐的分布 [39]。它试图优化输出序列与目标序列之间的整体编辑距离。这种编辑距离是将输出标签更改为目标标签所需的最小插入、替换和删除次数。

CTC 网络在每个步骤都有一个 softmax 输出层。这个 softmax 函数输出每个可能标签的标签分布,还有一个额外的空白符(Ø)。这个额外的空白符表示该时间步没有相关标签。因此,CTC 网络将在输入序列的任何点输出标签预测。然后通过从路径中删除所有空白和重复标签,将输出转换为序列标记。这相当于在网络从预测无标签到预测标签,或者从预测一个标签到另一个标签时输出一个新的标签。例如,“ØaaØabØØ”被转换为“aab”。这样做的效果是只需要确保整体标签序列正确,从而消除了对齐数据的需要。

进行这种简化意味着可以将多个输出序列简化为相同的输出标签。为了找到最可能的输出标签,我们必须添加所有与该标签对应的路径。搜索这个最可能的输出标签的任务称为解码(见解码部分)。

在语音识别中这样的标注示例可以输出一系列音素,给定一系列声学特征。基于 LSTM 的 CTC 目标函数的功能是在声学建模上提供最先进的结果,并且消除了使用 HMM 对时间变化进行建模的需要 [40],[41]。

基于注意力的模型

使用 CTC 序列到序列模型的替代方案是基于注意力的模型 [42]。这些注意力模型具有动态关注输入序列部分的能力。这使它们能够自动搜索输入信号的相关部分以预测正确的音素,而无需对部分进行明确的分割。

这些基于注意力的序列模型由一个 RNN 组成,它将输入的表示解码为一系列标签,在这种情况下是音素。在实践中,输入表示将由一个模型生成,该模型将输入序列编码为合适的表示。第一个网络称为解码器网络,而后者称为编码器网络 [43]。

解码器由一个注意力模型引导,该模型在编码的输入上的每一步都集中在一个注意力窗口上。注意力模型可以由上下文(它正在关注的内容)或基于位置的信息(它正在关注的位置)的组合驱动。然后,解码器可以使用先前的信息和注意力窗口的信息来输出下一个标签(音素)。

解码

一旦我们用声学模型对音素分布进行建模并训练了语言模型(参见语言建模部分),我们就可以将它们与发音词典结合起来得到一个单词在音频特征上的概率函数:

P(单词|音频特征)= P(音频特征|音素)* P(音素|单词)* P(单词)*

这个概率函数还没有给出最终的转录结果;我们仍然需要在单词序列的分布上进行搜索,以找到最可能的转录。这个搜索过程被称为解码。解码的所有可能路径可以用格数据结构来表示:


修剪后的词格 [44]

给定一系列音频特征序列,最可能的单词序列是通过搜索所有可能的单词序列来找到的 [33]。一种基于动态规划的流行搜索算法,它保证可以找到最可能的序列是维特比算法 [45]。这个算法是一种广度优先搜索算法,主要与在 HMM 中找到最可能的状态序列相关联。

对于大词汇量的语音识别,维特比算法在实践中变得难以处理。因此,在实践中,启发式搜索算法,如束搜索,被用来尝试找到最可能的序列。束搜索启发式只在搜索过程中保留前 n 个最佳解,并假设其余所有解不会导致最可能的序列。

存在许多不同的解码算法 [46],而从概率函数中找到最佳转录的问题大多被视为未解决。

端到端模型

我们想要通过提及端到端技术来总结本章内容。深度学习方法,例如 CTC [47]、[48]和基于注意力的模型 [49],使我们能够以端到端的方式学习完整的语音识别流程。它们这样做而不需要显式地建模音素。这意味着这些端到端模型将在一个单一模型中学习声学模型和语言模型,并直接输出单词的分布。这些模型通过将所有内容合并到一个模型中展示了深度学习的力量;通过这样做,模型在概念上变得更容易理解。我们推测这将导致语音识别在未来几年被认为是一个已解决的问题。

摘要

在本章的开头,我们学习了什么是 RNN,如何训练它们,在训练过程中可能出现的问题以及如何解决这些问题。在第二部分中,我们描述了语言建模的问题以及 RNN 如何帮助我们解决一些建模语言的困难。第三部分以一个实际示例的形式将这些信息汇集在一起,介绍了如何训练一个基于字符级的语言模型,以生成基于列夫·托尔斯泰的《战争与和平》的文本。最后一节简要概述了深度学习,特别是 RNN 如何应用于语音识别问题。

本章讨论的 RNN 是一种非常强大的方法,当涉及到许多任务时非常有前途,例如语言建模和语音识别。它们特别适用于建模序列问题,可以在序列上发现模式。

参考文献

Python 深度学习(二)(4)https://developer.aliyun.com/article/1511971

相关文章
|
1天前
|
机器学习/深度学习 人工智能 算法
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
14 0
|
9天前
|
机器学习/深度学习 自然语言处理 TensorFlow
使用Python实现深度学习模型:注意力机制(Attention)
使用Python实现深度学习模型:注意力机制(Attention)
22 0
使用Python实现深度学习模型:注意力机制(Attention)
|
11天前
|
机器学习/深度学习 数据可视化 PyTorch
使用Python实现深度学习模型:迁移学习与预训练模型
使用Python实现深度学习模型:迁移学习与预训练模型
32 0
|
12天前
|
机器学习/深度学习 人工智能 算法
食物识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
食物识别系统采用TensorFlow的ResNet50模型,训练了包含11类食物的数据集,生成高精度H5模型。系统整合Django框架,提供网页平台,用户可上传图片进行食物识别。效果图片展示成功识别各类食物。[查看演示视频、代码及安装指南](https://www.yuque.com/ziwu/yygu3z/yhd6a7vai4o9iuys?singleDoc#)。项目利用深度学习的卷积神经网络(CNN),其局部感受野和权重共享机制适于图像识别,广泛应用于医疗图像分析等领域。示例代码展示了一个使用TensorFlow训练的简单CNN模型,用于MNIST手写数字识别。
37 3
|
14天前
|
机器学习/深度学习 存储 TensorFlow
Python 深度学习(一)(4)
Python 深度学习(一)
29 2
|
14天前
|
机器学习/深度学习 算法 算法框架/工具
Python 深度学习(一)(3)
Python 深度学习(一)
34 2
|
14天前
|
机器学习/深度学习 算法 自动驾驶
Python 深度学习(一)(2)
Python 深度学习(一)
31 1
|
14天前
|
机器学习/深度学习 人工智能 算法
Python 深度学习(一)(1)
Python 深度学习(一)
16 1
|
14天前
|
机器学习/深度学习 分布式计算 算法
Python 深度学习(三)(4)
Python 深度学习(三)
19 0
|
14天前
|
机器学习/深度学习 运维 算法
Python 深度学习(三)(3)
Python 深度学习(三)
15 0
Python 深度学习(三)(3)