降噪自编码器(Denoising Autoencoder)

发布时间:2024年01月05日

降噪自编码器(Denoising Autoencoder)是一种用于无监督学习的神经网络模型。与普通的自编码器不同,降噪自编码器的目标是通过在输入数据中引入噪声,然后尝试从具有噪声的输入中重建原始无噪声数据。
以下是降噪自编码器的主要特点和工作原理:

1.噪声引入: 在训练阶段,降噪自编码器将输入数据添加一些噪声,例如高斯噪声或随机失活(random dropout)。这样的操作迫使网络学习对输入的噪声具有鲁棒性,使得模型更能够从嘈杂的数据中提取有用的特征。
2.网络结构: 降噪自编码器通常由编码器(encoder)和解码器(decoder)两个部分组成。编码器负责将输入数据映射到一个低维表示,而解码器则将这个低维表示还原为尽可能接近原始输入的输出。这个过程迫使模型学习提取输入数据中的关键特征。
3.损失函数: 降噪自编码器的目标是最小化重构误差,即原始输入与解码器输出之间的差异。常用的损失函数包括均方误差(Mean Squared Error,MSE)或交叉熵损失。
4.特征学习: 通过在输入中引入噪声,降噪自编码器迫使模型学习对输入的潜在表示,而不仅仅是简单地记住训练数据。这有助于模型学习数据的通用特征,提高了模型对新样本的泛化能力。
5.应用: 降噪自编码器广泛应用于特征学习、数据去噪、生成模型等任务。在训练后,编码器部分可以被用作特征提取器,产生的低维表示可以在其他任务中使用。

总体而言,降噪自编码器是一种有效的无监督学习方法,通过在训练数据中引入噪声,可以学习到更健壮、有意义的特征表示,对于数据的去噪和特征学习任务有着良好的性能。
对于输入层 x,以一定概率将其节点置0,得到 x1,用 x1去计算 y ,计算 z ,并将 z与原始 x做误差迭代,对结果误差较小的节点可以认为是噪声。每层处理重复上述工作。

在这里插入图片描述
在这里插入图片描述

from six.moves import urllib
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib.request.install_opener(opener)


import torch
import numpy as np
from torchvision import datasets
import torchvision.transforms as transforms
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
# 将数据转换为 Torch。浮动张量
transform = transforms.ToTensor()

# 加载训练数据集和测试数据集
train_data = datasets.MNIST(root='~/.pytorch/MNIST_data/', train=True,
                                   download=True, transform=transform)
test_data = datasets.MNIST(root='~/.pytorch/MNIST_data/', train=False,
                                  download=True, transform=transform)

# 创建训练和测试数据加载器
num_workers = 0
# 每批要加载多少个样品
batch_size = 20

# 准备数据加载程序
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, num_workers=num_workers)
test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, num_workers=num_workers)

# 可视化数据
import matplotlib.pyplot as plt
# 获取一批训练图像
dataiter = iter(train_loader)

# images, labels = dataiter.next()
images, labels = next(dataiter)
images = images.numpy()

# 从批处理中获取一个图像
img = np.squeeze(images[0])

fig = plt.figure(figsize = (5,5))
ax = fig.add_subplot(111)
ax.imshow(img, cmap='gray')


plt.show()

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader
import numpy as np
import matplotlib.pyplot as plt

# 假设您之前已经定义了train_loader并test_loader某个地方

class ConvDenoiser(nn.Module):
    def __init__(self):
        super(ConvDenoiser, self).__init__()
        self.encoder = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2),
            nn.Conv2d(32, 64, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.decoder = nn.Sequential(
            nn.ConvTranspose2d(64, 32, kernel_size=2, stride=2),
            nn.ReLU(),
            nn.ConvTranspose2d(32, 1, kernel_size=2, stride=2),
            nn.Sigmoid()  # To ensure output values are between 0 and 1
        )

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

# 初始化神经网络
model = ConvDenoiser()

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

# 训练模型的纪元数
n_epochs = 20

# 用于为图像添加噪点
noise_factor = 0.5

for epoch in range(1, n_epochs + 1):
    # 监控训练损失
    train_loss = 0.0

    # 训练模型
    for data in train_loader:
        images, _ = data

        # 向输入图像添加随机噪声
        noisy_imgs = images + noise_factor * torch.randn_like(images)
        # 将图像剪辑为介于 0 和 1 之间
        noisy_imgs = torch.clamp(noisy_imgs, 0., 1.)

        # 清除所有优化变量的梯度
        optimizer.zero_grad()
        # 前向传递:通过将*嘈杂*图像传递到模型来计算预测输出
        outputs = model(noisy_imgs)
        # 计算损失
        # “目标”仍然是原始的、不嘈杂的图像
        loss = criterion(outputs, images)
        # 后向传递:计算相对于模型参数的损失梯度
        loss.backward()
        # 执行单个优化步骤(参数更新)
        optimizer.step()
        # 更新跑步训练损失
        train_loss += loss.item() * images.size(0)

    # 打印平均训练统计信息
    train_loss = train_loss / len(train_loader)
    print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch, train_loss))

# Obtain one batch of test images
# dataiter = iter(test_loader)
# images, _ = dataiter.next()
dataiter = iter(train_loader)
images, labels = next(dataiter)
# 为测试图像添加噪点
noisy_imgs = images + noise_factor * torch.randn_like(images)
noisy_imgs = torch.clamp(noisy_imgs, 0., 1.)

# 获取示例输出
output = model(noisy_imgs)

# 准备要显示的图像
noisy_imgs = noisy_imgs.numpy()
output = output.detach().numpy()

# 绘制前十个输入图像,然后绘制重建图像
fig, axes = plt.subplots(nrows=2, ncols=10, sharex=True, sharey=True, figsize=(25, 4))

# 输入图像在顶行,重建在下行
for noisy_img, row in zip([noisy_imgs, output], axes):
    for img, ax in zip(noisy_img, row):
        ax.imshow(np.squeeze(img), cmap='gray')
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)

plt.show()
文章来源:https://blog.csdn.net/m0_71778249/article/details/135414904
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。