复现两篇论文中的时间序列预测模型

星期二, 08. 十月 2019 03:27下午
注:论文实现代码和论文.pdf都在git 账号下,欢迎交流讨论

论文题目:

  • Learning to Monitor Machine Health with Convolutional Bi-Directional LSTM Networks
  • Machine health monitoring using local feature-based gated recurrent unit networks

1.第一篇文章基本框架

fig_1.png

论文主要内容:通过论文提出的模型实现对故障的诊断(分类回归都可以实现)
论文的框架主要分为四个部分:
1、原始数据(可以是多个传感器数据)通过滑窗提取时频域特征,假设传感器数目为m,窗口数目为k,每个传感器提取的特征数目为n,则原始数据提过特征提取后的输入为[-1, k, m*n],其中-1表示batch数目。
住:这一部分在框图和代码中没有体现,但是在论文中可以看出来。如果读者需要套用这个模型,需要自己实现这一部分的功能,如果在用原始数据输入(不经过特征提取)也可以取得很好效果,则这一部分可以省略
2、卷积部分实现空间特征提取,保留时间信息,代码如下:

    @staticmethod
    def cnn_layer(cnn_input=None, k=None, m=None, s=None, d=None):
        cnn1 = tf.contrib.layers.conv2d(cnn_input,
                                        num_outputs=k,
                                        kernel_size=[m, d],
                                        stride=[1, d],
                                        padding='VALID', )
        cnn1_pool = tf.nn.max_pool(cnn1,
                                   ksize=[1, s, 1, 1],
                                   strides=[1, s, 1, 1],
                                   padding='SAME',
                                   name='cnn1_max_pool')
        cnn1_shape = cnn1_pool.get_shape()
        cnn_out = tf.reshape(cnn1_pool, shape=[-1, cnn1_shape[1], cnn1_shape[-1]])
        return cnn_out

可以参考图3结合代码的实现理解,注意理解卷积层池化层的kernel_size和ksize,其中d表示数据的长度,即m*n的值:


2.png

3、两层双向LSTM的堆叠,主要用于在cnn输出的基础上提取时间信息,代码如下:

    @staticmethod
    def bilstm_layer(bilstm_input=None, num_units=None):
        # first bi-lstm cell
        with tf.variable_scope('1st-bi-lstm-layer', reuse=tf.AUTO_REUSE):
            cell_fw_1 = tf.nn.rnn_cell.LSTMCell(num_units=num_units[0], state_is_tuple=True)
            cell_bw_1 = tf.nn.rnn_cell.LSTMCell(num_units=num_units[0], state_is_tuple=True)
            outputs_1, states_1 = tf.nn.bidirectional_dynamic_rnn(cell_fw_1, cell_bw_1, inputs=bilstm_input,
                                                                  dtype=tf.float32)

        # second bi-lstm cell
        with tf.variable_scope('2nd-bi-lstm-layer', reuse=tf.AUTO_REUSE):
            # input_2 = tf.add(outputs_1[0], outputs_1[1])
            input_2 = tf.concat([outputs_1[0], outputs_1[1]], axis=2)
            cell_fw_2 = tf.nn.rnn_cell.LSTMCell(num_units=num_units[1], state_is_tuple=True)
            cell_bw_2 = tf.nn.rnn_cell.LSTMCell(num_units=num_units[1], state_is_tuple=True)
            outputs_2, states_2 = tf.nn.bidirectional_dynamic_rnn(cell_fw_2, cell_bw_2, inputs=input_2,
                                                                  dtype=tf.float32)

        # bilstm output
        with tf.variable_scope('bi-lstm-layer-output', reuse=tf.AUTO_REUSE):
            bilstm_out = tf.concat([states_2[0].h, states_2[1].h], axis=1)
        return bilstm_out

可以参考图c结合代码的实现理解,注意理解两个双向lstm层的拼接(关于该部分的实现也是根据论文原文实现的,如果有问题还请讨论交流):


3.png

