終于把卷積神經(jīng)網(wǎng)絡(luò)算法搞懂了!!!
大家好,我是小寒
今天給大家介紹一個(gè)強(qiáng)大的算法模型,卷積神經(jīng)網(wǎng)絡(luò)算法
卷積神經(jīng)網(wǎng)絡(luò)(CNN)是一種專為處理像圖像等具有網(wǎng)格拓?fù)浣Y(jié)構(gòu)的數(shù)據(jù)而設(shè)計(jì)的深度學(xué)習(xí)模型。
CNN 通過(guò)使用卷積運(yùn)算來(lái)替代傳統(tǒng)神經(jīng)網(wǎng)絡(luò)的全連接層,能夠有效減少參數(shù)數(shù)量并保留空間信息,極大地提升了圖像識(shí)別、目標(biāo)檢測(cè)等任務(wù)的效果。
圖片
卷積神經(jīng)網(wǎng)絡(luò)的基本構(gòu)成
卷積神經(jīng)網(wǎng)絡(luò)主要由卷積層、池化層和全連接層組成。
1.卷積層
卷積層是 CNN 的核心組成部分,用于從輸入數(shù)據(jù)中提取局部特征。
其主要運(yùn)算是通過(guò)多個(gè)卷積核(filter)對(duì)輸入數(shù)據(jù)進(jìn)行卷積操作,生成特征圖 (feature map)。
圖片
- 卷積核
卷積核是一個(gè)小矩陣,它在輸入數(shù)據(jù)上滑動(dòng),應(yīng)用點(diǎn)積運(yùn)算來(lái)提取特定的局部特征。
卷積核的大小和數(shù)量是可調(diào)的超參數(shù)。 - Stride(步幅)
這是卷積核在輸入數(shù)據(jù)上移動(dòng)的步長(zhǎng)。
步幅越大,特征圖的尺寸越小。
圖片
- Padding(填充)
為保持卷積后的輸出尺寸與輸入相同,通常會(huì)在輸入數(shù)據(jù)的邊緣進(jìn)行零填充。
圖片
卷積層的輸出稱為特征圖(Feature Map),通過(guò)多次卷積操作,CNN 能夠逐層提取出越來(lái)越高層次的特征信息。
2.池化層
池化層的主要作用是通過(guò)下采樣來(lái)減少數(shù)據(jù)的維度,同時(shí)保留輸入的關(guān)鍵信息。
池化層通常插入在卷積層之后,用于減少計(jì)算量和參數(shù)數(shù)量,并在某種程度上減輕過(guò)擬合的風(fēng)險(xiǎn)。
常見的池化方法有最大池化和平均池化。
- 最大池化
最大池化是最常見的池化操作。它在局部窗口中選擇最大值。
例如,使用一個(gè)2x2的窗口,每次移動(dòng)步長(zhǎng)為2,對(duì)局部區(qū)域的像素值取最大值。
最大池化的目的在于保留最顯著的特征。
圖片
- 平均池化
它計(jì)算局部窗口內(nèi)所有值的平均。平均池化會(huì)平滑特征,適合于某些應(yīng)用場(chǎng)景。
圖片
3.全連接層
在經(jīng)過(guò)若干個(gè)卷積層和池化層之后,通常會(huì)將特征圖展平成一個(gè)向量,并將其傳遞給全連接層。
全連接層與傳統(tǒng)的前饋神經(jīng)網(wǎng)絡(luò)類似,每個(gè)神經(jīng)元與上一層的所有神經(jīng)元相連。
圖片
卷積神經(jīng)網(wǎng)絡(luò)的優(yōu)勢(shì)
- 局部連接性
通過(guò)卷積操作,CNN 能夠捕捉局部的空間特征,減少參數(shù)。 - 權(quán)值共享
卷積核的權(quán)值在圖像中多個(gè)位置共享,進(jìn)一步降低了參數(shù)量。 - 自動(dòng)提取特征
通過(guò)逐層的卷積操作,CNN 可以自動(dòng)提取從低級(jí)到高級(jí)的特征,不需要手工設(shè)計(jì)特征。
示例代碼
下面是一個(gè)使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)進(jìn)行圖像分類的完整示例代碼,采用 PyTorch 框架來(lái)實(shí)現(xiàn)。
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
# 定義 CNN 模型
class CNNModel(nn.Module):
def __init__(self):
super(CNNModel, self).__init__()
# 定義第一層卷積層,輸入通道為 3(CIFAR-10 中的彩色圖像),輸出通道為 32,卷積核大小為 3x3
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
# 定義第二層卷積層
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# 定義池化層
self.pool = nn.MaxPool2d(2, 2)
# 定義全連接層,假設(shè)輸入為 64*8*8,輸出為 512
self.fc1 = nn.Linear(64 * 8 * 8, 512)
# 定義第二個(gè)全連接層,輸出為 10(CIFAR-10 有 10 個(gè)類別)
self.fc2 = nn.Linear(512, 10)
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x)))
x = self.pool(torch.relu(self.conv2(x)))
x = x.view(-1, 64 * 8 * 8)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
# 超參數(shù)
batch_size = 64
learning_rate = 0.001
num_epochs = 10
# 數(shù)據(jù)預(yù)處理
transform = transforms.Compose([
transforms.RandomHorizontalFlip(), # 隨機(jī)水平翻轉(zhuǎn)
transforms.RandomCrop(32, padding=4), # 隨機(jī)裁剪
transforms.ToTensor(), # 轉(zhuǎn)換為張量
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 歸一化
])
# 加載 CIFAR-10 數(shù)據(jù)集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False)
model = CNNModel()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
# 訓(xùn)練模型
for epoch in range(num_epochs):
running_loss = 0.0
for i, (inputs, labels) in enumerate(trainloader, 0):
inputs, labels = inputs, labels
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 100 == 99:
print(f'Epoch [{epoch + 1}/{num_epochs}], Step [{i + 1}], Loss: {running_loss / 100:.4f}')
running_loss = 0.0
print('Finished Training')
# 在測(cè)試集上評(píng)估模型
correct = 0
total = 0
with torch.no_grad():
for inputs, labels in testloader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')