【基于TTEDNN的电力系统转子角稳定性预测】基于网格信息邻接矩阵的时序和拓扑嵌入深度神经网络预测转子角稳定性(Python代码实现)

  💥💥💞💞欢迎来到本博客❤️❤️💥💥

🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。

⛳️座右铭:行百里者,半于九十。

📋📋📋本文目录如下:🎁🎁🎁

目录

 ⛳️赠与读者

💥1 概述

📚2 运行结果

🎉3 参考文献

🌈4 Python代码、数据、文章


 ⛳️赠与读者

👨‍💻做科研,涉及到一个深在的思想系统,需要科研者逻辑缜密,踏实认真,但是不能只是努力,很多时候借力比努力更重要,然后还要有仰望星空的创新点和启发点。当哲学课上老师问你什么是科学,什么是电的时候,不要觉得这些问题搞笑。哲学是科学之母,哲学就是追究终极问题,寻找那些不言自明只有小孩子会问的但是你却回答不出来的问题。建议读者按目录次序逐一浏览,免得骤然跌入幽暗的迷宫找不到来时的路,它不足为你揭示全部问题的答案,但若能让人胸中升起一朵朵疑云,也未尝不会酿成晚霞斑斓的别一番景致,万一它居然给你带来了一场精神世界的苦雨,那就借机洗刷一下原来存放在那儿的“躺平”上的尘埃吧。

     或许,雨过云收,神驰的天地更清朗.......🔎🔎🔎

💥1 概述

摘要:

转子角稳定性(RAS)预测对于维持电力系统互联同步电机的正常运行至关重要。相量测量单元(PMU)的广泛部署促进了RAS预测数据驱动方法的发展。本文提出了一种时序和拓扑嵌入深度神经网络(TTEDNN)模型,通过从PMU数据中提取时序和拓扑特征来准确有效地预测RAS。电网信息邻接矩阵结合了电网的结构和电气参数信息。考虑了初始运行条件下具有扰动的小信号RAS和输电线路短路时的瞬态RAS。IEEE 39节点和IEEE 300节点电力系统的案例研究用于测试TTEDNN模型的性能、可扩展性和鲁棒性,以应对测量不确定性。结果显示,TTEDNN模型在现有的深度学习模型中表现最佳。此外,已经证明从小信号RAS条件到瞬态RAS条件的优越的转移学习能力。

数字化转型在电力系统的现代化中起着至关重要的作用。相量测量单元(PMU)的广泛部署使得能够收集广域电力系统的数据,从而帮助工程师以数据驱动的方式分析电力系统动态并预测系统稳定性[1],[2]。传统上,不稳定问题与转子角稳定性(RAS)有关[3],它是指电力系统中的同步电机在受到扰动后保持同步的能力[4]。随着可再生能源在现代电力系统中的渗透率越来越高,由于新兴的低惯性和随机特性,RAS需要更准确、更快速的预测。目前,RAS的预测方法可分为两类,即模型驱动方法和数据驱动方法[5]。

一种常用的模型驱动方法是基于高维非线性微分代数方程(DAEs)的费力时域仿真(TDS),该方程表示电力系统的动态[6]。TDS是耗时的,因为它要求整个状态轨迹来揭示系统的稳定性。尽管已经提出了不同的方法来加速TDS过程,例如并行计算[6]和高级硬件[7],但仍然需要大量的计算资源来处理日益复杂的电力系统和多样化的运行场景。李雅普诺夫函数族模型驱动方法用于电力系统稳定性评估的分析方法[8]。不幸的是,事实证明,找到一个李雅普诺夫函数来准确评估电力系统的RAS是非常困难的[9]。因此,一些研究人员发现了基于最大李雅普诺夫指数的无模型方法[10]。

最近,数据驱动方法,特别是深度学习方法,在预测电力系统中的RAS方面引起了广泛的研究兴趣[1],[2],[11],[12]。与模型驱动方法相比,深度学习性能不依赖于电力系统的先验知识和模型细节。此外,深度学习的强大泛化能力和离线训练和在线诊断模式的性质为满足实际应用中的高精度和快速在线要求提供了巨大的潜力[1]。

