30、图像风格迁移技术详解与实践

图像风格迁移技术详解与实践

1. 快速风格迁移

1.1 加载预训练模块

要将新风格应用到目标图像上,需要从 tfhub 加载预训练模块。使用以下语句:

import tensorflow_hub as hub
hub_module = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')

这里的模块名为 arbitrary-image-stylization-v1-256/2

1.2 执行风格迁移

模块加载完成后,将两个张量作为输入传递给模块进行转换:

import tensorflow as tf
outputs = hub_module(tf.constant(target_image), tf.constant(style_image))
stylized_image = outputs[0]

outputs 是一个形状为 (1, 300, 400, 3) 的张量,这是转换后图像的数据。注意, 300x400 是原始 1600x1200 图像的缩小版本。

1.3 显示输出图像

要显示图像,需要将张量转换为图像格式:

import numpy as np
import PIL.Image
tensor = stylized_image*256
tensor = np.array(tensor, dtype=np.uint8)
tensor = tensor[0]
PIL.Image.fromarray(tensor)

因为 stylized_image 中的数据范围是 0 1 ,所以需要将图像数据乘以 256 。如果要显示缩小后的图像,可以使用以下代码:

import matplotlib.pyplot as plt
plt.imshow(tensor)

1.4 完整代码示例

import tensorflow as tf
import re
import urllib
import numpy as np
import matplotlib.pyplot as plt
import PIL.Image
import tensorflow_hub as hub
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from matplotlib import gridspec
from IPython import display
from PIL import Image

def download_image_from_URL(imageURL):
    imageName = re.search('[a-z0-9\-]+\.(jpe?g|png|gif|bmp|JPG)', imageURL, re.IGNORECASE)
    imageName = imageName.group(0)
    urllib.request.urlretrieve(imageURL, imageName)
    imagePath = "./" + imageName
    return imagePath

# 目标图像的 URL
target_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/ferns.jpg"
target_path = download_image_from_URL(target_url)

# 风格图像的 URL
style_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/on-the-road.jpg"
style_path = download_image_from_URL(style_url)

content = Image.open(target_path)
style = Image.open(style_path)

plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(content)
plt.title('Content Image')
plt.subplot(1, 2, 2)
plt.imshow(style)
plt.title('Style Image')
plt.tight_layout()
plt.show()

def image_to_tensor_style(path_to_img):
    img = tf.io.read_file(path_to_img)
    img = tf.image.decode_image(img, channels=3, dtype=tf.float32)
    img = tf.image.resize(img, [256,256])
    img = img[tf.newaxis, :]
    return img

def image_to_tensor_target(path_to_img, image_size):
    img = tf.io.read_file(path_to_img)
    img = tf.image.decode_image(img, channels=3, dtype=tf.float32)
    img = tf.image.resize(img, [image_size,image_size], preserve_aspect_ratio=True)
    img = img[tf.newaxis, :]
    return img

output_image_size = 400
target_image = image_to_tensor_target(target_path,output_image_size)
style_image = image_to_tensor_style(style_path)

hub_module = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')
outputs = hub_module(tf.constant(target_image), tf.constant(style_image))
stylized_image = outputs[0]

tensor = stylized_image*256
tensor = np.array(tensor, dtype=np.uint8)
tensor = tensor[0]
PIL.Image.fromarray(tensor)
plt.imshow(tensor)

2. 深入理解风格迁移原理

2.1 风格迁移原理

风格迁移的原理是提取图像(通常是著名画作)的风格,并将其应用到你选择的图像内容上。因此,有两个输入图像:内容图像和风格图像,新生成的图像通常称为风格化图像。生成的图像包含与内容图像相同的内容,但具有与风格图像相似的风格。这显然不是通过简单地叠加图像来实现的,所以我们的程序必须能够分别区分给定图像的内容和风格。

2.2 VGG16 架构

Gatys 等人(2015)提出了风格迁移的核心思想,即预训练用于图像分类的卷积神经网络(CNN)知道如何编码图像的感知和语义信息。我们将使用 VGG16 来提取图像的特征,然后独立处理其内容和风格。

由于我们只对特征提取感兴趣,而不是图像分类,因此不需要 VGG 网络的全连接层或最终的 softmax 分类器。Keras 提供了预训练的 VGG16 模型,可以分离出各层。要移除最顶层的全连接层,在提取模型层时需要将 include_top 变量的值设置为 False

2.3 创建项目

创建一个新的 Colab 项目,并将其重命名为 CustomStyleTransfer 。安装以下两个包:

!pip install keras==2.3.1
!pip install tensorflow==2.1.0

