生成模型:变分自编码器-VAE

1.基本概念

1.1 概率

这里有:

  1. x为真实图像,开源为数据集, 编码器将其编码为分布参数
  2. x ^ \hat{x} x^为生成图像, 通过解码器获得
  3. p ( x ) ^ \hat{p(x)} p(x)^: 观测数据的分布, 即数据集所构成的经验分布
  4. p r e a l ( x ) p_{real}(x) preal(x): 真实世界的数据分布,这个是最理想的情况
  5. p ( x ) p(x) p(x):生成模型的分布,目的是接近 p r e a l ( x ) p_{real}(x) preal(x),避免过拟合到 p ( x ) ^ \hat{p(x)} p(x)^
  6. z ∼ N ( μ , σ ) 2 z \sim \mathcal{N}(\mu, \sigma)^2 zN(μ,σ)2 :潜空间向量, 通常希望约束于正态分布
  7. p ( z ) p(z) p(z):先验分布,即假设分布,在 VAE 中通常假设为标准正态分布
  8. q ϕ ( z ∣ x ) q_\phi(z∣x) qϕ(zx): 后验分布,是一种近似分布以逼近目标分布。依赖输入数据x,预测潜向量分布,即编码器
  9. p θ ( x ∣ z ) p_\theta(x∣z) pθ(xz): 条件分布,通过z生成x,即解码器

KL散度, 衡量分布相似性:

  • q ϕ ( z ∣ x ) = p ( z ) q_\phi(z∣x)=p(z) qϕ(zx)=p(z), 散度为 0,表示两个分布完全一致。

  • q ϕ ( z ∣ x ) ≠ p ( z ) q_\phi(z∣x)≠p(z) qϕ(zx)=p(z) 时,散度为正,值越大表示分布之间的差异越大。

KL 散度用于约束编码器生成的后验分布 q ϕ ( z ∣ x ) q_\phi(z∣x) qϕ(zx) 接近先验分布 p ( z ) p(z) p(z)

1.2 模型