在现有的深度学习模型中,卷积神经网络(CNN)在许多领域取得了重大成就[13],包括电力系统的RAS预测。例如,文献[2]提出了基于CNN和电压相量复平面图像的快速电力系统RAS评估模型。参考文献[11]设计了级联的CNN,以捕获来自不同TDS时间间隔的数据,提取特征,预测稳定性概率,并确定TDS终止。此外,其他深度学习模型也用于预测RAS,如堆叠去噪自动编码器(SDAE)[14]和长短期记忆(LSTM)网络[12]。深度学习模型的预测结果可用于完成进一步的运行任务,如预防性控制[15]。然而,由于电力系统是复杂的动态网络,上述深度学习模型的架构需要具有适当的可解释性,以解释电力系统的空间相关性。因此,在深度学习中有效地使用电网结构的重要拓扑信息仍然具有挑战性。

图神经网络(GNN)是一种有前景的深度学习模型,可以提取电力系统的空间相关性特征,因为GNN可以自然地将电力网络结构映射到其神经网络连接中。作为GNN家族的一员,图卷积网络(GCN)[16]将拓扑结构与卷积算法相结合,已被证明在复杂的动态网络分析中非常有效[17]。GCN在电力系统中的图结构数据上表现出良好的分类和预测能力[18]。例如,[19]开发了一种可解释的GCN,以有效地指导级联故障搜索。然而,GCN可能更擅长捕捉顺序特征,即电力系统动态时间序列的时间信息。需要额外的技术来从电力系统瞬态动力学的时域中提取特征。对于序列建模[20],卷积技术在最近的工作中得到了广泛的发展,并且在序列建模任务中超过了著名的循环网络架构的基线[21]。作为基于卷积技术的递归架构之一,时序卷积网络(也称为TCN)已被用于电力系统的时序预测,展示了强大的记忆能力[22]。

最近的研究中提出了基于GNN家族的RAS预测的一些相关方法。参考文献[23]介绍了用于RAS和短期电压不稳定预测的图注意力网络(GAT)[23]。参考文献[24]提出了具有残差结构的多图注意力网络(ResGAT)用于RAS评估,该网络适用于电力系统拓扑结构的变化[24]。设计了一种具有残差机制的类似GCN架构,以克服模型训练过程中的网络退化现象[25]。后来,提出了基于注意力的分层动态图池化网络,使深度学习模型对系统规模变化更加鲁棒[26]。引入了一种与LSTM相结合的多任务递归图卷积网络(RGCN),用于稳定性分类和关键发电机识别[27]。然而,据我们所知,没有现有的研究考虑了RAS预测的所有类别,即它们侧重于小信号RAS [25]或瞬态RAS [23]、[24]、[26]、[27]的场景。GNN模型在小信号和瞬态RAS上的综合预测性能尚不清楚。同时,很少有相关研究讨论模型对实际测量不确定性的鲁棒性,即PMU的测量噪声和采样周期。

本文通过结合GCN和TCN提出了时域和拓扑嵌入深度神经网络(TTEDNN)模型,以捕捉电力系统瞬态动力学的时空特征,用于RAS预测。总的来说,本文的主要贡献如下。

TTEDNN模型被提出用于通过从扰动后的瞬态动力学中提取的时间和空间特征来预测RAS。电网信息邻接矩阵用于整合电网的结构和电气参数信息。

TTEDNN模型对不同水平的测量噪声和不同PMU数据周期的鲁棒性得到了说明。

此外,还研究了TTEDNN模型的迁移学习能力。研究发现,用小信号扰动数据集训练的TTEDNN模型可以作为预测瞬态RAS的预训练模型。

本文的其余部分组织如下。第二节介绍了电力系统的RAS。第三节提出了TTEDNN模型的架构。第四节给出了案例研究。第五节得出了结论。详细文章见第4部分。

📚2 运行结果

部分代码:

from matplotlib import rcParams
from matplotlib import pyplot as plt
import numpy as np
import h5py
from sklearn.manifold import TSNE
import os
from tensorflow.keras.models import Model, load_model
from tensorflow.keras.optimizers import Adam
from utils.load_data import load_para
from trainer_keras import gen_adj
from spektral import GraphConv
from model.TCN import TempConvNet
from utils.load_data import load_data_one_IEEE_l


