?相關文章 + 視頻教程
《Pytorch深度學習框架實戰教程01》《視頻教程》
《Pytorch深度學習框架實戰教程02:開發環境部署》《視頻教程》
《Pytorch深度學習框架實戰教程03:Tensor 的創建、屬性、操作與轉換詳解》《視頻教程》
《Pytorch深度學習框架實戰教程04:Pytorch數據集和數據導入器》《視頻教程》
《Pytorch深度學習框架實戰教程05:Pytorch構建神經網絡模型》《視頻教程》
《Pytorch深度學習框架實戰教程06:Pytorch模型訓練和評估》《視頻教程》
《Pytorch深度學習框架實戰教程09:模型的保存和加載》《視頻教程》
《Pytorch深度學習框架實戰教程10:模型推理和測試》《視頻教程》
《Pytorch深度學習框架實戰教程-番外篇01-卷積神經網絡概念定義、工作原理和作用》
《Pytorch深度學習框架實戰教程-番外篇02-Pytorch池化層概念定義、工作原理和作用》
《Pytorch深度學習框架實戰教程-番外篇03-什么是激活函數,激活函數的作用和常用激活函數》
《PyTorch 深度學習框架實戰教程-番外篇04:卷積層詳解與實戰指南》
《Pytorch深度學習框架實戰教程-番外篇05-Pytorch全連接層概念定義、工作原理和作用》
《Pytorch深度學習框架實戰教程-番外篇06:Pytorch損失函數原理、類型和案例》
《Pytorch深度學習框架實戰教程-番外篇10-PyTorch中的nn.Linear詳解》
一、什么是池化層?
池化層(Pooling Layer)是卷積神經網絡(CNN)中與卷積層配合使用的重要組件,主要用于特征降維、減少計算量并增強模型的平移不變性。它通常緊跟在卷積層之后,對卷積層輸出的特征圖進行壓縮處理。
與卷積層不同,池化層沒有可學習的參數,其操作是確定性的(根據預設規則對局部區域進行聚合計算)。
二、池化層的工作原理
池化層的工作流程與卷積層類似,都通過滑動窗口處理特征圖,但計算方式不同:
- 滑動窗口:池化窗口(如 2×2)在特征圖上按指定步長滑動。
- 聚合計算:對窗口覆蓋的區域執行聚合操作(如取最大值、平均值等),得到一個值作為輸出特征圖的對應位置像素。
- 輸出特征圖:所有窗口的聚合結果構成尺寸更小的輸出特征圖。
三、常見池化方式圖示:
池化層的作用
- 特征降維:通過減少特征圖的空間尺寸(如 2×2 池化 + 步長 2 可將尺寸減半),降低后續層的計算量和參數數量。
- 增強平移不變性:局部微小位移不會改變池化結果(如最大值位置輕微移動不影響輸出),提高模型對輸入變化的魯棒性。
- 防止過擬合:通過信息聚合減少特征冗余,降低模型對局部細節的過度敏感。
- 擴大感受野:池化操作使高層神經元能感知到輸入圖像更大范圍的區域。
四、PyTorch 中的池化層詳解
PyTorch 的torch.nn
模塊提供了多種池化層,適用于不同場景:
池化層 | 作用 | 適用場景 |
---|---|---|
nn.MaxPool2d | 取窗口內最大值 | 保留顯著特征(如邊緣、紋理) |
nn.AvgPool2d | 取窗口內平均值 | 保留整體特征,平滑輸出 |
nn.MaxUnpool2d | 最大池化的逆操作(上采樣) | 特征圖恢復 |
nn.LPPool2d | 取窗口內 p 次冪的平均值的 p 次方根 | 靈活控制聚合強度 |
nn.AdaptiveMaxPool2d | 自適應最大池化(指定輸出尺寸) | 固定輸出尺寸,簡化網絡設計 |
nn.AdaptiveAvgPool2d | 自適應平均池化(指定輸出尺寸) | 同上 |
nn.MaxPool2d
核心參數(最常用)
python
運行
nn.MaxPool2d(kernel_size, # 池化窗口大小(int或tuple)stride=None, # 步長(默認與kernel_size相同)padding=0, # 填充大小dilation=1, # 窗口元素間隔(用于空洞池化)return_indices=False, # 是否返回最大值的索引(用于Unpool)ceil_mode=False # 是否使用向上取整計算輸出尺寸(默認向下取整)
)
輸出尺寸計算公式:
H_out = floor((H + 2×padding - dilation×(kernel_size-1) - 1) / stride + 1)
(與卷積層相同,ceil_mode=True
時用ceil
替代floor
)
五、示例程序:PyTorch 池化層實戰
以下示例展示不同池化層的效果,包括:
- 標準池化(MaxPool2d、AvgPool2d)
- 自適應池化(AdaptiveMaxPool2d)
- 池化對特征圖的影響可視化
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transforms# 1. 數據準備:加載圖片并生成特征圖(模擬卷積層輸出)
def prepare_feature_maps():# 加載圖片并轉為單通道灰度圖transform = transforms.Compose([transforms.Resize((128, 128)),transforms.Grayscale(), # 轉為單通道transforms.ToTensor()])# 使用示例圖片(實際運行時替換為你的圖片路徑)image = Image.open("example.jpg")image_tensor = transform(image).unsqueeze(0) # 形狀:[1, 1, 128, 128]# 模擬卷積層輸出:創建4個特征圖(實際中來自卷積層)# 這里通過簡單變換生成不同特征圖以展示效果feature_maps = []for i in range(4):# 對原圖進行簡單變換生成不同特征圖if i == 0:fm = image_tensor * (i+1)elif i == 1:fm = torch.roll(image_tensor, shifts=5, dims=2) # 水平偏移elif i == 2:fm = torch.roll(image_tensor, shifts=5, dims=3) # 垂直偏移else:fm = image_tensor * 0.5 + torch.roll(image_tensor, shifts=3, dims=(2,3)) * 0.5feature_maps.append(fm)# 合并為[1, 4, 128, 128](批次=1,通道=4,高=128,寬=128)return torch.cat(feature_maps, dim=1), image# 2. 定義池化層模型
class PoolingDemo(nn.Module):def __init__(self):super(PoolingDemo, self).__init__()# 2×2最大池化,步長2(默認與kernel_size相同)self.max_pool = nn.MaxPool2d(kernel_size=2, stride=2)# 3×3平均池化,步長2,填充1self.avg_pool = nn.AvgPool2d(kernel_size=3, stride=2, padding=1)# 自適應最大池化,固定輸出尺寸為(32, 32)self.adaptive_max_pool = nn.AdaptiveMaxPool2d(output_size=(32, 32))def forward(self, x):max_out = self.max_pool(x)avg_out = self.avg_pool(x)adaptive_max_out = self.adaptive_max_pool(x)return max_out, avg_out, adaptive_max_out# 3. 可視化函數
def visualize_pooling效果(original_img, input_fm, max_out, avg_out, adaptive_out):plt.figure(figsize=(16, 14))# 顯示原始圖片plt.subplot(5, 1, 1)plt.title("Original Image")plt.imshow(original_img, cmap='gray')plt.axis('off')# 顯示輸入特征圖(4個通道)plt.subplot(5, 1, 2)plt.title("Input Feature Maps (4 channels)")input_grid = np.zeros((128, 128*4))for i in range(4):fm = input_fm[0, i].detach().numpy() # 取第一個樣本的第i個通道input_grid[:, i*128:(i+1)*128] = fmplt.imshow(input_grid, cmap='gray')plt.axis('off')plt.text(-20, 64, f"Size: {input_fm.shape[2:]}", va='center', rotation=90)# 顯示最大池化結果plt.subplot(5, 1, 3)plt.title("Max Pooling (2×2, stride=2) Output")max_grid = np.zeros((64, 64*4)) # 尺寸減半為64×64for i in range(4):fm = max_out[0, i].detach().numpy()max_grid[:, i*64:(i+1)*64] = fmplt.imshow(max_grid, cmap='gray')plt.axis('off')plt.text(-20, 32, f"Size: {max_out.shape[2:]}", va='center', rotation=90)# 顯示平均池化結果plt.subplot(5, 1, 4)plt.title("Average Pooling (3×3, stride=2, padding=1) Output")avg_grid = np.zeros((64, 64*4)) # 尺寸約為64×64for i in range(4):fm = avg_out[0, i].detach().numpy()avg_grid[:, i*64:(i+1)*64] = fmplt.imshow(avg_grid, cmap='gray')plt.axis('off')plt.text(-20, 32, f"Size: {avg_out.shape[2:]}", va='center', rotation=90)# 顯示自適應池化結果plt.subplot(5, 1, 5)plt.title("Adaptive Max Pooling (output 32×32) Output")adaptive_grid = np.zeros((32, 32*4)) # 固定尺寸32×32for i in range(4):fm = adaptive_out[0, i].detach().numpy()adaptive_grid[:, i*32:(i+1)*32] = fmplt.imshow(adaptive_grid, cmap='gray')plt.axis('off')plt.text(-20, 16, f"Size: {adaptive_out.shape[2:]}", va='center', rotation=90)plt.tight_layout()plt.show()# 4. 主函數
if __name__ == "__main__":# 準備特征圖和原始圖片feature_maps, original_img = prepare_feature_maps()print(f"輸入特征圖形狀: {feature_maps.shape}") # [1, 4, 128, 128]# 初始化模型并執行池化操作model = PoolingDemo()max_pool_out, avg_pool_out, adaptive_pool_out = model(feature_maps)# 打印各池化層輸出形狀print(f"最大池化輸出形狀: {max_pool_out.shape}") # [1, 4, 64, 64]print(f"平均池化輸出形狀: {avg_pool_out.shape}") # [1, 4, 64, 64]print(f"自適應池化輸出形狀: {adaptive_pool_out.shape}") # [1, 4, 32, 32]# 可視化池化效果visualize_pooling效果(original_img=original_img,input_fm=feature_maps,max_out=max_pool_out,avg_out=avg_pool_out,adaptive_out=adaptive_pool_out)
代碼說明
-
數據準備:通過加載圖片并生成 4 個特征圖(模擬卷積層輸出),特征圖通過簡單變換(偏移、混合)模擬不同卷積核提取的特征。
-
池化層定義:
MaxPool2d(2, 2)
:2×2 窗口,步長 2,輸出尺寸為輸入的 1/2(128→64)。AvgPool2d(3, 2, 1)
:3×3 窗口,步長 2,填充 1,輸出尺寸接近輸入的 1/2。AdaptiveMaxPool2d(32, 32)
:無論輸入尺寸如何,輸出固定為 32×32,簡化網絡設計。
-
可視化結果:
- 最大池化輸出更銳利,保留局部顯著特征(如邊緣)。
- 平均池化輸出更平滑,保留整體區域信息。
- 自適應池化嚴格保證輸出尺寸,便于多層網絡拼接。
關鍵結論
- 池化層通過聚合局部特征實現降維,是 CNN 中控制計算復雜度的關鍵。
- 最大池化更適合保留銳利特征,平均池化更適合平滑特征。
- 自適應池化(
Adaptive*Pool
)通過指定輸出尺寸簡化網絡設計,在遷移學習和固定尺寸輸出場景中廣泛使用。 - 池化層通常緊跟卷積層,形成 "卷積 + 池化" 的經典組合,逐步提取高層特征。