引言

TensorFlow 版本1.15pip3 install tensorflow==1.15.0
这是《TensorFlow实战Google深度学习框架(第2版)》的学习笔记,所有代码在TensorFlow 1.15版本中运行正常

循环神经网络简介

上图展示了一个典型的循环神经网络(RNN),在每一时刻ttt,循环神经网络会针对该时刻的输入结合当前模型的状态给出一个输出,并更新模型状态。
循环神经网络的主题结构A的输入除了来自输入层xtx_txt​,还有一个循环的边来提供上一时刻的隐藏状态ht−1h_{t-1}ht−1​。
在每一时刻,循环神经网络的模型A在读取了xtx_txt​和ht−1h_{t-1}ht−1​之后会生成新的隐藏状态hth_tht​,并产生本时刻的输出oto_tot​。
由于模块A中的运算和变量在不同时刻是相同的,因此循环神经网络理论上可以被看作是同一个神经网络结构被无限复制的结果。

将完整的输入输出序列展开,可以得到下图所示的结构。

循环神经网络当前的状态hth_tht​是根据上一时刻的状态ht−1h_{t-1}ht−1​和当前的输入xtx_txt​共同决定的。
在时刻ttt,状态ht−1h_{t-1}ht−1​浓缩了前面序列x0,x1,⋯,xt−1x_0,x_1,\cdots,x_{t-1}x0​,x1​,⋯,xt−1​的信息,用于作为输出oto_tot​的参考。
RNN对长度为NNN的序列展开之后,可以视为一个有NNN个中间层的前馈神经网路。这个前馈神经网络没有循环链接,因此可以直接使用反向传播算法进行训练。
这样的训练方法称为沿时间反向传播(Back-Propagation Through Time,BPTT),是训练RNN最常见的方法。

以机器翻译为例来介绍RNN是如何解决实际问题的。RNN中每一个时刻的输入为需要翻译的句子中的单词。如下图所示。

需要翻译的句子为ABCD,那么RNN第一段每一个时刻的输入就分别是A、B、C和D,然后用_作为待翻译句子的结束符。
在第一段中,RNN没有输出。从结束符开始,RNN进入翻译阶段。该阶段中每一个时刻的输入是上一个时刻的输出,而最终得到的输出就是句子ABCD翻译的结果。
从图中可以看到句子ABCD对应的翻译结果就是XYZ,当输出_时翻译结束。

RNN可以看作是同一神经网络在时间序列上被复制多次的结果,这个被复制多次的结构被称之为循环体。
如何设循环体的网络结构是RNN解决实际问题的关键。下图展示了一个最简单的循环体结构。这个循环体中只使用了一个类似全连接层的神经网络结构。
下面通过下图所展示的神经网络来介绍RNN前向传播的完整流程。

RNN中状态是通过一个向量来表示的,这个向量的维度也称为RNN隐藏层的大小,假设其为nnn。从上图可以看出,循环体中的神经网络的输入有两部分,一部分为上一时刻的状态,另一部分为当前时刻的输入样本。

对于时间序列数据来说,每一时刻的输入样例可以是当前时刻的数值;对于语言模型来说,输入样例可以是当前单词对应的词向量。

假设输入向量的维度是xxx,隐藏状态的维度是nnn,那么上图中循环体的全连接层神经网络的输入大小为n+xn+xn+x(其他教程中会将上一时刻状态对应的权重和当前时刻输入对应的权重特意分开)。也就是将上一时刻的状态与当前时刻的输入拼接成一个大的向量作为循环体中神经网络的输入。
因为该全连接层的输出为当前时刻的状态,于是输出层的节点个数也为nnn,循环体中的参数个数为(n+x)×n+n(n+x) \times n + n(n+x)×n+n个。 也可以看出,循环体中的神经网络输出不但提供给了下一时刻作为状态,也提供出当前时刻的输出。

注意到循环体状态与最终输出的维度通常不同(比如在情感分析任务中,输入一段评论,输出是好评还是差评。),因此为了将当前时刻的状态转化为最终的输出,RNN还需要另外一个全连接神经网络来完成这个过程。下面展示了一个RNN前向传播的具体计算过程。

在图中,假设状态的维度是2,输入、输出的维度都是1,而且循环体中的全连接层中权重为:

