pytorch 中pad函数toch.nn.functional.pad()的使用

本文详细介绍了在图像处理中,如何使用PyTorch的padding操作给图像添加边界,通过多个实例展示了不同维度下padding的具体效果。

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

padding操作是给图像外围加像素点。
为了实际说明操作过程,这里我们使用一张实际的图片来做一下处理。
在这里插入图片描述
这张图片是大小是(256,256),使用pad来给它加上一个黑色的边框。具体代码如下:

import torch.nn,functional as F
import torch
from PIL import Image
im=Image.open("heibai.jpg",'r')

X=torch.Tensor(np.asarray(im))
print("shape:",X.shape)
dim=(10,10,10,10)
X=F.pad(X,dim,"constant",value=0)

padX=X.data.numpy()
padim=Image.fromarray(padX)
padim=padim.convert("RGB")#这里必须转为RGB不然会

padim.save("padded.jpg","jpeg")
padim.show()
print("shape:",padX.shape)

输出:

shape: torch.Size([256, 256])
shape: (276, 276)

可以看出给原图四个方向给加上10维度的0,维度变为256+10+10得到的图像如下:
在这里插入图片描述
我们在举几个简单例子:

x=np.asarray([[[1,2],[1,2]]])
X=torch.Tensor(x)
print(X.shape)
pad_dims = (
                    2, 2,
                    2, 2,
                    1, 1,

                )
X=F.pad(X,pad_dims,"constant")
print(X.shape)
print(X)

输出:

torch.Size([1, 2, 2])
torch.Size([3, 6, 6])
tensor([[[ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.]],

        [[ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  1.,  2.,  0.,  0.],
         [ 0.,  0.,  1.,  2.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.]],

        [[ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.],
         [ 0.,  0.,  0.,  0.,  0.,  0.]]])

可以知若pid_sim为(2,2,2,2,1,1)则原维度变化是2+2+2=6,1+1+1=3.也就是第一个(2,2) pad的是最后一个维度,第二个(2,2)pad是倒数第二个维度,第三个(1,1)pad是第一个维度。

再举一个四维度的,但是只pad三个维度:

x=np.asarray([[[[1,2],[1,2]]]])
X=torch.Tensor(x)#(1,2,2)
print(X.shape)
pad_dims = (
                    2, 2,
                    2, 2,
                    1, 1,

                )
X=F.pad(X,pad_dims,"constant")#(1,1,12,12)
print(X.shape)
print(X)



输出:

torch.Size([1, 1, 2, 2])
torch.Size([1, 3, 6, 6])
tensor([[[[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]],

         [[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  1.,  2.,  0.,  0.],
          [ 0.,  0.,  1.,  2.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]],

         [[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]]]])

再举一个四维度的,pad四个维度:

x=np.asarray([[[[1,2],[1,2]]]])
X=torch.Tensor(x)#(1,2,2)
print(X.shape)
pad_dims = (
                    2, 2,
                    2, 2,
                    1, 1,
                    2, 2

                )
X=F.pad(X,pad_dims,"constant")#(1,1,12,12)
print(X.shape)
print(X)

输出:

torch.Size([1, 1, 2, 2])
torch.Size([5, 3, 6, 6])
tensor([[[[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]],

         [[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]],

         [[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]]],


.........太多了


<think>好的,我现在需要回答用户关于PyTorchtorch.nn.functional模块的功能和用法的问题。首先,我应该回顾一下用户提供的引用内容,确保回答中包含这些信息。用户引用了三个不同的部分,分别关于ReLU、Sigmoid和pad函数torch.nn.functional中的使用,以及它们与torch.nn模块中对应类的区别。 接下来,我需要系统地介绍torch.nn.functional模块的整体功能。这个模块主要包含各种神经网络相关的函数,比如激活函数、卷积、池化等。用户提到的ReLU和Sigmoid都是激活函数,而pad则属于张量操作。需要指出的是,torch.nn.functional中的函数是直接调用的,不需要实例化,而torch.nn中的对应部分通常是类,需要先创建实例再使用。例如,torch.nn.ReLU是一个类,使用时需要先实例化,而torch.nn.functional.relu可以直接调用。 然后,我应该详细说明使用方法。比如,激活函数的调用方式,卷积操作需要的参数,以及如何与torch.nn模块结合使用。需要举例说明,特别是用户提供的代码示例,如torch.nn.functional.relu(input)的输出结果。此外,pad函数的具体参数,如填充的大小和模式,也需要解释清楚。 用户可能还想知道何时使用torch.nn.functional而不是torch.nn中的类。这时候需要比较两者的优缺点,比如函数式调用更适合自定义操作,而类更适合构建模块化的网络层。同时,要提到梯度计算的问题,确保用户了解这些函数在反向传播时的表现。 最后,根据用户提供的引用和问题,生成相关问题。比如,比较不同激活函数的实现方式,讨论函数式编程在构建复杂模型中的应用,或者填充操作的其他应用场景。这些问题应该帮助用户进一步探索相关知识,并巩固他们对torch.nn.functional模块的理解。 在组织回答时,要保持结构清晰,分点说明功能和用法,并适当使用示例代码和引用标记。确保所有数学表达式和公式按照系统级指令的要求,使用正确的LaTeX格式。同时,语言要简洁明了,用中文表达,避免技术术语过于晦涩,让用户容易理解。</think>### PyTorch torch.nn.functional 模块功能与使用详解 #### 一、模块功能概述 `torch.nn.functional` 是 PyTorch 的核心模块之一,提供**函数式接口**实现神经网络操作,涵盖以下功能: 1. **激活函数**:如 ReLU、Sigmoid、Tanh 2. **卷积运算**:包括 1D/2D/3D 卷积、转置卷积 3. **池化操作**:最大池化、平均池化、自适应池化 4. **正则化方法**:Dropout、BatchNorm 5. **损失函数**:交叉熵、均方误差 6. **张量操作**:填充(pad)、裁剪、插值 #### 二、核心特性与使用场景 1. **函数式编程范式**:直接调用函数,无需实例化对象 ```python import torch.nn.functional as F output = F.relu(input_tensor) # 直接调用激活函数 ``` 2. **与 torch.nn 模块对比**(以 ReLU 为例): - `torch.nn.ReLU` 是类,需实例化为网络层后使用 - `F.relu` 可直接在计算图中调用 ```python # 类方式(需继承 Module) class Net(nn.Module): def __init__(self): super().__init__() self.relu = nn.ReLU() def forward(self, x): return self.relu(x) # 函数式调用 def forward(x): return F.relu(x) ``` 3. **参数传递方式**: ```python # 卷积操作示例 conv_output = F.conv2d( input, weight, bias=None, stride=1, padding=0 # 显式传递所有参数 ) ``` #### 三、典型使用场景 1. **自定义网络层**:灵活组合基础操作 ```python def custom_layer(x, weight): x = F.pad(x, (1,1,1,1)) # 使用填充函数[^3] x = F.conv2d(x, weight) return F.leaky_relu(x, 0.1) ``` 2. **动态参数计算**:实现自适应逻辑 ```python def adaptive_dropout(x, p): current_p = calculate_based_on_input(x) return F.dropout(x, p=current_p, training=True) ``` 3. **与 nn.Module 协同使用**: ```python class CustomNet(nn.Module): def __init__(self): super().__init__() self.conv_weight = nn.Parameter(torch.randn(3,3,5,5)) def forward(self, x): x = F.conv2d(x, self.conv_weight) return F.sigmoid(x) # 使用函数式激活[^2] ``` #### 四、梯度处理机制 所有函数式操作均支持自动微分: $$ \frac{\partial L}{\partial x} = \begin{cases} 0 & \text{if } x \leq 0 \\ \frac{\partial L}{\partial y} & \text{if } x > 0 \end{cases} $$ (以 ReLU 反向传播为例) #### 五、最佳实践建议 1. **训练/推理模式切换**:对 Dropout/BatchNorm 等需手动处理 ```python if self.training: x = F.dropout(x, p=0.5) ``` 2. **内存优化**:适当使用 `torch.no_grad()` 包裹无需梯度的计算 3. **设备兼容性**:确保所有张量位于相同设备(CPU/GPU)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值