Python深度学习(6):循环神经网络

这篇关于LSTM,GRU的原理和实现部分还需要再完善一下…后期会更新的。

RNN简介

普通的网络上一次输入对下一次的输入的结果不会有影响,但是难免遇到需要记忆的场景。RNN与原先网络不同在于其保存上一次的输入,并赋予一个权重U加到本次的输出结果中。
普通网络: y i = a c t i v a t i o n ( w ∗ x i + b ) y_{i} = activation(w*x_{i}+b) yi=activation(wxi+b)
SimpleRNN: y i = a c t i v a t i o n ( w ∗ x i + u ∗ y i − 1 + b ) y_{i} = activation(w*x_{i}+u*y_{i-1}+b) yi=activation(wxi+uyi1+b)
LSTM层: y i = a c t i v a t i o n ( w ∗ x i + u ∗ y i − 1 + v ∗ c i + b ) y_{i} = activation(w*x_{i}+u*y_{i-1}+v*c_{i}+b) yi=activation(wxi+uyi1+vci+b)

SimpleRNN

在这里插入图片描述
代码实现

import numpy as np

timesteps = 20 #输入序列的时间步数
input_features = 4 #输入数据维度
output_features = 8 #输出数据维度

inputs = np.random.random((timesteps, input_features)) #随机初始化输入数据

state_t = np.zeros((output_features,)) #初始状态,全0向量

w = np.random.random((output_features, input_features)) #初始化w
u = np.random.random((output_features, output_features)) #初始化u
b = np.random.random((output_features,)) #初始化b

successive_out_puts = [] #输出列表
for input_t in inputs:
    output_t = np.tanh(np.dot(w, input_t) + np.dot(u, state_t) + b) #计算输出并使用tanh函数激活
    successive_out_puts.append(output_t) #将本次输出加入结果列表
    state_t = output_t #更新state_t

final_output_sequence = np.stack(successive_out_puts, axis = 0) #将输出列表改为numpy形式
print(final_output_sequence)

LSTM层

simpleRNN由于梯度消失问题,不可能学到长期依赖。LSTM允许过去的信息稍后重新进入,从而解决梯度消失问题。LSTM增加了一种携带信息跨越多个时间步的方法。携带信息用 c i c_{i} ci表示,它将与输入连接和循环连接进行运算(与权重矩阵 v v v做点积,加上偏置,再应用激活函数)
在这里插入图片描述

GRU层

门控循环单元GRU的工作原理与LSTM相似,只是基于LSTM做了一些简化。
在这里插入图片描述

SimpleRNN实现IMDB分类

在这里插入图片描述
代码详解

from keras.models import Sequential
from keras.layers import Embedding, SimpleRNN
from keras.datasets import imdb
from keras.layers import Dense
from keras.preprocessing import sequence
import matplotlib.pyplot as plt

max_features = 10000 #作为特征的单词个数
maxlen = 500
batch_size = 32

print('Loading data...')
(input_train, y_train), (input_test, y_test) = imdb.load_data(num_words = max_features) #加载数据
print(len(input_train), 'train sequences')
print(len(input_test), 'test sequences')

print('Pad sequences (samples x time')
input_train = sequence.pad_sequences(input_train, maxlen=maxlen)
input_test = sequence.pad_sequences(input_test, maxlen = maxlen)
print('input_train shape:', input_train.shape)
print('input_test shape:', input_test.shape)


model = Sequential()
model.add(Embedding(max_features, 32))
#simpleRNN有两种输出模式,一种返回每个时间步连续输出的完整序列,一种只返回每个输入序列的最终输出
#默认为第二种
model.add(SimpleRNN(32))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss = 'binary_crossentropy', metrics=['acc'])
history = model.fit(input_train, y_train, epochs=10, batch_size=128, validation_split=0.2)
print(model.summary())

#绘制loss曲线和acc曲线
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1,len(acc) + 1)

plt.plot(epochs, acc, 'bo', label = 'Training acc')
plt.plot(epochs, val_acc, 'b', label = 'Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'bo', label = 'training loss')
plt.plot(epochs, val_loss, 'b', label = 'Validation loss')
plt.title('Training and Validation loss')
plt.legend()

plt.show()

运行结果
在这里插入图片描述
在这里插入图片描述

LSTM实现IMDB分类

代码详解:
只需要简单修改上文中的网络结构

model = Sequential()
model.add(Embedding(max_features, 32))
model.add(LSTM(32))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss = 'binary_crossentropy', metrics=['acc'])
history = model.fit(input_train, y_train, epochs=10, batch_size=128, validation_split=0.2)
print(model.summary())

运行结果:
在这里插入图片描述
在这里插入图片描述

GRU实现IMDB分类

代码:

#将model.add(LSTM(32))即可
model.add(GRU(32))

运行结果:
在这里插入图片描述
在这里插入图片描述
使用SimpleRNN、LSTM、GRU分别对Imdb进行二分类问题,差不多在3轮左右都收敛了,RNN和GRU准确率在0.85,LSTM准确率最高在0.875左右

推荐资料

RNN
LSTM原理
LSTM与GRU

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值