DAY3--RNN神经网络学习笔记

单层RNN创建

import tensorflow as tf
import numpy as np

cell = tf.nn.rnn_cell.BasicRNNCell(num_units=128) # state_size = 128
print(cell.state_size) # 128

inputs = tf.placeholder(np.float32, shape=(32, 100)) # 32 是 batch_size,100是input_size  shape = (batch_size, input_size)
h0 = cell.zero_state(32, np.float32) # 通过zero_state得到一个全0的初始状态,形状为(batch_size, state_size)
output, h1 = cell.call(inputs, h0) #调用call函数

print(h1.shape) # (32, 128)

多层RNN创建

import tensorflow as tf
import numpy as np
# 每调用一次这个函数就返回一个BasicRNNCell
def get_a_cell():
   return tf.nn.rnn_cell.BasicRNNCell(num_units=128)
# 用tf.nn.rnn_cell MultiRNNCell创建3层RNN,每层神经元具有128个
cell = tf.nn.rnn_cell.MultiRNNCell([get_a_cell() for _ in range(3)]) # 3层RNN
# 得到的cell实际也是RNNCell的子类
# 它的state_size是(128, 128, 128)
# (128, 128, 128)并不是128x128x128的意思
# 而是表示共有3个隐层状态,每个隐层状态的大小为128
print(cell.state_size) # (128, 128, 128)
# 使用对应的call函数
inputs = tf.placeholder(np.float32, shape=(32, 100)) # 32 是 batch_size
h0 = cell.zero_state(32, np.float32) # 通过zero_state得到一个全0的初始状态,得到的输出为128
output, h1 = cell.call(inputs, h0)
print(h1) # tuple中含有3个32x128的向量

学习如何一次执行多步:tf.nn.dynamic_rnn

# inputs: shape = (batch_size, time_steps, input_size) 
# cell: RNNCell
# initial_state: shape = (batch_size, cell.state_size)。初始状态。一般可以取零矩阵
# inputs: shape = (batch_size, time_steps, input_size) 
# cell: RNNCell
# initial_state: shape = (batch_size, cell.state_size)。初始状态。一般可以取零矩阵

import tensorflow as tf

tf.reset_default_graph() 
batch_size = 32 # batch大小
input_size = 100 # 输入向量xt维度
state_size = 128 # 隐藏状态ht维度
time_steps = 10 # 序列长度  训练的循环次数,即训练每个词的预示范围

inputs = tf.random_normal(shape=[batch_size, time_steps, input_size], dtype=tf.float32)
print("inputs.shape:",inputs.shape) #(32,10,100)

lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units = state_size)
print(lstm_cell.state_size) #(c=128,h=128)

initial_state = lstm_cell.zero_state(batch_size, dtype = tf.float32)
print(initial_state.h, initial_state.c)  #(32,128),(32,128)

outputs, state = tf.nn.dynamic_rnn(lstm_cell, inputs, initial_state = initial_state)

print(outputs)  #(32,10,128)
print(state)    #(32,128) state是最终(最后一个time_step)的状态
print(state.h, state.c) #(32,128),(32,128)


比较好理解的回答:

文本处理中,一个单词代表一个timestep,在inference的时候,只能一个单词一个单词地输出;而在train的时候,我们有整个句子,因此可以一次feed若干个单词,比如Google is better than Apple,timestep为5,同时训练目标为is better than Apple [END]。
作者:尤洋
链接:https://www.zhihu.com/question/271774530/answer/364711129
来源:知乎

知乎中比较好的问题:

如何理解LSTM中的time step? - 尤洋的回答 - 知乎 https://www.zhihu.com/question/271774530/answer/364711129 评论中其他用户比较好的提问如下:

【1】鸟与声俱去(提问):假如train的时候time step是5,那weight的纬度不应该和time step的维度一致吗?所以在test时,只输入time step为1的数据,和weight的纬度不符啊?

HankGuo(回答):这个不是维度,既然是循环神经网络,循环的次数就是任意的,time step是循环次数。每次循环是一个单词,维度是单词的词向量。另外train和test的时候应该time step不一致。seq2seq的编码是大于1,解码等于1。

尤洋(回答):训练的时候会给如[batch_size, time_step, word_dim]维度的数据,最后一维是每个单词的embedding向量,每循环一次就将[batch_size, word_dim]输入一次,一共输入time_step次。

【2】荀日新(提问):请教一下,time_step就是rnn单元的个数吗?

尤洋(回答):两者不是一个东西,rnn个数是hidden layer和cell state的维度,time step是循环次数。

【3】q娃娃(提问):您好,请教一下,在时间序列中,time_step该如何理解?期待您的回复,非常感谢!

尤洋(回答):好比你有[batch, t, w]的数据,第一维是Batch,第二维是句子长度,第三维是每个单词的embedding,那么rnn就会循环t次,每次循环拿上一次的结果,以及这次的[batch, w]作为y输入。

【4】以梦为马(提问):您好,我还有个问题想问下,time step为1的时候,是不是可以理解为用前一个数据去预测后一个数据?但是这样感觉很不靠谱?

尤洋(回答):因为有Hidden state,前一个数据实际上是[hidden state, x],是整合了之前的信息的。

