昇思25天学习打卡营第7天|Pix2Pix实现图像转换

news2024/7/5 0:05:20

文章目录

      • 昇思MindSpore应用实践
        • 基于MindSpore的Pix2Pix图像转换
          • 1、Pix2Pix 概述
          • 2、U-Net架构
            • 定义UNet Skip Connection Block
          • 2、生成器部分
          • 3、基于PatchGAN的判别器
          • 4、Pix2Pix的生成器和判别器初始化
          • 5、模型训练
          • 6、模型推理
      • Reference

昇思MindSpore应用实践

本系列文章主要用于记录昇思25天学习打卡营的学习心得。

基于MindSpore的Pix2Pix图像转换
1、Pix2Pix 概述

Pix2Pix 是一个专门为图像到图像的转换任务设计的网络,可以实现语义/标签到真实图片、灰度图到彩色图、航空图到地图、白天到黑夜、线稿图到实物图的转换。Pix2Pix是将条件GAN(CGAN)应用于有监督(需要成对的输入素描图像Sketch和真实图像GT,来训练网络)的图像到图像翻译的经典之作,和所有的GANs一样,模型同样包括:生成器判别器两个部分。

CGAN:CGAN(条件GAN) 的目标是生成与给定条件匹配的数据样本。这些条件可以是标签、部分实例标注数据或任何其他形式的多模态辅助信息。CGAN 通过将条件并入网络的生成器和判别器中来指导数据生成过程。
在这里插入图片描述
相比普通的生成对抗损失:
L G A N ( G , D ) = E y [ l o g ( D ( y ) ) ] + E ( x , z ) [ l o g ( 1 − D ( x , z ) ) ] L_{GAN}(G,D)=\mathbb{E}_{y}[log(D(y))]+\mathbb{E}_{(x,z)}[log(1-D(x,z))] LGAN(G,D)=Ey[log(D(y))]+E(x,z)[log(1D(x,z))]

  • x x x:代表观测图像的数据。
  • z z z:代表随机噪声的数据。
  • y = G ( x , z ) y=G(x,z) y=G(x,z):生成器网络,给出由观测图像 x x x与随机噪声 z z z生成的“假”图片,其中 x x x来自于训练数据而非生成器。
  • D ( x , G ( x , z ) ) D(x,G(x,z)) D(x,G(x,z)):判别器网络,给出图像判定为真实图像的概率,其中 x x x来自于训练数据, G ( x , z ) G(x,z) G(x,z)来自于生成器。

CGAN多了来自于观测图像的条件 x x x(因此Pix2Pix训练时采用有监督的方式,需要标注好的语义数据,如下图中的
Map2Aerial数据集、Anime Sketch Colorization Pair 素描生成动漫数据集),
在这里插入图片描述
在这里插入图片描述

CGAN的目标可以表示为:

L C G A N ( G , D ) = E ( x , y ) [ l o g ( D ( x , y ) ) ] + E ( x , z ) [ l o g ( 1 − D ( x , G ( x , z ) ) ) ] L_{CGAN}(G,D)=\mathbb{E}_{(x,y)}[log(D(x,y))]+\mathbb{E}_{(x,z)}[log(1-D(x,G(x,z)))] LCGAN(G,D)=E(x,y)[log(D(x,y))]+E(x,z)[log(1D(x,G(x,z)))]

Pix2Pix 还包括 L1 损失,帮助生成器产生结构上接近真实图像的结果,这一点在图像翻译任务中尤为重要:
L L 1 ( G ) = E ( x , y , z ) [ ∣ ∣ y − G ( x , z ) ∣ ∣ 1 ] L_{L1}(G)=\mathbb{E}_{(x,y,z)}[||y-G(x,z)||_{1}] LL1(G)=E(x,y,z)[∣∣yG(x,z)1]

进而得到最终目标:

a r g min ⁡ G max ⁡ D L C G A N ( G , D ) + λ L L 1 ( G ) arg\min_{G}\max_{D}L_{CGAN}(G,D)+\lambda L_{L1}(G) argGminDmaxLCGAN(G,D)+λLL1(G)

图像转换问题本质上其实就是像素到像素的映射问题,Pix2Pix使用完全一样的网络结构和目标函数,仅更换不同的训练数据集就能分别实现以上的任务。

2、U-Net架构

