pytorch中建構CNN網絡
之前的章節中,安裝pytorch官網的教程,已經實作了LetNet-5網絡的建構以及可視化。本文将繼續探索建構CNN網絡的方式。将列舉4種方式。
torch.nn.Module 類
torch.nn.Module類是所有神經網絡的基類。是以建構一個神經網絡,需要繼承于torch.nn.Module。
- 神經網絡建構的基本格式
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
- torch.nn.Module類的主要方法
方法一:
add_module( name, module)
功能: 給目前的module添加一個字module
參數:
name
-------子module的名稱
module
-------子module
方法二:
applay(fn)
功能: 對所有子module使用fn
fn(sub_module)
方法三:
forward(*input)
功能: 神經網絡的前向計算。所有子類必須實作該方法。
方法四:
parameters()
功能:傳回moudle parameters的疊代器。
torch.nn.Sequential類
torch.nn.Sequential是一個順序容器container。根據傳入的構造方法依次添加module。也可以直接傳入一個有序字典OrderedDict。
# Example of using Sequential
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# Example of using Sequential with OrderedDict
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
實驗/建構神經網絡的不同方式
方法一
- 簡單方式
class Net1(nn.Module):
def __init__(self):
super(Net1, self).__init__()
self.conv1 = nn.Conv2d(in_channels=3,
out_channels=32,
kernel_size=3,
stride=1,
padding=1)
# why 32*32*3
self.fc1 = nn.Linear(in_features=32 * 3 * 3,
out_features=128)
self.fc2 = nn.Linear(in_features=128,
out_features=10)
def forward(self, x):
x = F.max_pool2d(F.relu(self.conv1(x)), 2)
x = x.view(x.size(0), -1)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
print("CNN model_1:")
model_1 = Net1()
print(model_1)
方法二
- 使用torch.nn.Sequential
class Net2(nn.Module):
def __init__(self):
super(Net2, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(in_channels=3,
out_channels=32,
kernel_size=3,
stride=1,
padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
)
self.fc = nn.Sequential(
nn.Linear(in_features=32 * 3 * 3,
out_features=128),
nn.ReLU(),
nn.Linear(in_features=128,
out_features=10)
)
def forward(self, x):
conv_out = self.conv(x)
res = conv_out.view(conv_out.size(0), -1)
out = self.fc(res)
return out
print('CNN model_2:')
print(Net2())
方法三
-
使用torch.nn.Sequential, 傳入有序字典
特點: 可以指定每一層的名稱
'''
使用字典OrderedDict形式
'''
class Net4(nn.Module):
def __init__(self):
super(Net4, self).__init__()
self.conv = nn.Sequential(
OrderedDict(
[
('conv1', nn.Conv2d(in_channels=3,
out_channels=32,
kernel_size=3,
stride=1,
padding=1)),
('relu1', nn.ReLU()),
('pool1', nn.MaxPool2d(kernel_size=2))
]
)
)
self.fc = nn.Sequential(
OrderedDict(
[
('fc1', nn.Linear(in_features=32 * 3 * 3,
out_features=128)),
('relu2', nn.ReLU()),
('fc2', nn.Linear(in_features=128,
out_features=10))
]
)
)
def forward(self, x):
conv_out = self.conv(x)
res = conv_out.view(conv_out.size(0), -1)
out = self.fc(res)
return out
print('CNN model_4:')
print(Net4())
方法四
- 使用add_module方法
add_module
是添加一個子module
采用此方式也可以指定每一層的名稱
'''
通過 add_module()添加
'''
class Net3(nn.Module):
def __init__(self):
super(Net3, self).__init__()
self.conv = nn.Sequential()
self.conv.add_module(name='conv1',
module=nn.Conv2d(in_channels=3,
out_channels=32,
kernel_size=1,
stride=1))
self.conv.add_module(name='relu1', module=nn.ReLU())
self.conv.add_module(name='pool1', module=nn.MaxPool2d(kernel_size=2))
self.fc = nn.Sequential()
self.fc.add_module('fc1', module=nn.Linear(in_features=32 * 3 * 3,
out_features=128))
self.fc.add_module('relu2', module=nn.ReLU())
self.fc.add_module('fc2', module=nn.Linear(in_features=128,
out_features=10))
def forward(self, x):
conv_out = self.conv(x)
res = conv_out.view(conv_out.size(0), -1)
out = self.fc(x)
return out
print('CNN model_3:')
print(Net3())
測試網絡
傳入一個
Tensor
大小: 1x3x6x6
x = torch.randn(1, 3, 6, 6)
model = Net4()
out = model(x)
print(out)
輸出結果:
該測試樣本的輸出:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnLxMWYlRWZlRjNidDMwgTZiFGOhRjYwADZhJDZ1AzYzE2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
添加連結描述