pytorch模型输入自动调整大小-pad

网络中常使用编译码与UNet网络,要求图像尺寸为2的倍数。但真实图像可能不符合输入要求,为此可利用torch自带的pad函数,在模型输入前填充大小为0的元素,输出前通过索引恢复为原始输入大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网络中经常使用编译码与UNet网络,需要图像是符合2的倍数。
由于真实图像中存在不符合输入的情况,因此在网络中使用torch自带的pad函数,在模型输入前补充大小为0的元素填充形状,输出前用索引得到原始输入一样的大小。
pad(input, pad, mode=‘constant’, value=0)

from torch import nn
import torch.nn.functional as f


class pretransition(nn.Module):
    def __init__(self, in_channel=3, out_channel=3, mid_channel=64, block_size=32):
        super().__init__()

        self.block_size = block_size
        self.con1 = nn.Sequential(
            nn.Conv2d(in_channel, mid_channel, 3, 2, 1),
            nn.Conv2d(mid_channel, mid_channel, 3, 2, 1),
            nn.Conv2d(mid_channel, mid_channel, 3, 2, 1),
        )

        self.con2 = nn.Sequential(
            nn.ConvTranspose2d(mid_channel, mid_channel, kernel_size=3, stride=2, padding=1, output_padding=1),
            nn.ConvTranspose2d(mid_channel, mid_channel, kernel_size=3, stride=2, padding=1, output_padding=1),
            nn.ConvTranspose2d(mid_channel, out_channel, kernel_size=3, stride=2, padding=1, output_padding=1),
        )

    def unpad_tensor(self, x, pad_width):
        min_height = pad_width[3]
        min_width = pad_width[1]

        if min_width == 0 and min_height == 0:
            return x
        elif min_width == 0 and min_height != 0:
            return x[:, :, 0:-min_height, :]
        elif min_width != 0 and min_height == 0:
            return x[:, :, :, 0:-min_width]
        else:
            return x[:, :, 0:-min_height, 0:-min_width]

    def pad_tensor(self, x, block_size=32):
        b, c, h, w = x.size()
        if h % 32 == 0:
            min_height = h
        else:
            min_height = (h // block_size + 1) * block_size
        if w % 32 == 0:
            min_width = w
        else:
            min_width = (w // block_size + 1) * block_size
        padding = (
            0, min_width - w,  # 前面填充1个单位,后面填充两个单位,输入的最后一个维度则增加1+2个单位,成为8
            0, min_height - h,
            0, 0,
            0, 0,
        )
        x = f.pad(x, padding)
        return x, padding

    def forward(self, x):

        x, padding = self.pad_tensor(x, block_size=self.block_size)
        x1 = self.con1(x)
        x2 = self.con2(x1)
        x2 = self.unpad_tensor(x2, padding)

        return x2


# 得到模型参数数量与计算时消耗内存大小
def get_modelsize(model, input):
    from thop import clever_format
    from thop import profile
    flops, params = profile(model, inputs=(input,))
    flops, params = clever_format([flops, params], "%.3f")
    print('Total flops:' + flops + '\t' + 'Total params:' + params)


def model_print():
    import torch
    test_net = pretransition(block_size=256)
    print(test_net)
    test_x = (torch.ones(1, 3, 253, 541))
    out = test_net(test_x)
    print('input: {}'.format(test_x.shape))

    print('output: {}'.format(out.shape))
    get_modelsize(test_net, test_x)


if __name__ == '__main__':
    model_print()

### PyTorch 中处理动态形状 在 PyTorch 中,张量的形状可以在运行时动态变化。这种灵活性使得 PyTorch 成为了研究和开发的理想工具之一。对于具有不同输入尺寸的情况,可以利用 `torch.nn` 模块中的组件来构建能够适应这些变动的网络结构。 #### 动态批大小的支持 PyTorch 的设计允许模型接受任意批量大小的数据作为输入而无需重新定义整个计算图。这意味着只要保持特征维度一致,就可以灵活调整每批次数据的数量[^1]。 ```python import torch from torch import nn class DynamicModel(nn.Module): def __init__(self): super(DynamicModel, self).__init__() self.fc = nn.Linear(784, 10) def forward(self, x): batch_size = x.size(0) # 获取当前batch size x = x.view(batch_size, -1) # 自动推断其他维度 out = self.fc(x) return out ``` #### 使用视图操作自动推理未知维度 通过调用 `.view()` 或者更推荐使用的 `.reshape()`, 可以让某些特定位置上的尺寸被设置成 `-1` ,这表示该处的具体数值由其它已知条件决定。此特性特别适用于当只有一个不确定因素存在的情况下简化代码逻辑. #### 处理可变长度序列 针对像自然语言处理这样的应用场景里经常遇到的不同样本间字符数目的差异问题,则可以通过填充(padding)、打包(packing)以及解包(unpacking)技术来进行有效管理: - **Padding**: 将较短序列补充到统一的最大长度; - **Packing/Unpacking**: 去除不必要的零填充部分,在RNN/LSTM层之前压缩实际有效的token数目;之后再恢复原始状态以便后续任务执行。 ```python # Padding example padded_sequence = nn.utils.rnn.pad_sequence([seq1, seq2], batch_first=True) # Packing & Unpacking examples packed_input = nn.utils.rnn.pack_padded_sequence(padded_sequence, lengths=[len(seq1), len(seq2)], enforce_sorted=False) output, hidden = rnn_layer(packed_input) unpacked_output, _ = nn.utils.rnn.pad_packed_sequence(output) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值