文章目录
- 普通方法
- 完整代码:
普通方法
使用神经网络: (CIFAR10的神经网络)
可以看到输入数据是 3通道3232的图片。
经过55的卷积核得到323232的数据。
在定义卷积层的时候,看一下padding是多少。
可以在官网查到公式:
显然 H为32,dilation默认为1,kernel_size= 5,
所以这个公式只有 stride和padding不知道了。
可以假设stride为1,则此时padding为2,
如果假设stride为2,则padding就是10+了 显然不合理。
所以此时算出来了stride为1,padding为2。参数默认stride为
1,不用设置。
则此时卷积层设置: self.conv1 = Conv2d(3, 32, 5, padding=2)
紧接着就是最大池化层的设置:self.maxpool1 = MaxPool2d(2)
以此类推将上面整个卷积和池化网络都定义出来,别忘了最后还有两层线性层。
.conv1 = Conv2d(3, 32, 5, padding=2)
self.maxpool1 = MaxPool2d(2)
self.conv2 = Conv2d(32,32,5,padding=2)
self.maxpool2 = MaxPool2d(2)
self.conv3 = Conv2d(32,64,5,padding=2)
self.maxpool3 = MaxPool2d(2)
# 线性层
self.flatten = Flatten() # 将数据展成一维的
self.linear1 = Linear(1024,64) # 这里为啥是1024 后面解释
self.linear2 = Linear(64,10)
然后直接在foreword里让数据逐一经过这些层。
def forward(self,x):
x = self.conv1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
x = self.linear1(x)
x = self.linear2(x)
return
加入数据验证网络的正确性:
text = Text()
inputs = torch.ones((64, 3, 32, 32))
output = text(inputs)
print(output.shape)
可以看到输出了 torch.Size([64, 10])
在上面经过卷积和池化之后,最后的线性层需要知道输入的数据维度,所以可以在写线性层之前看一下数据的维度,torch.Size([64, 64, 4, 4])
。把他展平之后显然是 【64,6444】
所以知道进入线性层的维度是 【64*1024】。
用 flatten() 函数可以直接得到 torch.Size([64, 1024])
。
完整代码:
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
class Text(nn.Module):
def __init__(self):
super(Text, self).__init__()
self.conv1 = Conv2d(3, 32, 5, padding=2)
self.maxpool1 = MaxPool2d(2)
self.conv2 = Conv2d(32, 32, 5, padding=2)
self.maxpool2 = MaxPool2d(2)
self.conv3 = Conv2d(32, 64, 5, padding=2)
self.maxpool3 = MaxPool2d(2)
# 线性层
self.flatten = Flatten() # 将数据展成一维的
self.linear1 = Linear(1024, 64)
self.linear2 = Linear(64, 10)
def forward(self, x):
x = self.conv1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
x = self.flatten(x)
x = self.linear1(x)
x = self.linear2(x)
return x
text = Text()
inputs = torch.ones((64, 3, 32, 32))
output = text(inputs)
print(output.shape)
sequential 方法
经过sequential改写之后的代码,就是简化了上面逐层写的步骤,一看就懂.
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
class Text(nn.Module):
def __init__(self):
super(Text, self).__init__()
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
# 线性层
Flatten(), # 将数据展成一维的
Linear(1024, 64),
Linear(64, 10),
)
def forward(self, x):
x = self.model1
return x
text = Text()
inputs = torch.ones((64, 3, 32, 32))
output = text(inputs)
print(output.shape)
使用tansorboard可视化卷积层中的各种数据
加入三行代码可视化上面的各种层。
write = SummaryWriter('logs')
write.add_graph(text,inputs)
write.close()
像这样:
这里面每一个都是可以打开的,双击图标就可以放大,比如我双击一下Text。
再双击我们建立的model:
可以看到这里就有我们建立的各种层了。
可以继续双击放大:
能看到里面的各种数据。比如右边灰色通道里面的输入输出数据维度等,这就为后期进行调试模型带来了极大的方便。