更快地用 NumPy 编写 LSTM 预测

发布时间:2022-10-07 / 作者:清心寡欲

本文介绍了更快地用 NumPy 编写 LSTM 预测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 NumPy(而不是 Tensorflow 或 PyTorch)编写了双向 LSTM 预测 function,我需要让它更快。 该网络有三层,但为了简单起见,我将只展示(和时间)第一层。 通过调用子函数LSTMf()LSTMb()来调用这个双 LSTM 层,以向前和向后处理输入数据(500 个点的数组)。 LSTMf()LSTMb()有循环,我怀疑这些循环花费的时间最多。 这是预测 function:

import numpy as np


def predict(xt, ht, c, u, t, whff, wxff, bff, whif, wxif, bif, whlf, wxlf, blf, whof, wxof, bof, whfb,
             wxfb, bfb, whib, wxib, bib, whlb, wxlb, blb, whob, wxob, bob):

    def tanh(a):
        return np.tanh(a)

    def sig(a):
        return 1 / (1 + np.exp(-a))

    def cell(x, h, c, wh1, wx1, b1, wh2, wx2, b2, wh3, wx3, b3, wh4, wx4, b4):
        new_c = c * sig(h @ wh1 + x @ wx1 + b1) + sig(h @ wh2 + x @ wx2 + b2) * tanh(h @ wh3 + x @ wx3 + b3)
        new_h = tanh(new_c) * sig(h @ wh4 + x @ wx4 + b4)
        return new_c, new_h

    def LSTMf(xt, ht, c, t, whf, wxf, bf, whi, wxi, bi, whl, wxl, bl, who, wxo, bo):
        h = ht[t - 1:t]
        for i in range(t):
            c, h = cell(xt[i:i + 1], h, c, whf, wxf, bf, whi, wxi, bi, whl, wxl, bl, who, wxo, bo)
            ht[i] = h
        return ht

    def LSTMb(xt, ht, c, t, whf, wxf, bf, whi, wxi, bi, whl, wxl, bl, who, wxo, bo):
        h = ht[0:1]
        for i in range(t - 1, -1, -1):
            c, h = cell(xt[i:i + 1], h, c, whf, wxf, bf, whi, wxi, bi, whl, wxl, bl, who, wxo, bo)
            ht[i] = h
        return ht

    # LSTM-bi 1
    hf = LSTMf(xt, ht.copy(), c, t, whff, wxff, bff, whif, wxif, bif, whlf, wxlf, blf, whof, wxof, bof)
    hb = LSTMb(xt, ht.copy(), c, t, whfb, wxfb, bfb, whib, wxib, bib, whlb, wxlb, blb, whob, wxob, bob)
    xt = np.concatenate((hf, hb), axis=1)
    return xt

输入数据和参数的rest可以人工生成,代码如下:

t = 500  # input's number of points
u = 64   # layer's number of units
xt = np.zeros((t, 1), dtype=np.float32)  # input
ht = np.zeros((t, u), dtype=np.float32)
ou = np.zeros((1, u), dtype=np.float32)
uu = np.zeros((u, u), dtype=np.float32)
weights = {'wxif':ou,'wxff':ou,'wxlf':ou,'wxof':ou,'whif':uu,'whff':uu,'whlf':uu,'whof':uu,'bif':ou,'bff':ou,'blf':ou,'bof':ou,
           'wxib':ou,'wxfb':ou,'wxlb':ou,'wxob':ou,'whib':uu,'whfb':uu,'whlb':uu,'whob':uu,'bib':ou,'bfb':ou,'blb':ou,'bob':ou}

yt = predict(xt, ht, ou, **weights)  # Call example

我已经将它(1)像这样,(2)用 Numba 和(3)用 Cython 定时:

import numpy as np
from predict import predict
from predict_numba import predict_numba
from predict_cython import predict_cython
import timeit


n = 100
print(timeit.Timer(lambda: predict(xt, ht, ou, u, t, **weights)).timeit(n)/n)        # 0.05198 s
predict_numba(xt, ht, ou, u, t, **weights)  # Dummy slow numba call
print(timeit.Timer(lambda: predict_numba(xt, ht, ou, u, t, **weights)).timeit(n)/n)  # 0.01149 s
print(timeit.Timer(lambda: predict_cython(xt, ht, ou, u, t, **weights)).timeit(n)/n) # 0.13345 s
  • 我想让这个预测快于 0.03 秒。
  • Numba 足够快,但我的第一次调用不能太慢(三层超过 30 秒)
  • Cython 很慢; 我不确定这是否是原因,但按照此处的建议( Cython:矩阵乘法)我没有输入大多数参数,因为操作“@”不支持 memory 视图。

最初我使用 Keras 和 CPU 或 GPU,但 NumPy 比任何一个都快。 我也听说过可能适用的 TorchScript。 我该怎么做才能使预测更快?

__

上下文:此 function 预测 ECG window 中的 R 峰,旨在尽可能频繁地调用,以预测实时采集的 ECG 的 R 峰。

PS。 如果您想了解计算的含义,可能会使用 LSTM 单元如何工作的描述: https://imgur.com/UFrd9oa




暂无解决方案

[英文标题]Make an LSTM prediction written in NumPy faster


声明:本媒体部分图片、文章来源于网络,版权归原作者所有,如有侵权,请联系QQ:330946442删除。