卷积层
1、class torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
一维卷积层,输入的尺度是(N, C_in,L_in),输出尺度( N,C_out,L_out)的计算方式:
N为批次,C_in即为in_channels,即一批内输入一维数据个数,L_in是是一维数据基数
shape:
输入: (N,C_in,L_in)
输出: (N,C_out,L_out)
输入输出的计算方式:
更好理解in out_channel,stride,kernal_size之间的关系
2、class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
二维卷积层, 输入的尺度是(N, C_in,H,W),输出尺度(N,C_out,H_out,W_out)的计算方式:
shape:
input: (N,C_in,H_in,W_in)
output: (N,C_out,H_out,W_out)
理解pytorch的padding策略
再去理解参数之间的关系
池化层
1、class torch.nn.MaxPool1d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
对于输入信号的输入通道,提供1维最大池化(max pooling)操作
如果输入的大小是(N,C,L),那么输出的大小是(N,C,L_out)的计算方式是:
参数:
- kernel_size(int or tuple) - max pooling的窗口大小
- stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
- padding(int or tuple, optional) - 输入的每一条边补充0的层数
- dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
- return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
- ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
shape:
输入: (N,C_in,L_in)
输出: (N,C_out,L_out)
2、class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
对于输入信号的输入通道,提供2维最大池化(max pooling)操作
如果输入的大小是(N,C,H,W),那么输出的大小是(N,C,H_out,W_out)和池化窗口大小(kH,kW)的关系是:
参数:
kernel_size(int or tuple) - max pooling的窗口大小
stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
padding(int or tuple, optional) - 输入的每一条边补充0的层数
dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
shape:
输入: (N,C,H_{in},W_in)
输出: (N,C,H_out,W_out)
nn与nn.functional有什么区别
需要维持状态的时候,用nn下的conv
不需要维持状态的时候,用nn.function下的conv
共享一部分参数的时候,适合用nn.function,具体见下文
PyTorch 中,nn 与 nn.functional 有什么区别
接下来讲讲shape在network中的存在
Define the neural network that has some learnable parameters (or weights)
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 1 input image channel, 6 output channels, 3x3 square convolution
# kernel
self.conv1 = nn.Conv2d(1, 6, 3)
self.conv2 = nn.Conv2d(6, 16, 3)
# an affine operation: y = Wx + b
self.fc1 = nn.Linear(16 * 6 * 6, 120) # 6*6 from image dimension
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # all dimensions except the batch dimension
num_features = 1
for s in size:
num_features *= s
return num_features
上面是一个典型的网络架构例子,从这个例子中可以看出,在定义conv的时候,只输入了channel的参数,不存在每个tensor shape的描述,shape的变化对网络并没有影响。
代码
import torch
import torch.nn as nn
m=nn.Conv2d(16,33,3,stride=2)
input=torch.randn(20,16,10,10)
output=m(input)
#H=(10-3)/2+1=4
#W=(10-3)/2+1=4
print(output.shape)
输出
torch.Size([20, 33, 4, 4])