为何要在Torch7中实现x=deepcopy(x)?及掩码处理代码解析
在Torch7中使用
deepcopy(x)的原因及代码逻辑解析 一、为啥要在Torch7里写x=deepcopy(x)?
懂Torch7的都清楚,它里面的张量(Tensor)默认是引用传递的——说白了就是你直接写y = x的话,y根本不是新的独立张量,只是个指向x内存地址的"别名",修改y的同时x也会被同步改动。而deepcopy(x)会完完整整复制一份x的所有数据、结构,新生成的变量和原变量彻底解耦,后续怎么操作都不会互相影响。
平时用到这个操作的场景挺多的:
- 需要保存模型或张量的原始状态,避免后续的训练、变换操作污染原始数据
- 碰到嵌套模型层、复杂张量结构这类递归型数据,需要完全独立的副本时
- 做梯度回传、参数更新前,先存个初始参数的快照,方便后续对比或者回滚操作
二、代码逻辑拆解
先把你输入里的代码补全(应该是输入时的小遗漏),完整代码如下:
if is_pooling then for k = 1, #color_codes do color_content_masks[k] = image.scale(color_content_masks[k], math.ceil(color_content_masks[k]:size(2)/2), math.ceil(color_content_masks[k]:size(1)/2)) color_style_masks[k] = image.scale(color_style_masks[k], math.ceil(color_style_masks[k]:size(2)/2), math.ceil(color_style_masks[k]:size(1)/2)) end elseif is_conv then local sap = nn.SpatialAveragePooling(3,3,1,1,1,1):float() for k = 1, #color_codes do color_content_masks[k] = sap:forward(color_content_masks[k]) color_style_masks[k] = sap:forward(color_style_masks[k]) end end
1. is_pooling分支:掩码下采样适配
当is_pooling为真时,这段代码是给每个颜色通道的内容掩码、风格掩码做尺寸减半的下采样:
- 循环遍历所有
color_codes对应的掩码(#color_codes代表颜色通道的总数) - 用
image.scale()缩放掩码:计算目标尺寸时用math.ceil(size/2)向上取整,哪怕原尺寸是奇数,缩放后也能得到整数维度,不会丢失像素信息 - 这一步是为了让掩码和池化操作后的特征图尺寸匹配,保证后续特征与掩码的对应关系
2. is_conv分支:掩码平滑预处理
当is_conv为真时,这段代码用空间平均池化对掩码做平滑处理:
- 先初始化一个3x3核、步长1、填充1的
SpatialAveragePooling层并转为float类型——这个配置很关键,填充1+步长1+3x3核的组合,会让处理后的掩码空间尺寸和原尺寸完全一致,不会发生形变 - 循环给每个颜色通道的掩码执行前向传播,也就是用平均池化模糊掩码的尖锐边缘
- 这种操作是为了避免掩码的硬边界在卷积时引入不必要的噪声,让后续的卷积特征提取更稳定
内容的提问来源于stack exchange,提问作者Mark Ou
相关产品推荐
相关产品推荐

