反卷积与人工棋盘模式

反卷积棋盘格模式

最近需要通过反卷积生成双目估计的深度图,在阅读反卷积的相关资料的时候看到了Deconvolution and Checkerboard Artifacts,对反卷积(转置卷积)和反卷积生成的棋盘模式笔记如下:

1. Deconvolution

 如下4X4的输入,卷积核为3X3,步长为1,没有padding,输出为2X2

卷积示意
输入矩阵展开为16维向量,x
输出矩阵展开为4维向量,y
卷积输出 y=Cx
C = 这里写图片描述.
在caffe中的conv操作即是如此展开进行卷积的.
deconvolution就是当输入为4维向量,y的时候,x就等于y左乘C^T.


2.棋盘模式

在最近的使用反卷积进行图片生成的工作中,如果将生成的图片放大,可以看到清晰的重复的棋盘模式.如下图
棋盘模式

Deconvolution and Checkerboard Artifacts,中对这种现象进行了分析:
卷积核的大小不能被步长整除,导致反卷积的时候同一个位置进行了多次覆盖,下图步长为2,大小为3.
这里写图片描述
为减轻这种现象可以采用,先对特征图进行resize,然后再进行反卷积,且试验中发现最邻近插值效果比双线性更好,在resize后,也别忘了对边缘使用padding进行填充,以减轻边缘的人工痕迹.
文中还提到了在对特征进行可视化的时候出现的人工棋盘痕迹,当我们在计算卷积层的梯度的时候,我们也在反向的进行反卷积,这也会造成人工棋盘痕迹.然而在实验中发现(deepdream),在不同尺度和偏置的情况下同时优化大量的特征可以消除这种梯度人工痕迹.(除了棋盘模式外,还有别的不规则的高频模式,文中认为它的一大来源是maxpooling).deepDreaming中实现了对这类高频噪音的识别和补偿.目前对于这种梯度上的人工痕迹还没有合理的认识和解释.一个可能的解释是,某些神经元的梯度是邻域内神经元的数倍,这导致整个网络太过于集中在某几个像素点上,而这几个像素上的一点扰动就会对产生巨大的影响,造成高频的人工痕迹?这个解释听起来不太令人信服.


