Keras库学习记-three 循环神经网络

循环神经网络

用来处理序列数据的神经网络,被称为循环神经网络RNNS)。

传统的神经网络模型中,层与层之间是全连接的,每层的节点之间是无连接的,因此无法高效处理序列问题。

处理序列数据的神经网络之所以称为循环神经网络,是因为一个序列当前的输出与前面的输出有关。具体的表现形式为:网络会对前面的信息进行记忆,并应用与当前输出的计算中,即隐藏层之间的节点不再是无连接的,而是有连接的,并且隐藏层的输入不仅包括输入层的输出,还包括上一时刻隐藏层的输出。

用于训练前馈神经网络的主要技术是反向传播,使用计算错误的数据来更新网络权重。在循环神经网络中,因为神经元的重复连接或循环连接,反向传播不适用,不能很好地完成网络权重的更新,这需要时间反向传播技术(BPTT)来解决循环神经网络的反向传播问题。

当反向传播用于非常深的神经网络和循环神经网络时,为了更新权重而需要计算的梯度变得不稳定,它们可能变成非常大的数值(梯度爆炸)或者非常小的数值(梯度消失)。使用这些数据来更新网络中的权重,使训练变得不稳定,并且使神经网络生成的模型不可靠。

在多层感知器神经网络中,通过使用激活函数使这个问题得到缓解,甚至使用无监督的预训练层来环节这个问题;在循环神经网络架构中,使用长短期记忆网络(LSTM)可以缓解这个问题。

 LSTM已被证明,对处理从自然语言翻译各样图像和视频自动字幕等序列问题具有非常良好的结果。目前被广泛应用在自然语言翻译、控制机器人、图像分析、文档摘要、语音识别、图像识别、手写识别、聊天机器人、预测疾病、点击率、股票、合成音乐等领域。


序列问题分类

一对多:序列输出,用于图像字幕。

多对一:序列输入,用于情感分类。

多对多:序列输入和输出,用于机器翻译。

同步多对多:同步序列输入和输出,用于视频分类。


多层感知器的时间序列预测

先编写一个简单的函数将单列数据转换为两列数据集,第一列包含当月(t)的旅客数,第二列包含下个月(t

+1)的旅客数。

窗口方法:使用多个时间项来进行下一个时间项的预测。

import numpy as np

from pandas import read_csv

from matplotlib import pyplot as plt

import math

from keras.models import Sequential

from keras.layers import Dense

#多层感知器

seed = 7

batch_size = 2

epochs = 200

filename = 'international-airline-passengers.csv'

footer = 3

look_back = 1

# look_back = 3   使用窗口方法的多层感知器,即t-2、t-1、t


def create_dataset(dataset):

    dataX,dataY = [],[]

    for i in range(len(dataset) - look_back -1):

        x = dataset[i:i+look_back, 0]

        dataX.append(x)

        y = dataset[i+look_back, 0]

        dataY.append(y)

        print('X: %s, Y: %s' % (x,y))

    return np.array(dataX),np.array(dataY)

def build_model():

    model = Sequential()

   # model.add(Dense(units=12,input_dim=look_back,activation='relu'))  窗口方法

    model.add(Dense(units=8,input_dim=look_back,activation='relu'))

    model.add(Dense(units=1))

    model.compile(loss='mean_squared_error',optimizer='adam')

    return model

