练习利用LSTM实现手写数字分类任务

练习利用LSTM实现手写数字分类任务

MNIST数据集中图片大小为28*28.

按照行进行展开成28维的特征向量。

考虑到这28个的向量之间存在着顺序依赖关系,我们可以将他们看成是一个长为28的输入序列,将其输入到LSTM中,LSTM可以从中提取到序列特征,再将此序列特征用一层全联接作为分类器,分类器输出10种分类类别。

综合代码

import tensorflow as tf
import numpy as np
from tensorflow.contrib.layers import fully_connected

import input_data
mnist = input_data.read_data_sets('MNIST_data/',one_hot = True)
#one_hot = True 独热编码,类似[0,0,0,1,0,0,0,0,0,0]这种形式,等价于class=3

n_inputs  = 28  #表示输入神经元的个数
n_steps   = 28  #表示序列长度
n_neurons = 150 #表示LSTM中隐藏层和输出层神经元呢个数
n_outputs = 10  #是最终分类器输出的类别数,mnist数据集是10分类任务

learning_rate = 0.01 #优化方法的学习率

X = tf.placeholder(tf.float32,[None,n_steps,n_inputs])
Y_labels = tf.placeholder(tf.int32,[None,n_outputs])

basic_cell = tf.contrib.rnn.BasicLSTMCell(n_neurons,forget_bias = 1.0, state_is_tuple = True) 
#获取一层LSTM网络,参数1是每个cell的输出神经元个数,参数2是遗忘的偏置,参数3表示双状态

outneurons, states = tf.nn.dynamic_rnn(basic_cell,X,dtype = tf.float32) 
#outneurons得到了输出序列

logits = fully_connected(tf.transpose(outneurons,perm = [1,0,2])[-1], n_outputs,activation_fn = None)
#在这里由于outneurons的维度为[batch_size,n_steps,n_inputs]的形式,而我们只需要最后一个cell对于所有batch的输出,因此把前两个维度调换一下,再取用[-1]取到最后一个cell对于所有batch的输出。shape为[batch_size,n_inputs]
#将其接到一层全连接网络作为分类器得到logits

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels = Y_labels,logits = logits)
loss = tf.reduce_mean(cross_entropy)
#对logits用softmax做归一化,计算其对于样本labels的交叉熵的和,取均值作为损失函数loss

optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate)
trainop = optimizer.minimize(loss)
#申请一个优化器,用来最后小化损失函数loss

correct = tf.equal(tf.argmax(logits,1),tf.argmax(Y_labels,1))
#分析正确率

accuracy = tf.reduce_mean(tf.cast(correct,tf.float32))

batch_size = 64 
init = tf.global_variables_initializer()
with tf.Session() as sess:
    init.run()
    for i in range(10000):
        x_batch, y_batch = mnist.train.next_batch(batch_size)
        x_batch = x_batch.reshape([-1,n_steps,n_inputs])
        sess.run(trainop,feed_dict = {X : x_batch,Y_labels : y_batch})
        if i % 200 == 0:
            print('train accuracy =',sess.run(accuracy,feed_dict = {X : x_batch,Y_labels : y_batch}))
    X_test = mnist.test.images.reshape((-1,n_steps,n_inputs))
    Y_test = mnist.test.labels
    print('test accuracy =',sess.run(accuracy,feed_dict = {X : X_test,Y_labels : Y_test}))
    

评估

实验表明求得得准确率可达到99%。

疑问

我将BasicLSTMCell换成BasicRNNCell就无法训练,这是为什么呢?难道跟LSTM有遗忘们相关吗?

好的,我可以为您介绍如何使用LSTM实现MNIST手写数字分类。 MNIST是一个常用的手写数字数据集,它包含60000个训练样本和10000个测试样本。每个样本是一个28x28的灰度图像,表示手写数字0-9中的一个。 LSTM(长短时记忆网络)是一种递归神经网络,特别适用于处理序列数据,如文本、语音、视频等。在MNIST手写数字分类任务中,我们可以将每个图像的像素值序列视为一个时间序列,然后使用LSTM对其进行分类。 以下是实现MNIST手写数字分类的步骤: 1. 准备数据集 首先,我们需要从Keras库中加载MNIST数据集。可以使用以下代码: ``` python from keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() ``` 数据集中的图像像素值范围在0到255之间,我们需要将其归一化到0到1之间。可以使用以下代码: ``` python x_train = x_train.astype('float32') / 255. x_test = x_test.astype('float32') / 255. ``` 还需要将标签转换为独热编码。可以使用以下代码: ``` python from keras.utils import to_categorical y_train = to_categorical(y_train, num_classes=10) y_test = to_categorical(y_test, num_classes=10) ``` 2. 构建LSTM模型 接下来,我们需要构建一个LSTM模型。可以使用以下代码: ``` python from keras.models import Sequential from keras.layers import LSTM, Dense model = Sequential() model.add(LSTM(128, input_shape=(28, 28))) model.add(Dense(10, activation='softmax')) model.summary() ``` 在这个模型中,我们使用了一个LSTM层和一个全连接层。LSTM层的输入形状是(28,28),因为每个图像都是28x28像素。全连接层的输出是10,因为我们要对10个数字进行分类。 3. 编译和训练模型 我们需要编译这个模型并对其进行训练。可以使用以下代码: ``` python model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_test, y_test)) ``` 在这个模型中,我们使用了交叉熵作为损失函数,Adam作为优化器,并使用准确率作为度量标准。我们将训练数据分成大小为128的批次,并对模型进行10次迭代。 4. 评估模型 训练完成后,我们需要评估模型的性能。可以使用以下代码: ``` python score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ``` 这将打印出测试集上的损失和准确率。 完整的代码如下: ``` python from keras.datasets import mnist from keras.utils import to_categorical from keras.models import Sequential from keras.layers import LSTM, Dense (x_train, y_train), (x_test, y_test) = mnist.load_data() x_train = x_train.astype('float32') / 255. x_test = x_test.astype('float32') / 255. y_train = to_categorical(y_train, num_classes=10) y_test = to_categorical(y_test, num_classes=10) model = Sequential() model.add(LSTM(128, input_shape=(28, 28))) model.add(Dense(10, activation='softmax')) model.summary() model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_test, y_test)) score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ``` 希望这能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值