卷積神經網絡(cnn):
卷積:
卷積在pytorch中有兩種方式,一種是torch.nn.Conv2d(),一種是torch.nn.functional.conv2d()。
1.輸入:
首先需要輸入一個torch.autograd.Variable()的類型
輸入參數:(batch,channel,H,W)
(1).batch是輸入的一批數據的數目
(2).通道數,一般彩色圖是3,灰度圖是1,而卷積網絡過程中的通道數比較大,會出現幾十到幾百的通道數
(3).H和w是輸入圖片的高度和寬度
如一個batch是32的圖片,每張圖片是3通道,高和寬是50和100,那么輸入的大小就是(32,3,50,100)。
2.內置參數:
torch.nn.Conv2d(
in_channels, #輸入的通道數
out_channels, #輸出的通道數(注:卷積核數,幾個卷積核就通道(輸出幾張圖片))
kernel_size, #卷積核大小
stride=1, #卷積核移動步長
padding=0, #補0的多少
dilation=1, #kernel間距
groups=1, #卷積核個數
bias=True )
3.卷積后尺寸計算:
- 輸入圖片大小 W×W
- Filter大小 F×F
- 步長 S
- padding的像素數 P
N = (W − F + 2P )/S+1
輸出圖片:N×N
池化:
1.作用:
- 降維,縮減模型大小,提高計算速度
- 降低過擬合概率,提升特征提取魯棒性
- 對平移和旋轉不敏感
一般較多使用最大池化,還有平均池化等。
torch.nn.max_pool():一般定義池化核大小(2,2)在2×2矩陣內 取最大值,一般具有縮小圖片大小作用(1/2)
2.內置參數
torch.nn.max_pool(
kernel_size, #池化核大小
stride=None, #步長
padding=0, #補0
dialtion=1,
return_indices=False,
ceil_model=False )

import torch import torch.nn as nn from torch.utils.data import TensorDataset from torch.utils.data import DataLoader class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Sequential( torch.nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, padding=1, stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=2), # 池化 2*2取最大 縮小一半 64*28*28--->64*14*14 torch.nn.ReLU() ) self.conv2 = nn.Sequential( torch.nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1, stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=2), torch.nn.ReLU() ) self.conv3 = nn.Sequential( torch.nn.Conv2d(in_channels=128, out_channels=64, kernel_size=3, padding=1, stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=2), torch.nn.ReLU() ) self.fc = torch.nn.Sequential( torch.nn.Linear(64*3*3, 120), torch.nn.ReLU(), torch.nn.Linear(120, 100), torch.nn.ReLU(), torch.nn.Linear(100, 100), torch.nn.LogSoftmax(dim=1) ) def forward(self, inputs): # 向前傳播函數 out = self.conv1(inputs) out = self.conv2(out) out = self.conv3(out) out = out.view(-1, 64*3*3) # 展開 拉成一維 輸入到全連接層 out = self.fc(out) return out net = Net() print(net) # rand()均勻分布, 數據集 假設100張 28*28 黑白照 x_train = torch.rand(size=(100, 1, 28, 28)) # x_train = torch.rand(100, 1, 28, 28) # 標簽 y = torch.tensor([0, 1]*50) # 損失函數與優化器 loss_func = torch.nn.CrossEntropyLoss() # 一般分類用此函數 optimizer = torch.optim.SGD(net.parameters(), lr=0.1) x = TensorDataset(x_train, y) xx = DataLoader(x, batch_size=100, shuffle=True) # 模型訓練 for epoch in range(100): for (x1, y1) in xx: y_pred = net(x1) loss = loss_func(y_pred, y1) print(loss.item()) optimizer.zero_grad() # 梯度清0 loss.backward() # 反向 optimizer.step()
import torch
import torch.nn as nn
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Sequential(
torch.nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, padding=1, stride=1),
torch.nn.MaxPool2d(kernel_size=2, stride=2), # 池化 2*2取最大 縮小一半 64*28*28--->64*14*14
torch.nn.ReLU()
)
self.conv2 = nn.Sequential(
torch.nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1, stride=1),
torch.nn.MaxPool2d(kernel_size=2, stride=2),
torch.nn.ReLU()
)
self.conv3 = nn.Sequential(
torch.nn.Conv2d(in_channels=128, out_channels=64, kernel_size=3, padding=1, stride=1),
torch.nn.MaxPool2d(kernel_size=2, stride=2),
torch.nn.ReLU()
)
self.fc = torch.nn.Sequential(
torch.nn.Linear(64*3*3, 120),
torch.nn.ReLU(),
torch.nn.Linear(120, 100),
torch.nn.ReLU(),
torch.nn.Linear(100, 100),
torch.nn.LogSoftmax(dim=1)
)
def forward(self, inputs): # 向前傳播函數
out = self.conv1(inputs)
out = self.conv2(out)
out = self.conv3(out)
out = out.view(-1, 64*3*3) # 展開 拉成一維 輸入到全連接層
out = self.fc(out)
return out
net = Net()
print(net)
# rand()均勻分布, 數據集 假設100張 28*28 黑白照
x_train = torch.rand(size=(100, 1, 28, 28))
# x_train = torch.rand(100, 1, 28, 28)
# 標簽
y = torch.tensor([0, 1]*50)
# 損失函數與優化器
loss_func = torch.nn.CrossEntropyLoss() # 一般分類用此函數
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)
x = TensorDataset(x_train, y)
xx = DataLoader(x, batch_size=100, shuffle=True)
# 模型訓練
for epoch in range(100):
for (x1, y1) in xx:
y_pred = net(x1)
loss = loss_func(y_pred, y1)
print(loss.item())
optimizer.zero_grad() # 梯度清0
loss.backward() # 反向
optimizer.step()