學(xué)習(xí)路線參考:
https://blog.51cto.com/u_15298598/3121189
https://github.com/Ailln/nlp-roadmap
https://juejin.cn/post/7113066539053482021
本節(jié)學(xué)習(xí)使用工具&閱讀文章:
https://easyai.tech/ai-definition/cnn/
https://blog.csdn.net/weixin_44912159/article/details/105345760
-
概述
卷積神經(jīng)網(wǎng)絡(luò)是神經(jīng)網(wǎng)絡(luò)的一個(gè)分支,其特色為包含卷積計(jì)算。CNN可以進(jìn)行監(jiān)督學(xué)習(xí)和非監(jiān)督學(xué)習(xí),有著較強(qiáng)的數(shù)據(jù)特征提取能力,且機(jī)器學(xué)習(xí)效果穩(wěn)定,不依賴特征工程。多用于圖像處理。
CNN中除了全連接層還存在著兩種特有的網(wǎng)絡(luò)層:卷積層、池化層。
CNN結(jié)構(gòu)
-
卷積層
用于提取輸入矩陣的特征。
卷積層的計(jì)算原理是卷積核在輸入矩陣上進(jìn)行滑動,每滑動一次,就將滑動區(qū)域的元素和自身相乘并累加,從而計(jì)算出輸出矩陣中對應(yīng)位置的元素。
卷積核是可學(xué)習(xí)的參數(shù),相當(dāng)于權(quán)重。
卷積層計(jì)算過程
假設(shè)輸入矩陣的規(guī)模為,滑動步長為
,卷積核規(guī)模為
,則卷積層的輸出矩陣尺寸為
。通?;瑒硬介L為1。
-
前向傳播
假設(shè)輸入集合為
,卷積核矩陣集合為
,卷積輸出矩陣為
,其規(guī)模為
,偏置量為
。則卷積過程可以表示為:
假設(shè)卷積層具有激活函數(shù)
,則卷積層的輸出結(jié)果為
-
池化層
用于對信息進(jìn)行抽樣,簡化輸入數(shù)據(jù)的同時(shí)保證特征不變性。
池化層的計(jì)算原理是池化核在輸入矩陣上進(jìn)行滑動,按照池化規(guī)則進(jìn)行計(jì)算。通常池化核的計(jì)算方法一般有最大值池化和平均值池化兩種。
池化層計(jì)算過程 -
Pytorch實(shí)現(xiàn)
-
數(shù)據(jù)準(zhǔn)備(使用MNIST數(shù)據(jù)集)
import torch from torch import nn from torch.utils.data import DataLoader from torchvision import datasets from torchvision.transforms import ToTensor, Lambda, Compose import matplotlib.pyplot as plt # 載入訓(xùn)練集 training_data = datasets.MNIST( root="data", train=True, download=True, transform=ToTensor() ) # 載入測試集 test_data = datasets.MNIST( root="data", train=False, download=True, transform=ToTensor() )print(training_data.train_data.size()) # [60000,28,28] plt.imshow(training_data.train_data[0].numpy()) # 展示第一張圖片 plt.show()展示第一張圖片batch_size = 128 # 創(chuàng)建數(shù)據(jù)管道 train_dataloader = DataLoader(training_data, batch_size=batch_size, shuffle=True) test_dataloader = DataLoader(test_data, batch_size=batch_size) # 檢查數(shù)據(jù)形狀 for X, y in test_dataloader: print("Shape of X [N, C, H, W]: ", X.shape, X.dtype) print("Shape of y: ", y.shape, y.dtype) break # N: 一個(gè)batch中的data實(shí)例數(shù)量 # C: 通道數(shù) # [H, W]: 圖片的高和寬 -
網(wǎng)絡(luò)搭建
class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Sequential( nn.Conv2d(1, 16, kernel_size=3, padding=1), # input:1 * 28 * 28, output:16 * 28 * 28 nn.ReLU(), nn.MaxPool2d(2) # input:16 * 28 * 28, output:16 * 14 * 14 ) self.conv2 = nn.Sequential( nn.Conv2d(16, 32, kernel_size=3, padding=1), # input:16 * 14 * 14, output:32 * 14 * 14 nn.ReLU(), nn.MaxPool2d(2) # input:32 * 14 * 14, output:32 * 7 * 7 ) self.classifier = nn.Sequential( nn.Linear(32 * 7 * 7, 10) # 將輸出分成10類 ) def forward(self, x): x = self.conv1(x) x = self.conv2(x) x = x.view(x.size(0), -1) # [batch, 32, 7, 7] → [batch, 32*7*7] out = self.classifier(x) return out model = CNN() print(model)CNN( (conv1): Sequential( (0): Conv2d(1, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) ) (conv2): Sequential( (0): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) ) (classifier): Sequential( (0): Linear(in_features=1568, out_features=10, bias=True) ) ) -
損失函數(shù)與優(yōu)化器定義
loss_fn = nn.CrossEntropyLoss() # 交叉熵 optimizer = torch.optim.Adam(model.parameters()) # Adam優(yōu)化 -
模型訓(xùn)練
# epochs: 迭代次數(shù) epochs=10 for i in range(epochs): # 每個(gè)epoch的迭代 model.train() # 訓(xùn)練模式 train_loss=0 for j, (X, y) in enumerate(train_dataloader): # 每個(gè)batch的迭代 # 前向傳播 pred = model(X) # 計(jì)算損失 loss = loss_fn(pred, y) train_loss += loss.item() # 反向傳播 optimizer.zero_grad() loss.backward() optimizer.step() # 每100個(gè)batch輸出損失值 if j % 100 == 0: loss = loss.item() print(f"epoch {i} batch {j} loss: {loss/batch_size:>7f}") # 每次迭代結(jié)束后輸出測試結(jié)果 with torch.no_grad(): model.eval() # 評估模式 test_loss=0 hit=0 for (X, y) in test_dataloader: pred = model(X) test_loss += loss_fn(pred, y).item() hit += (pred.argmax(1) == y).sum().item() print(f"epoch {i}, train loss: {train_loss/len(train_dataloader.dataset):>7f} test loss: {test_loss/len(test_dataloader.dataset):>7f} accuracy: {hit/len(test_dataloader.dataset) :>7f}")-
optimizer.zero_grad()
清空歷史梯度。
根據(jù)pytorch中的backward()函數(shù)的計(jì)算,當(dāng)網(wǎng)絡(luò)參量進(jìn)行反饋時(shí),梯度是被積累的而不是被替換掉。batch之間并不需要累積梯度,因此每個(gè)batch都要zero_grad。
-
loss.backward()
進(jìn)行反向傳播,并計(jì)算梯度。
-
optimizer.step()
優(yōu)化器對權(quán)重值進(jìn)行更新。
-
with torch.no_grad()
停止autograd模塊的工作,以起到加速和節(jié)省顯存的作用。它的作用是將該with語句包裹起來的部分停止梯度的更新。
-
-
結(jié)果
epoch 0 batch 0 loss: 0.017991 epoch 0 batch 100 loss: 0.018041 epoch 0 batch 200 loss: 0.018068 epoch 0 batch 300 loss: 0.018066 epoch 0 batch 400 loss: 0.018037 epoch 0, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 1 batch 0 loss: 0.018085 epoch 1 batch 100 loss: 0.017887 epoch 1 batch 200 loss: 0.018049 epoch 1 batch 300 loss: 0.018109 epoch 1 batch 400 loss: 0.018097 epoch 1, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 2 batch 0 loss: 0.017934 epoch 2 batch 100 loss: 0.017987 epoch 2 batch 200 loss: 0.018088 epoch 2 batch 300 loss: 0.017946 epoch 2 batch 400 loss: 0.018093 epoch 2, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 3 batch 0 loss: 0.017929 epoch 3 batch 100 loss: 0.017884 epoch 3 batch 200 loss: 0.018053 epoch 3 batch 300 loss: 0.017972 epoch 3 batch 400 loss: 0.017919 epoch 3, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 4 batch 0 loss: 0.018011 epoch 4 batch 100 loss: 0.017994 epoch 4 batch 200 loss: 0.017952 epoch 4 batch 300 loss: 0.018021 epoch 4 batch 400 loss: 0.018020 epoch 4, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 5 batch 0 loss: 0.018102 epoch 5 batch 100 loss: 0.018018 epoch 5 batch 200 loss: 0.018042 epoch 5 batch 300 loss: 0.018090 epoch 5 batch 400 loss: 0.017981 epoch 5, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 6 batch 0 loss: 0.017944 epoch 6 batch 100 loss: 0.017992 epoch 6 batch 200 loss: 0.018033 epoch 6 batch 300 loss: 0.018052 epoch 6 batch 400 loss: 0.018094 epoch 6, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 7 batch 0 loss: 0.018016 epoch 7 batch 100 loss: 0.018022 epoch 7 batch 200 loss: 0.018112 epoch 7 batch 300 loss: 0.018066 epoch 7 batch 400 loss: 0.018044 epoch 7, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 8 batch 0 loss: 0.018011 epoch 8 batch 100 loss: 0.018112 epoch 8 batch 200 loss: 0.018002 epoch 8 batch 300 loss: 0.018023 epoch 8 batch 400 loss: 0.018140 epoch 8, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000 epoch 9 batch 0 loss: 0.018014 epoch 9 batch 100 loss: 0.017930 epoch 9 batch 200 loss: 0.018003 epoch 9 batch 300 loss: 0.017927 epoch 9 batch 400 loss: 0.017920 epoch 9, train loss: 0.018034 test loss: 0.018228 accuracy: 0.099000
-