LSTM简单例子

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

mnist = input_data.read_data_sets('MINIST_data', one_hot=True)
#读出mnist数据

weight = {
    # 128====>hidden cell num ;
    'first': tf.Variable(tf.random_normal([28, 128])),#输入层权值矩阵,转化为128输出,输入到RNN层中
    'last': tf.Variable(tf.random_normal([128, 10]))#输出层权值矩阵
}
#权重字典

bias = {
    'first': tf.Variable(tf.constant(0.1, shape=[128, ])),
    'last': tf.Variable(tf.constant(0.1, shape=[10, ]))
}


def RNN(X, weights, biases):#X是一个三维数据[batch_size, step , pixel]
    X = tf.reshape(X, shape=[-1, 28]) #重构输入数据集,转化为2维输入,[批,输入尺寸]
    X_in = tf.matmul(X, weight['first']) + bias['first'] #全连接层实现
    X_in = tf.reshape(X_in, shape=[-1, 28, 128])#经过全连接层后X = [batch_size , step , output],这里的step指图片的相关性,
    # 用前28个数据预测该值,也可以说是句子的长度

    lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=128)#创建一个LSTMCell层,隐层神经元有128个,即有128个输出
    init_state = lstm_cell.zero_state(128, dtype=tf.float32)#创建初始状态矩阵


    outputs, state = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=init_state, time_major=False)#进行一次
    '''
    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
tf.nn.dynamic_rnn的返回值有两个:outputs和state
为了描述输出的形状,先介绍几个变量,batch_size是输入的这批数据的数量,max_time就是这批数据中序列的最长长度,
如果输入的三个句子,那max_time对应的就是最长句子的单词数量,cell.output_size其实就是rnn cell中神经元的个数。

outputs是一个tensor
如果time_major==True,outputs形状为 [max_time, batch_size, cell.output_size ](要求rnn输入与rnn输出形状保持一致)
如果time_major==False(默认),outputs形状为 [ batch_size, max_time, cell.output_size ]

state是一个tensor。state是最终的状态,也就是序列中最后一个cell输出的状态。一般情况下state的形状为 [batch_size, cell.output_size ],
但当输入的cell为BasicLSTMCell时,state的形状为[2,batch_size, cell.output_size ],其中2也对应着LSTM中的cell state和hidden state
)
    '''

    # results = tf.matmul(final_state[1], weight['last']) + bias['last']
    results = tf.layers.dense(outputs[:, -1, :], 10)#全连接层实现,将RNN网络输出值转化为10个输出 全连接层执行操作 outputs = activation(inputs.kernel+bias)
    """
    tf.layers.dense(
    inputs,
    units,
    activation=None,
    use_bias=True,
    kernel_initializer=None,  ##卷积核的初始化器
    bias_initializer=tf.zeros_initializer(),  ##偏置项的初始化器,默认初始化为0
    kernel_regularizer=None,    ##卷积核的正则化,可选
    bias_regularizer=None,    ##偏置项的正则化,可选
    activity_regularizer=None,   ##输出的正则化函数
    kernel_constraint=None,   
    bias_constraint=None,
    trainable=True,
    name=None,  ##层的名字
    reuse=None  ##是否重复使用参数
)
    """
    return results


x = tf.placeholder(tf.float32, [None, 28, 28])#图片尺寸
y = tf.placeholder(tf.float32, [None, 10])#输出层尺寸

pred = RNN(x, weight, bias)
# loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=pred, logits=y))
loss = tf.losses.softmax_cross_entropy(onehot_labels=y, logits=pred)#计算损失值,交叉熵
train = tf.train.AdamOptimizer(0.01).minimize(loss)#ADAM优化

correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))#对比测试矩阵中与标签矩阵中的相等数量
"""tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩阵维度和A是一样的
import tensorflow as tf
import numpy as np
A = [[1,3,4,5,6]]
B = [[1,3,4,3,2]]
with tf.Session() as sess:
    print(sess.run(tf.equal(A, B)))
输出:[[ True True True False False]]
2、tf.argmax(input, axis=None, name=None, dimension=None)
此函数是对矩阵按行或列计算最大值,输出最大值的下标
参数
input:输入Tensor
axis:0表示按列,1表示按行
name:名称
dimension:和axis功能一样,默认axis取值优先。新加的字段
返回:Tensor 一般是行或列的最大值下标向量
"""

accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))#计算正确率

init = tf.global_variables_initializer()#初始化placeholder

with tf.Session() as sess:#执行会话
    sess.run(init)
    step = 0
    for step in range(1200):
        step += 1
        batch_x, batch_y = mnist.train.next_batch(128)
        batch_x = batch_x.reshape([128, 28, 28])
        sess.run(train, feed_dict={x: batch_x, y: batch_y})

        if step % 50 == 0:
            print(sess.run(accuracy, feed_dict={x: batch_x, y: batch_y}))

https://blog.csdn.net/littlely_ll/article/details/79671393
RNN函数解析

发布了17 篇原创文章 · 获赞 1 · 访问量 3426

猜你喜欢

转载自blog.csdn.net/weixin_43983570/article/details/105174736
今日推荐