RNN和LSTM初级配方炼丹对比实验(Keras)

RNN和LSTM初级配方炼丹对比实验(Keras)

参考教程:

一、莫烦大佬的教程:
https://morvanzhou.github.io/tutorials/machine-learning/keras/2-4-RNN-classifier/
二、《21个项目玩转深度学习-基于TensorFlow的实践详解》
其实概念性的理解,个人觉得,还是得看看书,虽然很多人(包括我)也诟病一些中文书就知道翻译,但是有些书在入门阶段,作为完整、快速的理解一门新的知识,真的是最佳的手段了。
有些书就包括这本。

前言

还是得扯扯有的没的,目前我知道的几个主要的深度学习分支如下:
后面的几个经典算法,我没完全跟的上,简单写了一些。
在这里插入图片描述
所以发现,这四个大方向,是很有趣的。
作为一个智能体,需要哪些功能,才能完成一个比较健全的任务呢?
感知、记忆、决策、自我意识等功能都应该得有吧?
计算机视觉一般主要用作提取特征,作为视觉感知模块;
循环一般主要用作时间序列,可以处理像语言、股票等时序任务,也算是一种记忆感知,其实我现在一直不明白,有什么样的网络可以实现:这件东西我曾经见过的!这件东西是啥?的功能,感觉传统的分类网络应该不算,或者最后的输出结构不应该是那样的,直接预测出是什么种类,应该还得有一些其他的类似于人认知的功能,比如结合知识图谱?;
强化学习的前端是全连接,或者是卷积,那么是用到了计算机视觉的感知功能。最重要的部分其实是后面的决策模块(可以理解为actor最后面的全连接层,或者加上critic对actor的更新),基于当前感知做决策,以及根据环境反馈,对actor决策进行更新的critic。这样就完成了决策任务了。
生成对抗网络我不太熟悉,所以我就无法描述了,但是今天在“逆强化学习”的课程中,李宏毅老师说,其实inverse reinforcement learning的frame跟gan的就很像很像,所以感觉思路都是交叉的。如果要想在这方面深耕的话,是没有办法只关注于一个领域的。
毕竟智能需要各方面的整合才行。

OK,那么说说我为啥要学RNN。
RNN太重要了呀,强化学习处理的本来就是时序问题,虽然通过整个结构的循环可以处理一些时序的问题,但是如果能直接在感知部分直接提取时序相关的信息,岂不是更合适?
之前那篇自我感知的小机械臂用的就有一个循环感知的过程,直接提取连续五步的状态。
所以还是得学习一下的。

RNN的基础知识

这个比较坑,今天就不在博客上说了,大家可以自己搜一些其他的资料;
或者直接去看那本书。

实验部分:

实验描述:

将mnist数据集分为28*28.第一个28为time_step,第二个是输入数据向量维度为28.
大致的效果是将一张这样的图:
在这里插入图片描述
从上往下拆分,每次只输入RNN网络中一行的数据,分28步输入进去。
然后通过RNN网络的权重进行计算后,输出的维度为隐层数。

最后将最后一步的输出接上全连接网络,再接softmax,进行分类预测。
LSTM的输入输出模型差不多,内部细节可以另看其他资料。

数据集:

Mnist数据集

LSTM-40-mnist-Code:

import numpy as np
np.random.seed(1337)

from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN, Activation
from keras.optimizers import Adam
TIME_STEPS = 28
TIME_INPUT_SIZE = 28
BATCH_SIZE = 32
BATCH_INDEX = 0
OUTPUT_SIZE = 10
CELL_SIZE = 40
LR = 0.001

(x_train,y_train),(x_test,y_test) = mnist.load_data()
# data pre-processing
x_train = x_train.reshape(-1, 28, 28) / 255.      # normalize
x_test = x_test.reshape(-1, 28, 28) / 255.        # normalize
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)
print(x_train.shape)
print(y_train.shape)
model = Sequential()

model.add(SimpleRNN(
    batch_input_shape=(None, TIME_STEPS, TIME_INPUT_SIZE),
    #     output_dim是隐层节点数目,控制了网络的拟合能力和每次状态输出的维度!
    output_dim=CELL_SIZE,
    unroll=True,
))

model.add(Dense(OUTPUT_SIZE, activation='softmax'))