U-Net架构:Pix2Pix 使用 U-Net 架构作为其生成器,在传统的编解码网络结构基础上加入了跳跃连接的方式,可以更好地捕捉图像的细节和上下文信息,适合于图像到图像的翻译任务。相比于普通的编解码结构(Encoder-Decoder),U-Net在编码器和解码器之间引入了跳跃连接,极大地改善了梯度流:
在这里插入图片描述

定义UNet Skip Connection Block
import mindspore
import mindspore.nn as nn
import mindspore.ops as ops

class UNetSkipConnectionBlock(nn.Cell):
    def __init__(self, outer_nc, inner_nc, in_planes=None, dropout=False,
                 submodule=None, outermost=False, innermost=False, alpha=0.2, norm_mode='batch'):
        super(UNetSkipConnectionBlock, self).__init__()
        down_norm = nn.BatchNorm2d(inner_nc)
        up_norm = nn.BatchNorm2d(outer_nc)
        use_bias = False
        if norm_mode == 'instance':
            down_norm = nn.BatchNorm2d(inner_nc, affine=False)
            up_norm = nn.BatchNorm2d(outer_nc, affine=False)
            use_bias = True
        if in_planes is None:
            in_planes = outer_nc
        down_conv = nn.Conv2d(in_planes, inner_nc, kernel_size=4,
                              stride=2, padding=1, has_bias=use_bias, pad_mode='pad')
        down_relu = nn.LeakyReLU(alpha)
        up_relu = nn.ReLU()
        if outermost:
            up_conv = nn.Conv2dTranspose(inner_nc * 2, outer_nc,
                                         kernel_size=4, stride=2,
                                         padding=1, pad_mode='pad')
            down = [down_conv]
            up = [up_relu, up_conv, nn.Tanh()]
            model = down + [submodule] + up
        elif innermost:
            up_conv = nn.Conv2dTranspose(inner_nc, outer_nc,
                                         kernel_size=4, stride=2,
                                         padding=1, has_bias=use_bias, pad_mode='pad')
            down = [down_relu, down_conv]
            up = [up_relu, up_conv, up_norm]
            model = down + up
        else:
            up_conv = nn.Conv2dTranspose(inner_nc * 2, outer_nc,
                                         kernel_size=4, stride=2,
                                         padding=1, has_bias=use_bias, pad_mode='pad')
            down = [down_relu, down_conv, down_norm]
            up = [up_relu, up_conv, up_norm]

            model = down + [submodule] + up
            if dropout:
                model.append(nn.Dropout(p=0.5))
        self.model = nn.SequentialCell(model)
        self.skip_connections = not outermost

    def construct(self, x):
        out = self.model(x)
        if self.skip_connections:
            out = ops.concat((out, x), axis=1)
        return out
2、生成器部分

原始CGAN的输入是条件x和噪声z两种信息,这里的生成器只使用了条件信息,因此不能生成多样性的结果。因此Pix2Pix在训练和测试时都使用了dropout,这样可以生成多样性的结果。

通过MindSpore实现基于U-Net的生成器:

class UNetGenerator(nn.Cell):
    def __init__(self, in_planes, out_planes, ngf=64, n_layers=8, norm_mode='bn', dropout=False):
        super(UNetGenerator, self).__init__()
        unet_block = UNetSkipConnectionBlock(ngf * 8, ngf * 8, in_planes=None, submodule=None,
                                             norm_mode=norm_mode, innermost=True)
        for _ in range(n_layers - 5):
            unet_block = UNetSkipConnectionBlock(ngf * 8, ngf * 8, in_planes=None, submodule=unet_block,
                                                 norm_mode=norm_mode, dropout=dropout)
        unet_block = UNetSkipConnectionBlock(ngf * 4, ngf * 8, in_planes=None, submodule=unet_block,
                                             norm_mode=norm_mode)
        unet_block = UNetSkipConnectionBlock(ngf * 2, ngf * 4, in_planes=None, submodule=unet_block,
                                             norm_mode=norm_mode)
        unet_block = UNetSkipConnectionBlock(ngf, ngf * 2, in_planes=None, submodule=unet_block,
                                             norm_mode=norm_mode)
        self.model = UNetSkipConnectionBlock(out_planes, ngf, in_planes=in_planes, submodule=unet_block,
                                             outermost=True, norm_mode=norm_mode)

    def construct(self, x):
        return self.model(x)
3、基于PatchGAN的判别器

判别器使用的PatchGAN结构,可看做卷积。
生成的矩阵中的每个点代表原图的一小块区域(patch)。通过矩阵中的各个值来判断原图中对应每个Patch的真假。

