PyTorch 卷積神經(jīng)網(wǎng)絡(luò)
PyTorch 卷積神經(jīng)網(wǎng)絡(luò) (Convolutional Neural Networks, CNN) 是一類專門用于處理具有網(wǎng)格狀拓?fù)浣Y(jié)構(gòu)數(shù)據(jù)(如圖像)的深度學(xué)習(xí)模型。
CNN 是計(jì)算機(jī)視覺任務(wù)(如圖像分類、目標(biāo)檢測(cè)和分割)的核心技術(shù)。
1、輸入層(Input Layer)
接收原始圖像數(shù)據(jù),圖像通常被表示為一個(gè)三維數(shù)組,其中兩個(gè)維度代表圖像的寬度和高度,第三個(gè)維度代表顏色通道(例如,RGB圖像有三個(gè)通道)。
2、卷積層(Convolutional Layer)
用卷積核提取局部特征,如邊緣、紋理等。
公式:

- x:輸入圖像。
- k:卷積核(權(quán)重矩陣)。
- b:偏置。
應(yīng)用一組可學(xué)習(xí)的濾波器(或卷積核)在輸入圖像上進(jìn)行卷積操作,以提取局部特征。
每個(gè)濾波器在輸入圖像上滑動(dòng),生成一個(gè)特征圖(Feature Map),表示濾波器在不同位置的激活。
卷積層可以有多個(gè)濾波器,每個(gè)濾波器生成一個(gè)特征圖,所有特征圖組成一個(gè)特征圖集合。
3、激活函數(shù)(Activation Function)
通常在卷積層之后應(yīng)用非線性激活函數(shù),如 ReLU(Rectified Linear Unit),以引入非線性特性,使網(wǎng)絡(luò)能夠?qū)W習(xí)更復(fù)雜的模式。
ReLU 函數(shù)定義為 :f(x)=max(0,x),即如果輸入小于 0 則輸出 0,否則輸出輸入值。
4、池化層(Pooling Layer)
- 用于降低特征圖的空間維度,減少計(jì)算量和參數(shù)數(shù)量,同時(shí)保留最重要的特征信息。
- 最常見的池化操作是最大池化(Max Pooling)和平均池化(Average Pooling)。
- 最大池化選擇區(qū)域內(nèi)的最大值,而平均池化計(jì)算區(qū)域內(nèi)的平均值。
5、歸一化層(Normalization Layer,可選)
- 例如,局部響應(yīng)歸一化(Local Response Normalization, LRN)或批歸一化(Batch Normalization)。
- 這些層有助于加速訓(xùn)練過程,提高模型的穩(wěn)定性。
6、全連接層(Fully Connected Layer)
- 在 CNN 的末端,將前面層提取的特征圖展平(Flatten)成一維向量,然后輸入到全連接層。
- 全連接層的每個(gè)神經(jīng)元都與前一層的所有神經(jīng)元相連,用于綜合特征并進(jìn)行最終的分類或回歸。
7、輸出層(Output Layer)
根據(jù)任務(wù)的不同,輸出層可以有不同的形式。
對(duì)于分類任務(wù),通常使用 Softmax 函數(shù)將輸出轉(zhuǎn)換為概率分布,表示輸入屬于各個(gè)類別的概率。
8、損失函數(shù)(Loss Function)
用于衡量模型預(yù)測(cè)與真實(shí)標(biāo)簽之間的差異。
常見的損失函數(shù)包括交叉熵?fù)p失(Cross-Entropy Loss)用于多分類任務(wù),均方誤差(Mean Squared Error, MSE)用于回歸任務(wù)。
9、優(yōu)化器(Optimizer)
用于根據(jù)損失函數(shù)的梯度更新網(wǎng)絡(luò)的權(quán)重。常見的優(yōu)化器包括隨機(jī)梯度下降(SGD)、Adam、RMSprop等。
10、正則化(Regularization,可選)
包括 Dropout、L1/L2 正則化等技術(shù),用于防止模型過擬合。
這些層可以堆疊形成更深的網(wǎng)絡(luò)結(jié)構(gòu),以提高模型的學(xué)習(xí)能力。
CNN 的深度和復(fù)雜性可以根據(jù)任務(wù)的需求進(jìn)行調(diào)整。
import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms import matplotlib.pyplot as plt # 1. 數(shù)據(jù)加載與預(yù)處理 transform = transforms.Compose([ transforms.ToTensor(), # 轉(zhuǎn)為張量 transforms.Normalize((0.5,), (0.5,)) # 歸一化到 [-1, 1] ]) # 加載 MNIST 數(shù)據(jù)集 train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True) test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True) train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=64, shuffle=False) # 2. 定義 CNN 模型 class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() # 定義卷積層 self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1) # 輸入1通道,輸出32通道 self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) # 輸入32通道,輸出64通道 # 定義全連接層 self.fc1 = nn.Linear(64 * 7 * 7, 128) # 展平后輸入到全連接層 self.fc2 = nn.Linear(128, 10) # 10 個(gè)類別 def forward(self, x): x = F.relu(self.conv1(x)) # 第一層卷積 + ReLU x = F.max_pool2d(x, 2) # 最大池化 x = F.relu(self.conv2(x)) # 第二層卷積 + ReLU x = F.max_pool2d(x, 2) # 最大池化 x = x.view(-1, 64 * 7 * 7) # 展平 x = F.relu(self.fc1(x)) # 全連接層 + ReLU x = self.fc2(x) # 最后一層輸出 return x # 創(chuàng)建模型實(shí)例 model = SimpleCNN() # 3. 定義損失函數(shù)與優(yōu)化器 criterion = nn.CrossEntropyLoss() # 多分類交叉熵?fù)p失 optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9) # 4. 模型訓(xùn)練 num_epochs = 5 model.train() # 設(shè)置模型為訓(xùn)練模式 for epoch in range(num_epochs): total_loss = 0 for images, labels in train_loader: outputs = model(images) # 前向傳播 loss = criterion(outputs, labels) # 計(jì)算損失 optimizer.zero_grad() # 清空梯度 loss.backward() # 反向傳播 optimizer.step() # 更新參數(shù) total_loss += loss.item() print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss / len(train_loader):.4f}") # 5. 模型測(cè)試 model.eval() # 設(shè)置模型為評(píng)估模式 correct = 0 total = 0 with torch.no_grad(): # 關(guān)閉梯度計(jì)算 for images, labels in test_loader: outputs = model(images) _, predicted = torch.max(outputs, 1) total += labels.size(0) correct += (predicted == labels).sum().item() accuracy = 100 * correct / total print(f"Test Accuracy: {accuracy:.2f}%") # 6. 可視化測(cè)試結(jié)果 dataiter = iter(test_loader) images, labels = next(dataiter) outputs = model(images) _, predictions = torch.max(outputs, 1) fig, axes = plt.subplots(1, 6, figsize=(12, 4)) for i in range(6): axes[i].imshow(images[i][0], cmap='gray') axes[i].set_title(f"Label: {labels[i]}\nPred: {predictions[i]}") axes[i].axis('off') plt.show()


浙公網(wǎng)安備 33010602011771號(hào)