adam = Adam(LR)
model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])

import time
import matplotlib.pyplot as plt
train_cost = []
train_accuracy = []
test_cost = []
test_accuracy = []

start_time = time.time()
for step in range(4001):
    x_batch = x_train[BATCH_INDEX: BATCH_INDEX+BATCH_SIZE, :, :]
    y_batch = y_train[BATCH_INDEX: BATCH_INDEX+BATCH_SIZE, :]
    cost, accuracy  = model.train_on_batch(x_batch, y_batch)
    train_cost.append(cost)
    train_accuracy.append(accuracy)

    BATCH_INDEX += BATCH_SIZE
    if BATCH_INDEX >= x_train.shape[0]:
        BATCH_INDEX=0
    if step%50==0:
        print("step:", step)
        print("cost:", cost)
        cost,accuracy = model.evaluate(x_test, y_test, batch_size=y_test.shape[0], verbose=False)
        test_cost.append(cost)
        test_accuracy.append(accuracy)
        print('test cost: ', cost, 'test accuracy: ', accuracy)
        
print("epoch_time:",(time.time()-start_time)/4001)

plt.figure(num = 1)
plt.ion()

plt.xlabel('epoch')
plt.ylabel('loss and accuracy')

plt.plot(train_cost, label = "loss")
plt.plot(train_accuracy, label = "accuracy")
plt.legend(loc = "best")

plt.show()

plt.figure(num = 2)
plt.ion()

plt.xlabel('epoch')
plt.ylabel('loss and accuracy')

plt.plot(test_cost, label = "loss")
plt.plot(test_accuracy, label = "accuracy")
plt.legend(loc = "best")
plt.show()        

实验内容:

测试LSTM和simpleRNN对精度和时间的影响。
以及隐层节点数变化对精度和时间的影响。
猜想:LSTM更强。时间也长一些。
节点数越多,精度越高

实验结果:

LSTM-80
test cost: 0.11618449538946152
test accuracy: 0.9639999866485596
epoch_time: 0.04046541754825805

LSTM-40
test cost: 0.20324485003948212
test accuracy: 0.9412999749183655
epoch_time: 0.04428503430506433

Epoch=4001/lr=0.001RNN-40RNN-80LSTM-40LSTM-80
Test cost0.34960.2080.2030.1162
Test accuracy0.90360.9430.94120.964
Epoch time0.01010.01040.04430.0404

表格分析:

由上面的表格可以看出来以下几点:

  • simpleRNN的训练时间确实要少很多,是LSTM的四分之一。

  • 但是cell_size对训练的时间影响并不大。

  • 另外可以看出来LSTM的训练精度确实比simpleRNN要好一些。

  • 在同样的节点数40时,精度提高了四个点,节点数80时上升2个点。

  • 节点数对精度的提升也很明显,simpleRNN中40-80的差距是4个点,LSTM的40-80的差距是2个点。

但是可以从训练过程中可以看出,精度和loss的波动比较大。如下图——

训练过程记录

lstm-40-train-accuracy-loss-graph-epoch-40001
在这里插入图片描述

lstm-40-test-accuracy-loss-graph-epoch-40001
这里的epoch-80是不对的,因为每50个train-epoch才测试一次,因此下面的每个epoch数字需要做一个变换。
也许每个train-epoch都测试的话,可能波动也比较大了。
在这里插入图片描述
好了,我又跑了一遍,发现波动性确实蛮大的:
但是大概的趋势还可以,是不是跟优化策略有关?我试试其他的?
在这里插入图片描述

SGD-不收敛

只将优化器换成了SGD,学习率都没变,仍然是0.001。那就只能再整一下,加点动量。

在这里插入图片描述
在这里插入图片描述

SGD加动量和牛顿什么的

加了动量=0.9和牛顿=true之后,可以达到下面的效果:
test cost: 0.9125387668609619 test accuracy: 0.7081999778747559

在这里插入图片描述

在这里插入图片描述

SGD加动量不加牛顿~

test cost: 0.9364890456199646 test accuracy: 0.7028999924659729
epoch_time: 0.1839553209818235

在这里插入图片描述
在这里插入图片描述

反正SGD确实没有Adam好,至少在这个任务,这个数据集下,是这样的~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hehedadaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值