if __name__ == '__main__':

    np.random.seed(seed)

    data = read_csv(filename,usecols=[1],engine='python',skipfooter=footer)

    dataset = data.values.astype('float32')

    train_size = int(len(dataset)*0.67)

    validation_size = len(dataset) - train_size

    train,validation = dataset[0:train_size,:],dataset[train_size:len(dataset),:]

    X_train,y_train = create_dataset(train)

    X_validation,y_validation = create_dataset(validation)


    model = build_model()

    model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=0)


    train_score = model.evaluate(X_train,y_train,verbose=0)

    print('Train Score: %.2f MSE (%.2f RMSE)' % (train_score,math.sqrt(train_score)))

    validation_score = model.evaluate(X_validation,y_validation,verbose=0)

    print('Validation Score: %.2f MSE (%.2f RMSE)' % (validation_score,math.sqrt(validation_score)))


    predict_train = model.predict(X_train)

    predict_validation = model.predict(X_validation)


    predict_train_plot = np.empty_like(dataset)

    predict_train_plot[:,:] = np.nan

    predict_train_plot[look_back:len(predict_train)+look_back,:] = predict_train


    predict_validation_plot = np.empty_like(dataset)

    predict_validation_plot[:,:] = np.nan

    predict_validation_plot[len(predict_train)+look_back*2+1:len(dataset)-1,:] = predict_validation


    plt.plot(dataset,color='blue')

    plt.plot(predict_train_plot,color='green')

    plt.plot(predict_validation_plot,color='red')

    plt.show()


LSTM方法

使用时间步长的LSTM回归

在为LSTM神经网络准备数据时,数据中包括时间步长,并设置为相同的数值。但是在一些序列问题中,可能每个样本都有不同的时间步长。(如对机器故障进行测量,每个观测到的故障点都是一个样本,观察到的结果是故障间隔的时间步长,观察到的变量是特征。)

时间步长提供了另一种方式来描述时间序列问题,与上面的窗口方法相同,将时间序列中先前的时间步长作为输入,来预测下一个时间步长的输出,而不是将过去的观察结果作为单独的输入特征

这种将时间不长作为输入特征的方法,的确能够提高时间序列问题预测的精确度。

在对数据进行reshape处理时,将列设置为时间步长,并将其设置为1.

LSTM的批次间记忆

通常情况下,每个训练批次之后,或者调用model.predict()或者model.evaluate()函数之后,网络的状态都会重新设置。在Keras中,通过设置LSTM层的stateful为True,来保存LSTM层的内部状态,从而获得更好的控制。

为了保持状态,要求在训练神经网络模型时不忽略数据。这需要每个epoch训练结束后,通过调用model.reset_states()函数,显式地充值网络状态,即创建外循环epoch,并在每个epoch中调用model.fit()和model.reset_state()函数。

import numpy as np

from matplotlib import pyplot as plt

from pandas import read_csv

import math

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

from sklearn.preprocessing import MinMaxScaler

from sklearn.metrics import mean_squared_error

seed = 7

batch_size = 1

epochs = 100

filename = 'international-airline-passengers.csv'

footer = 3

look_back = 1

# look_back = 3 窗口方法

def create_dataset(dataset):

    dataX,dataY = [],[]

    for i in range(len(dataset)-look_back-1):

        x = dataset[i:i+look_back,0]

        dataX.append(x)

        y = dataset[i+look_back,0]

        dataY.append(y)

        print('X: %s, Y: %s' % (x,y))

    return np.array(dataX),np.array(dataY)

def build_model():

    model = Sequential()

    model.add(LSTM(units=4,input_shape=(1,look_back)))

    # 批次间记忆

    # model.add(LSTM(units=4,batch_input_shape=(batch_size,look_back,1),stateful=True))

    # 堆叠批次间记忆

    # model.add(LSTM(units=4,batch_input_shape=(batch_size,look_back,1),stateful=True,return_sequences=True))

    # model.add(LSTM(units=4,batch_input_shape=(batch_size,look_back,1),stateful=True)))

    model.add(Dense(units=1))

    model.compile(loss='mean_squared_error',optimizer='adam')

    return model