import mindspore.nn as nn

class ConvNormRelu(nn.Cell):
    def __init__(self,
                 in_planes,
                 out_planes,
                 kernel_size=4,
                 stride=2,
                 alpha=0.2,
                 norm_mode='batch',
                 pad_mode='CONSTANT',
                 use_relu=True,
                 padding=None):
        super(ConvNormRelu, self).__init__()
        norm = nn.BatchNorm2d(out_planes)
        if norm_mode == 'instance':
            norm = nn.BatchNorm2d(out_planes, affine=False)
        has_bias = (norm_mode == 'instance')
        if not padding:
            padding = (kernel_size - 1) // 2
        if pad_mode == 'CONSTANT':
            conv = nn.Conv2d(in_planes, out_planes, kernel_size, stride, pad_mode='pad',
                             has_bias=has_bias, padding=padding)
            layers = [conv, norm]
        else:
            paddings = ((0, 0), (0, 0), (padding, padding), (padding, padding))
            pad = nn.Pad(paddings=paddings, mode=pad_mode)
            conv = nn.Conv2d(in_planes, out_planes, kernel_size, stride, pad_mode='pad', has_bias=has_bias)
            layers = [pad, conv, norm]
        if use_relu:
            relu = nn.ReLU()
            if alpha > 0:
                relu = nn.LeakyReLU(alpha)
            layers.append(relu)
        self.features = nn.SequentialCell(layers)

    def construct(self, x):
        output = self.features(x)
        return output

class Discriminator(nn.Cell):
    def __init__(self, in_planes=3, ndf=64, n_layers=3, alpha=0.2, norm_mode='batch'):
        super(Discriminator, self).__init__()
        kernel_size = 4
        layers = [
            nn.Conv2d(in_planes, ndf, kernel_size, 2, pad_mode='pad', padding=1),
            nn.LeakyReLU(alpha)
        ]
        nf_mult = ndf
        for i in range(1, n_layers):
            nf_mult_prev = nf_mult
            nf_mult = min(2 ** i, 8) * ndf
            layers.append(ConvNormRelu(nf_mult_prev, nf_mult, kernel_size, 2, alpha, norm_mode, padding=1))
        nf_mult_prev = nf_mult
        nf_mult = min(2 ** n_layers, 8) * ndf
        layers.append(ConvNormRelu(nf_mult_prev, nf_mult, kernel_size, 1, alpha, norm_mode, padding=1))
        layers.append(nn.Conv2d(nf_mult, 1, kernel_size, 1, pad_mode='pad', padding=1))
        self.features = nn.SequentialCell(layers)

    def construct(self, x, y):
        x_y = ops.concat((x, y), axis=1)
        output = self.features(x_y)
        return output
4、Pix2Pix的生成器和判别器初始化

实例化Pix2Pix生成器和判别器:

import mindspore.nn as nn
from mindspore.common import initializer as init

g_in_planes = 3
g_out_planes = 3
g_ngf = 64
g_layers = 8
d_in_planes = 6
d_ndf = 64
d_layers = 3
alpha = 0.2
init_gain = 0.02
init_type = 'normal'


net_generator = UNetGenerator(in_planes=g_in_planes, out_planes=g_out_planes,
                              ngf=g_ngf, n_layers=g_layers)
for _, cell in net_generator.cells_and_names():
    if isinstance(cell, (nn.Conv2d, nn.Conv2dTranspose)):
        if init_type == 'normal':
            cell.weight.set_data(init.initializer(init.Normal(init_gain), cell.weight.shape))
        elif init_type == 'xavier':
            cell.weight.set_data(init.initializer(init.XavierUniform(init_gain), cell.weight.shape))
        elif init_type == 'constant':
            cell.weight.set_data(init.initializer(0.001, cell.weight.shape))
        else:
            raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
    elif isinstance(cell, nn.BatchNorm2d):
        cell.gamma.set_data(init.initializer('ones', cell.gamma.shape))
        cell.beta.set_data(init.initializer('zeros', cell.beta.shape))


net_discriminator = Discriminator(in_planes=d_in_planes, ndf=d_ndf,
                                  alpha=alpha, n_layers=d_layers)
