深度学习之LSTM案例分析(一)

#背景知识

见《深度学习之tensorflow(六)》【https://blog.csdn.net/m0_37621024/article/details/88680580

 

#《深度学习之tensorflow(六)》中的代码

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

#载入数据集
mnist = input_data.read_data_sets('MNIST_data/',one_hot=True)

#输入图片是28*28
n_inputs = 28 #输入一行,一行有28个数据
max_time = 28 #一共28行
lstm_size = 100 #隐层单元
n_classes = 10 #10个分类
batch_size = 50 #每批次50个样本
n_batch = mnist.train.num_examples // batch_size #计算一共有多少个批次

#这里的none表示第一个维度可以是任意的长度
x = tf.placeholder(tf.float32,[None,784]) '''784=28*28'''
#正确的标签
y = tf.placeholder(tf.float32,[None,10])

#初始化权值
weights = tf.Variable(tf.truncated_normal([lstm_size,n_classes], stddev=0.1)) '''*1'''
#初始化偏置值
biases = tf.Variable(tf.constant(0.1, shape=[n_classes]))

#定义RNN网络
def RNN(X,weights,biases):
    # inputs=[batch_size, max_time, n_inputs]
    inputs = tf.reshape(X,[-1,max_time,n_inputs]) '''*2'''
    #定义LSTM基本CELL
    lstm_cell = tf.contrib.rnn.BasicLSTMCell(lstm_size) '''*3'''
    # final_state[0]是cell_state
    # final_state[1]是hidden_state
    outputs,final_state = tf.nn.dynamic_rnn(lstm_cell,inputs,dtype=tf.float32) '''*4'''
    results = tf.nn.softmax(tf.matmul(final_state[1],weights) + biases) '''*5'''
    return results

#计算RNN的返回值
prediction = RNN(x, weights, biases)
#损失函数
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y))
#使用AdamOptimizer进行优化
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
#结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1)) #argmax返回一维张量中最大的值所在的位置
#求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) #把correct_prediction变为float32类型
#初始化
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(6): '''6次迭代'''
        for batch in range(n_batch): '''每一批次计算:'''
            batch_xs,batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
            
        acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
        print('Iter ' + str(epoch) + 'Testing Accuracy= ' + str(acc))

注释:

*1:tf.truncated_normal函数

tf.truncated_normal(
    shape,
    mean=0.0,
    stddev=1.0,
    dtype=tf.float32,
    seed=None,
    name=None
)

从截断的正态分布中输出随机值. 

生成的值遵循具有指定平均值和标准偏差的正态分布,不同之处在于其平均值大于 2 个标准差的值将被丢弃并重新选择.

{ 函数参数:

  • shape:一维整数张量或 Python 数组,输出张量的形状.
  • mean:dtype 类型的 0-D 张量或 Python 值,截断正态分布的均值.
  • stddev:dtype 类型的 0-D 张量或 Python 值,截断前正态分布的标准偏差.
  • dtype:输出的类型.
  • seed:一个 Python 整数.用于为分发创建随机种子.查看tf.set_random_seed行为.
  • name:操作的名称(可选).

函数返回值:

tf.truncated_normal函数返回指定形状的张量填充随机截断的正常值. }

https://www.w3cschool.cn/tensorflow_python/tensorflow_python-fibz28ss.html

 

*2:tf.reshape函数

reshape(
    tensor,
    shape,
    name=None
)

{ 参数:

  • tensor:一个Tensor.
  • shape:一个Tensor;必须是以下类型之一:int32,int64;用于定义输出张量的形状.
  • name:操作的名称(可选).

返回值:

该操作返回一个Tensor.与tensor具有相同的类型. }

例如:

# tensor 't' is [1, 2, 3, 4, 5, 6, 7, 8, 9]
# tensor 't' has shape [9]
reshape(t, [3, 3]) ==> [[1, 2, 3],
                        [4, 5, 6],
                        [7, 8, 9]]

# tensor 't' is [[[1, 1], [2, 2]],
#                [[3, 3], [4, 4]]]
# tensor 't' has shape [2, 2, 2]
reshape(t, [2, 4]) ==> [[1, 1, 2, 2],
                        [3, 3, 4, 4]]

# tensor 't' is [[[1, 1, 1],
#                 [2, 2, 2]],
#                [[3, 3, 3],
#                 [4, 4, 4]],
#                [[5, 5, 5],
#                 [6, 6, 6]]]
# tensor 't' has shape [3, 2, 3]
# pass '[-1]' to flatten 't'
reshape(t, [-1]) ==> [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]

