结合CNN与RNN处理序列(Tensorflow)

一、可以使用卷积处理序列的原因

前面提到过:
循环神经网络就是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network)。
LSTM,GRU,BRNN(双向循环神经网络),都是为了将该词与周围的词相关联,而离得太远的词之间的相关性很弱,所以会浪费掉很多计算。

卷积神经网络中每层卷积层由若干卷积单元组成,每个卷积单元的参数都是通过反向传播算法优化得到的。通过卷积运算提取输入的不同特征实现特征映射。卷积层将全局模式变为局部模式
视觉处理中,我们使用的是二维卷积
在这里插入图片描述

所以可以使用一维卷积,从序列中提取序列段,识别序列中的局部模式
在这里插入图片描述

二、一维卷积神经网络

一维卷积神经网络可用于音频生成,机器翻译等。使用一维卷积神经网络处理句子,可以很好的识别单词、单词段,单词级的一维神经网络可以学会单词构词法。

1、一维卷积层Conv1D:

使用方法与Conv2D大致相同。

kernel_size : 一个整数或一个整数的元组/列表,指定一维卷积窗口的长度。
strides:表示步长。
padding:表示填充方式:“SAME”表示采用填充的方式,简单地理解为以0填充边缘,当stride为1时,输入和输出的维度相同;“VALID”表示采用不填充的方式,多余地进行丢弃。“CAUSAL”导致因果(膨胀)卷积,例如 输出[t]不依赖于输入[t + 1:]。 在对模型不应违反时间顺序的时间数据进行建模时很有用。

输入为(samples,time,features),卷积窗口为时间轴上的一维窗口。

tf.keras.layers.Conv1D(
filters, kernel_size, strides=1, padding=‘valid’,
data_format=‘channels_last’, dilation_rate=1, groups=1,
activation=None, use_bias=True, kernel_initializer=‘glorot_uniform’,
bias_initializer=‘zeros’, kernel_regularizer=None,
bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
bias_constraint=None, **kwargs
)

# The inputs are 128-length vectors with 10 timesteps, and the batch size
# is 4.
input_shape = (4, 10, 128)
x = tf.random.normal(input_shape)
y = tf.keras.layers.Conv1D(32, 3, activation='relu',input_shape=input_shape[1:])(x)
print(y.shape)

2、一维池化MaxPool1D:

提取一维子序列,输出其最大值(最大池化)或平均值(平均池化),降低输入长度。

采用pool_size定义的窗口上的最大值来对输入表示进行下采样。 窗口移动了很多步。 使用“有效”填充选项时的结果输出具有以下形状:output_shape =(input_shape-pool_size + 1)/步幅
使用“相同”填充选项时,结果输出形状为:output_shape = input_shape / strides
pool_size:整数,最大池窗口的大小。
strides:整数或无。 指定每个合并步骤的合并窗口移动了多少。 如果为None,它将默认为pool_size。
填充“valid”或“same”之一(不区分大小写)。 “valid”表示没有填充。 “same”导致向输入的左/右或上/下均匀填充,以使输出具有与输入相同的高度/宽度尺寸。

tf.keras.layers.MaxPool1D(
pool_size=2, strides=None, padding=‘valid’,
data_format=‘channels_last’, **kwargs
)

x = tf.constant([1., 2., 3., 4., 5.])
x = tf.reshape(x, [1, 5, 1])
tf.keras.layers.MaxPooling1D(pool_size=2,strides=1, padding='valid')

3、实现一维卷积神经网络

Conv1D层MaxPooling1D层堆叠,最后做全局池化或使用Flatten层,将三维输出转化为二维。可以在模型中添加Dense层做分类和回归。

示例:

import tensorflow as tf
from tensorflow import keras
from keras.datasets import imdb
from keras.preprocessing import sequence

#加载数据集
import numpy as np
max_features = 1000
max_len = 500

(x_train,y_train),(x_test,y_test) = imdb.load_data(num_words=max_features)
x_train = sequence.pad_sequences(x_train,maxlen=max_len)
x_test = sequence.pad_sequences(x_test,maxlen=max_len)

#一维卷积神经网络

model = keras.Sequential([
  keras.layers.Embedding(max_features,128,input_length=max_len),
  keras.layers.Conv1D(32,7,activation='relu'),
  keras.layers.MaxPooling1D(5),
  keras.layers.Conv1D(32,7,activation='relu'),
  keras.layers.GlobalMaxPooling1D(), #全局池化
  keras.layers.Dense(1)    
])

#model.summary()

model.compile(optimizer=tf.optimizers.RMSprop(lr=1e-4),loss=tf.losses.binary_crossentropy,metrics=['acc'])

history = model.fit(x_train,y_train,epochs=10,batch_size=128)

三、CNN和RNN结合处理序列

一维卷积神经网络分别处理每个输入序列段,对时间不敏感,在所有位置学习模式,但不知道该模式的时间位置。对新数据点的解释应该与较早时间数据点的解释不一样才对。
所以,结合卷积神经网络的速度和轻量RNN的顺序敏感性
可以在RNN前面使用卷积作为预处理步骤

猜你喜欢

转载自blog.csdn.net/qq_43842886/article/details/113852939
今日推荐