去噪扩散概率模型(Denoising Diffusion Probabilistic Models, DDPM)-Python案例

1、去噪概率模型(Denoising Probabilistic Models)

去噪概率模型(Denoising Probabilistic Models)是一类通过学习数据的潜在分布来去除噪声的生成模型。其核心思想是,在有噪声的数据中,模型通过条件概率学习输入数据与噪声之间的关系,从而能够生成去噪后的数据。

去噪概率模型的基本步骤

  1. 数据准备:将原始数据添加噪声,构造带噪声的样本。
  2. 模型训练:使用带噪声的样本来训练模型,目标是最大化去噪后的样本的概率。
  3. 去噪过程:给定带噪声的样本,模型生成去噪后的样本。

PyTorch 示例代码

以下是一个简单的去噪自编码器的示例,使用PyTorch实现:

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
import os

# 定义去噪自编码器
class DenoisingAutoencoder(nn.Module):
    def __init__(self):
        super(DenoisingAutoencoder, self).__init__()
        self.encoder = nn.Sequential(
            nn.Linear(784, 256),
            nn.ReLU(),
            nn.Linear(256, 64),
            nn.ReLU(),
        )
        self.decoder = nn.Sequential(
            nn.Linear(64, 256),
            nn.ReLU(),
            nn.Linear(256, 784),
            nn.Sigmoid(),
        )

    def forward(self, x):
        encoded = self.encoder(x)
        decoded = self.decoder(encoded)
        return decoded

# 定义 MNIST 数据集类
class MNISTDataset(Dataset):
    def __init__(self, images_path, labels_path, transform=None):
        self.images = self.load_images(images_path)
        self.labels = self.load_labels(labels_path)
        self.transform = transform

    def load_images(self, path):
        with open(path, 'rb') as f:
            f.read(16)  # 跳过前16个字节
            images = np.frombuffer(f.read(), np.uint8).reshape(-1, 1, 28, 28)
        return torch.tensor(images, dtype=torch.float32).view(-1, 784)  # Flatten images

    def load_labels(self, path):
        with open(path, 'rb') as f:
            f.read(8)  # 跳过前8个字节
            labels = np.frombuffer(f.read(), np.uint8)
        return labels

    def __len__(self):
        return len(self.labels)

    def __getitem__(self, idx):
        image = self.images[idx]
        label = self.labels[idx]

        if self.transform:
            image = self.transform(image)

        return image, label

# 数据准备
data_root = r'./MNIST'
train_dataset = MNISTDataset(
    images_path=os.path.join(data_root, 'train-images-idx3-ubyte'),
    labels_path=os.path.join(data_root, 'train-labels-idx1-ubyte')
)

test_dataset = MNISTDataset(
    images_path=os.path.join(data_root, 't10k-images-idx3-ubyte'),
    labels_path=os.path.join(data_root, 't10k-labels-idx1-ubyte')
)

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

# 模型、损失函数和优化器
model = DenoisingAutoencoder()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 可视化函数
def show_images(original, noisy, denoised):
    plt.figure(figsize=(12, 4))
    plt.subplot(1, 3, 1)
    plt.title("Original")
    plt.imshow(original.view(28, 28).detach().numpy(), cmap='gray')
    
    plt.subplot(1, 3, 2)
    plt.title("Noisy")
    plt.imshow(noisy.view(28, 28).detach().numpy(), cmap='gray')
    
    plt.subplot(1, 3, 3)
    plt.title("Denoised")
    plt.imshow(denoised.view(28, 28).detach().numpy(), cmap='gray')
    
    plt.show()

# 训练模型
for epoch in range(5):
    for data, _ in train_loader:
        optimizer.zero_grad()
        noisy_data = data + 0.5 * torch.randn_like(data)  # 添加噪声
        noisy_data = torch.clamp(noisy_data, 0., 1.)
        
        output = model(noisy_data)
        
        loss = criterion(output, noisy_data)
        loss.backward()
        optimizer.step()
    
    print(f'Epoch {epoch + 1}, Loss: {loss.item()}')

# 可视化原始、带噪声和去噪后的图片
test_data, _ = next(iter(train_loader))
noisy_test_data = test_data + 0.5 * torch.randn_like(test_data)
noisy_test_data = torch.clamp(noisy_test_data, 0., 1.)
denoised_output = model(noisy_test_data)