<think>我们正在讨论反卷积(转置卷积)在时序数据中的应用以及是否会出现棋盘效应问题。棋盘效应(CheckerboardArtifacts)是反卷积操作中常见的问题,主要出现在生成的图像或特征图中出现棋盘状的伪影。这是因为在反卷积操作中,输入像素被不同的卷积核权重以不均匀的方式放大,导致输出特征图某些位置的值被过度放大或抑制。现在的问题是:时序数据(一维数据)用反卷积会出现棋盘效应吗?答案是:会,但表现形式可能不同。解释:反卷积操作的棋盘效应源于核大小(kernelsize)和步长(stride)之间的比例关系。当核大小不能被步长整除时,输出中会出现不均匀的重叠,导致周期性模式棋盘状)。在二维图像中,棋盘效应表现为明显的方格状伪影。在一维时序数据中,这种效应会表现为周期性震荡(如正弦波状的起伏)或不均匀的采样点。如何减轻一维反卷积棋盘效应?1.使用核大小能够被步长整除的配置(例如stride=2,kernel_size=4或6,这样4/2=2,6/2=3,都是整数)。2.使用上采样(插值)配合普通卷积(这可以避免棋盘效应)。3.使用PixelShuffle(子像素卷积)的一维变体(SubPixelConvolutionfor1D)。下面,我们用一维反卷积(转置卷积)的PyTorch代码来演示棋盘效应以及解决方案。注意:我们使用一维时序数据(例如音频信号、时间序列等)。我们将进行以下实验:1.创建一个全1的输入(一维),然后通过反卷积层进行上采样。2.展示当步长stride=2,核大小kernel_size=3(不能被整除)时出现的棋盘效应。3.展示当步长stride=2,核大小kernel_size=4(能被整除)时,棋盘效应消失。4.使用插值(上采样)配合普通卷积来避免棋盘效应。代码实现:</think> ### 时序数据中的反卷积棋盘效应反卷积操作在时序数据中同样会出现棋盘效应,但其表现形态和形成机制二维图像有所不同。在时序数据中使用反卷积时,棋盘效应主要表现为**周期性的信号波动**和**不均匀的信号重建**。 #### 时序数据中的棋盘效应特点1. **周期性伪影**:在重建序列中出现固定间隔的振幅波动2. **信号不连续**:重建点之间出现非自然的跃迁3. **频率混叠**:高频分量低频分量相互干扰4. **位置依赖性**:重建效果信号位置高度相关 #### Python示例:时序反卷积棋盘效应```python import numpy as np import matplotlib.pyplot as plt import torch import torch.nn as nn from torch.nn.functional import interpolate # 生成基础时序信号 def create_signal(length=20): x = np.linspace(0, 4*np.pi, length) signal = np.sin(x) + 0.5*np.sin(3*x) return torch.tensor(signal).float() # 不同配置的反卷积层 def apply_deconv(signal, kernel_size, stride): signal = signal.view(1, 1, -1) # [batch, channels, length] deconv = nn.ConvTranspose1d( in_channels=1, out_channels=1, kernel_size=kernel_size, stride=stride, padding=(kernel_size-1)//2, # 中心填充 output_padding=stride-1 # 调整输出长度 ) # 初始化固定权重以便比较 nn.init.constant_(deconv.weight, 1.0/kernel_size) nn.init.constant_(deconv.bias, 0.0) output = deconv(signal) return output.squeeze().detach().numpy() # 创建原始信号 original = create_signal(20) # 应用不同反卷积策略 k3s2 = apply_deconv(original, kernel_size=3, stride=2) # 会引发棋盘效应 k4s2 = apply_deconv(original, kernel_size=4, stride=2) # 缓解棋盘效应 k2s2 = apply_deconv(original, kernel_size=2, stride=2) # 避免棋盘效应 # 创建图表 plt.figure(figsize=(12, 8)) # 原始信号 plt.subplot(4, 1, 1) plt.stem(np.arange(len(original)), original.numpy(), use_line_collection=True) plt.title("原始时序信号") plt.grid(True, linestyle='--', alpha=0.7) # 引发棋盘效应的配置 plt.subplot(4, 1, 2) plt.stem(np.arange(len(k3s2)), k3s2, use_line_collection=True) plt.title("反卷积 (kernel_size=3, stride=2) - 明显棋盘效应") plt.grid(True, linestyle='--', alpha=0.7) # 缓解棋盘效应的配置 plt.subplot(4, 1, 3) plt.stem(np.arange(len(k4s2)), k4s2, use_line_collection=True) plt.title("反卷积 (kernel_size=4, stride=2) - 轻微棋盘效应") plt.grid(True, linestyle='--', alpha=0.7) # 避免棋盘效应的配置 plt.subplot(4, 1, 4) plt.stem(np.arange(len(k2s2)), k2s2, use_line_collection=True) plt.title("反卷积 (kernel_size=2, stride=2) - 无棋盘效应") plt.grid(True, linestyle='--', alpha=0.7) plt.tight_layout() plt.show() ``` #### 代码解析: 1. **信号生成**:创建包含多个频率分量的合成时序信号 2. **反卷积配置**: - `kernel_size=3, stride=2`:导致严重棋盘效应 - `kernel_size=4, stride=2`:轻微棋盘效应(4可被2整除) - `kernel_size=2, stride=2`:无棋盘效应(2可被2整除) 3. **棋盘效应成因**:当`kernel_size % stride != 0`时,输出位置的贡献权重不平衡,导致周期性波动 4. **可视化**:使用茎状图直观展示不同配置下的重建效果差异 #### 时序反卷积中的棋盘效应解决方案 1. **核大小步长匹配**: ```python # 确保 kernel_size 是 stride 的整数倍 deconv = nn.ConvTranspose1d(..., kernel_size=stride*2, stride=stride) ``` 2. **使用插值+卷积替代**: ```python def upsample_conv(signal, scale_factor): # 先插值上采样 upsampled = interpolate(signal, scale_factor=scale_factor, mode='linear') # 再用1x1卷积调整特征 conv = nn.Conv1d(1, 1, kernel_size=1) return conv(upsampled) ``` 3. **采用亚像素卷积**(1D版本): ```python def subpixel_conv1d(signal, scale_factor): # 原始卷积处理 conv = nn.Conv1d(1, scale_factor, kernel_size=3, padding=1) out = conv(signal) # 重排为时序序列 batch, channels, length = out.shape return out.view(batch, -1, length * scale_factor) ``` 4. **添加后处理平滑**: ```python # 高斯滤波消除高频伪影 smooth = nn.Conv1d(1, 1, kernel_size=5, padding=2, bias=False) smooth.weight = nn.Parameter(torch.tensor([[[0.1, 0.2, 0.4, 0.2, 0.1]]]).float()) output = smooth(deconv_output) ``` #### 时序反卷积使用建议 1. **简单上采样**:优先使用线性/三次样条插值 2. **特征关联上采样**: - 步长小时使用反卷积 - 步长大时使用插值+卷积组合 3. **信号重建**:采用无重叠的`kernel_size = stride` 4. **语音处理**:在Mel谱图重建中使用`kernel_size = stride * 2 - 1` 在时序数据应用中,如音频处理、传感器信号复原、金融时间序列预测等场景,合理选择反卷积参数可以显著减少棋盘效应带来的负面影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值