MATLAB代码:对于对抗生成网络GAN的风光场景生成算法 关键词:场景生成 GAN 对抗生成网络 风光场景 参考文档:可加好友; 仿真平台: python+tensorflow 主要内容:代码主要做的是基于数据驱动的风光新能源场景生成模型,具体为,通过构建了一种对抗生成网络,实现了风光等新能源的典型场景生成,并且设置了多种运行方式,从而可以以不同的时间间隔来查看训练结果以及测试结果。 三种方式依次为:a) 时间场景生成;b) 时空场景生成;c) 基于事件的场景生成;相较于传统的基于蒙特卡洛或者拉丁超立方等场景生成法,数据驱动法更加具有创新性,而且结果更可信,远非那些方法可以比拟的。

风光场景生成这事儿,传统方法总带着点"硬算"的味道。蒙特卡洛撒点就像天女散花,拉丁超立方摆得整整齐齐却少了点灵气。直到GAN带着神经网络的骚操作进场,这事儿突然变得有意思了——让数据自己教机器怎么编故事。

咱先看个最基础的时间场景生成。核心在于用LSTM捕捉时序里的弯弯绕绕。下面这段生成器的代码藏着点小心机:

def build_generator(time_steps):
    model = tf.keras.Sequential()
    model.add(layers.Dense(256, input_dim=100, use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    
    model.add(layers.Reshape((10, 16)))  # 把噪声压成时间序列的胚子
    model.add(layers.LSTM(128, return_sequences=True))
    model.add(layers.LSTM(64, return_sequences=True))
    model.add(layers.TimeDistributed(layers.Dense(1)))  # 每个时间步输出一个特征
    
    return model

注意那个TimeDistributed层,它像给每个时间点单独戴了副眼镜,让生成器能同时处理不同时间步的特征。判别器那边更狠,直接把时间序列当视频来处理,用一维卷积核在时间轴上滑动抓特征。

进阶到时空场景生成时,代码画风突变。ConvLSTM层登场,这货能把时间和空间特征一锅端:

class SpatioTemporalGenerator(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv_lstm1 = layers.ConvLSTM2D(64, (3,3), padding='same', return_sequences=True)
        self.conv_lstm2 = layers.ConvLSTM2D(32, (3,3), padding='same')
        self.final_conv = layers.Conv2D(1, (3,3), activation='tanh', padding='same')
        
    def call(self, inputs):
        x = self.conv_lstm1(inputs)
        x = self.conv_lstm2(x)  # 时空特征在此处纠缠
        return self.final_conv(x)

这里有个骚操作:把噪声向量先reshape成(8,8,8)的三维张量,假装是个迷你时空立方体。ConvLSTM在处理时,每个cell都带着卷积核在空间维度上滑动,时间维度上记忆,完美实现"左手画圆右手画方"。

MATLAB代码:对于对抗生成网络GAN的风光场景生成算法 关键词:场景生成 GAN 对抗生成网络 风光场景 参考文档:可加好友; 仿真平台: python+tensorflow 主要内容:代码主要做的是基于数据驱动的风光新能源场景生成模型,具体为,通过构建了一种对抗生成网络,实现了风光等新能源的典型场景生成,并且设置了多种运行方式,从而可以以不同的时间间隔来查看训练结果以及测试结果。 三种方式依次为:a) 时间场景生成;b) 时空场景生成;c) 基于事件的场景生成;相较于传统的基于蒙特卡洛或者拉丁超立方等场景生成法,数据驱动法更加具有创新性,而且结果更可信,远非那些方法可以比拟的。

最带劲的是事件驱动的生成模式。我们给GAN装上触发器,像这样在训练循环里加料:

def train_step(real_images, event_labels):
    noise = tf.random.normal([BATCH_SIZE, noise_dim])
    
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        conditioned_noise = tf.concat([noise, event_labels], axis=1)  # 把事件标签焊接到噪声上
        generated_images = generator(conditioned_noise, training=True)
        
        real_output = discriminator(real_images, training=True)
        fake_output = discriminator(generated_images, training=True)
        
        gen_loss = generator_loss(fake_output, event_labels)
        disc_loss = discriminator_loss(real_output, fake_output, event_labels)

重点在那个conditioned_noise的拼接操作,相当于给生成器塞小纸条:"这次要生成台风天的场景"。我们在光伏数据里预设了20种事件标签,从设备故障到极端天气应有尽有。

训练时有个邪门技巧:每隔50个batch就把生成结果用t-SNE降维可视化,看着潜在空间里的场景分布从一锅粥慢慢变成星座图,比看loss曲线带感多了。有一次生成了个昼夜交替的光伏出力曲线,判别器居然被忽悠得给出了0.9的置信度——后来发现是生成器把云层移动的影子效果模拟得太逼真。

代码里还埋着个时空场景的保存技巧:

def save_scenario(scene, mode):
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    if mode == 'event':
        np.savez(f'scenario_{timestamp}.npz', 
                data=scene.numpy(),
                metadata={'generator_version': 2.1})

这个npz文件里不仅存数据矩阵,还带着生成器版本号。后来做消融实验时发现,2.1版生成器在阴雨天气场景里总多出个不自然的出力尖峰,回滚到1.7版就正常——版本追踪的重要性就这么来的。

比起传统方法,这套玩意最牛的是能生成从没见过但合理的场景。有次生成了个光伏出力在正午骤降的场景,大家都以为是噪声,结果和气象数据一对照——那天正好有日食。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