VAE与普通自编码器区别如下:

  • 普通自编码器(AE) 会直接将 x映射到一个固定的潜向量z
  • 变分自编码器(VAE) 则通过学习概率分布的参数(均值 μ ( x ) \mu(x) μ(x),方差 σ 2 ( x ) \sigma^2(x) σ2(x) 来学习一个潜在分布 q ϕ ( x ∣ z ) q_\phi(x|z) qϕ(xz)

VAE训练一个自编码器, 目标是生成潜空间的分布参数,即潜向量z的均值和方差,而不是z本身。

因为学习的是一个分布参数,z具有随机性,即 x 和 z 不是一一对应的,是一对多的关系,

其设计原因分析如下:

1.数据分布复杂:真实世界中的非结构化数据分布是及其复杂且多样的。如果每个
x都严格映射到一个z,则潜在空间无法表达数据的多样性,数据映射的z存在随机性。

2.有助于模型泛化: 学习一个分布近似分布而不是固定映射。在生成任务中,随机采样z具有多样性,而不仅仅是直接复现训练数据, 适应未见过的数据。

2.方法

2.1 编码器-E

E将输入数据映射为潜在空间的概率分布参数: 均值 μ \mu μ 与 方差 σ 2 \sigma^2 σ2

μ \mu μ σ 2 \sigma^2 σ2 分别代表潜空间向量的各元素均值和方差。

这里假定 q q q是可以通过学习参数 θ \theta θ学到,公式如下:

N ( z ; μ ( x ) , σ 2 ( x ) ) \mathcal{N}(z; \mu(x), \sigma^2(x)) N(z;μ(x),σ2(x))

表示z服从正态分布,其均值为 μ ( x ) \mu(x) μ(x)$

q θ q_\theta qθ用编码器E来学习:

$E(x) = \mu(x), \sigma^2(x), z \sim ( \mu(x), \sigma^2(x)) $

2.2 解码器-D

D的目的是,输入潜向量 z,重构输入数据 x, 得到 x ^ \hat{x} x^

  • 重参数化

由于分布输出的z是随机采样,存在不确定性,这里在送入D前重参数化:

z = u + σ ⋅ ϵ , ϵ ∼ N ( 0 , 1 ) z = u + \sigma \cdot \epsilon, \epsilon \sim \mathcal{N}(0,1) z=u+σϵ,ϵN(0,1)

即z是一个确定的函数,将随机性与模型参数 μ , σ \mu, \sigma μ,σ分离。

再送入解码器:

x ^ = D ( z ) \hat{x} = D(z) x^=D(z)

2.3 训练

VAE是将E和D作为一个整体训练(即整个自编码器), 损失函数如下:

L VAE = E z ∼ q ϕ ( z ∣ x ) [ − log ⁡ p θ ( x ∣ z ) ] + D KL ( q ϕ ( z ∣ x ) ∥ p ( z ) ) \mathcal{L}_{\text{VAE}} = \mathbb{E}_{z \sim q_\phi(z|x)} \left[ -\log p_\theta(x|z) \right] + D_\text{KL}(q_\phi(z|x) \parallel p(z)) LVAE=Ezqϕ(zx)[logpθ(xz)]+DKL(qϕ(zx)p(z))

简化为:

L VAE \mathcal{L}_{\text{VAE}} LVAE = 重构损失 + KL散度

2.3.1 重构损失

表示在潜向量z按照近似后验分布 q ϕ ( z ∣ x ) q_\phi(z∣x) qϕ(zx)采样时,模型重构数据 x ^ \hat{x} x^的对数似然期望值:

− E z ∼ q ϕ ( z ∣ x ) [ log ⁡ p θ ( x ∣ z ) ] -\mathbb{E}_{z \sim q_\phi(z \mid x)}\left[\log p_\theta(x \mid z)\right] Ezqϕ(zx)[logpθ(xz)]

这里加了负号,即最大化重构概率转为损失值最小化

直观理解:

1.编码器 q ϕ ( z ∣ x ) q_\phi(z|x) qϕ(zx)为每个输入数据x提供一组潜向量z的分布参数。

2.解码器$p_\theta(x|z)尝试根据z重构原始数据x。

3.对 log ⁡ θ ( x ∣ z ) \log_\theta(x|z) logθ(xz)取期望值,是对不同z的采样重构结果进行平均。

如果解码器能很好地重构x, log ⁡ θ ( x ∣ z ) \log_\theta(x|z) logθ(xz)值就大,相反就小。

  • 如果是二值像素, 即0 和 1。可以用交叉熵,即BCE(Binary Cross Entropy)

即判断像素值接近 0 还是接近 1:

BCE = − 1 N ∑ i = 1 N [ x i log ⁡ ( x ^ i ) + ( 1 − x i ) log ⁡ ( 1 − x ^ i ) ] \text{BCE} = -\frac{1}{N} \sum_{i=1}^{N} \left[ x_i \log(\hat{x}_i) + (1 - x_i) \log(1 - \hat{x}_i) \right] BCE=N1i=1N[xilog(x^i)+(1xi)log(1x^i)]

  • 如果是[0,255],或者归一化为[0,1],[-1,1]的像素,可以用MSE

MSE = 1 N ∑ i = 1 N ( x i − x ^ i ) 2 \text{MSE} = \frac{1}{N} \sum_{i=1}^{N} (x_i - \hat{x}_i)^2 MSE=N1i=1N(xix^i)2

2.3.2 KL散度

KL 散度的定义:

D KL ( q ϕ ( z ∣ x ) ∥ p ( z ) ) = E q ϕ ( z ∣ x ) [ log ⁡ q ϕ ( z ∣ x ) p ( z ) ] D_\text{KL}(q_\phi(z|x) \parallel p(z)) = \mathbb{E}_{q_\phi(z|x)} \left[ \log \frac{q_\phi(z|x)}{p(z)} \right] DKL(qϕ(zx)p(z))=Eqϕ(zx)[logp(z)qϕ(zx)]

展开:

D KL = E z ∼ q ϕ ( z ∣ x ) [ − log ⁡ p θ ( x ∣ z ) + log ⁡ q ϕ ( z ∣ x ) p ( z ) ] D_\text{KL} = \mathbb{E}_{z \sim q_\phi(z|x)} \left[ -\log p_\theta(x|z) + \log \frac{q_\phi(z|x)}{p(z)} \right] DKL=Ezqϕ(zx)[logpθ(xz)+logp(z)qϕ(zx)]

进一步分解为:

D KL = − 1 2 ∑ i = 1 d ( 1 + log ⁡ σ i 2 − μ i 2 − σ i 2 ) D_\text{KL} = -\frac{1}{2} \sum_{i=1}^d \left( 1 + \log \sigma_i^2 - \mu_i^2 - \sigma_i^2 \right) DKL=21i=1d(1+logσi2μi2σi2)

3.代码实现

训练VAE生成手写数字。

3.1 参数设置

  • 模型:极简的7层全连接自编码器(E-4层, D-3层)

  • 数据集:pytorch自带的mnist手写数据集,每个样本像素为单通道 [28,28]

  • epoch: 50次

  • batch-size:64

  • learing-rate:1e-3 或 5e-4

3.2 代码概述

  • 导入必要的库
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
  • 编码器:将输入数据映射为潜在变量 z 的均值 μ \mu μ 和方差 σ 2 \sigma^2 σ2
  • 解码器:从潜在变量 z 重构原始数据
class VAE(nn.Module):
    def __init__(self, input_dim, latent_dim):
        super(VAE, self).__init__()
        # 编码器
        self.encoder = nn.Sequential(
            nn.Linear(input_dim, 512),
            nn.ReLU(),
            nn.Linear(512, 256),
            nn.ReLU()
        )
        self.fc_mu = nn.Linear(256, latent_dim)  # 均值
        self.fc_logvar = nn.Linear(256, latent_dim)  # 对数方差

        # 解码器
        self.decoder = nn.Sequential(
            nn.Linear(latent_dim, 256),
            nn.ReLU(),
            nn.Linear(256, 512),
            nn.ReLU(),
            nn.Linear(512, input_dim),
            nn.Sigmoid()  # 用 Sigmoid 将输出值压缩到 [0, 1]
        )

    def reparameterize(self, mu, logvar):
        """使用重参数化技巧生成潜在变量 z"""
        std = torch.exp(0.5 * logvar)  # 标准差
        eps = torch.randn_like(std)    # 标准正态分布的随机噪声
        return mu + eps * std

    def forward(self, x):
        # 编码
        h = self.encoder(x)
        mu = self.fc_mu(h)
        logvar = self.fc_logvar(h)

        # 重参数化
        z = self.reparameterize(mu, logvar)

        # 解码
        recon_x = self.decoder(z)
        return recon_x, mu, logvar
  • 损失函数
def vae_loss(recon_x, x, mu, logvar):
    # 重构误差(BCE)
    recon_loss = nn.functional.binary_cross_entropy(recon_x, x, reduction='sum')

    # KL 散度
    kl_div = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

    return recon_loss + kl_div
  • 数据加载和超参数设置
# 超参数
latent_dim = 20  # 潜在空间维度
input_dim = 28 * 28  # MNIST 图像大小
batch_size = 64
epochs = 50
lr = 0.001

# 数据加载器
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True)
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
  • 训练 VAE, 先初始化模型和优化器