注意,在编写本文时,该项目中使用的预训练 VGG16 模型只能在上述指定的 Keras 和 TensorFlow 版本下运行,尚不支持更新的版本。

导入所需的库:

import tensorflow as tf
import re
import urllib
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from matplotlib import pyplot as plt
from IPython import display
from PIL import Image
import numpy as np
from tensorflow.keras.applications import vgg16
from tensorflow.keras import backend as K
from keras import backend as K
from scipy.optimize import fmin_l_bfgs_b

2.4 下载图像

编写一个下载函数并调用它来下载项目所需的两个图像:

def download_image_from_URL(imageURL):
    imageName = re.search('[a-z0-9\-]+\.(jpe?g|png|gif|bmp|JPG)', imageURL, re.IGNORECASE)
    imageName = imageName.group(0)
    urllib.request.urlretrieve(imageURL, imageName)
    imagePath = "./" + imageName
    return imagePath

# 目标图像的 URL
target_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/blank-sign.jpg"
target_path = download_image_from_URL(target_url)

# 风格图像的 URL
style_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/road.jpg"
style_path = download_image_from_URL(style_url)

# 调整目标图像的大小
from tensorflow.keras.preprocessing.image import load_img
width, height = load_img(target_path).size
img_height = 400
img_width = int(width * img_height / height)

2.5 显示图像

使用以下代码显示两个图像:

content = Image.open(target_path)
style = Image.open(style_path)

plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(content)
plt.title('Content Image')
plt.subplot(1, 2, 2)
plt.imshow(style)
plt.title('Style Image')
plt.tight_layout()
plt.show()

2.6 图像预处理

由于要使用 VGG16 模型提取图像特征,需要按照 VGG 训练过程处理图像数据。Keras 提供了 preprocess_input 函数,该函数接受编码一批图像的张量或 numpy 数组作为输入,并返回预处理后的 numpy 数组或类型为 float32 tf.tensor 。该方法将图像从 RGB 转换为 BGR,并对每个通道进行零中心化。

def preprocess_image(image_path):
    img = load_img(image_path, target_size=(img_height, img_width))
    img = img_to_array(img)
    img = np.expand_dims(img, axis=0)
    img = tf.keras.applications.vgg16.preprocess_input(img)
    return img

def deprocess_image(x):
    # Remove zero-center by mean pixel
    x[:, :, 0] += 103.939
    x[:, :, 1] += 116.779
    x[:, :, 2] += 123.68
    # 'BGR'->'RGB'
    x = x[:, :, ::-1]
    x = np.clip(x, 0, 255).astype('uint8')
    return x

2.7 模型构建

将图像张量数据输入 VGG16 模型,提取特征图、内容和风格表示。模型将加载预训练的 ImageNet 权重。

target = K.constant(preprocess_image(target_path))
style = K.constant(preprocess_image(style_path))

# 用于存储生成图像的占位符
combination_image = K.placeholder((1, img_height, img_width, 3))

# 将三个图像组合成一个批次
input_tensor = K.concatenate([target, style, combination_image], axis=0)

# 构建 VGG16 网络
model = vgg16.VGG16(input_tensor=input_tensor, weights='imagenet', include_top=False)

# 查看模型摘要
model.summary()

2.8 损失计算

2.8.1 内容损失

内容损失表示随机生成的噪声图像(G)与内容图像(C)的相似程度。计算公式如下:
[L_{content}(P, F) = \frac{1}{2}\sum_{i,j}(F_{ij}^l - P_{ij}^l)^2]
代码实现:

def content_loss(base, combination):
    return K.sum(K.square(combination - base))
2.8.2 风格损失

计算风格损失需要先计算 Gram 矩阵,Gram 矩阵用于找到不同通道之间的相关性,后续用于衡量风格。

def gram_matrix(x):
    features = K.batch_flatten(K.permute_dimensions(x, (2, 0, 1)))
    gram = K.dot(features, K.transpose(features))
    return gram

def style_loss(style, combination):
    S = gram_matrix(style)
    C = gram_matrix(combination)
    channels = 3
    size = img_height * img_width
    return K.sum(K.square(S - C)) / (4. * (channels ** 2) * (size ** 2))
2.8.3 总变差损失

为了使输出图像更平滑,定义总变差损失:

def total_variation_loss(x):
    a = K.square(x[:, :img_height - 1, :img_width - 1, :] - x[:, 1:, :img_width - 1, :])
    b = K.square(x[:, :img_height - 1, :img_width - 1, :] - x[:, :img_height - 1, 1:, :])
    return K.sum(K.pow(a + b, 1.25))
