pytorch为噪声矩阵创造自适应的权重


为每个高斯噪声创造一个能够自适应学习的权重,然后将这个噪声叠加或者连接到神经网络的过程当中。
噪声叠加的样例代码如下:

import torch
import torch.nn as nn

# 如果gpu运算可用
if torch.cuda.is_available():
    # 在GPU中创造与矩阵匹配的高斯噪声
    @torch.no_grad()
    def create_gaussian_noise(img):
        noise = torch.cuda.FloatTensor(img.shape)
        noise = torch.randn(img.shape, out=noise)
        return noise
else:
    # 在CPU中创造与矩阵匹配的高斯噪声
    @torch.no_grad()
    def create_gaussian_noise(img):
        noise = torch.FloatTensor(img.shape)
        noise = torch.randn(img.shape, out=noise)
        return noise

# 生成器,基于上采样
class G_net(nn.Module):
    def __init__(self):
        super(G_net, self).__init__()
        self.convTran1 = nn.Sequential(
            nn.ConvTranspose2d(64, 128, kernel_size=4, stride=2, padding=0, bias=False),
            nn.LeakyReLU(0.2)
        )
        # 高斯噪声的权重
        self.gaussian_noise_weight_1 = torch.nn.Parameter(
            torch.cuda.FloatTensor(1) if torch.cuda.is_available() else torch.FloatTensor(1), requires_grad=True)
        self.gaussian_noise_weight_1.data.fill_(0.3)

        self.bn1 = nn.BatchNorm2d(128)

    def forward(self, imgs):
        # 反卷积层
        imgs = self.convTran1(imgs)
        # 此处样例为叠加噪声,实际过程中用拼接应该更合适
        imgs += self.gaussian_noise_weight_1 * create_gaussian_noise(imgs)
        # BN层
        imgs = self.bn1(imgs)
        return imgs

注:此处仅为噪声权重自适应学习的写法样例,不是实际的做法,直接将噪声叠加到原本矩阵上很容易在之后的过程中使得权重趋于0。
按照类似styleGan的做法,更合理的改动可能为:将高斯噪声设置为单通道,然后连接到原有的特征图中。

补充一下拼接单通道噪声的写法:

import torch
import torch.nn as nn

# 如果gpu运算可用
if torch.cuda.is_available():
    # 创造与矩阵匹配的单通道高斯噪声
    @torch.no_grad()
    def create_gaussian_noise(img):
        B, _, H, W = img.shape
        noise = torch.cuda.FloatTensor(B, 1, H, W)
        noise = torch.randn((B, 1, H, W), out=noise)
        return noise
else:
    @torch.no_grad()
    def create_gaussian_noise(img):
        B, _, H, W = img.shape
        noise = torch.FloatTensor(B, 1, H, W)
        noise = torch.randn((B, 1, H, W), out=noise)
        return noise

# 生成器,基于上采样
class G_net(nn.Module):
    def __init__(self):
        super(G_net, self).__init__()
        self.convTran1 = nn.Sequential(
            nn.ConvTranspose2d(64, 128, kernel_size=4, stride=2, padding=0, bias=False),
            nn.LeakyReLU(0.2)
        )
        # 高斯噪声的权重
        self.gaussian_noise_weight_1 = torch.nn.Parameter(
            torch.cuda.FloatTensor(1) if torch.cuda.is_available() else torch.FloatTensor(1), requires_grad=True)
        self.gaussian_noise_weight_1.data.fill_(0.3)

        self.bn1 = nn.BatchNorm2d(128)

    def forward(self, imgs):
        # 反卷积层
        imgs = self.convTran1(imgs)
        # 拼接噪声
        imgs = torch.cat((imgs, self.gaussian_noise_weight_1 * create_gaussian_noise(imgs)), 1)
        # BN层
        imgs = self.bn1(imgs)
        return imgs

注:这种写法的训练显存占用会大幅度增加!

实际训练中噪声、激活函数和BN层的先后顺序视具体情况调整。

更多推荐