vae = VAE(input_dim=input_dim, latent_dim=latent_dim).to('cuda')
optimizer = optim.Adam(vae.parameters(), lr=lr)

for epoch in range(epochs):
    vae.train()
    total_loss = 0

    for images, _ in dataloader:
        # 预处理数据
        images = images.view(-1, input_dim).to('cuda')

        # 前向传播
        recon_images, mu, logvar = vae(images)

        # 计算损失
        loss = vae_loss(recon_images, images, mu, logvar)

        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        total_loss += loss.item()

    print(f"Epoch [{epoch+1}/{epochs}] Loss: {total_loss / len(dataloader.dataset):.4f}")
  • 生成新样本时,只需要随机从潜在空间中采样z,然后通过解码器生成数据:
vae.eval()
with torch.no_grad():
    # 从标准正态分布采样
    z = torch.randn(256, latent_dim).to('cuda')  # 16x16 = 256 个样本
    generated_images = vae.decoder(z).view(-1, 1, 32, 32).cpu()

    # 创建 16x16 的网格
    grid = torchvision.utils.make_grid(generated_images, nrow=16, normalize=True)

    # 保存生成的图像为文件
    torchvision.utils.save_image(grid, 'generated_images.png', normalize=True)

    # 显示图像
    plt.imshow(grid.permute(1, 2, 0))
    plt.axis('off')  # 去除坐标轴
    plt.show()