for _, cell in net_discriminator.cells_and_names():
    if isinstance(cell, (nn.Conv2d, nn.Conv2dTranspose)):
        if init_type == 'normal':
            cell.weight.set_data(init.initializer(init.Normal(init_gain), cell.weight.shape))
        elif init_type == 'xavier':
            cell.weight.set_data(init.initializer(init.XavierUniform(init_gain), cell.weight.shape))
        elif init_type == 'constant':
            cell.weight.set_data(init.initializer(0.001, cell.weight.shape))
        else:
            raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
    elif isinstance(cell, nn.BatchNorm2d):
        cell.gamma.set_data(init.initializer('ones', cell.gamma.shape))
        cell.beta.set_data(init.initializer('zeros', cell.beta.shape))

class Pix2Pix(nn.Cell):
    """Pix2Pix模型网络"""
    def __init__(self, discriminator, generator):
        super(Pix2Pix, self).__init__(auto_prefix=True)
        self.net_discriminator = discriminator
        self.net_generator = generator

    def construct(self, reala):
        fakeb = self.net_generator(reala)
        return fakeb
5、模型训练

训练分为两个主要部分:训练判别器和训练生成器;
训练判别器的目的是最大程度地提高判别图像真伪的概率;
训练生成器是希望能产生更好的虚假图像;
在这两个部分中,分别获取训练过程中的损失,并在每个周期结束时进行统计。

通过MindSpore进行训练:

import numpy as np
import os
import datetime
from mindspore import value_and_grad, Tensor

epoch_num = 3
ckpt_dir = "results/ckpt"
dataset_size = 400
val_pic_size = 256
lr = 0.0002
n_epochs = 100
n_epochs_decay = 100

def get_lr():
    lrs = [lr] * dataset_size * n_epochs
    lr_epoch = 0
    for epoch in range(n_epochs_decay):
        lr_epoch = lr * (n_epochs_decay - epoch) / n_epochs_decay
        lrs += [lr_epoch] * dataset_size
    lrs += [lr_epoch] * dataset_size * (epoch_num - n_epochs_decay - n_epochs)
    return Tensor(np.array(lrs).astype(np.float32))

dataset = ds.MindDataset("./dataset/dataset_pix2pix/train.mindrecord", columns_list=["input_images", "target_images"], shuffle=True, num_parallel_workers=1)
steps_per_epoch = dataset.get_dataset_size()
loss_f = nn.BCEWithLogitsLoss()
l1_loss = nn.L1Loss()

def forword_dis(reala, realb):
    lambda_dis = 0.5
    fakeb = net_generator(reala)
    pred0 = net_discriminator(reala, fakeb)
    pred1 = net_discriminator(reala, realb)
    loss_d = loss_f(pred1, ops.ones_like(pred1)) + loss_f(pred0, ops.zeros_like(pred0))
    loss_dis = loss_d * lambda_dis
    return loss_dis

def forword_gan(reala, realb):
    lambda_gan = 0.5
    lambda_l1 = 100
    fakeb = net_generator(reala)
    pred0 = net_discriminator(reala, fakeb)
    loss_1 = loss_f(pred0, ops.ones_like(pred0))
    loss_2 = l1_loss(fakeb, realb)
    loss_gan = loss_1 * lambda_gan + loss_2 * lambda_l1
    return loss_gan

d_opt = nn.Adam(net_discriminator.trainable_params(), learning_rate=get_lr(),
                beta1=0.5, beta2=0.999, loss_scale=1)
g_opt = nn.Adam(net_generator.trainable_params(), learning_rate=get_lr(),
                beta1=0.5, beta2=0.999, loss_scale=1)

grad_d = value_and_grad(forword_dis, None, net_discriminator.trainable_params())
grad_g = value_and_grad(forword_gan, None, net_generator.trainable_params())

def train_step(reala, realb):
    loss_dis, d_grads = grad_d(reala, realb)
    loss_gan, g_grads = grad_g(reala, realb)
    d_opt(d_grads)
    g_opt(g_grads)
    return loss_dis, loss_gan

if not os.path.isdir(ckpt_dir):
    os.makedirs(ckpt_dir)

g_losses = []
d_losses = []
data_loader = dataset.create_dict_iterator(output_numpy=True, num_epochs=epoch_num)