2.8.4 计算总损失

首先选择 VGG16 的内容和风格层,然后定义一些权重变量,用于计算损失分量的加权平均值。

# Dict mapping layer names to activation tensors
outputs_dict = dict([(layer.name, layer.output) for layer in model.layers])

# 用于内容损失的层
content_layer = 'block5_conv2'

# 用于风格损失的层
style_layers = ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1', 'block5_conv1']

# 损失分量的权重
total_variation_weight = 1e-4
style_weight = 10.
content_weight = 0.025

# 定义损失
loss = K.variable(0.)
layer_features = outputs_dict[content_layer]
target_features = layer_features[0, :, :, :]
combination_features = layer_features[2, :, :, :]
loss = loss + content_weight * content_loss(target_features, combination_features)

for layer_name in style_layers:
    layer_features = outputs_dict[layer_name]
    style_reference_features = layer_features[1, :, :, :]
    combination_features = layer_features[2, :, :, :]
    sl = style_loss(style_reference_features, combination_features)
    loss += (style_weight / len(style_layers)) * sl
    loss += total_variation_weight * total_variation_loss(combination_image)

2.9 评估器类

定义一个 Evaluator 类,用于一次性计算损失和梯度:

grads = K.gradients(loss, combination_image)[0]

# Function to fetch the values of the current loss and the current gradients
fetch_loss_and_grads = K.function([combination_image], [loss, grads])

class Evaluator(object):
    def __init__(self):
        self.loss_value = None
        self.grads_values = None

    def loss(self, x):
        assert self.loss_value is None
        x = x.reshape((1, img_height, img_width, 3))
        outs = fetch_loss_and_grads([x])
        loss_value = outs[0]
        grad_values = outs[1].flatten().astype('float64')
        self.loss_value = loss_value
        self.grad_values = grad_values
        return self.loss_value

    def grads(self, x):
        assert self.loss_value is not None
        grad_values = np.copy(self.grad_values)
        self.loss_value = None
        self.grad_values = None
        return grad_values

evaluator = Evaluator()

2.10 生成输出图像

使用 L-BFGS 算法进行优化,从随机像素开始生成风格化图像:

iterations = 50
x = preprocess_image(target_path)
x = x.flatten()

for i in range(1, iterations):
    x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x, fprime=evaluator.grads, maxfun=10)
    print('Iteration %0d, loss: %0.02f' % (i, min_val))

img = x.copy().reshape((img_height, img_width, 3))
img = deprocess_image(img)

2.11 显示图像

plt.figure(figsize=(50, 50))
plt.subplot(3,3,1)
plt.imshow(load_img(target_path, target_size=(img_height, img_width)))
plt.subplot(3,3,2)
plt.imshow(load_img(style_path, target_size=(img_height, img_width)))
plt.subplot(3,3,3)
plt.imshow(img)
plt.show()

2.12 完整代码

!pip install keras==2.3.1
!pip install tensorflow==2.1.0

import tensorflow as tf
import re
import urllib
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from matplotlib import pyplot as plt
from IPython import display
from PIL import Image
import numpy as np
from tensorflow.keras.applications import vgg16
from tensorflow.keras import backend as K
from keras import backend as K
from scipy.optimize import fmin_l_bfgs_b

def download_image_from_URL(imageURL):
    imageName = re.search('[a-z0-9\-]+\.(jpe?g|png|gif|bmp|JPG)', imageURL, re.IGNORECASE)
    imageName = imageName.group(0)
    urllib.request.urlretrieve(imageURL, imageName)
    imagePath = "./" + imageName
    return imagePath

# 目标图像的 URL
target_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/blank-sign.jpg"
target_path = download_image_from_URL(target_url)

# 风格图像的 URL
style_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/road.jpg"
style_path = download_image_from_URL(style_url)

# Dimensions for the generated picture.
width, height = load_img(target_path).size
img_height = 400
img_width = int(width * img_height / height)

content = Image.open(target_path)
style = Image.open(style_path)

plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(content)
plt.title('Content Image')
plt.subplot(1, 2, 2)
plt.imshow(style)
plt.title('Style Image')
plt.tight_layout()
plt.show()

# Preprocess the data as per VGG16 requirements
def preprocess_image(image_path):
    img = load_img(image_path, target_size=(img_height, img_width))
    img = img_to_array(img)
    img = np.expand_dims(img, axis=0)
    img = tf.keras.applications.vgg16.preprocess_input(img)
    return img