# 显示图像
show_images(test_data[0], noisy_test_data[0], denoised_output[0])

输出

Epoch 1, Loss: 0.08383525162935257
Epoch 2, Loss: 0.07632550597190857
Epoch 3, Loss: 0.07644318789243698
Epoch 4, Loss: 0.07475438714027405
Epoch 5, Loss: 0.0726914331316948

在这里插入图片描述

说明

  • 去噪自编码器:该模型包括编码器和解码器。编码器将输入数据压缩到低维表示,解码器将其还原为原始数据。
  • 数据处理:在数据准备阶段,随机噪声被添加到原始数据中。
  • 训练过程:模型通过最小化重建误差(均方误差)来学习去噪。

这个示例展示了如何使用PyTorch实现基本的去噪概率模型。

2、去噪扩散概率模型

去噪扩散概率模型(Denoising Diffusion Probabilistic Models, DDPM)是一种生成模型,通过逐步去噪从随机噪声中生成高质量数据。其核心思想是模拟一个正向过程,在这个过程中,数据被逐渐添加噪声,并训练一个反向过程,从噪声逐渐恢复数据。

关键步骤

  1. 正向过程:逐步向数据中添加噪声,直到它变得接近标准正态分布。(扩散)
  2. 反向过程:通过神经网络学习如何去噪,从而从随机噪声恢复到原始数据分布。(去噪)
  3. 训练:使用一个变分下界(VLB)来优化模型。

PyTorch 示例

以下是一个简化的去噪扩散概率模型的示例代码框架:

import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
import os
import numpy as np

# 定义 U-Net 网络
class UNet(nn.Module):
    def __init__(self):
        super(UNet, self).__init__()
        self.encoder1 = nn.Conv2d(1, 64, kernel_size=3, padding=1)
        self.encoder2 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.decoder1 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2)
        self.decoder2 = nn.Conv2d(64, 1, kernel_size=3, padding=1)

    def forward(self, x):
        enc1 = torch.relu(self.encoder1(x))
        enc2 = torch.relu(self.encoder2(self.pool(enc1)))
        dec1 = self.decoder1(enc2)
        dec2 = self.decoder2(dec1 + enc1)  # Skip connection
        return torch.sigmoid(dec2)

# 噪声调度函数
def noise_schedule(t):
    return torch.minimum(torch.tensor(1.0).cuda(), t.float().view(-1, 1, 1, 1) / 1000)  # 变换为形状 (batch_size, 1, 1, 1)

class MNISTDataset(Dataset):
    def __init__(self, images_path, labels_path, transform=None):
        self.images = self.load_images(images_path)
        self.labels = self.load_labels(labels_path)
        self.transform = transform

    def load_images(self, path):
        with open(path, 'rb') as f:
            f.read(16)  # 跳过前16个字节
            images = np.frombuffer(f.read(), np.uint8).reshape(-1, 1, 28, 28)
        return torch.tensor(images, dtype=torch.float32)  # 保持原形状 (batch_size, 1, 28, 28)

    def load_labels(self, path):
        with open(path, 'rb') as f:
            f.read(8)  # 跳过前8个字节
            labels = np.frombuffer(f.read(), np.uint8)
        return labels

    def __len__(self):
        return len(self.labels)

    def __getitem__(self, idx):
        image = self.images[idx]
        label = self.labels[idx]

        if self.transform:
            image = self.transform(image)

        return image, label

# 数据准备
data_root = r'./MNIST'
train_dataset = MNISTDataset(
    images_path=os.path.join(data_root, 'train-images-idx3-ubyte'),
    labels_path=os.path.join(data_root, 'train-labels-idx1-ubyte')
)

test_dataset = MNISTDataset(
    images_path=os.path.join(data_root, 't10k-images-idx3-ubyte'),
    labels_path=os.path.join(data_root, 't10k-labels-idx1-ubyte')
)

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

# 模型、损失函数和优化器
model = UNet().cuda()  # 使用GPU
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.MSELoss()