4.实验结果

4.1 损失函数

损失函数值有效下降,在数据集迭代34次(ep33)后下降约一半:

在这里插入图片描述

4.2 最终效果

  • epoch-1:

在这里插入图片描述

  • epoch-12:

在这里插入图片描述

  • epoch-33:

在这里插入图片描述

5.概率相关补充

5.1 条件概率-贝叶斯定理

p ( x , z ) = p ( x ∣ z ) p ( z ) p(x,z) = p(x|z)p(z) p(x,z)=p(xz)p(z)

p ( z ∣ x ) = p ( x , z ) p ( x ) = p ( x ∣ z ) p ( z ) p ( x ) p(z \mid x) = \frac{p(x, z)}{p(x)} = \frac{p(x \mid z) p(z)}{p(x)} p(zx)=p(x)p(x,z)=p(x)p(xz)p(z)

5.2 KL散度函数:

D K L ( q ( z ∣ x ) ∥ p ( z ) ) = E q ( z ∣ x ) [ log ⁡ p ( z ) q ( z ∣ x ) ] = ∫ q ( z ∣ x ) log ⁡ q ( z ∣ x ) p ( z )   d z = ∑ z q ( z ∣ x ) log ⁡ q ( z ∣ x ) p ( z ) D_{KL}(q(z|x) \parallel p(z)) = \mathbb{E}_{q(z|x)} \left[ \log \frac{p(z)}{q(z|x)} \right] = \int q(z|x) \log \frac{q(z|x)}{p(z)} \, dz = \sum_{z} q(z|x) \log \frac{q(z|x)}{p(z)} DKL(q(zx)p(z))=Eq(zx)[logq(zx)p(z)]=q(zx)logp(z)q(zx)dz=zq(zx)logp(z)q(zx)

KL衡量一个分布相对于另一个分布的信息损失或“距离”,是一个正数:

证明可利用:

log ⁡ x ≤ x − 1 , ∀ x > 0 \log x \leq x - 1, \quad \forall x > 0 logxx1,x>0

给log内分数上负号,颠倒分子分母,则:

∑ z q ( z ∣ x ) log ⁡ p ( z ) q ( z ∣ x ) ≤ ∑ z − p ( z ) q ( z ∣ x ) < 0 \sum_{z}q(z|x) \log \frac{p(z)}{q(z|x)} \leq \sum_z -\frac{p(z)}{q(z|x)} < 0 zq(zx)logq(zx)p(z)zq(zx)p(z)<0

5.3 概率密度函数:

p ( z ) ∼ N ( 0 , 1 ) p(z) \sim \mathcal{N}(0,1) p(z)N(0,1):

p ( z ) = 1 ( 2 π ) d / 2 exp ⁡ ( − 1 2 ∑ i = 1 d z i 2 ) p(z) = \frac{1}{(2\pi)^{d/2}} \exp \left( -\frac{1}{2} \sum_{i=1}^{d} z_i^2 \right) p(z)=(2π)d/21exp(21i=1dzi2)

注:d是维度

p ( z ) ∼ N ( μ , σ ) p(z) \sim \mathcal{N}(\mu,\sigma) p(z)N(μ,σ):

q ( z ∣ x ) = 1 ( 2 π ) d / 2 ∣ Σ ∣ 1 / 2 exp ⁡ ( − 1 2 ∑ i = 1 d ( z i − μ i ) 2 σ i 2 ) ; Σ = d i a g ( σ 1 2 , . . . , σ d 2 ) q(z|x) = \frac{1}{(2\pi)^{d/2} |\Sigma|^{1/2}} \exp \left( -\frac{1}{2} \sum_{i=1}^{d} \frac{(z_i - \mu_i)^2}{\sigma_i^2} \right); \Sigma = diag(\sigma_1^2,...,\sigma_d^2) q(zx)=(2π)d/2∣Σ1/21exp(21i=1dσi2(ziμi)2);Σ=diag(σ12,...,σd2)

