• 从零开始应用LSTM网络


    数据预处理

    该部分包含生成差分数据,归一化,数据缩放,生成监督数据集等。

    将数据转换成有监督数据

    # coding=utf-8
    from pandas import read_csv
    from datetime import datetime
    from pandas import DataFrame
    from pandas import concat
    
    
    # load data
    def parser(x):
        return datetime.strptime(x, '%Y/%m/%d')
    
    
    series = read_csv("data_set\shampoo-sales.csv", header=0, parse_dates=[0], index_col=0, squeeze=True,
                      date_parser=parser)
    
    '''                     
    将数据转换成有监督数据  
    即包含input output      
    训练的目的就是找到训练数据input和output的关系                                                                           
    此处的input是t时间步的数据,output为t+1时间步的数据                                                                     
    具体实现就是将整体的时间数据向后滑动一格,和原始数据拼接,就是有监督的数据                                              
    '''
    # 这个函数说了一大堆,简单说就是把data数组重新构造成两两一组的二维数组,每个数据对格式是[0,n],[n,n+1],[n+1,n+2],
    # 第一组数据用0补全,即为[0,n],这就是所谓的监督学习数据
    def timeseries_to_supervised(data, lag=1):  # lag表示的是当前的值只与历史lag个时间步长的值有关,也就是用lag个数据预测下一个
        df = DataFrame(data)
        colums = [df.shift(i) for i in range(1, lag + 1)]  # 原始数据时间窗向后移动lag步长
        colums.append(df)  # 拼接数据
        df = concat(colums, axis=1)  # 横向拼接重塑数据,格式:input putput
        df.fillna(0, inplace=True)  # 由于数据整体向后滑动lag后,前面的lag个数据是Na形式,用0来填充
        return df
    
    
    X = series.values
    supervised = timeseries_to_supervised(X, 1)
    print(supervised.head())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    原数据:
    原数据
    转换为监督数据后:
    在这里插入图片描述

    数据缩放

    # coding=utf-8
    from pandas import read_csv
    from pandas import datetime
    from pandas import Series
    from sklearn.preprocessing import MinMaxScaler
    # load data
    def parser(x):
        return datetime.strptime(x, '%Y/%m/%d')
    
    series = read_csv('data_set/shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True,
                      date_parser=parser)
    print (series.head())
    # 所谓缩放,就是把一组数组中的数字都变成[-1,1]范围的数字,取数组中最大的那个数组,令其为1,最小的数字,令其为-1,
    # 剩下的数字根据比例关系,在[-1,1]中给其找一个对应值
    # 缩放
    X = series.values
    X = X.reshape(len(X), 1)  # MinMaxScaler函数需要矩阵作为输入,所以reshape数据为矩阵,因为是一维数组,所以生成的是n行1列的一个矩阵
    scaler = MinMaxScaler(feature_range=(-1, 1))  # 定义缩放范围,-1,1是数据缩放的范围
    scaler = scaler.fit(X)  # 调用缩放数据的fun
    scalered_X = scaler.transform(X)#转换成一个[-1,1]区间的矩阵
    scalered_series = Series(scalered_X[:, 0])#把矩阵序列化成列表
    print (scalered_series)
    
    # 逆缩放,反着来一遍,转换回去
    inverted_X = scaler.inverse_transform(scalered_X)#把数值为[-1,1]之间的矩阵转换成正常数据的矩阵
    inverted_series = Series(inverted_X[:, 0])#把矩阵转换成列表
    print (inverted_series.head())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    搭建网络

    从0开始实现深度学习网络

    我们搭建网络并训练的流程为:

    读取数据,如读取时间序列,图片等
    数据预处理,如将其转换为监督数据,数据归一化,缩放等,划分数据集
    搭建模型,设置网络层结构,设置参数,神经元个数等
    编译模型,设置批次大小,损失函数,优化器等
    训练模型,设置迭代次数,批次大小传入数据等
    保存模型,如参数权值等
    模型预测数据,使用已保存模型进行数据预测
    模型评估,设置评估函数
    结果分析,如通过图像。

    数据读取,使用的是numpy的read_csv

    # 读取时间数据的格式化
    def parser(x):
        return datetime.strptime(x, '%Y/%m/%d')
    # 加载数据
    series = read_csv('data_set/shampoo-sales.csv', 
    header=0, parse_dates=[0], index_col=0, squeeze=True,
                      date_parser=parser)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    转换为差分数据,即将数据变为稳定的

    # 转换成差分数据
    def difference(dataset, interval=1):
        diff = list()
        for i in range(interval, len(dataset)):
            value = dataset[i] - dataset[i - interval]
            diff.append(value)
        return Series(diff)
    diff_values = difference(raw_values, 1)#转换成差分数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    转换为有监督数据,即input,output形式

    # 转换成有监督数据
    def timeseries_to_supervised(data, lag=1):
        df = DataFrame(data)
        columns = [df.shift(i) for i in range(1, lag + 1)]  # 数据滑动一格,作为input,df原数据为output
        columns.append(df)
        df = concat(columns, axis=1)
        df.fillna(0, inplace=True)
        return df
    # 让数据变成稳定的
    # 把稳定的数据变成有监督数据
    supervised = timeseries_to_supervised(diff_values, 1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    划分训练集测试集

    # 数据拆分:训练数据、测试数据,前24行是训练集,后12行是测试集
    train, test = supervised_values[0:-12], supervised_values[-12:]
    
    • 1
    • 2

    数据缩放至-1到1之间

    # 缩放
    def scale(train, test):
        # 根据训练数据建立缩放器
        scaler = MinMaxScaler(feature_range=(-1, 1))
        scaler = scaler.fit(train)
        # 转换train data
        train = train.reshape(train.shape[0], train.shape[1])
        train_scaled = scaler.transform(train)
        # 转换test data
        test = test.reshape(test.shape[0], test.shape[1])
        test_scaled = scaler.transform(test)
        return scaler, train_scaled, test_scaled
    scaler, train_scaled, test_scaled = scale(train, test)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    模型训练,这里批次大小设置为1,即每次训练一个数据,使用手写循环调用fit,从而没训练一次数据便完成一次权值更新

    def fit_lstm(train, batch_size, nb_epoch, neurons):
        X, y = train[:, 0:-1], train[:, -1]
        X = X.reshape(X.shape[0], 1, X.shape[1])
        model = Sequential()
        # 添加LSTM层
        model.add(LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True))
        model.add(Dense(1))  # 输出层1个node
        # 编译,损失函数mse+优化算法adam
        model.compile(loss='mean_squared_error', optimizer='adam')
        for i in range(nb_epoch):
            # 按照batch_size,一次读取batch_size个数据
            model.fit(X, y, epochs=1, batch_size=batch_size, verbose=0, shuffle=False)
            model.reset_states()  #更新权值
            print("当前计算次数:"+str(i))
        return model
    lstm_model = fit_lstm(train_scaled, 1, 1500, 1)  # 训练数据,batch_size,epoche次数, 神经元个数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    预测数据

    # 预测
    train_reshaped = train_scaled[:, 0].reshape(len(train_scaled), 1, 1)#训练数据集转换为可输入的矩阵
    lstm_model.predict(train_reshaped, batch_size=1)#用模型对训练数据矩阵进行预测
    
    • 1
    • 2
    • 3

    预测数据并完成性能分析

    predictions = list()
    for i in range(len(test_scaled)):#根据测试数据进行预测,取测试数据的一个数值作为输入,计算出下一个预测值,以此类推
        # 1步长预测
        X, y = test_scaled[i, 0:-1], test_scaled[i, -1]
        yhat = forcast_lstm(lstm_model, 1, X)
        # 逆缩放
        yhat = invert_scale(scaler, X, yhat)
        # 逆差分
        yhat = inverse_difference(raw_values, yhat, len(test_scaled) + 1 - i)
        predictions.append(yhat)
        expected = raw_values[len(train) + i + 1]
        print('Moth=%d, Predicted=%f, Expected=%f' % (i + 1, yhat, expected))
    
    print(predictions)
    # 性能报告
    rmse = sqrt(mean_squared_error(raw_values[-12:], predictions))
    print('Test RMSE:%.3f' % rmse)
    # 绘图
    pyplot.plot(raw_values[-12:])
    pyplot.plot(predictions)
    pyplot.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    1.< tag-动态规划和路径组合问题>lt.62. 不同路径 + lt.63. 不同路径 II
    前端使用 Konva 实现可视化设计器(3)- 单选、多选、选择框
    寄存器(内存访问)
    微服务入门案例
    企业架构LNMP学习笔记48
    服务网格安全防护
    第三十章 管理许可(三)
    【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割1(综述篇)
    工程师新红利,我国预计到2025年培养20万名这类人才
    光流法动目标检测
  • 原文地址:https://blog.csdn.net/pengxiang1998/article/details/127188018