# 训练过程
num_epochs = 5
for epoch in range(num_epochs):
    for images, _ in train_loader:
        images = images.cuda()  # 使用GPU
        optimizer.zero_grad()
        
        # 添加噪声
        t = torch.randint(0, 1000, (images.size(0),)).cuda()  # 随机时间步
        noise = torch.randn_like(images).cuda()
        noisy_images = images + noise_schedule(t) * noise  # 使用正确的噪声调度
        
        # 模型输出
        predicted_noise = model(noisy_images)
        
        # 计算损失
        loss = criterion(predicted_noise, noise)
        loss.backward()
        optimizer.step()
    
    print(f'Epoch {epoch + 1}, Loss: {loss.item()}')

# 可视化结果
test_image, _ = next(iter(train_loader))
test_image = test_image.cuda()  # 使用GPU
with torch.no_grad():
    noisy_test_image = test_image + torch.randn_like(test_image).cuda()  # 加入随机噪声
    predicted_noise = model(noisy_test_image)

# 显示原始、带噪声和去噪后的图像
def show_images(original, noisy, denoised):
    plt.figure(figsize=(12, 4))
    plt.subplot(1, 3, 1)
    plt.title("Original")
    plt.imshow(original[0].squeeze(0).cpu().numpy(), cmap='gray')

    plt.subplot(1, 3, 2)
    plt.title("Noisy")
    plt.imshow(noisy[0].squeeze(0).cpu().numpy(), cmap='gray')

    plt.subplot(1, 3, 3)
    plt.title("Denoised")
    plt.imshow(denoised[0].squeeze(0).cpu().numpy(), cmap='gray')

    plt.show()

show_images(test_image, noisy_test_image, predicted_noise)

输出

Epoch 1, Loss: 0.7177927494049072
Epoch 2, Loss: 0.7039206027984619
Epoch 3, Loss: 0.7078389525413513
Epoch 4, Loss: 0.712163507938385
Epoch 5, Loss: 0.6767022013664246

在这里插入图片描述
效果不太好的样子…

说明

  • UNet:这是一个简单的网络结构,可以替换为更复杂的模型。
  • 噪声调度:这里示例的噪声调度非常简单,实际应用中可以更复杂。
  • 训练过程:每个 epoch 中生成带噪声的图像,并优化模型以预测噪声。

如果需要更复杂的模型或其他类型的去噪方法,可以进一步探索变分自编码器(VAE)、生成对抗网络(GAN)等。

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

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

相关文章

pytest框架之fixture测试夹具详解

前言 大家下午好呀,今天呢来和大家唠唠pytest中的fixtures夹具的详解,废话就不多说了咱们直接进入主题哈。 一、fixture的优势 ​ pytest框架的fixture测试夹具就相当于unittest框架的setup、teardown,但相对之下它的功能更加强大和灵活。 …

基于SSM医疗信息管理系统(源码+定制+参考)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

Python数字图像处理实战——基于OpenCV实现多种滤波器(附完整代码和结果图)

Python数字图像处理实战——基于OpenCV实现多种滤波器(附完整代码和结果图) 关于作者 作者:小白熊 作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测…

分辨率提高4到8倍!AI高清修复工具-upscayl使用方法!

你还在为手中的模糊照片苦恼吗? 是不是想把老照片或低分辨率的图片用于大尺寸印刷,却因为画质糟糕而无从下手? 现在你不再需要高深的Photoshop技能,也不用花费巨资找人修图。借助AI高清修复工具Upscayl,只需几秒钟&am…

Python、R语言Lasso、Ridge岭回归、XGBoost分析Airbnb房屋数据:旅游市场差异、价格预测

全文链接:https://tecdat.cn/?p37839 原文出处:拓端数据部落公众号 分析师: Kefan Yu 在大众旅游蓬勃发展的背景下,乡村旅游已成为推动乡村经济、社会和文化发展的关键力量。当前,乡村旅游接待设施主要以招待所、…

基于Python的抑郁症患者看护系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

如何实现Vue2项目升级Vue3?

Vue3正式版已经发布有两年多了,如今它也已成为Vue的默认开发版本,如果你想要对之前Vue2项目进行升级重构,可以从以下几个维度入手: ① 构建工具 ② 入口文件 ③ 插件 ④ 指令 ⑤ 路由 ⑥ 状态管理 ⑦ 其他 一、构建工具 Vue3推荐使…

HTB:Base[WriteUP]

目录 连接至HTB服务器并启动靶机 1.Which two TCP ports are open on the remote host? 2.What is the relative path on the webserver for the login page? 3.How many files are present in the /login directory? 4.What is the file extension of a swap file? …

