GRU(门控循环单元)Keras实现入门

GRU(Gated Recurrent Unit)是一种循环神经网络,它包含了一些特殊的门控机制,用于控制信息的流动和更新。比起RNN(Recurrent Neural Network),GRU支持隐状态的门控,这意味着模型有专门的机制来确定应该何时更新隐状态,以及应该何时重置隐状态。

 GRU中的更新门(Update Gate)是其中种门控机制,它可以控制新状态中有多少个是旧状态的副本。在GRU中,每个时刻都会有一个新的输入向量和一个旧的状态向量。更新门是一个sigmoid函数,它的输出控制了新状态中有多少是由旧状态的副本组成的。如果更新门的输出接近1,那么新状态就会完全由旧状态的副本组成,新的输入信息就会被完全忽略掉。如果更新门的输出接近0,那么旧状态就会被完全忽略掉,新的输入信息就会完全覆盖旧状态。此门控机制的好处是:它可以让模型根据需要选择性地保留旧状态中有用的信息,并忽略不必要的信息,从而更好地适应不同的输入序列。这对于处理长序列的任务特别有用,因为长序列中可能包含很多无关信息,而GRU的更新门可以帮助模型过滤掉这些无关信息,只保留有用的信息。

重置门(Reset Gate)也是GRU中的一种门控机制,它的作用是控制模型在当前时间步是否需要“遗忘”过去的状态信息。更具体地说,重置门允许我们控制“可能还想记住”的过去状态的数量。在GRU中,每个时间步都有一个当前的输入向量和一个旧的状态向量。重置门是一个sigmoid函数,它的输出表示在当前时间步,模型是否需要丢弃之前的状态信息。如果重置门的输出接近0,那么模型会忽略之前的状态信息,只根据当前输入来更新状态,从而更好地适应短序列数据。如果重置门的输出接近1,那么模型会保留之前的状态信息,并结合当前输入来更新状态,从而更好地适应长序列数据。此门控机制的好处是:它允许我们控制模型在当前时间步是否需要“遗忘”过去的状态信息,并且可以自适应地调整遗忘的数量。这种门控机制的设计可以让模型更好地适应不同的序列数据,从而提高模型的泛化能力和性能。

 

候选隐状态是更新门(Update Gate)和重置门(Reset Gate)所计算出的隐状态。具体来说,GRU的候选隐状态由以下公式计算:

\tilde{h_t} = \tanh(W_{ih}x_t + b_{ih} + r_t \odot (W_{hh}h_{t-1} + b_{hh}))

其中,$x_t$是当前时间步的输入,$h_{t-1}$是上一个时间步的隐状态,$r_t$是重置门,$\odot$表示按元素相乘,$W_{ih}$$W_{hh}$$b_{ih}$$b_{hh}$是可学习的参数。 

在计算候选隐状态时,重置门和上一个时间步的隐状态$h_{t-1}$相乘,得到的结果表示应该保留多少上一个时间步的信息。然后将当前时间步的输入x_t和上一步的隐状态$h_{t-1}$分别与对应的参数进行线性变换,再加上偏置项,得到两个向量。这两个向量分别与重置门相乘,得到的结果表示应该保留多少当前时间步的信息。将这两个向量相加,再通过tanh函数进行激活,得到候选隐状态$\tilde{h_t}$

接下来我来展示以下如何利用Keras来实现GRU的方法:(讲个题外话,之前我的前一篇文章LSTM我是用Pytorch实现的,但我发现相比于Keras的API更面向人类编程,更适合初学者,所以本篇教程我将用Keras来实现)

from keras.models import Sequential
from keras.layers import GRU, Dense

model = Sequential()
model.add(GRU(units=64, activation='tanh', input_shape=(10, 1)))
model.add(Dense(units=1, activation='sigmoid'))

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# X_train shape: (batch_size, timesteps, input_dim)
# y_train shape: (batch_size, output_dim)
model.fit(X_train, y_train, batch_size=32, epochs=10)

首先导入了需要的库和模块,然后使用Sequential()构建了一个序列模型

在序列模型中,我添加了一个GRU层,该层具有64个神经元和tanh激活函数,并且输入形状为(10, 1)。在此基础上我添加了一个全连接层,具有一个输出单元和sigmoid激活函数。

使用compile()方法来编译模型,指定优化器、损失函数和评估指标,并使用fit()方法来训练模型

GRU层的input_shape应该是一个三元组(timesteps, input_dim),其中timesteps表示输入序列的时间步数,input_dim表示每个时间步的输入特征维度。在上面的代码中,我将timesteps设置为10,input_dim设置为1。

fit()方法的输入数据X_trainy_train应该是Numpy数组,其中X_train的形状应该是(batch_size, timesteps, input_dim)y_train的形状应该是(batch_size, output_dim)

以下是使用Keras实现GRU模型来对MNIST手写数字数据集进行分类的代码示范,希望能对你对于如何代码实现GRU模型有更深的印象:

import tensorflow as tf
from keras.layers import GRU, Dense
from keras.models import Sequential
from keras.datasets import mnist
from keras.utils import to_categorical

# 加载数据集
(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(GRU(units=128, activation='tanh', input_shape=(28, 28)))
model.add(Dense(units=10, activation='softmax'))

# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 训练模型
model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_test, y_test))

# 在测试集上评估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)

参考文献:

文章图片来自A. Zhang, Z. C. Lipton, M. Li and A. J. Smola, "Dive into Deep Learning," arXiv preprint arXiv:2106.11342, 2021.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值