zoukankan      html  css  js  c++  java
  • tensorflow学习之(十一)RNN+LSTM神经网络的构造

    #RNN 循环神经网络
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    tf.set_random_seed(1)   # set random seed
    
    # 导入数据
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    
    # hyperparameters
    lr = 0.001                  # learning rate
    training_iters = 1000000     # train step 上限 循环次数
    batch_size = 128
    n_inputs = 28               # MNIST data input (img shape: 28*28) 指图片一行有28个像素,RNN每次提取一行
    n_steps = 28                # time steps 指图片有28行,所以RNN需要提取28次
    n_hidden_units = 128        # neurons in hidden layer
    n_classes = 10              # MNIST classes (0-9 digits)
    
    # x y placeholder
    x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
    y = tf.placeholder(tf.float32, [None, n_classes])
    
    # 对 weights biases 初始值的定义
    weights = {
        # shape (28, 128)
        'in': tf.Variable(tf.random_normal([n_inputs, n_hidden_units])),
        # shape (128, 10)
        'out': tf.Variable(tf.random_normal([n_hidden_units, n_classes]))
    }
    biases = {
        # shape (128, )
        'in': tf.Variable(tf.constant(0.1, shape=[n_hidden_units, ])),
        # shape (10, )
        'out': tf.Variable(tf.constant(0.1, shape=[n_classes, ]))
    }
    
    def RNN(X, weights, biases):
        #hidden layer for input to cell
        ##############################
        #X(128batch,28steps,28inputs) ==>(128*28,28inputs)
        X = tf.reshape(X,[-1,n_inputs])
        #X_in ==> (128batch * 28steps,128hidden)
        X_in = tf.matmul(X,weights['in'])+biases['in']
        # X_in ==> (128batch , 28steps,128hidden)
        X_in = tf.reshape(X_in,[-1,n_steps,n_hidden_units])
    
    
        #cell
        #############################
        lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_units, forget_bias=1.0,state_is_tuple=True)
        # forget_bias=1.0不忘记任何的输入
        # lstm cell is divided into two parts(c_state,m_state) c_state为主线,m_state为分线
        # (可以理解为c_state为之前一直留下来的记忆,m_state为当前产生的记忆)
    
        _init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
        # 初始化全零 state _init_state会生成一个元组(c_state,m_state)
        # rnn计算时会保留每一步的计算结果在state中,就是lstm的记忆
    
        outputs, final_state = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=_init_state,time_major=False)
        # time_major=False 因为28steps在第二个维度(128batch , 28steps,128hidden),若在第一个维度(28steps,128batch,128hidden),time_major=True
        # final_state是最后的state,而outputs是每一步的结果
        # X_in 为输入层传过来的值[128,28,128]
    
        '''
        BasicLSTMCell代表每一个lstm单元(即每个时刻的处理单元)
        第一个参数代表单个lstm单元中隐藏层的大小
        因为每个时刻的输入也是一个向量,所以lstm隐藏层单元不是只有一个。
        lstm中处理的全部都是向量,没有单独的数字
        '''
    
        '''
        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(lstm_cell, X_in, initial_state=init_state, time_major=False)
        cell:RNNCell 实例。
        inputs:RNN输入。如果time_major==False(默认),必须要是形如[batch_size,max_time]的张量,或者这些元素的嵌套元组。 
            如果time_major == True,必须是形如[max_time, batch_size, ...]的张量,  或者这些元素的嵌套元组. 
            这也可能是一个满足这个属性的(可能嵌套的)张量元组. 前两个维度必须匹配所有输入,否则排名和其他形状组件可能会有所不同. 
            在这种情况下,每个时间步的单元输入将复制这些元组的结构,除了时间维(从中获取时间)。 
            在每个时间步的单元格输入将是张量或(可能嵌套的)张量元组,每个张量元素的尺寸为[batch_size,...]。
        sequence_length:(可选)一个int32 / int64向量,大小为[batch_size]。 用于在批量元素的序列长度超过时复制通过状态和零输出输出。所以它比正确性更重要。
        initial_state:(可选)RNN的初始状态。 如果cell.state_size是一个整数,则它必须是形如 [batch_size,cell.state_size]的张量。
            如果cell.state_size是一个元组,它应该是一个在cell.state_size中具有形状[batch_size,s]的张量元组。
        dtype:(可选)初始状态和预期输出的数据类型。 如果未提供initial_state或RNN状态具有异构dtype,则为必需。
        parallel_iterations:(默认:32)。 并行运行的迭代次数。 那些没有任何时间依赖性并且可以并行运行的操作将会是。
            此参数为空间换取时间。 值>> 1使用更多的内存,但花费的时间更少,而更小的值使用更少的内存,但计算需要更长的时间。
        swap_memory:透明地交换前向推理中产生的张量,但是需要GPU支持back prop。 
            这允许对通常不适合单个GPU的RNN进行训练,并且性能损失非常小(或没有)。
        time_major:输入和输出张量的形状格式,如果time_major == True,则这些张量必须为[max_time,batch_size,depth]。
            如果为false,则这些张量必须为[batch_size,max_time,depth]。 使用time_major = True可以提高效率,因为它避免了RNN计算开始和结束时的转置。 但是,大多数TensorFlow数据都是批处理主数据,所以默认情况下,此功能接受输入并以批处理主要形式发出输出。
        scope:用于创建子图的VariableScope; 默认为“rnn”。
        返回值:
        output:RNN输出张量。如果time_major == False (default),输出张量形如[batch_size, max_time, cell.output_size]。
        ast_states是由(c,h)组成的tuple,均为[batch,列数]。
        '''
        #hidden layer for output as the final results 输出隐藏层
        ##############################################
        #第一种计算results的方法
        #使用final_state[1]的原因,final_state包含两个state(c_state,m_state),final_state[1]为分线剧情的结果
        #results = tf.matmul(final_state[1], weights['out']) + biases['out'] #final_state[1]指分线(m_state)的结果=outputs[-1]
    
        #第二种计算results的方法 把 outputs 变成 列表 [(batch, outputs)..] * steps
        outputs = tf.unstack(tf.transpose(outputs, [1, 0, 2]))
        results = tf.matmul(outputs[-1], weights['out']) + biases['out']  # 选取最后一个 output,为分类结果
    
        return results
    
    pred = RNN(x, weights, biases)
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=pred))
    train_op = tf.train.AdamOptimizer(lr).minimize(cost)
    
    correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
    
    # init= tf.initialize_all_variables() # tf 马上就要废弃这种写法
    # 替换成下面的写法:
    init = tf.global_variables_initializer()
    
    with tf.Session() as sess:
        sess.run(init)
        step = 0
        while step * batch_size < training_iters:
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
            sess.run([train_op], feed_dict={
                x: batch_xs,
                y: batch_ys,
            })
            if step % 20 == 0:
                print(sess.run(accuracy, feed_dict={
                x: batch_xs,
                y: batch_ys,
            }))
            step += 1
  • 相关阅读:
    121.买卖股票 求最大收益1 Best Time to Buy and Sell Stock
    409.求最长回文串的长度 LongestPalindrome
    202.快乐数 Happy Number
    459.(KMP)求字符串是否由模式重复构成 Repeated Substring Pattern
    326.是否为3的平方根 IsPowerOfThree
    231.是否为2的平方根 IsPowerOfTwo
    461.求两个数字转成二进制后的“汉明距离” Hamming Distance
    206.反转单链表 Reverse Linked List
    448. 数组中缺少的元素 Find All Numbers Disappeared in an Array
    常见表单元素处理
  • 原文地址:https://www.cnblogs.com/Harriett-Lin/p/9597346.html
Copyright © 2011-2022 走看看