也可以写成这样:

q ( z ∣ x ) = 1 ( 2 π ) d / 2 σ 1 σ 2 ⋯ σ d exp ⁡ ( − 1 2 ∑ i = 1 d ( z i − μ i ) 2 σ i 2 ) q(z|x) = \frac{1}{(2\pi)^{d/2} \sigma_1 \sigma_2 \cdots \sigma_d} \exp \left( -\frac{1}{2} \sum_{i=1}^{d} \frac{(z_i - \mu_i)^2}{\sigma_i^2} \right) q(zx)=(2π)d/2σ1σ2σd1exp(21i=1dσi2(ziμi)2)

Ref

  • Auto-Encoding Variational Bayes / Variational autoencoder
  • https://arxiv.org/abs/1312.6114
  • https://www.zhihu.com/question/579890053/answer/38625999761

本文全部代码:

  • https://github.com/disanda/GM.git

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

中国省级产业结构高级化及合理化数据测算(2000-2023年)

一、数据介绍 数据名称&#xff1a;中国省级产业结构高级化、泰尔指数 数据年份&#xff1a;2000-2023年 数据范围&#xff1a;31个省份 数据来源&#xff1a;中国统计年鉴、国家统计局 数据整理&#xff1a;内含原始版本、线性插值版本、ARIMA填补版本 数据说明&#xf…

高级数据库系统 复习提纲

第一章 数据库技术的回顾与发展 简述三代数据库的发展历史及其对应特点&#xff1a; 新型数据库在“数据模型”上的创新&#xff1a; 简述数据库和什么相关技术结合&#xff0c;产生了什么新型数据库&#xff1f; 1. 数据库和并行处理技术结合&#xff0c;产生“并行数据库”…

C++实现图书管理系统(Qt C++ GUI界面版)

前瞻 本项目基于【C】图书管理系统(完整版) 图书管理系统功能概览&#xff1a; 登录&#xff0c;注册学生,老师借书&#xff0c;查看自己当前借书情况&#xff0c;还书。管理员增加书&#xff0c;查看当前借阅情况&#xff0c;查看当前所有借阅人&#xff0c;图书信息。 效果…

【LeetCode: 560. 和为 K 的子数组 + 前缀和 + 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

微信小程序实现登录注册

文章目录 1. 官方文档教程2. 注册实现3. 登录实现4. 关于作者其它项目视频教程介绍 1. 官方文档教程 https://developers.weixin.qq.com/miniprogram/dev/framework/路由跳转的几种方式&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab…

嵌入式系统 (2.嵌入式硬件系统基础)

2.嵌入式硬件系统基础 2.1嵌入式硬件系统的组成 嵌入式硬件系统以嵌入式微处理器为核心&#xff0c;主要由嵌入式微处理器、总线、存储器、输入/输出接口和设备组成。 嵌入式微处理器 嵌入式微处理器采用冯诺依曼结构或哈佛结构&#xff1a;前者指令和数据共享同一存储空间…

多模态大模型初探索:通过ollama部署多模态大模型

文章目录 前言模型下载 前言 今天和同事聊天&#xff0c;聊到多模态大模型&#xff0c;感觉可以作为2025年的一个新的探索方向。希望和大家一起学习&#xff0c;一起进步。 今天也是尝试了我能想到的最基本最快速地本地部署多模态大模型的方式&#xff0c;那便是使用ollama。…

【超详细】React SSR 服务端渲染实战

前言 这篇文章和大家一起来聊一聊 React SSR&#xff0c;本文更偏向于实战。你可以从中学到&#xff1a; 从 0 到 1 搭建 React SSR 服务端渲染需要注意什么 react 18 的流式渲染如何使用 文章如有误&#xff0c;欢迎指出&#xff0c;大家一起学习交流&#xff5e;。 &…

js策略模式

定义一组算法&#xff0c;将每个算法封装成一个独立的类&#xff0c;并使它们可以互相替换。策略模式使得算法的变化不会影响到使用算法的客户。 const priceProcessor {pre(originPrice) {if (originPrice > 100) {return originPrice - 20;}return originPrice * 0.9;}…

Python中的可变对象与不可变对象;Python中的六大标准数据类型哪些属于可变对象,哪些属于不可变对象