def draw_training_curve(exp_num):

    f = h5py.File('./result/%s/histroy.h5' % (exp_num), 'r')
    HISTORY = f['train_history'][()]
    f.close()
    del f

    acc_values = HISTORY[0, :]
    loss_values = HISTORY[2, :]
    config = {
        "font.family": 'Times New Roman',
        "mathtext.fontset": 'stix',
        "font.serif": ['SimSun'],
    }
    rcParams.update(config)
    fig = plt.figure(figsize=(4, 4), dpi=300)
    plt.rc('axes', lw=0.5)
    ax1 = fig.subplots()
    left = 0.15
    bottom = 0.15
    plt.subplots_adjust(
        left=left, bottom=bottom, right=1-2*bottom+left, top=1-bottom
    )
    ax2 = ax1.twinx()
    epochs = range(1, len(HISTORY[0, :]) + 1)
    ax1.plot(
        epochs, acc_values,     'r',
        linewidth=.5,
        label='ACC'
    )
    ax1.plot(
        epochs, loss_values,    'b',
        linewidth=.5,
        label='Loss'
    )
    ax1.set_ylabel('Training ACC')
    ax2.set_ylabel('Training Loss')

    ax1.set_ylim([0, 1])
    ax2.set_ylim([0, 1])
    ax1.tick_params(direction='in', width=0.5, length=2)
    ax2.tick_params(direction='in', width=0.5, length=2)
    ax1.set_xlabel('Epochs')
    legend = ax1.legend(fancybox=False, facecolor='none', edgecolor='k')
    plt.savefig('training.png')
    plt.show()


def get_layer_output(model, layer_index, inputs):

    layer = Model(inputs=model.input,
                  outputs=model.get_layer(index=layer_index).output)
    layer_out = layer.predict(inputs)
    return np.array(layer_out)


def get_middle_output(exp_num, N, data_number, timelength, TEST_SIZE, relative, normalize, standard, mode, move, WSZ, adj_mode, chosedlength, learning_rate):

    A, PY = load_para(
        N=N, adj_mode=adj_mode
    )

    X_train, X_train_theta, X_val, X_val_theta, X_test, X_test_theta, Y_train, Y_val, Y_test, a, b = load_data_one_IEEE_l(
        N=N,
        length=data_number,
        timelength=timelength,
        chosedlength=chosedlength,
        TEST_SIZE=TEST_SIZE,
        relative=relative,
        normalize=normalize,
        standard=standard,
        mode=mode,
        move=move,
        WSZ=WSZ
    )

    F = X_train.shape[-1]
    n_out = 1

    # process adj matrix, create filter for GCN and convert to sparse tensor
    if adj_mode != 3:
        # (N, N)
        adj = GraphConv.preprocess(A=A)
        del X_train_theta, X_val_theta, X_test_theta
        adj_train = np.repeat(
            a=np.expand_dims(adj, axis=0),
            repeats=X_train.shape[0],
            axis=0
        )
        adj_val = np.repeat(
            a=np.expand_dims(adj, axis=0),
            repeats=X_val.shape[0],
            axis=0
        )
        adj_test = np.repeat(
            a=np.expand_dims(adj, axis=0),
            repeats=X_test.shape[0],
            axis=0
        )
    else:
        # (length, N, N)
        adj_train = gen_adj(x_omega=X_train, x_theta=X_train_theta, PY=PY)
        adj_val = gen_adj(x_omega=X_val, x_theta=X_val_theta, PY=PY)
        adj_test = gen_adj(x_omega=X_test, x_theta=X_test_theta, PY=PY)

        adj_train = np.array([GraphConv.preprocess(adj_train[i, :, :]) for i in range(Y_train.shape[0])])
        adj_val = np.array([GraphConv.preprocess(adj_val[i, :, :]) for i in range(Y_val.shape[0])])
        adj_test = np.array([GraphConv.preprocess(adj_test[i, :, :]) for i in range(Y_test.shape[0])])

    path = './result/' + str(exp_num) + '/'

    def get_lr_metric(optimizer):
        def lr(y_true, y_pred):
            return optimizer.lr
        return lr

    opt = Adam(learning_rate=learning_rate)
    lr_metric = get_lr_metric(opt)
    model = load_model(
        path + '_model.h5',
        custom_objects={'GraphConv': GraphConv, 'TempConvNet': TempConvNet, 'lr': lr_metric}
    )

    output_3_train = get_layer_output(
        model=model, layer_index=3, inputs=[X_train, adj_train]
    )  # second GCN output
    output_3_val = get_layer_output(
        model=model, layer_index=3, inputs=[X_val, adj_val]
    )  # second GCN output
    output_3_test = get_layer_output(
        model=model, layer_index=3, inputs=[X_test, adj_test]
    )  # second GCN output

    Y_predict_train = model.predict([X_train, adj_train])
    Y_predict_val = model.predict([X_val, adj_val])
    Y_predict_test = model.predict([X_test, adj_test])

    f = h5py.File(path + '_middle_output.h5', 'w')
    f.create_dataset('/true/train', data=Y_train)
    f.create_dataset('/true/val',   data=Y_val)
    f.create_dataset('/true/test',  data=Y_test)
    f.create_dataset('/output/train', data=Y_predict_train)
    f.create_dataset('/output/val',   data=Y_predict_val)
    f.create_dataset('/output/test',  data=Y_predict_test)
    f.create_dataset('/middle/3/train', data=output_3_train)
    f.create_dataset('/middle/3/val',   data=output_3_val)
    f.create_dataset('/middle/3/test',  data=output_3_test)
    f.close()
    del f


