知名外貿(mào)網(wǎng)站建設公司/seo是什么意思 seo是什么職位
CNN的原理
從 DNN 到 CNN
(1)卷積層與匯聚
? 深度神經(jīng)網(wǎng)絡 DNN 中,相鄰層的所有神經(jīng)元之間都有連接,這叫全連接;卷積神經(jīng)網(wǎng)絡 CNN 中,新增了卷積層(Convolution)與匯聚(Pooling)。
? DNN 的全連接層對應 CNN 的卷積層,匯聚是與激活函數(shù)類似的附件;單個卷積層的結(jié)構(gòu)是:卷積層-激活函數(shù)-(匯聚),其中匯聚可省略。
(2)CNN:專攻多維數(shù)據(jù)
在深度神經(jīng)網(wǎng)絡 DNN 課程的最后一章,使用 DNN 進行了手寫數(shù)字的識別。但是,圖像至少就有二維,向全連接層輸入時,需要多維數(shù)據(jù)拉平為 1 維數(shù)據(jù),這樣一來,圖像的形狀就被忽視了,很多特征是隱藏在空間屬性里的,而卷積層可以保持輸入數(shù)據(jù)的維數(shù)不變,當輸入數(shù)據(jù)是二維圖像時,卷積層會以多維數(shù)據(jù)的形式接收輸入數(shù)據(jù),并同樣以多維數(shù)據(jù)的形式輸出至下一層
導包
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
import matplotlib.pyplot as plt
制作數(shù)據(jù)集
# 制作數(shù)據(jù)集
# 數(shù)據(jù)集轉(zhuǎn)換參數(shù)
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(0.1307, 0.3081)
])
# 下載訓練集與測試集
train_Data = datasets.MNIST(
root = 'D:/Postgraduate/CNN', # 下載路徑
train = True, # 是 train 集
download = True, # 如果該路徑?jīng)]有該數(shù)據(jù)集,就下載
transform = transform # 數(shù)據(jù)集轉(zhuǎn)換參數(shù)
)
test_Data = datasets.MNIST(
root = 'D:/Postgraduate/CNN', # 下載路徑
train = False, # 是 test 集
download = True, # 如果該路徑?jīng)]有該數(shù)據(jù)集,就下載
transform = transform # 數(shù)據(jù)集轉(zhuǎn)換參數(shù)
)
# 批次加載器
train_loader = DataLoader(train_Data, shuffle=True, batch_size=256)
test_loader = DataLoader(test_Data, shuffle=False, batch_size=256)
訓練網(wǎng)絡
class CNN(nn.Module):def __init__(self):super(CNN,self).__init__()self.net = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Tanh(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(6, 16, kernel_size=5), nn.Tanh(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(16, 120, kernel_size=5), nn.Tanh(),nn.Flatten(),nn.Linear(120, 84), nn.Tanh(),nn.Linear(84, 10)
)def forward(self, x):y = self.net(x)return y
# 創(chuàng)建子類的實例,并搬到 GPU 上
model = CNN().to('cuda:0')
# 訓練網(wǎng)絡
# 損失函數(shù)的選擇
loss_fn = nn.CrossEntropyLoss() # 自帶 softmax 激活函數(shù)
# 優(yōu)化算法的選擇
learning_rate = 0.9 # 設置學習率
optimizer = torch.optim.SGD(model.parameters(),lr = learning_rate,
)
# 訓練網(wǎng)絡
epochs = 5
losses = [] # 記錄損失函數(shù)變化的列表
for epoch in range(epochs):for (x, y) in train_loader: # 獲取小批次的 x 與 yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = model(x) # 一次前向傳播(小批量)loss = loss_fn(Pred, y) # 計算損失函數(shù)losses.append(loss.item()) # 記錄損失函數(shù)的變化optimizer.zero_grad() # 清理上一輪滯留的梯度loss.backward() # 一次反向傳播optimizer.step() # 優(yōu)化內(nèi)部參數(shù)
Fig = plt.figure()
plt.plot(range(len(losses)), losses)
plt.show()
測試網(wǎng)絡
# 測試網(wǎng)絡
correct = 0
total = 0
with torch.no_grad(): # 該局部關(guān)閉梯度計算功能for (x, y) in test_loader: # 獲取小批次的 x 與 yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = model(x) # 一次前向傳播(小批量)_, predicted = torch.max(Pred.data, dim=1)correct += torch.sum( (predicted == y) )total += y.size(0)
print(f'測試集精準度: {100*correct/total} %')
使用網(wǎng)絡
# 保存網(wǎng)絡
torch.save(model, 'CNN.path')
new_model = torch.load('CNN.path')
完整代碼
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
import matplotlib.pyplot as plt# 制作數(shù)據(jù)集
# 數(shù)據(jù)集轉(zhuǎn)換參數(shù)
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(0.1307, 0.3081)
])
# 下載訓練集與測試集
train_Data = datasets.MNIST(
root = 'D:/Postgraduate/python_project/CNN', # 下載路徑
train = True, # 是 train 集
download = True, # 如果該路徑?jīng)]有該數(shù)據(jù)集,就下載
transform = transform # 數(shù)據(jù)集轉(zhuǎn)換參數(shù)
)
test_Data = datasets.MNIST(
root = 'D:/Postgraduate/python_project/CNN', # 下載路徑
train = False, # 是 test 集
download = True, # 如果該路徑?jīng)]有該數(shù)據(jù)集,就下載
transform = transform # 數(shù)據(jù)集轉(zhuǎn)換參數(shù)
)
# 批次加載器
train_loader = DataLoader(train_Data, shuffle=True, batch_size=256)
test_loader = DataLoader(test_Data, shuffle=False, batch_size=256)class CNN(nn.Module):def __init__(self):super(CNN,self).__init__()self.net = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Tanh(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(6, 16, kernel_size=5), nn.Tanh(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(16, 120, kernel_size=5), nn.Tanh(),nn.Flatten(),nn.Linear(120, 84), nn.Tanh(),nn.Linear(84, 10)
)def forward(self, x):y = self.net(x)return y
# 創(chuàng)建子類的實例,并搬到 GPU 上
model = CNN().to('cuda:0')
# 訓練網(wǎng)絡
# 損失函數(shù)的選擇
loss_fn = nn.CrossEntropyLoss() # 自帶 softmax 激活函數(shù)
# 優(yōu)化算法的選擇
learning_rate = 0.9 # 設置學習率
optimizer = torch.optim.SGD(model.parameters(),lr = learning_rate,
)
# 訓練網(wǎng)絡
epochs = 5
losses = [] # 記錄損失函數(shù)變化的列表
for epoch in range(epochs):for (x, y) in train_loader: # 獲取小批次的 x 與 yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = model(x) # 一次前向傳播(小批量)loss = loss_fn(Pred, y) # 計算損失函數(shù)losses.append(loss.item()) # 記錄損失函數(shù)的變化optimizer.zero_grad() # 清理上一輪滯留的梯度loss.backward() # 一次反向傳播optimizer.step() # 優(yōu)化內(nèi)部參數(shù)
Fig = plt.figure()
plt.plot(range(len(losses)), losses)
plt.show()# 測試網(wǎng)絡
correct = 0
total = 0
with torch.no_grad(): # 該局部關(guān)閉梯度計算功能for (x, y) in test_loader: # 獲取小批次的 x 與 yx, y = x.to('cuda:0'), y.to('cuda:0')Pred = model(x) # 一次前向傳播(小批量)_, predicted = torch.max(Pred.data, dim=1)correct += torch.sum( (predicted == y) )total += y.size(0)
print(f'測試集精準度: {100*correct/total} %')# 保存網(wǎng)絡
torch.save(model, 'CNN.path')
new_model = torch.load('CNN.path')