Wrnn=[0.10.20.30.40.50.6]W_{rnn} = \left[ \begin{matrix} 0.1 & 0.2 \\ 0.3 & 0.4 \\ 0.5 & 0.6 \end{matrix} \right] Wrnn​=⎣⎡​0.10.30.5​0.20.40.6​⎦⎤​

偏置项的大小为brnn=[0.1,−0.1]b_{rnn} = [0.1,-0.1]brnn​=[0.1,−0.1],用于输出的全连接层权重为:

Woutput=[1.02.0]W_{output}= \left[ \begin{matrix} 1.0 \\ 2.0 \end{matrix} \right] Woutput​=[1.02.0​]

偏置项大小为boutput=0.1b_{output} = 0.1boutput​=0.1。那么在时刻t0t_0t0​,因为没有上一时刻,一般初始化状态为hinit=[0,0]h_{init}=[0,0]hinit​=[0,0],而当前的输入为1,所以拼接得到的向量为[0,0,1][0,0,1][0,0,1],通过循环体中的全连接层神经网络得到的结果为:

tanh([0,0,1]×[0.10.20.30.40.50.6]+[0.1,−0.1])=tanh([0.6,0.5])=[0.537,0.462]tanh \left( [0,0,1] \times \left[ \begin{matrix} 0.1 & 0.2 \\ 0.3 & 0.4 \\ 0.5 & 0.6 \end{matrix} \right] + [0.1,-0.1] \right ) = tanh([0.6,0.5]) =[0.537,0.462] tanh⎝⎛​[0,0,1]×⎣⎡​0.10.30.5​0.20.40.6​⎦⎤​+[0.1,−0.1]⎠⎞​=tanh([0.6,0.5])=[0.537,0.462]

这个结果将作为下一个时刻的输入状态,同时循环神经网络也会使用该状态生成输出。

将该向量作为输入提供给用于输出的前连接神经网络可以得到t0t_0t0​时刻的最终输出:

[0.537,0.462]×[1.02.0]+0.1=1.56[0.537,0.462] \times \left[ \begin{matrix} 1.0 \\ 2.0 \end{matrix} \right] + 0.1 = 1.56 [0.537,0.462]×[1.02.0​]+0.1=1.56

使用t0t_0t0​时刻的状态可以类似地推导得出t1t_1t1​时刻的状态为[0.860,0.884][0.860,0.884][0.860,0.884],而t1t_1t1​时刻的输出为2.732.732.73。
在得到循环神经网络的前向传播结果之后,可以和其他神经网络类似地定义损失函数。

循环神经网络唯一的区别在于因为它每个时刻都有一个输出,所以循环神经网络的总损失为所有时刻(或者部分时刻)上的损失函数的总和。
以下代码实现了这个简单的循环神经网络前向传播的过程:

import numpy as npX = [1,2]
state = [0.0,0.0]
# 分开定义不同输入部分的权重以方便操作
w_cell_state = np.array([[0.1,0.2],[0.3,0.4]])
w_cell_input = np.array([0.5,0.6])
b_cell = np.array([0.1,-0.1])# 定义用于输出的全连接层参数
w_output = np.array([[1.0],[2.0]])
b_output = 0.1# 按照时间顺序执行循环神经网络的前向传播过程
for i in range(len(X)):# 计算循环体中的全连接层神经网路before_activation = np.dot(state, w_cell_state) + X[i] * w_cell_input + b_cellstate = np.tanh(before_activation)# 根据当前时刻状态计算最终输出final_output = np.dot(state, w_output) + b_output# 输出每个时刻的信息print('before activation: ',before_activation)print('state: ', state)print('output: ', final_output)

输出:

before activation:  [0.6 0.5]
state:  [0.53704957 0.46211716]
output:  [1.56128388]
before activation:  [1.2923401  1.39225678]
state:  [0.85973818 0.88366641]
output:  [2.72707101]

和其他神经网络类似,在定义完损失函数后,套用优化框架TensorFlow就可以自动完成模型训练的过程。
卢纶上RNN可以支持任意长度的序列,然而如果序列过长,一方面会导致优化时出现梯度消失和梯度爆炸的问题,另一方面,展开后的前馈神经网络会占用过大的内存,所以实际上一般会规定一个最大长度。