def deprocess_image(x):
    # Remove zero-center by mean pixel
    x[:, :, 0] += 103.939
    x[:, :, 1] += 116.779
    x[:, :, 2] += 123.68
    # 'BGR'->'RGB'
    x = x[:, :, ::-1]
    x = np.clip(x, 0, 255).astype('uint8')
    return x

target = K.constant(preprocess_image(target_path))
style = K.constant(preprocess_image(style_path))

# This placeholder will contain our generated image
combination_image = K.placeholder((1, img_height, img_width, 3))

# We combine the 3 images into a single batch
input_tensor = K.concatenate([target, style, combination_image], axis=0)

# Build the VGG16 network with our batch of 3 images as input.
model = vgg16.VGG16(input_tensor=input_tensor, weights='imagenet', include_top=False)
model.summary()

# compute content loss for the generated image
def content_loss(base, combination):
    return K.sum(K.square(combination - base))

def gram_matrix(x):
    features = K.batch_flatten(K.permute_dimensions(x, (2, 0, 1)))
    gram = K.dot(features, K.transpose(features))
    return gram

def style_loss(style, combination):
    S = gram_matrix(style)
    C = gram_matrix(combination)
    channels = 3
    size = img_height * img_width
    return K.sum(K.square(S - C)) / (4. * (channels ** 2) * (size ** 2))

def total_variation_loss(x):
    a = K.square(x[:, :img_height - 1, :img_width - 1, :] - x[:, 1:, :img_width - 1, :])
    b = K.square(x[:, :img_height - 1, :img_width - 1, :] - x[:, :img_height - 1, 1:, :])
    return K.sum(K.pow(a + b, 1.25))

# Dict mapping layer names to activation tensors
outputs_dict = dict([(layer.name, layer.output) for layer in model.layers])

# Name of layer used for content loss
content_layer = 'block5_conv2'

# Name of layers used for style loss;
style_layers = ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1', 'block5_conv1']

# Weights in the weighted average of the loss components
total_variation_weight = 1e-4
style_weight = 10.
content_weight = 0.025

# Define the loss by adding all components to a `loss` variable
loss = K.variable(0.)
layer_features = outputs_dict[content_layer]
target_features = layer_features[0, :, :, :]
combination_features = layer_features[2, :, :, :]
loss = loss + content_weight * content_loss(target_features, combination_features)

for layer_name in style_layers:
    layer_features = outputs_dict[layer_name]
    style_reference_features = layer_features[1, :, :, :]
    combination_features = layer_features[2, :, :, :]
    sl = style_loss(style_reference_features, combination_features)
    loss += (style_weight / len(style_layers)) * sl
    loss += total_variation_weight * total_variation_loss(combination_image)

grads = K.gradients(loss, combination_image)[0]

# Function to fetch the values of the current loss and the current gradients
fetch_loss_and_grads = K.function([combination_image], [loss, grads])

class Evaluator(object):
    def __init__(self):
        self.loss_value = None
        self.grads_values = None

    def loss(self, x):
        assert self.loss_value is None
        x = x.reshape((1, img_height, img_width, 3))
        outs = fetch_loss_and_grads([x])
        loss_value = outs[0]
        grad_values = outs[1].flatten().astype('float64')
        self.loss_value = loss_value
        self.grad_values = grad_values
        return self.loss_value

    def grads(self, x):
        assert self.loss_value is not None
        grad_values = np.copy(self.grad_values)
        self.loss_value = None
        self.grad_values = None
        return grad_values

evaluator = Evaluator()

iterations = 50
x = preprocess_image(target_path)
x = x.flatten()

for i in range(1, iterations):
    x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x, fprime=evaluator.grads, maxfun=10)
    print('Iteration %0d, loss: %0.02f' % (i, min_val))

img = x.copy().reshape((img_height, img_width, 3))
img = deprocess_image(img)

plt.figure(figsize=(50, 50))
plt.subplot(3,3,1)
plt.imshow(load_img(target_path, target_size=(img_height, img_width)))
plt.subplot(3,3,2)
plt.imshow(load_img(style_path, target_size=(img_height, img_width)))
plt.subplot(3,3,3)
plt.imshow(img)
plt.show()

总结

本文介绍了两种图像风格迁移的方法:一种是使用预训练的 tfhub 模块进行快速风格迁移;另一种是深入理解风格迁移原理,使用 VGG16 模型手动实现风格迁移。通过详细的代码示例和步骤说明,帮助读者掌握图像风格迁移的技术。

3. 两种风格迁移方法对比