if __name__ == '__main__':

    np.random.seed(seed)


    data = read_csv(filename,usecols=[1],engine='python',skipfooter=footer)

    dataset = data.values.astype('float32')


    scaler = MinMaxScaler()

    dataset = scaler.fit_transform(dataset)

    train_size = int(len(dataset)*0.67)

    validation_size = len(dataset) - train_size

    train,validation = dataset[0:train_size,:],dataset[train_size:len(dataset),:]


    X_train,y_train = create_dataset(train)

    X_validation,y_validation = create_dataset(validation)


    X_train = np.reshape(X_train,(X_train.shape[0],1,X_train.shape[1]))

    X_validation = np.reshape(X_validation,(X_validation.shape[0],1,X_validation.shape[1]))


    # 使用时间步长/批次间记忆

    # X_train = np.reshape(X_train,(X_train.shape[0],X_train.shape[1],1))

    # X_validation = np.reshape(X_validation,(X_validation.shape[0],X_validation.shape[1],1))


    model = build_model()

    model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=2)


    predict_train = model.predict(X_train)

    predict_validation = model.predict(X_validation)

    '''

    批次间记忆

    for i in range(epochs):

        history = model.fit(X_train,y_train,epochs=epochs,batch_size=batch_size,verbose=0,shuffle=False)

        mean_loss = np.mean(history.history['loss'])

        print('mean loss %.5f for loop %s' % (mean_loss,str(i)))

        model.reset_states()

    predict_train = model.predict(X_train,batch_size=batch_size)

    model.reset_states()

    predict_validation = model.predict(X_validation,batch_size=batch_size)

    '''

    predict_train = scaler.inverse_transform(predict_train)

    y_train = scaler.inverse_transform([y_train])

    predict_validation = scaler.inverse_transform(predict_validation)

    y_validation = scaler.inverse_transform([y_validation])


    train_score = math.sqrt(mean_squared_error(y_train[0],predict_train[:,0]))

    print('Train Scores: %.2f RMSE' % train_score)

    validation_score = math.sqrt(mean_squared_error(y_validation[0],predict_validation[:,0]))

    print('Validation Score: %.2f RMSE' % validation_score)


    predict_train_plot = np.empty_like(dataset)

    predict_train_plot[:,:] = np.nan

    predict_train_plot[look_back:len(predict_train)+look_back,:] = predict_train


    predict_validation_plot = np.empty_like(dataset)

    predict_validation_plot[:,:] = np.nan

    predict_validation_plot[len(predict_train)+look_back*2+1:len(dataset)-1,:] = predict_validation


    dataset = scaler.inverse_transform(dataset)

    plt.plot(dataset,color='blue')

    plt.plot(predict_train_plot,color='green')

    plt.plot(predict_validation_plot,color='red')

    plt.show()


混合使用LSTM和CNN

卷积神经网络对稀疏结构的数据处理非常有效。IMDB影评数据确实在评价的单词序列中具有一维稀疏空间结构,CNN能够挑选出不良情绪的不变特征。通过CNN学习后的空间特征,可以被LSTM层学习为序列。在词嵌入层之后,可以通过添加一维CNN和最大池化层,将合并的特征提供给LSTM。

from keras.datasets import imdb

from keras.preprocessing import sequence

from keras.layers.embeddings import Embedding

from keras.layers import Dense

from keras.models import Sequential

from keras.layers import LSTM,Dropout

from keras.layers.convolutional import Conv1D,MaxPooling1D

import numpy as np

seed = 7

top_words = 5000

max_words = 500

out_dimension = 32

batch_size = 128

epochs = 2

dropout_rate = 0.2

def build_model():

    model = Sequential()

    model.add(Embedding(top_words,out_dimension,input_length=max_words))

    model.add(Conv1D(filters=32,kernel_size=3,padding='same',activation='relu'))

    model.add(MaxPooling1D(pool_size=2))

    # model.add(Dropout(dropout_rate))

    model.add(LSTM(units=100))

    # model.add(Dropout(dropout_rate))

    model.add(Dense(units=1,activation='sigmoid'))

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

    model.summary()

    return model

if __name__ == '__main__':

    np.random.seed(seed=seed)


    (x_train,y_train),(x_validation,y_validation) = imdb.load_data(num_words=top_words)

    x_train = sequence.pad_sequences(x_train,maxlen=max_words)

    x_validation = sequence.pad_sequences(x_validation,maxlen=max_words)


    model = build_model()

    model.fit(x_train,y_train,batch_size=batch_size,epochs=epochs,verbose=2)

    scores = model.evaluate(x_validation,y_validation,verbose=2)

    print('Accuracy: %.2f%%' % (scores[1]*100))


(来自19年草稿箱)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容