长短期记忆网络结构

RNN存在长期依赖问题,RNN模型有效保存离当前位置很远的长下文信息。假设序列长度很长,且abs(W) < 1,每经过一个时刻,梯度就会变少一点,经过TTT时刻后可能会变成0,导致RNN无法学习到时间久远的信息。

长短期记忆网络(LSTM)的设计就是为了解决这个问题。在很多任务上,采用LSTM结构的循环神经网络比标准的循环神经网络表现更好。
LSTM是一种拥有三个门结构的特殊网络结构。

LSTM靠一些门结构让信息有选择性地影响循环神经网络中每个时刻的状态。
所有门结构就是一个使用sigmoid神经网络和一个按位做乘法的操作,这两个操作合在一起就是一个门结构。
之所以该结构叫做门是因为使用 sigmoid 作为激活函数的全连接神经网络层会输出0到1之间的数值,描述当前输入有多少信息量可以通过这个结构。
于是这个结构的功能就类似于 门, 门打开时sigmoid 经网络层输出为1时),全部信息都可以通过; 关上时( sigmoid 经网络层输出为0 ),任何信息都无法通过。

为了使循环神经网络更有效的保存长期记忆。上图中遗忘门和输入门至关重要,它们是 LSTM 结构的核心。
遗忘门的作用是让循环神经网络"忘记"之前没有用的信息。
遗忘门会根据当前的输入xtx_txt​和上一时刻输出ht−1h_{t-1}ht−1​,决定哪一部分记忆需要被遗忘。
假设状态ccc的维度为nnn。遗忘门会根据当前的输入xtx_txt​和上一时刻输出ht−1h_{t-1}ht−1​计算维度为nnn的向量f=sigmoid(W1x+W2h)f=sigmoid(W_1x+ W_2h)f=sigmoid(W1​x+W2​h),它在每一维度上的值都在(0,1)范围内。再将上一时刻的状态ct−1c_{t-1}ct−1​与fff向量按位相乘,那么fff取值接近0的维度上的信息就会被"忘记",而取值接近1的维度上的信息会被保留。

在循环神经网络"忘记"了部分之前的状态后,它还需要从当前的输入补充最新的记忆。
这个过程就是输入门完成的 。如图,"输入门"会根据xtx_txt​和ht−1h_{t-1}ht−1​决定哪些信息加入到状态ct−1c_{t-1}ct−1​中生成新的状态ctc_tct​。
这时输入门和需要写入的新状态都从xtx_txt​和ht−1h_{t-1}ht−1​计算产生。

通过遗忘门和输入门,LSTM 结构可以更加有效地决定哪些信息应该被遗忘,哪些信息应该得到保留。

LSTM结构在计算得到新的状态ctc_tct​后需要产生当前时刻的输出,这个过程是通过输出门完成的。
输出门会根据最新的状态ctc_tct​、上一时刻的输出ht−1h_{t-1}ht−1​和当前的输入xtx_txt​来决定该时刻的输出hth_tht​。

使用LSTM结构的循环神经网络的前向传播是个相对比较复杂的过程。具体LSTM每个门的公式定义如下:

z=tanh(Wz[ht−1,xt])(输入值)i=sigmoid(Wi[ht−1,xt])(输入门)f=sigmoid(Wf[ht−1,xt])(遗忘门)o=sigmoid(Wo[ht−1,xt])(输出门)ct=f⋅ct−1+i⋅z(新状态)ht=o⋅tanhct(输出)z = tanh(W_z[h_{t-1},x_t])\,\,\,\,\,\,\,\,(输入值)\\ i = sigmoid(W_i[h_{t-1},x_t])\,\,\,\,\,\,\,\,(输入门)\\ f = sigmoid(W_f[h_{t-1},x_t])\,\,\,\,\,\,\,\,(遗忘门)\\ o = sigmoid(W_o[h_{t-1},x_t])\,\,\,\,\,\,\,\,(输出门)\\ c_t = f \cdot c_{t-1} + i \cdot z\,\,\,\,\,\,\,\,(新状态)\\ h_t = o \cdot tanh c_t\,\,\,\,\,\,\,\,(输出) z=tanh(Wz​[ht−1​,xt​])(输入值)i=sigmoid(Wi​[ht−1​,xt​])(输入门)f=sigmoid(Wf​[ht−1​,xt​])(遗忘门)o=sigmoid(Wo​[ht−1​,xt​])(输出门)ct​=f⋅ct−1​+i⋅z(新状态)ht​=o⋅tanhct​(输出)