def hidden_layer(exp_num):

    f = h5py.File('./result/%s/middle_output.h5' % (exp_num), 'r')
    output_3_train = f['/middle/3/train'][()]
    Y_train = f['/true/train'][()]
    Y_predict_train = f['/output/train'][()]
    Y_predict_train_int = np.rint(Y_predict_train)
    f.close()
    del f

    color_train = []
    for i in Y_train:
        if i == 0:
            color_train.append('g')
        else:
            color_train.append('k')
    color_train_pre = []
    for i in Y_predict_train_int:
        if i == 0:
            color_train_pre.append('g')
        else:
            color_train_pre.append('k')
    color_train_error = []
    for i in range(Y_train.shape[0]):
        if Y_train[i] != Y_predict_train_int[i]:
            color_train_error.append('r')
        else:
            color_train_error.append('w')

    # true-pre-error
    tsne = TSNE(n_components=2, init='pca', random_state=0)
    tsne = tsne.fit_transform(output_3_train)
    plt.figure(figsize=(16, 8))
    plt.subplot(1, 3, 1)
    plt.xlim(-80, 80)
    plt.ylim(-80, 80)
    plt.scatter(tsne[:, 0], tsne[:, 1], s=1, c=color_train)
    plt.subplot(1, 3, 2)
    plt.xlim(-80, 80)
    plt.ylim(-80, 80)
    plt.scatter(tsne[:, 0], tsne[:, 1], s=1, c=color_train_pre)
    plt.subplot(1, 3, 3)
    plt.xlim(-80, 80)
    plt.ylim(-80, 80)
    plt.scatter(tsne[:, 0], tsne[:, 1], s=1, cmap='RdYlBu', c=Y_predict_train)
    plt.savefig('hidden_layer.png')
    plt.show()


# training process visualization
draw_training_curve(exp_num=1)
# hidden layer activations visualization
get_middle_output(exp_num=1, N=14, data_number=1000, timelength=101, chosedlength=11, TEST_SIZE=0.2, relative=False, normalize=False, standard=False, mode=1, move=False, WSZ=5, adj_mode=2)
hidden_layer(exp_num=1)

🎉3 参考文献

文章中一些内容引自网络,会注明出处或引用为参考文献,难免有未尽之处,如有不妥,请随时联系删除。

🌈4 Python代码、数据、文章

资料获取,更多粉丝福利,MATLAB|Simulink|Python资源获取

                                                           在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值