在 Keras 中为循环神经网络添加自定义注意层
【翻译自 : Adding A Custom Attention Layer To Recurrent Neural Network In Keras 】
【说明:Jason Brownlee PhD大神的文章个人很喜欢,所以闲暇时间里会做一点翻译和学习实践的工作,这里是相应工作的实践记录,希望能帮到有需要的人!】
深度学习网络在过去几年中广受欢迎。 “注意力机制”与深度学习网络相结合以提高其性能。 向网络添加注意力组件在机器翻译、图像识别、文本摘要和类似应用等任务中显示出显着改进。
在 Keras 中创建自定义注意力层需要哪些方法
如何将新层合并到用 SimpleRNN 构建的网络中
教程概述
为时间序列预测准备一个简单的数据集
如何使用通过 SimpleRNN 构建的网络进行时间序列预测
向 SimpleRNN 网络添加自定义注意力层
先决条件
什么是注意力?
从零开始的注意力机制
RNN 简介以及为它们提供动力的数学
了解 Keras 中的简单循环神经网络
数据集
本文的重点是基本了解如何为深度学习网络构建自定义注意力层。 为此,我们将使用一个非常简单的斐波那契数列示例,其中一个数字由前两个数字构成。 序列的前 10 个数字如下所示:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
当给定之前的“t”数字时,我们能否让机器准确地重建下一个数字? 这意味着丢弃除最后两个之外的所有先前输入并对最后两个数字执行正确的操作。
在本教程中,我们将从 t 个时间步构建训练示例,并使用 t+1 处的值作为目标。 例如,如果 t=3,则训练示例和相应的目标值将如下所示:
SimpleRNN 网络
在本节中,我们将编写基本代码来生成数据集并使用 SimpleRNN 网络来预测斐波那契数列的下一个数字。
输入部分
from pandas import read_csv
import numpy as np
from keras import Model
from keras.layers import Layer
import keras.backend as K
from keras.layers import Input, Dense, SimpleRNN
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.metrics import mean_squared_error
准备数据集
def get_fib_seq(n, scale_data=True):# Get the Fibonacci sequenceseq = np.zeros(n)fib_n1 = 0.0fib_n = 1.0 for i in range(n):seq[i] = fib_n1 + fib_nfib_n1 = fib_nfib_n = seq[i] scaler = []if scale_data:scaler = MinMaxScaler(feature_range=(0, 1))seq = np.reshape(seq, (n, 1))seq = scaler.fit_transform(seq).flatten() return seq, scalerfib_seq = get_fib_seq(10, False)[0]
print(fib_seq)[ 1. 2. 3. 5. 8. 13. 21. 34. 55. 89.]
def get_fib_XY(total_fib_numbers, time_steps, train_percent, scale_data=True):dat, scaler = get_fib_seq(total_fib_numbers, scale_data) Y_ind = np.arange(time_steps, len(dat), 1)Y = dat[Y_ind]rows_x = len(Y)X = dat[0:rows_x]for i in range(time_steps-1):temp = dat[i+1:rows_x+i+1]X = np.column_stack((X, temp))# random permutation with fixed seed rand = np.random.RandomState(seed=13)idx = rand.permutation(rows_x)split = int(train_percent*rows_x)train_ind = idx[0:split]test_ind = idx[split:]trainX = X[train_ind]trainY = Y[train_ind]testX = X[test_ind]testY = Y[test_ind]trainX = np.reshape(trainX, (len(trainX), time_steps, 1)) testX = np.reshape(testX, (len(testX), time_steps, 1))return trainX, trainY, testX, testY, scalertrainX, trainY, testX, testY, scaler = get_fib_XY(12, 3, 0.7, False)
print('trainX = ', trainX)
print('trainY = ', trainY)trainX = [[[ 8.][13.][21.]][[ 5.][ 8.][13.]][[ 2.][ 3.][ 5.]][[13.][21.][34.]][[21.][34.][55.]][[34.][55.][89.]]]
trainY = [ 34. 21. 8. 55. 89. 144.]
设置网络
现在让我们建立一个两层的小型网络。 第一个是 SimpleRNN 层,第二个是 Dense 层。 以下是该模型的摘要。
# Set up parameters
time_steps = 20
hidden_units = 2
epochs = 30# Create a traditional RNN network
def create_RNN(hidden_units, dense_units, input_shape, activation):model = Sequential()model.add(SimpleRNN(hidden_units, input_shape=input_shape, activation=activation[0]))model.add(Dense(units=dense_units, activation=activation[1]))model.compile(loss='mse', optimizer='adam')return modelmodel_RNN = create_RNN(hidden_units=hidden_units, dense_units=1, input_shape=(time_steps,1), activation=['tanh', 'tanh'])
model_RNN.summary()Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
simple_rnn_3 (SimpleRNN) (None, 2) 8
_________________________________________________________________
dense_3 (Dense) (None, 1) 3
=================================================================
Total params: 11
Trainable params: 11
Non-trainable params: 0
训练网络并评估
下一步是添加生成数据集、训练网络并对其进行评估的代码。 这一次,我们将在 0 和 1 之间缩放数据。我们不需要传递 scale_data 参数,因为它的默认值为 True。
# Generate the dataset
trainX, trainY, testX, testY, scaler = get_fib_XY(1200, time_steps, 0.7)model_RNN.fit(trainX, trainY, epochs=epochs, batch_size=1, verbose=2)# Evalute model
train_mse = model_RNN.evaluate(trainX, trainY)
test_mse = model_RNN.evaluate(testX, testY)# Print error
print("Train set MSE = ", train_mse)
print("Test set MSE = ", test_mse)
Train set MSE = 5.631405292660929e-05
Test set MSE = 2.623497312015388e-05
向网络添加自定义注意力层
注意层的调用方法
# Add attention layer to the deep learning network
class attention(Layer):def __init__(self,**kwargs):super(attention,self).__init__(**kwargs)def build(self,input_shape):self.W=self.add_weight(name='attention_weight', shape=(input_shape[-1],1), initializer='random_normal', trainable=True)self.b=self.add_weight(name='attention_bias', shape=(input_shape[1],1), initializer='zeros', trainable=True) super(attention, self).build(input_shape)def call(self,x):# Alignment scores. Pass them through tanh functione = K.tanh(K.dot(x,self.W)+self.b)# Remove dimension of size 1e = K.squeeze(e, axis=-1) # Compute the weightsalpha = K.softmax(e)# Reshape to tensorFlow formatalpha = K.expand_dims(alpha, axis=-1)# Compute the context vectorcontext = x * alphacontext = K.sum(context, axis=1)return context
带有注意力层的 RNN 网络
def create_RNN_with_attention(hidden_units, dense_units, input_shape, activation):x=Input(shape=input_shape)RNN_layer = SimpleRNN(hidden_units, return_sequences=True, activation=activation)(x)attention_layer = attention()(RNN_layer)outputs=Dense(dense_units, trainable=True, activation=activation)(attention_layer)model=Model(x,outputs)model.compile(loss='mse', optimizer='adam') return model model_attention = create_RNN_with_attention(hidden_units=hidden_units, dense_units=1, input_shape=(time_steps,1), activation='tanh')
model_attention.summary()Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 20, 1)] 0
_________________________________________________________________
simple_rnn_2 (SimpleRNN) (None, 20, 2) 8
_________________________________________________________________
attention_1 (attention) (None, 2) 22
_________________________________________________________________
dense_2 (Dense) (None, 1) 3
=================================================================
Total params: 33
Trainable params: 33
Non-trainable params: 0
_________________________________________________________________
用注意力训练和评估深度学习网络
是时候训练和测试我们的模型了,看看它在预测序列的下一个斐波那契数时表现如何。
model_attention.fit(trainX, trainY, epochs=epochs, batch_size=1, verbose=2)# Evalute model
train_mse_attn = model_attention.evaluate(trainX, trainY)
test_mse_attn = model_attention.evaluate(testX, testY)# Print error
print("Train set MSE with attention = ", train_mse_attn)
print("Test set MSE with attention = ", test_mse_attn)Train set MSE with attention = 5.3511179430643097e-05
Test set MSE with attention = 9.053358553501312e-06
您可以通过使用 LSTM 而不是 SimpleRNN 将这个示例更进一步,或者您可以通过卷积和池化层构建网络。 如果您愿意,您也可以将其更改为编码器解码器网络。
# Prepare data
def get_fib_seq(n, scale_data=True):# Get the Fibonacci sequenceseq = np.zeros(n)fib_n1 = 0.0fib_n = 1.0 for i in range(n):seq[i] = fib_n1 + fib_nfib_n1 = fib_nfib_n = seq[i] scaler = []if scale_data:scaler = MinMaxScaler(feature_range=(0, 1))seq = np.reshape(seq, (n, 1))seq = scaler.fit_transform(seq).flatten() return seq, scalerdef get_fib_XY(total_fib_numbers, time_steps, train_percent, scale_data=True):dat, scaler = get_fib_seq(total_fib_numbers, scale_data) Y_ind = np.arange(time_steps, len(dat), 1)Y = dat[Y_ind]rows_x = len(Y)X = dat[0:rows_x]for i in range(time_steps-1):temp = dat[i+1:rows_x+i+1]X = np.column_stack((X, temp))# random permutation with fixed seed rand = np.random.RandomState(seed=13)idx = rand.permutation(rows_x)split = int(train_percent*rows_x)train_ind = idx[0:split]test_ind = idx[split:]trainX = X[train_ind]trainY = Y[train_ind]testX = X[test_ind]testY = Y[test_ind]trainX = np.reshape(trainX, (len(trainX), time_steps, 1)) testX = np.reshape(testX, (len(testX), time_steps, 1))return trainX, trainY, testX, testY, scaler# Set up parameters
time_steps = 20
hidden_units = 2
epochs = 30# Create a traditional RNN network
def create_RNN(hidden_units, dense_units, input_shape, activation):model = Sequential()model.add(SimpleRNN(hidden_units, input_shape=input_shape, activation=activation[0]))model.add(Dense(units=dense_units, activation=activation[1]))model.compile(loss='mse', optimizer='adam')return modelmodel_RNN = create_RNN(hidden_units=hidden_units, dense_units=1, input_shape=(time_steps,1), activation=['tanh', 'tanh'])# Generate the dataset for the network
trainX, trainY, testX, testY, scaler = get_fib_XY(1200, time_steps, 0.7)
# Train the network
model_RNN.fit(trainX, trainY, epochs=epochs, batch_size=1, verbose=2)# Evalute model
train_mse = model_RNN.evaluate(trainX, trainY)
test_mse = model_RNN.evaluate(testX, testY)# Print error
print("Train set MSE = ", train_mse)
print("Test set MSE = ", test_mse)# Add attention layer to the deep learning network
class attention(Layer):def __init__(self,**kwargs):super(attention,self).__init__(**kwargs)def build(self,input_shape):self.W=self.add_weight(name='attention_weight', shape=(input_shape[-1],1), initializer='random_normal', trainable=True)self.b=self.add_weight(name='attention_bias', shape=(input_shape[1],1), initializer='zeros', trainable=True) super(attention, self).build(input_shape)def call(self,x):# Alignment scores. Pass them through tanh functione = K.tanh(K.dot(x,self.W)+self.b)# Remove dimension of size 1e = K.squeeze(e, axis=-1) # Compute the weightsalpha = K.softmax(e)# Reshape to tensorFlow formatalpha = K.expand_dims(alpha, axis=-1)# Compute the context vectorcontext = x * alphacontext = K.sum(context, axis=1)return contextdef create_RNN_with_attention(hidden_units, dense_units, input_shape, activation):x=Input(shape=input_shape)RNN_layer = SimpleRNN(hidden_units, return_sequences=True, activation=activation)(x)attention_layer = attention()(RNN_layer)outputs=Dense(dense_units, trainable=True, activation=activation)(attention_layer)model=Model(x,outputs)model.compile(loss='mse', optimizer='adam') return model # Create the model with attention, train and evaluate
model_attention = create_RNN_with_attention(hidden_units=hidden_units, dense_units=1, input_shape=(time_steps,1), activation='tanh')
model_attention.summary() model_attention.fit(trainX, trainY, epochs=epochs, batch_size=1, verbose=2)# Evalute model
train_mse_attn = model_attention.evaluate(trainX, trainY)
test_mse_attn = model_attention.evaluate(testX, testY)# Print error
print("Train set MSE with attention = ", train_mse_attn)
print("Test set MSE with attention = ", test_mse_attn)
在 Keras 中为循环神经网络添加自定义注意层相关推荐
- Keras 中的循环神经网络 (RNN)
简介 循环神经网络 (RNN) 是一类神经网络,它们在序列数据(如时间序列或自然语言)建模方面非常强大. 简单来说,RNN 层会使用 for 循环对序列的时间步骤进行迭代,同时维持一个内部状态 ...
- 自然语言处理--Keras 实现LSTM循环神经网络分类 IMDB 电影评论数据集
LSTM 对于循环网络的每一层都引入了状态(state)的概念,状态作为网络的记忆(memory).但什么是记忆呢?记忆将由一个向量来表示,这个向量与元胞中神经元的元素数量相同.记忆单元将是一个由 n ...
- Tensorflow与keras学习 (3)——循环神经网络RNN
循环神经网络RNN 3.1 RNN与LSTM介绍: 循环神经网络中的神经单元类似于模拟数字电路技术中的门电路,具有很多控制门来控制输入输出. RNN结构: LSTM结构: 相比与传统的神经网络,RNN ...
- 深度学习中的循环神经网络LSTM详解
(一).什么是循环神经网络LSTM? LSTM指的是长短期记忆网络(Long Short Term Memory),它是循环神经网络中最知名和成功的扩展.由于循环神经网络有梯度消失和梯度爆炸的问题,学 ...
- PyTorch中的循环神经网络RNN函数及词嵌入函数介绍
一.pytroch中的RNN相关函数介绍 1.对于简单的RNN结构,有两种方式进行调用: 1.1 torch.nn.RNN():可以接收一个序列的输入,默认会传入全0的隐藏状态,也可以自己定义初始的隐 ...
- 使用深度学习中的循环神经网络(LSTM)进行股价预测
tushare ID:468684 一.开发环境: 操作系统:Windows10 开发工具:PyCharm 2021.1.1 (Professional Edition) Python版本:Pytho ...
- keras lastm循环神经网络训练验证测试
在keras 上实践,通过keras例子来理解lastm循环神经网络 翻译 2016年12月07日 19:05:19 标签: 神经网络 9341 本文是对这篇博文的翻译和实践: http://mac ...
- 通过keras例子理解LSTM 循环神经网络(RNN)
博文的翻译和实践: Understanding Stateful LSTM Recurrent Neural Networks in Python with Keras 正文 一个强大而流行的循环神经 ...
- Keras——用Keras搭建RNN分类循环神经网络
文章目录 1.前言 2.用Keras搭建RNN循环神经网络 2.1.导入必要模块 2.2.超参数设置 2.3.数据预处理 2.4.搭建模型 2.5.激活模型 2.6.训练+测试 1.前言 这次我们用循 ...
- Python深度学习(循环神经网络)--学习笔记(十三)
6.2 理解循环神经网络 目前见过的所有神经网络(比如密集连接网络和卷积神经网络)都有一个特点,那就是它们都没有记忆.它们单独处理每个输入,在输入与输入之间没有保存任何状态.对于这样的网络,要想处理数 ...
最新文章
- Kotlin基本语法和使用
- 如何安装体验 Ubuntu on Windows
- 置顶 | 2021学习单/读书单(该来的总会来,过好当下,静待花开)
- 【架构】技术-工具-平台-语言框架
- linux下的连接文件——软连接和硬连接的区别
- Javascript 严格模式详解
- Spring集成web环境(手动实现)
- Redis常用API-使用文档
- border-radius 移动之伤
- python安装笔记_Python学习笔记(一)python的安装和配置
- 学了CPDA数据分析师认证课程对工作有什么好处?
- 十代主板改win7_微星Z490装win7 Bios设置|微星Z490主板10代CPU装win7
- Tera Term简单配置
- eigen一维向量_Eigen中的矩阵及向量运算
- bzoj 1921: [Ctsc2010]珠宝商
- learn language Part-One
- 使用OneR算法进行分类(Python实现)
- 链接元宇宙,开启新纪元
- 计算机硬件日语,求一些电脑硬件的日语说法(比如显卡等)
- 【CTS2019】氪金手游(动态规划)
热门文章
- C++值传递、指针传递、引用传递的区别
- Exchange 2016 之删除与恢复用户邮箱
- asp.net页面生命周期之页面的终结阶段
- dubbo如何正确关闭Spring容器
- Chapter 1 Securing Your Server and Network(7):禁用SQL Server Browse
- LeetCode 976. 三角形的最大周长(Largest Perimeter Triangle) 33
- 洛谷 P2804 神秘数字
- 汽车智力游戏-汽车游戏大全
- Tomcat内存设置方法(转载并实践)
- 计算机酒店管理论文摘要,酒店餐饮管理系统论文摘要目录.doc