Python中的可变对象与不可变对象&#xff1b;Python中的六大标准数据类型哪些属于可变对象&#xff0c;哪些属于不可变对象 Python中的可变对象与不可变对象一、Python的六大标准数据类型1. 数字类型 (Number)2. 字符串 (String)3. 列表 (List)4. 元组 (Tuple)5. 集合 (Set)6. …

js状态模式

允许一个对象在其内部状态改变时改变它的行为。 状态模式将对象的状态封装成独立的类&#xff0c;并使它们可以互相转换 // 定义状态接口class State {constructor() {if (this.constructor State) {throw new Error(不能实例化抽象类);}}// 定义状态方法handle(context) {th…

基于64QAM的载波同步和定时同步性能仿真,包括Costas环和gardner环

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要 载波同步是…

【Web安全】SQL 注入攻击技巧详解:布尔盲注(Boolean-Based Blind SQL Injection)

【Web安全】SQL 注入攻击技巧详解&#xff1a;布尔盲注&#xff08;Boolean-Based Blind SQL Injection&#xff09; 引言 布尔盲注&#xff08;Boolean-Based Blind SQL Injection&#xff09;是一种在无法直接从数据库获取数据的情况下&#xff0c;通过观察数据库响应的布尔…

太速科技-418-基于AD9361 +ZYNQ7020 的软件无线电 SDR 套件

基于AD9361 ZYNQ7020 的软件无线电 SDR 套件 一、板卡信息 ● ZYNQ芯片采用XC7Z020&#xff0c;逻辑容量更大&#xff0c;支持更大的逻辑设计&#xff1b; ● 内存采用两片512M DDR3&#xff0c;共1GByte&#xff0c;更大容量。 ● 支持千兆网口&#xff0c;支持ZEDFMCO…

SpringBoot日常:集成Kafka

文章目录 1、pom.xml文件2、application.yml3、生产者配置类4、消费者配置类5、消息订阅6、生产者发送消息7、测试发送消息 本章内容主要介绍如何在springboot项目对kafka进行整合&#xff0c;最终能达到的效果就是能够在项目中通过配置相关的kafka配置&#xff0c;就能进行消息…

分布式IO模块:激光切割机产线高效控制的创新引擎

在智能制造的浪潮中&#xff0c;激光切割技术以其高精度、高效率的特点&#xff0c;成为了现代工业生产中不可或缺的一部分。特别是在汽车制造、航空航天、电子设备及精密零部件加工等领域&#xff0c;激光切割机以其无与伦比的切割精度和灵活性&#xff0c;引领着制造业的转型…

RK3562编译Android13 ROOT固件教程,触觉智能开发板演示

本文介绍编译Android13 ROOT权限固件的方法&#xff0c;触觉智能RK3562开发板演示&#xff0c;搭载4核A53处理器&#xff0c;主频高达2.0GHz&#xff1b;内置独立1Tops算力NPU&#xff0c;可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。 关闭seli…

wireshark抓包工具新手使用教程

wireshark抓包工具新手入门使用教程 一、Wireshark软件安装二、Wireshark 抓包示范三、Wireshakr抓包界面四、Wireshark过滤器设置五、wireshark过滤器表达式的规则六、Wireshark抓包分析TCP三次握手七、Wireshark分析常用列标签格式 Wireshark是一款开源的网络协议分析工具&am…

如何用Python编程实现自动整理XML发票文件

传统手工整理发票耗时费力且易出错&#xff0c;而 XML 格式发票因其结构化、标准化的特点&#xff0c;为实现发票的自动化整理与保存提供了可能。本文将详细探讨用python来编程实现对 XML 格式的发票进行自动整理。 一、XML 格式发票的特点 结构化数据&#xff1a;XML 格式发票…

【网络安全 | 漏洞挖掘】HubSpot 全账户接管(万字详析)

未经许可,不得转载。 今天我们将分享一个关于在 Bugcrowd 平台的 HubSpot 公共漏洞赏金计划中实现全账户接管的故事。 文章目录 正文SQL 注入主机头污染(Host Header Poisoning)负载均衡器主机头覆盖(Load Balancer Host Header Override)Referer Header 测试ORIGIN Heade…