问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

GAN数据增强技术详解

创作时间:
作者:
@小白创作中心

GAN数据增强技术详解

引用
CSDN
1.
https://blog.csdn.net/m0_53850135/article/details/143255210

GAN(生成对抗网络)是一种强大的数据增强技术,在深度学习领域有着广泛的应用。本文将详细介绍GAN的基本原理、相关技术和具体实现方法,帮助读者深入了解这一前沿技术的核心概念和应用场景。

GAN基本概念

生成器(Generator)

深度学习中的神经网络需要大量的数据进行学习和训练,才能使模型效果较好。当某些领域的数据集不足时,可以采用GAN来生成数据。

用什么生成想要的数据?

输入随机噪声,一组向量,满足某种分布。每一个维度对应想要生成数据的某个特征。

判别器(Discriminator)

输入为所想要的数据类型(有原始的、生成的),判别器会判别此数据为真的概率。概率越大,生成器生成的数据越真实。生成器欺骗判别器,判别器要努力分辨生成器生成的图片,会相互博弈。双方不断学习,对抗。

自编码器(Auto-encoder)

为什么随机噪声可以生成想要的数据呢?

生成器所要做的就是解码器(Decoder)的工作。

相关工作

Dropout算法

Dropout算法是一种防止神经网络过拟合的正则化技术。通过在训练过程中随机“丢弃”部分神经元,从而减小神经网络对某些特定神经元或特征的依赖,提升模型的泛化能力。

  • 在每次前向传播时,随机地忽略一部分神经元,使它们在这次迭代中不参与计算,也不会更新相应的权重。换句话说,某些神经元在这一轮迭代中被“丢弃”(设置为 0),从而使网络更加健壮,防止网络依赖某些特定的特征。
  • 对于每一个神经元,以概率p决定是否丢弃(即让该神经元的输出变为0)。
  • 丢弃的神经元在这一轮前向传播中不会传递其激活层,而它们的权重不会在反向传播中更新。
  • 没有丢弃的神经元,它们的输出保持不变,即输出值没有被乘以p。
  • 训练阶段:每个神经元有一定概率被丢弃,丢弃的神经元在这一轮中不参与计算。
  • 测试阶段:不丢弃任何神经元,但为了保持与训练阶段一致,将所有神经元的输出乘以 p,以确保输出的总期望值一致。
import torch
import torch.nn as nn
import torch.optim as optim

class SimpleNet(nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        self.fc1 = nn.Linear(784, 256)
        self.dropout = nn.Dropout(p=0.5)  # Dropout层,p为丢弃概率
        self.fc2 = nn.Linear(256, 10)
    
    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.dropout(x)  # 训练时会随机丢弃50%的神经元
        x = self.fc2(x)
        return x

# 创建模型
model = SimpleNet()

分段线性单元(如ReLU)具有良好的梯度特性,适合反向传播。

生成模型

一、受限波尔兹曼机(RBM)

RBM是一种无向图模型,主要用于特征学习、降维和生成建模等任务。属于生成模型,能够通过学习数据的分布来生成新的数据。

  • RBM的结构:特殊波尔兹曼机,两层组成。
  • 可见层:直接与输入数据相对应,例如图像的像素、用户的评分等。
  • 隐藏层:表示输入数据的特征,RBM 通过这些特征对输入进行建模。
  • 特点:
  • 无向图结构:可见层和隐藏层之间的连接是无向的。
  • 受限:同一层内的神经元(节点)之间没有连接,只有可见层和隐藏层之间有连接。这种结构使得推断和学习变得更简单。
import numpy as np

class RBM:
    def __init__(self, visible_units, hidden_units, learning_rate=0.1):
        self.visible_units = visible_units
        self.hidden_units = hidden_units
        self.learning_rate = learning_rate
        
        # 权重初始化
        self.weights = np.random.randn(visible_units, hidden_units) * 0.01
        self.visible_bias = np.zeros(visible_units)
        self.hidden_bias = np.zeros(hidden_units)
        
    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))
    
    def sample_hidden(self, visible_data):
        # 根据可见层采样隐藏层
        hidden_activation = np.dot(visible_data, self.weights) + self.hidden_bias
        hidden_prob = self.sigmoid(hidden_activation)
        return hidden_prob, (hidden_prob > np.random.rand(len(hidden_prob))).astype(np.float32)
    
    def sample_visible(self, hidden_data):
        # 根据隐藏层采样可见层
        visible_activation = np.dot(hidden_data, self.weights.T) + self.visible_bias
        visible_prob = self.sigmoid(visible_activation)
        return visible_prob, (visible_prob > np.random.rand(len(visible_prob))).astype(np.float32)
    
    def train(self, data, epochs=1000):
        for epoch in range(epochs):
            # 正向传播:从可见层到隐藏层
            hidden_prob, hidden_sample = self.sample_hidden(data)
            
            # 反向传播:从隐藏层重建可见层
            visible_prob, visible_sample = self.sample_visible(hidden_sample)
            
            # 再次从重建的可见层到隐藏层
            hidden_prob_recon, hidden_sample_recon = self.sample_hidden(visible_sample)
            
            # 更新权重和偏置
            self.weights += self.learning_rate * (np.outer(data, hidden_prob) - np.outer(visible_sample, hidden_prob_recon))
            self.visible_bias += self.learning_rate * (data - visible_sample)
            self.hidden_bias += self.learning_rate * (hidden_prob - hidden_prob_recon)
            
            if epoch % 100 == 0:
                error = np.mean((data - visible_sample) ** 2)
                print(f'Epoch: {epoch}, Reconstruction Error: {error}')
                