for epoch in range(epoch_num):
    for i, data in enumerate(data_loader):
        start_time = datetime.datetime.now()
        input_image = Tensor(data["input_images"])
        target_image = Tensor(data["target_images"])
        dis_loss, gen_loss = train_step(input_image, target_image)
        end_time = datetime.datetime.now()
        delta = (end_time - start_time).microseconds
        if i % 2 == 0:
            print("ms per step:{:.2f}  epoch:{}/{}  step:{}/{}  Dloss:{:.4f}  Gloss:{:.4f} ".format((delta / 1000), (epoch + 1), (epoch_num), i, steps_per_epoch, float(dis_loss), float(gen_loss)))
        d_losses.append(dis_loss.asnumpy())
        g_losses.append(gen_loss.asnumpy())
    if (epoch + 1) == epoch_num:
        mindspore.save_checkpoint(net_generator, ckpt_dir + "Generator.ckpt")

在这里插入图片描述

6、模型推理

导入模型训练保存的权重:

from mindspore import load_checkpoint, load_param_into_net

param_g = load_checkpoint(ckpt_dir + "Generator.ckpt")
load_param_into_net(net_generator, param_g)
dataset = ds.MindDataset("./dataset/dataset_pix2pix/train.mindrecord", columns_list=["input_images", "target_images"], shuffle=True)
data_iter = next(dataset.create_dict_iterator())
predict_show = net_generator(data_iter["input_images"])
plt.figure(figsize=(10, 3), dpi=140)
for i in range(10):
    plt.subplot(2, 10, i + 1)
    plt.imshow((data_iter["input_images"][i].asnumpy().transpose(1, 2, 0) + 1) / 2)
    plt.axis("off")
    plt.subplots_adjust(wspace=0.05, hspace=0.02)
    plt.subplot(2, 10, i + 11)
    plt.imshow((predict_show[i].asnumpy().transpose(1, 2, 0) + 1) / 2)
    plt.axis("off")
    plt.subplots_adjust(wspace=0.05, hspace=0.02)
plt.show()

图像翻译效果如下:
在这里插入图片描述

Reference

昇思官方文档-Pix2Pix实现图像转换
昇思大模型平台
AI 助你无码看片,生成对抗网络(GAN)大显身手

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1886499.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity 动画事件

Unity中的动画事件是一种在动画播放过程中触发自定义行为的方法。动画事件允许开发者在动画的特定时间点执行代码,例如播放声音、改变游戏状态或触发其他动画。以下是使用Unity动画事件的一些关键点: 动画事件的创建:在Unity的Animation窗口…

Hadoop3:Yarn的Tool接口案例

一、需求 依然以wordcount案例为基础,进行开发 我们知道,用hadoop自带的example.jar执行wordcount 命令如下 hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount -D mapreduce.job.queuename…

973. 最接近原点的 K 个点-k数组维护+二分查找

973. 最接近原点的 K 个点-k数组维护二分查找 给定一个数组 points ,其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点,并且是一个整数 k ,返回离原点 (0,0) 最近的 k 个点。 这里,平面上两点之间的距离是 欧几里德距离&#…

【Rust入门教程】hello world程序

文章目录 前言Hello World程序运行总结 前言 对于学习任何一种新的编程语言,我们都会从编写一个简单的Hello World程序开始。这是一个传统,也是一个开始。在这篇文章中,我们将一起学习如何在Rust中编写你的第一个程序:Hello Worl…

干货分享|如何将前端代理服务器(BFF)接入身份认证(2)

续集2 前篇文章在前面发布,同学们可以自行找一下。 本篇文章将继续通过实例来详细讲解如何将前端代理服务器(BFF)接入身份认证。我们将使用一个示例应用来演示 BFF 与身份认证的集成过程。 1)在 Keycloak 中新建一个安全领域 …

红队工具Finger 安装具体以步骤-示例centos

1.git clone https://github.com/EASY233/Finger.git 如果没有 yum install git 2.pip3 install -r requirements.txt 找到finger所在的文件夹 可以用find -name "Finger"进入文件中配置命令 前提要安装python yum install python-pip33.python3 Finger.py -h

中国AI产业迎来标准化大跃进,程序员们准备好了吗

中国AI产业迎来标准化大跃进,程序员们准备好了吗? 程序员们,你们是否已经感受到了人工智能技术的浪潮?现在,中国工信部联合其他部门发布了《国家人工智能产业综合标准化体系建设指南(2024版)》&…

龙迅LT8641UXE HDMI四进一出切换开关,支持标准HDMI 2.0内置MCU

龙迅LT8641UXE描述: Lontium LT8641UX HDMI2.0开关具有符合HDMI2.0/1.4规范的4:1开关,最大6Gbps高速数据速率,自适应均衡RX输入和预先强调的TX输出支持长电缆应用,没有XTAL板上节省BOM成本。LT8641UX HDMI2.0开关自动…