4、全连接层实现最终结果输出,这一部分的实现相对简单,主要对上一层最后在timestep输出的隐层特征作为输入得到最终的结果,代码如下所示:

    @staticmethod
    def fc_layer(fc_input=None, num_units=None, keep_prob=None):
        fc_input_ = tf.nn.dropout(fc_input, keep_prob=keep_prob)
        fc1 = tf.layers.dense(fc_input_, num_units[0], activation=tf.nn.relu,
                              kernel_initializer=tf.glorot_uniform_initializer())
        fc1_ = tf.nn.dropout(fc1, keep_prob=keep_prob)
        fc_out = tf.layers.dense(fc1_, num_units[1], activation=tf.nn.relu,
                                 kernel_initializer=tf.glorot_uniform_initializer())
        # fc_out = tf.layers.dense(fc_out, 1, activation=None, use_bias=False,
        #                          kernel_initializer=tf.glorot_normal_initializer())
        return fc_out

所有代码实现请参考本人git.

2.第二篇文章基本框架

4.png

论文主要内容:通过论文提出的模型实现对故障的诊断(分类回归都可以实现)
论文的框架主要分为四个部分:
1、原始数据(可以是多个传感器数据)通过滑窗提取时频域特征,假设传感器数目为m,窗口数目为k,每个传感器提取的特征数目为n,则原始数据提过特征提取后的输入为[-1, k, m*n],其中-1表示batch数目。(这与论文1中提到的是一样的,而且可以从下图中看出来),这一部分的内容同样需要读者自己实现。
2、双向GRU实现时间特征提取,这一部分也相对简单,代码如下:

    @staticmethod
    def bigru_layer(bilstm_input=None, num_units=None):
        cell_fw = tf.nn.rnn_cell.GRUCell(num_units=num_units, name='fw')
        cell_bw = tf.nn.rnn_cell.GRUCell(num_units=num_units, name='bw')
        outputs, states = tf.nn.bidirectional_dynamic_rnn(cell_fw, cell_bw, inputs=bilstm_input, dtype=tf.float32)
        bigru_out = tf.concat([states[0], states[1]], axis=1)
        return bigru_out

3、权重平均化部分,这一部分主要通过fc实现,但是需要先对输入到gru的数据进行处理,参考原文公式和代码,由于原文公式较长,该部分只粘贴代码,其主要思想是实现不同窗口在同一个time step上做类似指数的平均,参考代码如下:

    @staticmethod
    def get_weight_average_layer(weight_average_input=None):
        _arr_weight_average_input = np.array(weight_average_input)
        _, T, _ = _arr_weight_average_input.shape
        _arr = []
        for ck in _arr_weight_average_input:    # every batch
            qk = np.array([np.exp(np.min([k - 1, T - k])) for k in range(1, T+1)])
            sigma_qk = np.sum(qk, dtype=np.float32)
            wk = np.array([qj * 1.0 / sigma_qk for qj in qk])
            c = np.array([wk[k]*ck[k] for k in range(T)]).sum(axis=0)
            _arr.append(c)
        return np.array(_arr)

4、这一部分相对简单,就是将第2和第3部分的结果进行concat再通过一个fc学习,代码如下:

    @staticmethod
    def fc_layer_2(fc_input=None, num_units=None, keep_prob=None):
        fc_input_ = tf.nn.dropout(fc_input, keep_prob=keep_prob)
        fc_out = tf.layers.dense(fc_input_, num_units, activation=tf.nn.relu,
                                 kernel_initializer=tf.glorot_uniform_initializer())
        # fc_out = tf.nn.dropout(fc, keep_prob=keep_prob)
        return fc_out

所有代码实现请参考本人git.

注:

  • 代码中有任何问题欢迎与本人交流讨论;
  • 代码需要支持tensorflow-gpu(>=1.10.0)才能运行;
  • git 上有参考论文和部分用于实验的数据,读者可以运行main_test文件对模型进行检验;
  • git 中data文件夹下的数据是一个回归问题,随着程序的运行mse会在100附近;
  • 代码中所有参数的表示都在类中注明了。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容