# 示例使用
rbm = RBM(visible_units=6, hidden_units=3, learning_rate=0.1)
# 输入数据
data = np.array([1, 1, 0, 0, 1, 0])  # 示例输入数据
rbm.train(data, epochs=1000)

因为 RBM 的能量函数比较复杂,直接计算梯度并不简单,因此使用了一种近似的方法,叫做对比散度(Contrastive Divergence, CD) 来近似计算梯度,从而进行权重更新。

二、深度信念网络(DBNs)

DBNs 是混合模型,它们结合了无向层(undirected layer)和有向层(directed layers)的特点。这使得 DBN 同时包含无向图模型(如受限玻尔兹曼机,RBM)的优点和有向图模型(如前馈神经网络)的特性。

  • 无向层:DBN 的底层是一个受限玻尔兹曼机(RBM),它是一个无向图模型,学习输入数据的概率分布。
  • 有向层:在 RBM 之上,DBN 堆叠了多个有向层,这些有向层可以是标准的神经网络(如多层感知机)。这些有向层通过对前一层学习到的特征进行进一步处理和提取。

替代的训练准则

除了最大化对数似然函数(log-likelihood)之外,还存在一些替代方法,它们用于优化生成模型,但不依赖于对数似然的近似或边界。

  • Score Matching(得分匹配):一种用于估计概率密度的准则,通过最小化模型密度函数的导数与真实数据分布导数之间的差异来进行优化。这种方法不需要计算配分函数(partition function),因此可以避免一些计算上的复杂性。
  • Noise-Contrastive Estimation (NCE)(噪声对比估计):NCE 是一种通过将生成模型转换为判别问题来进行优化的准则。NCE 不直接拟合数据的概率分布,而是将模型的任务转化为区分真实数据与噪声样本的问题。

应用到自编码器

去噪自编码器(Denoising Auto-Encoders, DAEs)和收缩自编码器(Contractive Auto-Encoders) 是两类生成模型,它们的学习规则与得分匹配(Score Matching)方法有相似之处,尤其是在受限玻尔兹曼机(RBM)的训练中。两种用于特征学习和表示学习的自编码器变体,它们通过不同的方式进行正则化,确保模型学习到更鲁棒和稳定的特征。这两种自编码器都是通过对原始的自编码器进行改进,以应对过拟合和特征学习中的挑战。

NCE和判别准则

不显式定义概率分布的生成模型:一些生成模型不会直接通过显式地定义概率分布来生成数据,而是通过训练一个生成器模型,使其能够从目标分布中生成样本。这种方法的优势在于生成器可以通过反向传播进行训练,而不必处理复杂的概率分布估计问题。这类方法在深度学习中越来越受欢迎,因为它们可以高效地训练生成模型。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号