其中Wz,Wi,Wf,WoW_z,W_i,W_f,W_oWz​,Wi​,Wf​,Wo​是4个维度为[2n,n][2n,n][2n,n]的参数矩阵。下图用流程图的形式展示了上面的公式。

整个流程的输入为:ct−1,ht−1,xtc_{t-1},h_{t-1},x_tct−1​,ht−1​,xt​,输出为:ct,htc_t,h_tct​,ht​。

在TensorFlow中,LSTM结构可以被很简单地实现,以下代码展示了在TensorFlow中实现LSTM的前向传播过程:

import tensorflow as tf# 定义一个LSTM结构,在TensorFlow中通过rnn_cell_BasicLSTMCell就可以实现一个完整LSTM结构
# LSTM使用的变量也会在该函数中自动被声明
lstm = tf.nn.rnn_cell_BasicLSTMCell(lstm_hidden_size)# 初始化全0的状态
# state是一个包含两个张量LSTMStateTuple类,其中state.c好state.h分别对应与上图中的c和h状态
state = lstm.zero_state(batch_size, tf.float32)# 定义损失函数
loss = 0.0
# 用num_steps表示训练数据的序列长度
for i in range(num_steps):# 在第一个时刻声明LSTM结构中使用的变量,在之后的时刻都需要复用之前定义好的变量。if i > 0:tf.get_variable_scope().reuse_variables()# 每一步处理时间序列中的一个时刻,将当前输入current_input(图中的xₜ)# 和前一时刻状态state(hₜ₋₁和cₜ₋₁)传入定义的LSTM结构可以得到当前LSTM的输出lstm_output(hₜ)# 和更新后状态state(hₜ和cₜ)。# lstm_output用于输出给其他层,state用于输出给下一时刻lstm_output, state = lstm(current_input, state)# 将当前时刻LSTM结构的输出传入一个全连接层得到最后的输出final_output = full_connected(lstm_output)# 计算当前时刻输出的损失loss += calc_loss(final_output, expected_output)

循环神经网络的变种

双向循环神经网络和深层循环神经网络

在经典的循环神经网络中,状态的传输是从前往后单向的。然而,在有些问题中,当前时刻的输出不仅和之前的状态有关系,也和之后的状态相关。
这时就需要使用双向循环神经网络(bidirectional RNN)来解决这类问题。
例如预测一个语句中缺失的单词不仅需要根据前文来判断,也需要根据后面的内容,这时双向循环网络就可以发挥它的作用 。
双向循环神经网络是由两个独立的循环神经网络叠加在一起组成的。
输出由这两个循环神经网络的输出拼接而成。
下图展示了一个双向循环神经网络的结构图。

从图中可以看出,双向循环神经网络的主题结构就是两个单向循环神经网络的结合。在每一个时刻ttt,输入会同时提供给这两个方向相反的循环神经网络。
两个网络独立进行计算,各自产生该时刻的新状态和输出,而双向循环神网络的最终输出是这两个单向循环神经网络的输出的简单拼接。

两个循环神经网络除方向不同以外,其余结构完全对称。每一层网络中的循环体可以自由选用任意结构,如前面介绍过的简单RNN、LSTM均作为向循环网络的循环体。双向循环神经网络的前向传播过程和单向的循环神经网络十分类似。


深层循环神经网络是循环神经网络的另外一种变种。在网络中设置了多个循环层,将每层询函网络的输出传给下一层间处理。增强模型的表达能力。 如上图所示,在一个LLL层的深层循环网络中,每一时刻的输入xtx_txt​到输出oto_tot​之间有LLL个循环体,网络因此可以从输入中抽取更加高层的信息。
TensorFlow中提供了MultiRNNCell类来实现深层循环神经网络的前向传播过程:

lstm_cell = tf.nn.rnn_cell.BasicLSTMCell
# number_of_layers表示有多少层
stacked_lstm = tf.nn.rnn_cell.MultiRNNCell([lstm_cell(lstm_size) for _ in range(number_of_layers)])# 通过zero_state函数来获取初始状态
state = stacked_lstm.zero_state(batch_size, tf.float32)# 计算每一时刻的前向传播结果
for i in range(len(num_steps)):if i >0:tf.get_variable_scope().reuse_variables()stacked_lstm_output, state = stacked_lstm(current_input, state)final_output = fully_connected(stacked_lstm_output)loss += calc_loss(final_output, expected_output)

循环神经网络的dropout


(图中实现箭头表示不使用dropout,虚线箭头表示使用dropout)

循环神经网络也可以使用dropout,一般只在不同循环体结构之间使用dropout,而不再同一层的循环体结构之间使用。

也就是说从时刻t−1t-1t−1传递到时刻ttt时,循环神经网络不会进行状态的dropout;而在同一时刻t中,不同层循环体之间会使用dropout

上图展示了循环神经网络使用dropout的方法。假设要从t−2t-2t−2时刻的输入xt−2x_{t-2}xt−2​传递到t+1t+1t+1时刻的输出yt+1y_{t+1}yt+1​,那么xt−2x_{t-2}xt−2​将首先传入第一层循环体结构,这个过程会使用dropout

但是从t−2t-2t−2时刻的第一层循环体结构传递到第一层的t−1,t,t+1t-1,t,t+1t−1,t,t+1时刻不会使用dropout。在t+1t+1t+1时刻的第一层循环体结构传递到同一时刻内更高层的循环体结构时,会再次使用dropout

使用tf.nn.rnn_cell.DropoutWrapper类可以很容易实现dropout功能。
以下代码展示了如何在TensorFlow中实现带dropout的循环神经网络:

# 使用DropoutWrapper类来实现dropout功能
stacked_lstm = rnn_cell.MultiRNNCell([tf.nn.rnn_cell.DropoutWrapper(lstm_cell(lstm_size)) for _ in range(number_of_layers)])
)

循环神经网络样例应用

这一节以时序预测为例,利用循环神经网络实现对sin⁡x\sin xsinx取值的预测。


下面给出使用TensorFlow实现预测正弦函数sinsinsin。因为循环神经网络模型预测的是离散时刻的取值,所以在程序中需要将连续的sinsinsin函数曲线离散化。

所谓离散化就是在一个给定的区间[0,MAX]内,通过有限个采样点模拟一个连续的曲线。
比如在以下程序中每隔SAMPLE_ITERVAL对sinsinsin函数进行一次采样,采样得到的序列就是sinsinsin函数离散化之后的结果。

以下程序为预测离散化之后的sinsinsin函数。

