#背景知识
见《深度学习之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_major
:inputs
和outputs
Tensor的形状格式.如果是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)