BILSTM实现MNIST数据集学习

from __future__ import print_function
import tensorflow as tf
from tensorflow.contrib import rnn
import numpy as np

# Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MINIST_data/", one_hot=True)

#初始参数设置
lr = 0.001
train_set = 10000
batch_size = 128
display_step = 10
# n_steps*n_input其实就是那张图 把每一行拆到每个time step上。
n_input = 28#隐藏层层输入
n_step = 28#隐藏层的时间片

#隐藏层大小
n_hidden =128 #特征分类
n_class = 10 #10个输出

#tf graph input  输入参数
x = tf.placeholder("float",[None, n_step, n_input]) #输入层
y = tf.placeholder("float",[None, n_class]) #标签样本

#权重与偏置设置
weights = {
    'out' : tf.Variable(tf.random_normal([2*n_hidden*n_step, n_class]))
}
biase = {
    'out' : tf.Variable(tf.random_normal([n_class]))
}

#开始定义隐藏层
def RNN(x, weights, biase):
    # Prepare data shape to match `bidirectional_rnn` function requirements
    # Current data input shape: (batch_size, n_steps, n_input)
    # Required shape: 'n_steps' tensors list of shape (batch_size, n_input)
    # Unstack to get a list of 'n_steps' tensors of shape (batch_size, n_input)
    # 变成了n_steps*(batch_size, n_input)

    # x = tf.unstack(x, n_step, 1) #方法一

    """
    tf.unstack()
tf.unstack(value, num=None, axis=0, name=’unstack’)
以指定的轴axis,将一个维度为R的张量数组转变成一个维度为R-1的张量。即将一组张量以指定的轴,减少一个维度。正好和stack()相反。

将张量value分割成num个张量数组。如果num没有指定,则是根据张量value的形状来指定。如果value.shape[axis]不存在,则抛出ValueError的异常。

假如一个张量的形状是(A, B, C, D)。
如果axis == 0,则输出的张量是value[i, :, :, :],i取值为[0,A),每个输出的张量的形状为(B,C,D)。
如果axis == 1,则输出的张量是value[:, i, :, :],i取值为[0,B),每个输出的张量的形状为(A,C,D)。
如果axis == 2,则输出的张量是value[:, :, i, :],i取值为[0,C),每个输出的张量的形状为(A,B,D)。依次类推。

举例如下:
‘x’ is [[1,1,1,1],[2,2,2,2],[3,3,3,3]] # 形状是(3,4),维度为2
unstack(x,axis=0) =>以指定的维度0为轴,转变成3个形状为(4)张量[1,1,1,1],[2,2,2,2],[3,3,3,3]
unstack(x,axis=1) =>以指定的维度1为轴,转变成4个形状为(3)张量[1,2,3],[1,2,3],[1,2,4],[1,2,3]

axis可这样理解:unstack就是要将一个张量降低为低一个维度的张量数组。axis就是将axis指定的维度,用所有这个张量里同维度的数据代替。

参数:
value: 一个将要被降维的维度大于0的张量。
num: 整数。指定的维度axis的长度。如果设置为None(默认值),将自动求值。
axis: 整数.以轴axis指定的维度来转变 默认是第一个维度即axis=0。支持负数。取值范围为[-R, R)
name: 这个操作的名字(可选)
返回:
从张量value降维后的张量数组。
异常:
ValueError: 如果num没有指定并且无法求出来。
ValueError: 如果axis超出范围 [-R, R)。

代码:
    import tensorflow as tf
    import numpy as np
    t=np.random.randint(1,10,(3,5))
    ustack1=tf.unstack(t,axis=1)
    ustack2=tf.unstack(t,axis=0)
    sess=tf.Session()
    print(t)
    print(sess.run(ustack1))
    print(sess.run(ustack2))

输出结果如下:
[[4 7 3 5 5]
 [3 5 8 4 1]
 [2 2 9 8 7]]
[array([4, 3, 2]), array([7, 5, 2]), array([3, 8, 9]), array([5, 4, 8]), array([5, 1, 7])]
[array([4, 7, 3, 5, 5]), array([3, 5, 8, 4, 1]), array([2, 2, 9, 8, 7])]
    """


    #定义LSTM层,双向
    fw_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)
    bw_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)


    #双向LSTM层运算
    # outputs, _, _ = rnn.static_bidirectional_rnn(fw_cell, bw_cell, x,dtype = tf.float32) #方法一
    # return tf.matmul(outputs[-1], weights['out']) + biase['out'] #方法一

    #方法二
    (fw_output,bw_output), _ = tf.nn.bidirectional_dynamic_rnn(fw_cell, bw_cell, x, dtype=tf.float32) #需要将输出的output连接
    outputs = tf.concat([fw_output,bw_output],2)
    outputs = tf.reshape(outputs,[-1,2*n_hidden*n_step])
    return tf.matmul(outputs, weights['out'])+biase['out']

pred = RNN(x, weights, biase)#定义向前函数
print(tf.shape(pred))
# Define loss and optimizer
# softmax_cross_entropy_with_logits:Measures the probability error in discrete classification tasks in which the classes are mutually exclusive
# return a 1-D Tensor of length batch_size of the same type as logits with the softmax cross entropy loss.
# reduce_mean就是对所有数值(这里没有指定哪一维)求均值。
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
optimizer = tf.train.AdamOptimizer(learning_rate=lr).minimize(cost)
#图的连接

correct_pred = tf.equal(tf.argmax(pred, axis=1), tf.argmax(y,axis=1))#获取相等数组列表
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))#计算正确率

#初始化变量
init = tf.global_variables_initializer()

#执行图
with tf.Session() as sess:
    sess.run(init)#执行变量初始化
    step = 1#当前为第几个batch
    while step*batch_size < train_set:
        batch_x,batch_y = mnist.train.next_batch(batch_size)
        # Reshape data to get 28 seq of 28 elements
        batch_x = batch_x.reshape((batch_size, n_step, n_input))
        # Run optimization op (backprop) 执行优化器
        sess.run(optimizer, feed_dict={x: batch_x, y: batch_y})

        if step % display_step == 0:
            # Calculate batch accuracy
            acc = sess.run(accuracy, feed_dict={x: batch_x, y: batch_y})
            # Calculate batch loss
            loss = sess.run(cost, feed_dict={x: batch_x, y: batch_y})
            print("Iter " + str(step * batch_size) + ", Minibatch Loss= " + \
            "{:.6f}".format(loss) + ", Training Accuracy= " + \
            "{:.5f}".format(acc))
        step += 1
    print("Optimization Finished!")

    # Calculate accuracy for 128 mnist test images
    test_len = 128
    test_data = mnist.test.images[:test_len].reshape((-1, n_step, n_input))
    test_label = mnist.test.labels[:test_len]
    print("Testing Accuracy:", \
        sess.run(accuracy, feed_dict={x: test_data, y: test_label}))


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

猜你喜欢

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