import numpy as np
import tensorflow as tf
import matplotlib as mpl
mpl.use('Agg')
from matplotlib import pyplot as plt
%matplotlib inlineHIDDEN_SIZE = 30 #LSTM中隐藏节点的个数
NUM_LAYERS = 2 # LSTM的层数
TIME_STEPS = 10 #RNN的训练序列长度
TRAINING_STEPS = 10000 #训练轮数
BATCH_SIZE = 32 #batch大小TRAINING_EXAMPLES = 10000 #训练数据个数
TESTING_EXAMPLES = 1000 #测试数据个数
SAMPLE_GAP = 0.01 #采样间隔def generate_data(seq):X = []y = []# 序列的第i项和后面的TIME_STEPS- 1项合在一起作为输入;# 第i+TIME_STEPS项作为输出。# 即用sin函数前面的TIME_STEPS个点的信息,预测第i+TIME_STEPS个点的函数值for i in range(len(seq) - TIME_STEPS):X.append([seq[i: i + TIME_STEPS]])y.append([seq[i + TIME_STEPS]])return np.array(X,dtype=np.float32), np.array(y, dtype=np.float32)def lstm_model(X, y, is_training):# 使用多层的LSTM结构cell = tf.nn.rnn_cell.MultiRNNCell([tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE) for _ in range(NUM_LAYERS)])# 使用TensorFlow接口将多层的LSTM结构连接成RNN网络并计算其前向传播结果。outputs, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)# outputs是顶层LSTM在每一步的输出结果,它的维度是[batch_size, time, HIDDEN_SIZE]# 在本问题只关注最后一个时刻的输出结果output = outputs[:, -1, :]# 对LSTM网络的输出再做一个加一层全连接层并计算损失,这里默认的损失为平均平方差损失函数predictions = tf.contrib.layers.fully_connected(output, 1, activation_fn=None)# 只在训练时计算损失函数和优化步骤if not is_training:return predictions, None, None# 计算损失函数loss = tf.losses.mean_squared_error(labels=y, predictions=predictions)# 创建模型优化器并得到优化步骤train_op = tf.contrib.layers.optimize_loss(loss, tf.train.get_global_step(),optimizer='Adagrad', learning_rate=0.1)return predictions, loss, train_opdef train(sess, X_train,y_train):# 将训练数据以数据集的方式提供给计算图ds = tf.data.Dataset.from_tensor_slices((X_train,y_train))ds = ds.repeat().shuffle(1000).batch(BATCH_SIZE)X, y = ds.make_one_shot_iterator().get_next()# 调用模型,得到预测结果、损失函数和训练操作with tf.variable_scope('model'):predictions, loss, train_op = lstm_model(X, y,True)# 初始化变量sess.run(tf.global_variables_initializer())for i in range(TRAINING_STEPS):_, l = sess.run([train_op, loss])if i % 100 == 0:print('train step:' + str(i) + ', loss: ' + str(l))def run_eval(sess,X_test,y_test):# 将测试数据以数据集的方式提供给计算图ds = tf.data.Dataset.from_tensor_slices((X_test,y_test))ds = ds.batch(1)X, y = ds.make_one_shot_iterator().get_next()# 调用模型得到计算结果,这里不需要输入真实的y值with tf.variable_scope('model', reuse=True):prediction, _, _ = lstm_model(X,[0.0], False)# 将预测结果存入一个数组predictions = []labels = []for i in range(TESTING_EXAMPLES):p, l = sess.run([prediction, y]) # prediction返回预测结果,y是真实标签,是张量形式,其实就是lpredictions.append(p)labels.append(l)# 计算rmse作为评价指标predictions =np.array(predictions).squeeze()labels = np.array(labels).squeeze()rmse = np.sqrt(((predictions - labels) ** 2).mean(axis=0))print('Mean Square Error is : %f' % rmse)# 对预测的sin函数曲线进行绘图plt.figure()plt.plot(predictions, label='predictions')plt.plot(labels, label='real_sin')plt.legend()plt.show()# 用正弦函数生成训练和测试数据集合test_start = (TRAINING_EXAMPLES + TIME_STEPS) * SAMPLE_GAP
test_end = test_start + (TESTING_EXAMPLES + TIME_STEPS) * SAMPLE_GAPX_train, y_train = generate_data(np.sin(np.linspace(0,test_start,TRAINING_EXAMPLES + TIME_STEPS, dtype=np.float32)))
X_test, y_test = generate_data(np.sin(np.linspace(test_start,test_end,TESTING_EXAMPLES+ TIME_STEPS, dtype=np.float32)))with tf.Session() as sess:# 训练模型train(sess, X_train, y_train)run_eval(sess, X_test,y_test)

输出

train step:0, loss: 0.46630305
train step:100, loss: 0.004968104
train step:200, loss: 0.0039649797
train step:300, loss: 0.003130244
train step:400, loss: 0.0033371607
train step:500, loss: 0.002481162
train step:600, loss: 0.001641924
train step:700, loss: 0.0011706473
train step:800, loss: 0.001559411
train step:900, loss: 0.0014115167
...
train step:9600, loss: 3.721119e-06
train step:9700, loss: 3.12407e-06
train step:9800, loss: 4.0001687e-06
train step:9900, loss: 3.608016e-06
Mean Square Error is : 0.001973

可以看到预测得到的结果和真实的sinsinsin函数几乎是重合的。也就是说,通过RNN可以非常好地预测sinsinsin函数的取值。