springboot如何集成mybatis?

背景:以前一直是直接cv一个项目中现成的xml文件,然后再去自己配置mapper等数据。自己准备做一个单独的例子试一下。 步骤1:在pom.xml文件中插入mybatis-generator插件,这里选的版本是1.3.2,然后指定的generator文件是在…

IDM6.42下载器!下载速度就像坐上了火箭,嗖嗖的快到飞起!

亲爱的朋友们,今天我要给大家安利一款下载神器——Internet Download Manager 6.42(简称IDM)!这款软件简直就是下载界的“速度与激情”,用了它之后,你会发现下载速度就像坐上了火箭,嗖嗖的快到飞…

Python 如何使用 SQLAlchemy 进行复杂查询

Python 如何使用 SQLAlchemy 进行复杂查询 一、引言 SQLAlchemy 是 Python 生态系统中非常流行的数据库处理库,它提供了一种高效、简洁的方式与数据库进行交互。SQLAlchemy 是一个功能强大的数据库工具,支持结构化查询语言(SQL)…

Windows 通过 Docker 安装 GitLab

1. 安装 Docker Desktop 下载网站:Windows | Docker Docs 2. 拉取 GitLab Docker 镜像 打开 PowerShell 或 命令提示符,拉取 GitLab 镜像: docker pull gitlab/gitlab-ee:latest或则使用社区版: docker pull gitlab/gitlab-ce…

【C++】STL——stack和queue

目录 前言容器配接器(适配器)stack的使用stack的模拟实现queue的使用queue的模拟实现双端队列(deque) 前言 前面我们已经学习了STL容器中的string、vector还有list。 【C】string的模拟实现 【C】STL——vector的模拟实现 【C】S…

CTF-PWN方向 栈溢出等基础知识笔记(2)

ret2syscall 要求有0x80这种系统调用存在 (0x0A是回车的意思) 案例 通过file查看这个文件 发现是静态编译的文件 所以很多库函数都被编译进去了 但是不存在bin/sh字符串 不存在system和backdoor函数 系统调用需要用到的寄存器 通过ROPgadget工具来查找…

传统图像处理Opencv分割不同颜色的夹子

任务要求🍉 1. 计算图像中夹子的总数。 2. 分别计算不同颜色夹子的个数。 3. 使用以下方法适应三张图片,并在每张图像上显示结果: - 阈值方法 - HSV颜色空间 - 连通域分析 - 形态学图像处理 - Canny边缘检测 4. 在结果中显示计…

《数据密集型应用系统设计》笔记——第二部分 分布式数据系统(ch5-9)

第5章 数据复制 目的: 地理位置更近,降低延迟故障冗余提高读吞吐量 主节点与从节点(主从复制) 主从复制: 写请求发送给主节点,主节点将新数据写入本地存储;主节点将数据更改作为复制的日志发送…

使用java做一个微信机器人

微信机器人这个功能,目前在市面上运用的还是不是很多,每个人实现机器人的目的也不一样,有的为了自动加好友;有的为了自动拉群:也有的为了机器人对话聊天等等一系列。想必大家对微信机器人感兴趣的伙伴,但是大多数走到一半遇到各种…

Android Jetpack Compose中UI刷新的几种方式

Android Jetpack Compose中UI刷新的几种方式 在 Jetpack Compose 中,如果你想强制刷新 UI,可以使用 remember 和 mutableStateOf 来创建一个可观察的状态。当这个状态变化时,Compose 会自动重组 UI。以下是一些常见的方法来实现这一点: 1. 使用 mutableStateOf 你可以使…

[SQL] 安装

一 Windows 1.1 下载 进入Mysql的官方网站,点击下载->找到社区版本 选择对应操作系统进行下载。 点击下载 选择直接下载即可 1.2 安装 选择Full安装: MySQL服务器、客户端程序和其他附加工具如果只需要服务端那就选择Server only即可 点击执行,等待组件下载完…

【Unity踩坑】UWP项目安装包认证失败

问题:在Unity导出的VS项目,打包生成appx后,进行应用认证时失败。提示部分API不支持。 API __C_specific_handler in kernel32.dll is not supported for this application type. UnityPlayer.dll calls this API.API DXGIGetDebugInterface1 …