ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于LSTM的网络异常流量预测模型实现与工程实践

基于LSTM的网络异常流量预测模型实现与工程实践 1. 这篇文章真正要解决的问题很多搞网络运维和安全的同学应该都遇到过这样的场景凌晨两点监控大屏上某个节点的流量曲线突然拔高告警短信一口气发了二三十条。你爬起来登录设备看了一眼发现流量确实涨了但既不像攻击也不像业务高峰最后折腾一晚上结论是某台机器在跑定时同步任务。这其实是网络异常流量检测最常见的困境规则写得太松漏报规则写得太紧误报。传统的静态阈值方案比如连续五分钟流量超过 800Mbps 就告警在业务量相对稳定的机房可能还能用一阵子但只要业务出现周期性波动、活动促销、新系统上线这套规则立刻失效。你需要一套能理解流量历史规律的方法而不是只会卡数字的报警器。基于深度学习 LSTM 算法的网络异常流量预测模型本质上是在做这样一件事把网络流量看成一条时间序列用 LSTM 这类适合序列建模的神经网络去学习流量的正常变化规律预测未来一段时间内的流量走势再把预测值和真实值做对比残差超过阈值就判定为异常。它不再回答流量是不是超过 800M这个问题而是回答流量是否符合它自己过去一贯的模式。这篇文章要带你从头到尾实现一个基于 LSTM 的网络异常流量预测模型包括环境准备、数据集处理、模型设计与训练、异常判定策略、代码实现和常见问题排查。读完你能跑通一条完整的实验链路并且理解每个环节到底在解决什么问题。文章不会把代码甩给你就完事每一步都会解释为什么这么做以及做错了会出现什么后果。2. 网络异常流量预测的核心概念与原理2.1 为什么传统方法不够用传统的异常流量检测主流方案有两大类。第一类是基于规则匹配比如五元组过滤、特征匹配、黑名单 IP 封禁。这类方法的优点是速度快、解释性好缺点是攻击者只要稍微变换一下特征规则就失效了。第二类是基于统计阈值比如计算流量均值、方差当实时流量超过均值加三倍标准差时触发告警。这类方法比纯规则灵活一些但对流量分布的假设太强真实网络流量往往是非平稳、突发性强、存在周期性的均值方差这些统计量根本描述不了完整的规律。LSTM 方案的本质区别在于它不做静态对比而是做动态预测。模型从历史流量中学习到这个网络在每天几点会有什么规模的流量、周几会出现明显波动、遇到突发请求后会怎么回落这些隐含模式。有了这个预测能力再去看实际流量和预测值之间的差距自然能识别出真正的异常。2.2 LSTM 到底是什么LSTM全称 Long Short-Term Memory长短期记忆网络。它是循环神经网络 RNN 的一种改进结构专门用来解决长序列建模中梯度消失和长期依赖的问题。拿网络流量举例子你今天下午三点出现一个流量尖峰原因可能是上周同一时间做过一次全量数据迁移也可能是三天前上线了一个定时任务。普通 RNN 在处理这种当前时刻的输出依赖很久以前的信息的情况时梯度在反向传播过程中会指数级衰减导致模型学不到长期规律。LSTM 在神经元内部引入了三个门结构遗忘门、输入门、输出门。这里不用把数学公式全部背下来你只需要记住一个直觉LSTM 每个时间步都会决定我要忘掉哪些旧信息、记住哪些新信息、输出哪些信息。这个机制让它能够把网络流量的周期性特征、趋势特征、突变成分分别编码到不同的记忆通道中从而在预测时综合考虑长期规律和近期变化。2.3 用 LSTM 做异常流量预测的整体思路用 LSTM 做异常检测通常有两种路线。第一种是分类路线把流量特征直接喂给 LSTM输出正常或异常的标签。这种路线依赖高质量标注数据而真实环境里正常流量远多于异常流量正负样本严重不均衡。第二种是预测路线也是本文采用的方案先用正常流量数据训练 LSTM 模型让模型学会预测下一个时间点的流量值然后持续输入实时流量将模型预测值和真实观测值做差残差超过动态阈值就判定为异常。预测路线的优势很明显。第一它只需要正常数据就能训练不需要大量标注异常样本第二它能发现未知类型异常因为模型只认识正常模式任何偏离正常模式的流量都会被识别出来第三残差本身是一个连续的数值我们可以根据业务容忍度调整检测灵敏度而不是只能给出非黑即白的结论。整个检测流程可以拆成四个步骤数据采集与清洗拿到网络流量时间序列。数据预处理与窗口化把连续流量切成固定长度的序列样本。训练 LSTM 预测模型用正常流量拟合下一时刻的流量值。设定残差阈值实时预测并判定异常。3. 环境准备与前置条件3.1 开发环境建议本文的核心代码基于 Python 和 TensorFlow/Keras。为了保证模型训练效果和代码可复现性建议你准备以下环境。操作系统方面Windows 10/11、Ubuntu 20.04 或 macOS 都可以运行本文代码。如果你有 NVIDIA 显卡并且打算用 GPU 加速训练建议使用 Ubuntu 环境驱动和 CUDA 的配置会更顺利一些。Python 版本建议使用 3.8 以上。TensorFlow 对 Python 版本有明确要求建议到 TensorFlow 官网确认你选择的版本支持的 Python 版本范围。为避免版本冲突强烈建议使用 Anaconda 创建独立虚拟环境。3.2 安装依赖库创建虚拟环境并安装核心依赖命令如下conda create -n traffic-lstm python3.9 conda activate traffic-lstm pip install tensorflow pandas numpy matplotlib scikit-learn这里说明一下每个库的用途库名用途tensorflow提供 LSTM 模型的搭建与训练能力pandas读取和处理流量数据numpy数值计算、数组操作matplotlib绘制流量曲线和预测对比图scikit-learn数据标准化、计算评估指标有两点需要特别提醒。第一TensorFlow 的 CPU 版本和 GPU 版本的安装方式不完全一样如果你只是想先跑通流程CPU 版本足够如果想训练更大的模型再额外配置 CUDA 和 cuDNN。第二版本请以实际安装时的情况为准本文代码使用的是 Keras 的常见 API在 TensorFlow 2.x 版本中均可运行不要纠结具体版本号。4. 数据集准备与预处理流程4.1 数据源选择网络异常流量的公开数据集有很多选择常见的有 KDD Cup 1999、NSL-KDD、UNSW-NB15、CICIDS 2017 等。KDD Cup 1999 虽然年代很久远但因为是教学和科研中使用最多的数据集之一资料丰富适合用来验证模型结构。NSL-KDD 解决了原始 KDD 数据集中大量冗余记录的问题训练集和测试集的样本比例更合理也是不错的选择。不过这里要强调一个容易被初学者忽略的问题很多公开数据集本身就是离散连接记录格式每条记录是一条网络连接的统计特征而不是时间戳 流量值的时间序列。如果直接拿这种数据喂给 LSTM 做流量预测语义上是不匹配的。本文的重点是时间序列预测路线所以更推荐你自己从实际网络设备上导出流量数据或者构造一个时间序列数据源。比如定期从路由器或服务器的流量监控接口采集数据输出格式如下timestamp,bytes_in,bytes_out 2024-01-01 00:00:00,152345,89210 2024-01-01 00:05:00,168920,91033 2024-01-01 00:10:00,175001,95432如果你的环境只能拿到公开数据集也可以将数据集的连接记录按时间戳聚合成等间隔的流量序列。比如把每小时内的所有连接记录的字节数累加形成一条小时级流量时间序列。4.2 数据预处理的关键步骤拿到原始时间序列后不能直接送入 LSTM必须经过以下步骤。首先是时间戳对齐。实际采集的数据往往存在缺失时间点比如某台设备宕了十分钟或者网络抖动导致采样失败。缺失值常用的处理方式有三种直接删除、线性插值、前向填充。对于流量数据线性插值通常效果更好。import pandas as pd df pd.read_csv(traffic.csv, parse_dates[timestamp]) df df.set_index(timestamp) # 重采样为5分钟间隔缺失值用线性插值填充 df df.resample(5min).mean() df df.interpolate(methodlinear) df df.dropna()然后是异常值处理。这里有个容易陷入循环的坑我们训练模型去检测异常但在预处理阶段又要先剔除异常值。实际上训练阶段可以使用经过人工确认的正常流量数据或者用一些简单的统计方法剔除明显的离群值比如超过均值的 5 倍标准差。最后是数据标准化。LSTM 使用 tanh 和 sigmoid 作为激活函数如果输入数据的量纲差异太大会造成梯度更新不稳定。最常用的方式是 MinMaxScaler 或 StandardScaler。from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler(feature_range(0, 1)) scaled_data scaler.fit_transform(df[[bytes_in, bytes_out]].values)标准化有一个实现细节必须注意只能用训练集的数据去 fit然后用同一个 scaler 去 transform 训练集、验证集和测试集。绝对不能在全部数据上 fit否则会引入未来信息导致验证结果虚高。4.3 构造监督学习样本LSTM 的输入要求是三维张量形状为(样本数量, 时间步长, 特征数量)。时间步长代表模型一次能看到多长的历史窗口。比如时间步长设为 12输入间隔为 5 分钟数据那模型就是根据过去 1 小时的流量来预测下一个时间点的流量。下面这个函数完成滑动窗口切分import numpy as np def create_sequences(data, lookback12): 将二维特征矩阵转换为LSTM输入序列和预测目标。 data: (样本数, 特征数) lookback: 时间窗口大小 返回 X: (样本数 - lookback, lookback, 特征数) y: (样本数 - lookback, 特征数) X, y [], [] for i in range(len(data) - lookback): X.append(data[i : i lookback]) y.append(data[i lookback]) return np.array(X), np.array(y)为什么窗口大小会影响检测效果窗口太小模型看不到周期性规律预测会很差窗口太大训练数据量减少而且模型可能把很久之前的噪声也学进来。实践中可以先用一小部分验证集尝试不同的 lookback 值对比模型误差。5. LSTM 异常流量预测模型设计5.1 网络结构选型基于 LSTM 的流量预测模型网络结构不需要太复杂复杂反而容易过拟合。推荐一个经典的堆叠 LSTM 结构from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout model Sequential( [ LSTM(64, return_sequencesTrue, input_shape(lookback, n_features)), Dropout(0.2), LSTM(32, return_sequencesFalse), Dropout(0.2), Dense(16, activationrelu), Dense(n_features), ] ) model.compile(optimizeradam, lossmse, metrics[mae])这里的设计思路是逐层提取特征。第一层 LSTM 设置return_sequencesTrue因为它需要把完整的时间步输出传给第二层 LSTM提取更高层的时序特征。第二层 LSTM 只输出最后一个时间步的结果再接全连接层完成回归预测。Dropout层的目的是防止过拟合它会在训练过程中随机丢弃一部分神经元输出让模型不依赖单一特征。对于流量数据来说特征维度往往不高过于复杂的模型很容易死记硬背训练数据泛化能力反而差。5.2 损失函数与评估指标回归预测的损失函数最常用的就是均方误差 MSEMSE mean((y_true - y_pred)^2)它会给大误差更大的惩罚这对异常检测场景是友好的因为预测偏差越大越需要被关注。另外还要关注平均绝对误差 MAE它的单位与原始数据一致可解释性更好。比如你预测入流量MAE 等于 5 兆字节每秒代表模型平均每个时间点的预测值和真实值差 5MB。5.3 阈值确定策略训练好预测模型后下一步就是确定异常判定的阈值。常见做法是在验证集上计算每个时间点的预测残差绝对值然后取某个高百分位数作为阈值比如 95 或 99 百分位数。# 假设 valid_pred 是验证集预测结果valid_true 是验证集真实值 residuals np.abs(valid_true - valid_pred) threshold_95 np.percentile(residuals, 95) threshold_99 np.percentile(residuals, 99)选择 95 还是 99 百分位取决于业务上对误报的容忍度。安全要求高的场景可以选 95宁可多报警也不能漏报告警疲劳严重的场景选 99保证报警质量优先。6. 完整代码实现6.1 项目结构为了便于理解和扩展建议按照下面的结构组织代码traffic-anomaly-detection/ ├── data/ │ └── traffic.csv ├── preprocess.py ├── train_model.py ├── predict_anomaly.py ├── anomaly_threshold.py └── requirements.txt6.2 数据加载与预处理脚本文件路径preprocess.pyimport pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler def load_and_preprocess(csv_path, interval5min): # 读取原始流量数据 df pd.read_csv(csv_path, parse_dates[timestamp]) df df.set_index(timestamp) # 重采样并线性插值 df df.resample(interval).mean() df df.interpolate(methodlinear).dropna() # 选择参与建模的特征列 feature_cols [bytes_in, bytes_out] data df[feature_cols].values return df, data, feature_cols def split_data(data, train_ratio0.7, valid_ratio0.15): 按时间顺序切分训练集、验证集、测试集。 total len(data) train_end int(total * train_ratio) valid_end int(total * (train_ratio valid_ratio)) train_data data[:train_end] valid_data data[train_end:valid_end] test_data data[valid_end:] return train_data, valid_data, test_data def normalize_data(train_data, valid_data, test_data): 只在训练集上fit再应用到验证集和测试集。 scaler MinMaxScaler(feature_range(0, 1)) scaled_train scaler.fit_transform(train_data) scaled_valid scaler.transform(valid_data) scaled_test scaler.transform(test_data) return scaler, scaled_train, scaled_valid, scaled_test def create_sequences(data, lookback12): X, y [], [] for i in range(len(data) - lookback): X.append(data[i : i lookback]) y.append(data[i lookback]) return np.array(X), np.array(y)6.3 模型训练脚本文件路径train_model.pyimport numpy as np from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping from preprocess import load_and_preprocess, split_data, normalize_data, create_sequences def build_model(lookback, n_features): model Sequential( [ LSTM(64, return_sequencesTrue, input_shape(lookback, n_features)), Dropout(0.2), LSTM(32, return_sequencesFalse), Dropout(0.2), Dense(16, activationrelu), Dense(n_features), ] ) model.compile(optimizeradam, lossmse, metrics[mae]) return model def main(): df, raw_data, feature_cols load_and_preprocess(data/traffic.csv) train_data, valid_data, test_data split_data(raw_data) scaler, scaled_train, scaled_valid, scaled_test normalize_data( train_data, valid_data, test_data ) lookback 12 X_train, y_train create_sequences(scaled_train, lookback) X_valid, y_valid create_sequences(scaled_valid, lookback) X_test, y_test create_sequences(scaled_test, lookback) n_features X_train.shape[2] model build_model(lookback, n_features) early_stop EarlyStopping(monitorval_loss, patience10, restore_best_weightsTrue) history model.fit( X_train, y_train, validation_data(X_valid, y_valid), epochs50, batch_size32, callbacks[early_stop], verbose1, ) model.save(lstm_traffic_model.h5) print(模型训练完成已保存到 lstm_traffic_model.h5) if __name__ __main__: main()这里使用了EarlyStopping回调当验证集损失连续多轮不再下降时就提前停止训练。它有两个好处一是节省训练时间二是防止模型在训练集上过度拟合。6.4 异常检测与可视化脚本文件路径predict_anomaly.pyimport numpy as np import pandas as pd import matplotlib.pyplot as plt from tensorflow.keras.models import load_model from preprocess import load_and_preprocess, split_data, normalize_data, create_sequences def calculate_residuals(model, X, y, scaler): 返回真实值和预测值之间的绝对残差。 y_pred_scaled model.predict(X, verbose0) y_pred scaler.inverse_transform(y_pred_scaled) y_true scaler.inverse_transform(y) residuals np.abs(y_true - y_pred) return y_true, y_pred, residuals def detect_anomalies(residuals, threshold, feature_namebytes_in): 残差超过阈值的位置判定为异常。 anomaly_index residuals[:, 0] threshold return anomaly_index def main(): df, raw_data, feature_cols load_and_preprocess(data/traffic.csv) train_data, valid_data, test_data split_data(raw_data) scaler, _, _, scaled_test normalize_data(train_data, valid_data, test_data) lookback 12 X_test, y_test create_sequences(scaled_test, lookback) model load_model(lstm_traffic_model.h5) y_true, y_pred, residuals calculate_residuals(model, X_test, y_test, scaler) # 示例用验证集残差确定阈值这里简化处理直接设置 threshold 50.0 # 单位与原始数据一致例如 MB anomalies detect_anomalies(residuals, threshold) # 可视化 timestamps df.index[lookback len(scaled_test) - len(y_true) :] plt.figure(figsize(12, 5)) plt.plot(timestamps, y_true[:, 0], labelactual, colorblue, alpha0.7) plt.plot(timestamps, y_pred[:, 0], labelpredicted, colororange, alpha0.7) plt.scatter( timestamps[anomalies], y_true[anomalies, 0], colorred, labelanomaly, s30, ) plt.xlabel(time) plt.ylabel(bytes_in (MB)) plt.legend() plt.xticks(rotation45) plt.tight_layout() plt.savefig(anomaly_result.png, dpi150) print(异常检测结果图已保存到 anomaly_result.png) if __name__ __main__: main()在这个脚本中calculate_residuals函数会把标准化后的预测值和真实值通过inverse_transform还原为原始量纲这样阈值设置和结果分析都更直观。7. 运行结果与效果验证7.1 预期的训练输出执行python train_model.py后你会看到类似下面的训练日志Epoch 20/50 1200/1200 [] - 2s 2ms/step - loss: 0.0031 - mae: 0.0312 - val_loss: 0.0028 - val_mae: 0.0298 Epoch 21/50 1200/1200 [] - 2s 2ms/step - loss: 0.0029 - mae: 0.0301 - val_loss: 0.0027 - val_mae: 0.0291需要注意两点。第一损失值是在标准化后的尺度上计算的数值很小是正常现象不代表模型效果差。第二验证集 loss 应该在训练过程中逐渐下降并保持平稳如果出现验证集 loss 持续升高说明模型已经过拟合可以调大 Dropout 比例或者减少训练轮数。7.2 如何判断模型效果模型训练完成后需要从三个维度评估。第一个维度是回归误差。在测试集上计算 MAE 和 RMSE再还原到原始单位。如果测试集 MAE 相对流量均值不到 10%说明模型预测精度已经比较理想。第二个维度是预测曲线拟合度。观察可视化图中的真实流量曲线和预测流量曲线它们应该在趋势上高度重合在细节上存在一些小偏差。如果预测曲线变成一条直线说明模型没有学到有效特征大概率是学习率过大或数据标准化有问题。第三个维度是异常检测的有效性。在测试数据中人为注入一些明显异常值比如把某个时间点的流量突然拉高 5 倍。如果模型检测不到可能原因有阈值设置过高、窗口太小导致模型看不到流量背景、异常率太低导致训练集中完全没有异常样本的上下文特征。7.3 验证流程示例python preprocess.py python train_model.py python predict_anomaly.py执行完最后一步后检查当前目录下是否生成了anomaly_result.png。打开图片你应该能看到蓝色实际流量曲线、橙色预测曲线以及红色散点标记的异常位置。如果运行失败第一步先看控制台输出的异常堆栈。常见的情况是数据文件路径不对、TensorFlow 未正确安装、数据集特征列名和代码不一致。按这个顺序排查大部分问题都能快速定位。8. 常见问题与排查思路下面整理我在实际使用这类模型时遇到过的典型问题以及对应的排查方法。问题现象可能原因排查方式解决方案训练 loss 一直不下降数据未标准化打印输入数据范围检查是否在 0~1 之间使用 MinMaxScaler 或 StandardScaler预测曲线是平稳直线窗口过短或学习率过大降低学习率增大 lookback尝试 lookback 为 24/48学习率设为 0.0001模型训练很慢环境只用了 CPU查看 TensorFlow 是否识别 GPU安装 GPU 版 TensorFlow或降低输入维度验证集 loss 回升过拟合检查训练集和验证集 loss 曲线增加 Dropout、减少 LSTM 单元数、减小训练轮数所有点都被判定为异常阈值设置过低打印残差分布调大阈值或改用百分位数方法确定阈值所有点都正常但漏报明显攻击异常流量被标准化掩盖检查异常流量量级是否被压缩使用特征工程增加滑动均值、滑动方差等衍生特征测试集比训练集误差大很多数据分布漂移对比两段数据的统计量定期用最新数据微调模型这里要特别提醒一个陷阱如果你在数据预处理阶段用全量数据的均值和标准差做标准化那么你的测试集信息已经被偷看到了。训练出的模型在测试集上的表现会偏乐观一旦部署到真实环境预测误差会显著变大。要避免这个问题标准化器必须只在训练集上 fit验证集和测试集只能用同一个标准化器做 transform。这是很多新手容易忽略但影响很大的细节。另一个常见问题是异常注入方式。不少同学在做验证时直接在原始数据后面拼接一段大流量数据然后问为什么模型检测不到异常。原因可能是 LSTM 的实时预测过程中异常点之前的一段时间内模型看到的输入窗口可能还没有包含异常信息或者模型预测本身就具有滞后性。更合理的验证方式是把几个已知的时间点改成异常值然后观察模型能否在异常发生后的 1 到 2 个时间步内发出告警。9. 最佳实践与工程建议9.1 特征工程不要只依赖原始字节数单纯使用bytes_in和bytes_out两个维度模型的表达能力非常有限。在实际项目中建议增加这些衍生特征滑动平均、滑动标准差、流量变化率一阶差分、TCP 连接数、新建连接速率。LSTM 虽然能自动提取时序特征但输入特征的质量仍然直接影响模型的天花板。如果网络流量包含明显的日周期性比如白天业务高峰、凌晨低谷还可以考虑把小时数或星期几作为周期编码特征加入输入。这样做的好处是模型不用自己从几千个时间步里艰难地学到这显然是每天的午高峰学习难度大大降低。9.2 模型需要定期更新网络流量模式不是一成不变的。新业务上线、用户行为变化、网络架构调整都会导致流量的正常模式发生漂移。一个在半年前训练得很好的模型今天可能已经频繁误报。工程上常见的策略是定期微调或者增量训练。比如每周用最近一个月的正常流量数据重新训练一次模型或者设置模型的自动重训任务当检测到验证集残差分布明显变化时触发重训。生产环境的异常检测模型本质上是一个需要持续维护的活系统。9.3 告警要结合多级策略LSTM 模型的输出不应该直接驱动最高等级的告警。更合理的做法是设置多级阈值残差超过 95 百分位时标记为疑似异常进入人工关注队列超过 99 百分位且持续多个时间步时才触发正式告警。这样可以显著降低误报率。另外模型预测的残差不仅包含真实异常的信息也包含模型自身的不确定性。流量波动本来就剧烈的时间段即使没有异常出现残差也可能很大。这时可以采用自适应阈值根据最近一段时间的残差标准差动态调整阈值让检测系统在流量剧烈波动时更宽容在流量平稳时更灵敏。9.4 生产部署时的注意事项把模型部署到生产环境有几个细节值得注意。第一在线预测的输入时间步必须和训练时完全一致。如果你训练时用的是过去 12 个点预测下一个点那么线上服务必须每到一个新时间点就滑动窗口生成新的输入序列。不能把整个历史数据重新拼接成超大序列去预测这样会破坏序列结构。第二模型推理服务建议独立部署和业务应用解耦。可以通过 REST API 或者消息队列对外提供预测服务异常判定逻辑和阈值配置做成可动态调整的配置项不要硬编码在代码里。第三异常检测的结果需要保存下来方便事后回溯。建议记录每条异常记录的时间、预测值、真实值、残差、阈值和判定结果。这些数据是后续调优模型和阈值的重要依据。第四涉及生产网络数据的采集和处理务必遵守你所在单位的安全规范和法律法规。不要在没有授权的情况下采集流量数据不要在不安全的环境下传输和存储数据特征处理过程中也要注意对隐私信息的脱敏。模型训练和推理的系统访问权限要遵循最小权限原则。9.5 模型选型以外的路聊到最后还是想提醒一句LSTM 并不是网络异常流量检测的唯一解也不永远是最好解。如果流量数据量非常大时序很长可以考虑 Transformer 类模型它在捕捉长距离依赖方面表现更强。如果对实时性要求更高可以尝试轻量级的一维卷积网络或时序卷积网络 TCN。如果标记数据充足也可以把问题建模为分类任务用有监督的 LSTM 分类模型直接输出异常类别。但在大多数通用场景下LSTM 预测 残差阈值检测的组合依然是一个性价比很高的起点。它实现简单对先验知识要求低能够适应数据驱动的新模式。建议你在跑通本文代码以后再根据自己实际环境的数据特点逐步加入周期特征、多级告警和自适应阈值把模型工程化落地。如果你正在准备相关的课程设计、毕业设计或者生产级安全系统的初版方案这套数据预处理 LSTM 时序预测 残差检测的框架可以直接作为基线。保留加粗强调的技术关键词从预测的角度建立模型别把思路局限在分类里你会发现异常检测的问题被重新打开了一扇门。
返回列表