如何获取音频伴奏

如何获取音频伴奏 在今天的互联网上,有许多好听的音乐.面对这些音乐,我们有时需要伴奏音频,许多音频在网站上可以查找到,但有些不行,今天,我们要通过audacity软件截取音频伴奏. 下载audacity软件 audacity-64.exe 访问密码:8221 或官方网站(访问较慢) 选择简体…

LLM指令微调Prompt的最佳实践(二):Prompt迭代优化

文章目录 1. 前言2. Prompt定义3. 迭代优化——以产品说明书举例3.1 产品说明书3.2 初始Prompt3.3 优化1: 添加长度限制3.4 优化2: 细节纠错3.5 优化3: 添加表格 4. 总结5. 参考 1. 前言 前情提要: 《LLM指令微调Prompt的最佳实践(一)&#…

时序约束(二): input delay约束和output delay约束

一、input delay约束 在千兆以太网数据收发项目中,RGMII的数据输入方式为DDR,源同步输入方式,可以用之前提到的分析模型进行约束。 在时序约束原理中我们提到,input delay约束的就是发射沿lunch到数据有效的延时,根据…

本地项目推送到gitlab仓库的保姆级教程

目录 1、安装git (1)Windows系统 (2)Linux系统 2、gitlab创建空白项目 3、创建密钥 4、将密钥添加到gitlab中 5、远程配置 (1)配置全局的用户和邮箱 (2)本地文件夹初始化 …

Rust: polars行遍历,从dataframe到struct及Bar设计比较

pandas提供了iterrows()、itertuples()、apply等行遍历的方式,还是比较方便的。 polars的列操作功能非常强大,这个在其官网上有详细的介绍。由于polars底层的arrow是列存储模式,行操作效率低下,官方也不推荐以行方式进行数据操作。…

序号不足两位前面补0

预期目标 原始效果 代码实现 {${(index 1).toString().padStart(2, 0)}. ${item.sentence}}要实现自动编号并确保显示为两位数的格式,可以在 {index 1} 的地方进行格式化。在 JavaScript 中,可以使用 String.prototype.padStart() 方法来补足数字到指定…

Webpack: Loader开发 (1)

概述 如何扩展 Webpack?有两种主流方式,一是 Loader —— 主要负责将资源内容翻译成 Webpack 能够理解、处理的 JavaScript 代码;二是 Plugin —— 深度介入 Webpack 构建过程,重塑 构建逻辑。 相对而言,Loader 的职责…

三个方法教大家学会RAR文件转换为ZIP格式

在日常工作当中,RAR和ZIP是两种常见的压缩文件格式。有时候,大家可能会遇到将RAR文件转换为ZIP格式的情况,这通常是为了方便在特定情况下打开或使用文件。下面给大家分享几个RAR文件转换为ZIP格式的方法,下面随小编一起来看看吧~ …

如何通过指纹浏览器使用代理IP?

1.指纹浏览器定义 指纹浏览器是 一种浏览器技术,它根据用户设备的硬件、软件和配置等特征生成唯一标识符(称为“指纹”)。此指纹用于识别和追踪用户身份,即使用户更改其 IP 地址或清除浏览器数据(如缓存和 Cookie&…

美国抗攻击服务器有哪些可靠的解决方案

美国抗攻击服务器在面对日益严重的网络安全威胁时,需要采取一系列可靠的解决方案来确保服务器的稳定运行和数据安全。以下是一些科普性质的抗攻击服务器解决方案: 一、流量清洗与过滤 流量清洗是美国抗攻击服务器应对DDoS攻击的重要措施。当检测到异常流…

助力构建新型电力系统自主可控实时底座

近日,2024亚洲新型电力系统及储能展览会&亚洲新型电力及储能论坛会在广州广交会展馆圆满落下帷幕!科东软件携多款电力产品亮相展会,并在2024亚洲新型电力及储能论坛发表《“鸿道Intewell操作系统助力构建新型电力系统自主可控实时底座”》的主…

机器学习-EM算法

目录 一:最大似然估计 二:EM算法 加入隐变量 EM算法推导 1.Jensen不等式 点个赞呗!!! 一:最大似然估计 举个栗子:一个袋子里有很多个球,每次放回的取一个球,取了十次,其中有六次白球,4次黑球。那么就认为袋子里面取到白球的概率为6/10,黑球的概率为4/10。…