TensorFlow学习笔记——循环神经网络相关推荐

  1. TensorFlow学习笔记——深层神经网络

    引言 TensorFlow 版本1.15pip3 install tensorflow==1.15.0. 这是<TensorFlow实战Google深度学习框架(第2版)>的学习笔记,所有 ...

  2. 深度学习笔记——循环神经网络RNN/LSTM

    原文来自知乎专栏NLP进阶之路,作者韦伟. 以下文章是摘录了原文部分内容的学习笔记,侵删. 循环神经网络(Rerrent Neural Network) RNN是神经网络的一种,RNN对具有序列特性的 ...

  3. NLP学习笔记-循环神经网络RNN、情感分类、LSTM(二)

    循环神经网络和自然语言处理介绍 1. 文本的tokenization 1.1 概念和工具的介绍 tokenization就是通常所说的分词,分出的每一个词语我们把它称为token. 常见的分词工具很多 ...

  4. Tensorflow学习笔记——搭建神经网络

    目录 1.搭建神经网络6步法 2.函数用法和介绍 (1)tf.keras.models.Sequential() (2)Model.compile() (3)model.fit() (4)model. ...

  5. tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数

    tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报  分类: tensorflow(4)  目录(?)[+] 本笔记目的 ...

  6. 【深度学习】循环神经网络(RNN)的tensorflow实现

    [深度学习]循环神经网络(RNN)的tensorflow实现 一.循环神经网络原理 1.1.RNN的网络结构 1.2.RNN的特点 1.3.RNN的训练 二.循环神经网络的tensorflow实现 参 ...

  7. tensorflow学习笔记——使用TensorFlow操作MNIST数据(1)

    续集请点击我:tensorflow学习笔记--使用TensorFlow操作MNIST数据(2) 本节开始学习使用tensorflow教程,当然从最简单的MNIST开始.这怎么说呢,就好比编程入门有He ...

  8. tensorflow学习笔记1

    tensorflow学习笔记1 本文主要记录我在慕课上观看北大曹建老师的<人工智能实践:Tensorflow笔记>,链接:https://www.icourse163.org/course ...

  9. TensorFlow学习笔记--第三节张量(tensor)及其定义方法

    目录 在TensorFlow中,所有的数据通过张量的形式来表示 1张量及属性: 1.1维数(阶) 1.2 形状 1.3数据类型 TensorFlow 支持以下三种类型的张量: **1.常量** **2 ...

  10. tensorflow学习笔记(八):LSTM手写体(MNIST)识别

    文章目录 一.LSTM简介 二.主要函数 三.LSTM手写体(MNIST)识别 1.MNIST数据集简介 2.网络描述 3.项目实战 一.LSTM简介 LSTM是一种特殊的RNN,很好的解决了RNN中 ...

最新文章

  1. 动态加载的html没有js效果,JS利用html5实现loadding动态加载效果代码实例
  2. jni java c++ 参数传递问题解决
  3. 最短网络 Agri-Net
  4. iOS开发之复制字符串到剪贴板
  5. 涨价妥妥的!一加7 Pro欧洲价格曝光:顶配或超6000
  6. 分析器错误信息: 未能加载类型命名空间.类...
  7. 用python爬取杭电oj的数据
  8. 程序设计语言及其文法
  9. js获取当前页面url信息
  10. python源文件是什么意思_.py文件是什么?
  11. matlab 盒形图怎么画,请问如何用sas画盒形图?程序是什么?谢谢!
  12. 悉尼大学计算机科学专业,悉尼大学计算机科学专业
  13. markdown语法中的空格_MarkDown语法
  14. Pizza Cutter Gym - 101908C
  15. C++运算符重载(简单易懂)
  16. [整理][VBA]Excel合并表格
  17. 什么是python 包_什么是python包
  18. win10安装linux子系统详细教程(非虚拟机方式)
  19. 联合分布(一):什么是概率分布
  20. SysML图例-核聚变

热门文章

  1. SSCLI中GC源码分析(1) - EE与BCL之间的调用接口FCall
  2. 最近一个快要结束的项目的BUG分析
  3. mysql grant权限分配(转)。
  4. 变革中国:市场经济的中国之路
  5. 新手小白之学习python一飞冲天日志之—基本数据类型,条件控制语句
  6. go学习笔记-包处理
  7. JS原型链原理(链表)
  8. 为什么需要软件过程改善(Software Process Improvement)?
  9. Linux和Win文件互传及vim的使用
  10. huawei交换机普通远程登陆配置