3.1 快速风格迁移(使用 tfhub 模块)

  • 优点
    • 简单易用 :只需加载预训练模块,将目标图像和风格图像作为输入传递给模块,即可快速得到风格化图像,代码实现简单,无需复杂的模型构建和训练过程。
    • 速度快 :由于使用了预训练的模型,避免了从头开始训练模型的时间消耗,能够在较短时间内完成风格迁移。
  • 缺点
    • 灵活性低 :只能使用预训练模块提供的固定风格迁移方式,无法对风格迁移的过程进行深入调整和优化。
    • 定制性差 :对于一些特殊的风格需求或个性化的风格迁移任务,难以满足要求。

3.2 手动实现风格迁移(使用 VGG16 模型)

  • 优点
    • 高度定制化 :可以根据自己的需求选择不同的层来计算内容损失和风格损失,调整损失函数的权重,从而实现个性化的风格迁移效果。
    • 深入理解原理 :通过手动实现风格迁移的过程,能够深入理解风格迁移的原理和背后的数学知识,有助于进一步优化和改进风格迁移算法。
  • 缺点
    • 实现复杂 :需要进行图像预处理、模型构建、损失计算、梯度计算等多个步骤,代码实现较为复杂,对开发者的技术要求较高。
    • 训练时间长 :使用 L - BFGS 算法进行优化时,需要多次迭代计算损失和梯度,训练时间较长。
方法 优点 缺点
快速风格迁移(tfhub 模块) 简单易用、速度快 灵活性低、定制性差
手动实现风格迁移(VGG16 模型) 高度定制化、深入理解原理 实现复杂、训练时间长

4. 风格迁移的应用场景

4.1 艺术创作

风格迁移可以将著名画作的风格应用到普通照片上,创造出具有艺术感的图像,为艺术家和设计师提供新的创作灵感。例如,将梵高的《星月夜》风格应用到风景照片上,使照片具有梵高画作的独特笔触和色彩风格。

4.2 图像处理

在图像处理领域,风格迁移可以用于图像的美化和修复。通过将高质量图像的风格迁移到低质量图像上,提高图像的视觉效果和质量。

4.3 娱乐应用

许多手机应用程序利用风格迁移技术,为用户提供有趣的拍照和图像处理功能。用户可以选择不同的风格模板,将自己的照片转换为各种风格的艺术作品,增加娱乐性。

5. 未来发展趋势

5.1 模型轻量化

随着移动设备和嵌入式设备的普及,对风格迁移模型的轻量化需求越来越高。未来的研究将致力于开发更轻量级的模型,减少模型的计算量和存储空间,以便在资源有限的设备上运行。

5.2 实时风格迁移

目前的风格迁移方法在处理大规模图像或视频时,速度较慢,难以实现实时处理。未来的研究将聚焦于提高风格迁移的速度,实现实时风格迁移,应用于视频直播、游戏等领域。

5.3 多风格融合

现有的风格迁移方法主要是将一种风格应用到图像上,未来的研究可能会探索多风格融合的技术,将多种不同的风格同时应用到图像上,创造出更加丰富和独特的风格效果。

6. 总结与展望

本文详细介绍了图像风格迁移的两种方法,包括快速风格迁移和手动实现风格迁移,并对两种方法的优缺点进行了对比分析。同时,探讨了风格迁移的应用场景和未来发展趋势。

风格迁移作为计算机视觉领域的一个重要研究方向,具有广泛的应用前景和发展潜力。随着技术的不断进步和创新,相信风格迁移技术将在更多领域得到应用,为人们带来更加丰富和精彩的视觉体验。

希望本文能够帮助读者深入理解图像风格迁移的原理和实现方法,激发读者在该领域的研究和探索热情。在实际应用中,读者可以根据自己的需求和场景选择合适的风格迁移方法,实现个性化的风格迁移效果。

附录:风格迁移流程 mermaid 流程图

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px

    A([开始]):::startend --> B{选择方法}:::decision
    B -->|快速风格迁移| C(加载预训练模块):::process
    B -->|手动实现风格迁移| D(创建项目并安装依赖):::process
    C --> E(准备目标图像和风格图像):::process
    E --> F(执行风格迁移):::process
    F --> G(显示风格化图像):::process
    D --> H(下载图像):::process
    H --> I(显示图像):::process
    I --> J(图像预处理):::process
    J --> K(构建 VGG16 模型):::process
    K --> L(计算损失):::process
    L --> M(定义评估器类):::process
    M --> N(生成风格化图像):::process
    N --> G
    G --> O([结束]):::startend

以上流程图展示了两种风格迁移方法的整体流程,帮助读者更好地理解风格迁移的步骤和过程。

基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样统计,通过模拟系统元件的故障修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值