# -1 can also be used to infer the shape

# -1 is inferred to be 9:
reshape(t, [2, -1]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
                         [4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 2:
reshape(t, [-1, 9]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
                         [4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 3:
reshape(t, [ 2, -1, 3]) ==> [[[1, 1, 1],
                              [2, 2, 2],
                              [3, 3, 3]],
                             [[4, 4, 4],
                              [5, 5, 5],
                              [6, 6, 6]]]

# tensor 't' is [7]
# shape `[]` reshapes to a scalar
reshape(t, []) ==> 7

https://www.w3cschool.cn/tensorflow_python/tensorflow_python-bumd2ide.html

 

*3:tf.contrib.rnn

TensorFlow RNN和单元(contrib)
用于构造 RNN 单元和附加 RNN 操作的模块

所有 RNN 单元的基本界面:
tf.contrib.rnn.RNNCell

用于 TensorFlow 核心 RNN 方法的核心 RNN 单元:
tf.contrib.rnn.BasicRNNCell
tf.contrib.rnn.BasicLSTMCell
tf.contrib.rnn.GRUCell
tf.contrib.rnn.LSTMCell
tf.contrib.rnn.LayerNormBasicLSTMCell

存储分离“RNNCell”状态的类:
tf.contrib.rnn.LSTMStateTuple

核心 RNN 单元包装器(RNNCells 包装其他 RNNCells):
tf.contrib.rnn.MultiRNNCell
tf.contrib.rnn.LSTMBlockWrapper
tf.contrib.rnn.DropoutWrapper
tf.contrib.rnn.EmbeddingWrapper
tf.contrib.rnn.InputProjectionWrapper
tf.contrib.rnn.OutputProjectionWrapper
tf.contrib.rnn.DeviceWrapper
tf.contrib.rnn.ResidualWrapper

阻止RNNCells:
tf.contrib.rnn.LSTMBlockCell
tf.contrib.rnn.GRUBlockCell

熔融RNNCells:
tf.contrib.rnn.FusedRNNCell
tf.contrib.rnn.FusedRNNCellAdaptor
tf.contrib.rnn.TimeReversedFusedRNN
tf.contrib.rnn.LSTMBlockFusedCell

LSTM样细胞:
tf.contrib.rnn.CoupledInputForgetGateLSTMCell
tf.contrib.rnn.TimeFreqLSTMCell
tf.contrib.rnn.GridLSTMCell

RNNCell包装:
tf.contrib.rnn.AttentionCellWrapper
tf.contrib.rnn.CompiledWrapper

TensorFlow 构造循环神经网络

TensorFlow 提供了一些构建循环神经网络的方法:
tf.contrib.rnn.static_rnn
tf.contrib.rnn.static_state_saving_rnn
tf.contrib.rnn.static_bidirectional_rnn
tf.contrib.rnn.stack_bidirectional_dynamic_rnn

https://www.w3cschool.cn/tensorflow_python/tensorflow_python-l8ba28vr.html

 

*4:tf.nn.dynamic_rnn函数

tf.nn.dynamic_rnn(
    cell,
    inputs,
    sequence_length=None,
    initial_state=None,
    dtype=None,
    parallel_iterations=None,
    swap_memory=False,
    time_major=False,
    scope=None
)

{ 参数:

  • cell:RNNCell的一个实例.
  • inputs:RNN输入.如果time_major == False(默认),则是一个shape为[batch_size, max_time, ...]Tensor,或者这些元素的嵌套元组.如果time_major == True,则是一个shape为[max_time, batch_size, ...]Tensor,或这些元素的嵌套元组.这也可能是满足此属性的Tensors(可能是嵌套的)元组.前两个维度必须匹配所有输入,否则秩和其他形状组件可能不同.在这种情况下,在每个时间步输入到cell将复制这些元组的结构,时间维度(从中获取时间)除外.在每个时间步输入到个cell将是一个Tensor或(可能是嵌套的)Tensors元组,每个元素都有维度[batch_size, ...].
  • sequence_length:(可选)大小为[batch_size]的int32/int64的向量.超过批处理元素的序列长度时用于复制状态和零输出.所以它更多的是正确性而不是性能.
  • initial_state:(可选)RNN的初始状态.如果cell.state_size是整数,则必须是具有适当类型和shape为[batch_size, cell.state_size]Tensor.如果cell.state_size是一个元组,则应该是张量元组,在cell.state_size中为s设置shape[batch_size, s].
  • dtype:(可选)初始状态和预期输出的数据类型.如果未提供initial_state或RNN状态具有异构dtype,则是必需的.
  • parallel_iterations:(默认值:32).并行运行的迭代次数.适用于那些没有任何时间依赖性并且可以并行运行的操作.该参数用于交换空间的时间.远大于1的值会使用更多内存但占用更少时间,而较小值使用较少内存但计算时间较长.
  • swap_memory:透明地交换推理中产生的张量,但是需要从GPU到CPU的支持.这允许训练通常不适合单个GPU的RNN,具有非常小的(或没有)性能损失.
  • time_majorinputsoutputsTensor的形状格式.如果是true,则这些 Tensors的shape必须为[max_time, batch_size, depth].如果是false,则这些Tensors的shape必须为[batch_size, max_time, depth].使用time_major = True更有效,因为它避免了RNN计算开始和结束时的转置.但是,大多数TensorFlow数据都是batch-major,因此默认情况下,此函数接受输入并以batch-major形式发出输出.
  • scope:用于创建子图的VariableScope;默认为“rnn”.

返回:

一对(outputs, state),其中:

  • outputs:RNN输出Tensor.

    如果time_major == False(默认),这将是shape为[batch_size, max_time, cell.output_size]Tensor.

    如果time_major == True,这将是shape为[max_time, batch_size, cell.output_size]Tensor.

    注意,如果cell.output_size是整数或TensorShape对象的(可能是嵌套的)元组,那么outputs将是一个与cell.output_size具有相同结构的元祖,它包含与cell.output_size中的形状数据有对应shape的Tensors.

  • state:最终的状态.如果cell.state_size是int,则会形成[batch_size, cell.state_size].如果它是TensorShape,则将形成[batch_size] + cell.state_size.如果它是一个(可能是嵌套的)int或TensorShape元组,那么这将是一个具有相应shape的元组.如果单元格是LSTMCells,则state将是包含每个单元格的LSTMStateTuple的元组.

可能引发的异常:

  • TypeError:如果cell不是RNNCell的实例.
  • ValueError:如果输入为None或是空列表. }

示例:

# create a BasicRNNCell
rnn_cell = tf.nn.rnn_cell.BasicRNNCell(hidden_size)

# 'outputs' is a tensor of shape [batch_size, max_time, cell_state_size]

# defining initial state
initial_state = rnn_cell.zero_state(batch_size, dtype=tf.float32)

# 'state' is a tensor of shape [batch_size, cell_state_size]
outputs, state = tf.nn.dynamic_rnn(rnn_cell, input_data,
                                   initial_state=initial_state,
                                   dtype=tf.float32)

''''''
# create 2 LSTMCells
rnn_layers = [tf.nn.rnn_cell.LSTMCell(size) for size in [128, 256]]

# create a RNN cell composed sequentially of a number of RNNCells
multi_rnn_cell = tf.nn.rnn_cell.MultiRNNCell(rnn_layers)

# 'outputs' is a tensor of shape [batch_size, max_time, 256]
# 'state' is a N-tuple where N is the number of LSTMCells containing a
# tf.contrib.rnn.LSTMStateTuple for each cell
outputs, state = tf.nn.dynamic_rnn(cell=multi_rnn_cell,
                                   inputs=data,
                                   dtype=tf.float32)

 

*5:tf.nn.softmax函数

tf.nn.softmax(
    logits,
    axis=None,
    name=None,
    dim=None
)

计算softmax激活。(弃用的参数)

有些参数已被弃用。它们将在将来的版本中删除。更新说明:不推荐使用dim,而是使用axis。

此函数执行相当于:

softmax = tf.exp(logits) / tf.reduce_sum(tf.exp(logits), axis)

{ 参数:

  • logits:一个非空的Tensor。必须是下列类型之一:half, float32,float64。
  • axis:将在其上执行维度softmax。默认值为-1,表示最后一个维度。
  • name:操作的名称(可选)。
  • dim:axis的已弃用的别名。

返回:

一个Tensor,与logits具有相同的类型和shape。

可能引发的异常:

  • InvalidArgumentError:如果logits为空或axis超出logits的最后一个维度。 }

 


(Placeholder)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章