初学卷积神经网络
·
卷积神经网络(Convolutional Neural Network, CNN)是一类专门处理具有网格结构数据(如图像)的深度学习模型。它在计算机视觉领域取得了巨大成功,广泛应用于图像分类、目标检测、图像分割等任务。下面从核心思想、基本组成、工作原理和典型架构等方面。
我认为卷积神经网络是将图片转化成特征图,通过卷积神经网络的感受野(卷积核)进行识别分类的技术。可以将卷积核想象成一个放大镜,每次我们只查看特征图上的一小块,之后缓慢平移。通过这个放大镜获得的信息将交由下一层处理。
一、卷积层
.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4,padding=2)
这是卷积层截取的部分代码,其中in_channels为收入特征图数量, out_channels为输出特征图数量, kernel_size为卷积核大小, stride为步长,padding是输入特征图扩展的纬度,是zeropadding。
二、.池化层
.pool1 = nn.MaxPool2d(3, stride=2)
这表示池化窗口为3*3,步长为2。
三、全连接层
参考第一篇和第二篇,使用nn.Linear。
四、典型 CNN 架构
1、AlexNet
import torchvision.models as models
import torch.nn as nn
alexnet = models.alexnet()
print(alexnet)
class MyAlexNet(nn.Module):
def __init__(self):
super(MyAlexNet, self).__init__()
self.relu = nn.ReLU()
self.drop = nn.Dropout(0.5)
self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4,padding=2)
self.pool1 = nn.MaxPool2d(3, stride=2)
self.conv2 = nn.Conv2d(64,192,5,1,2)
self.pool2 = nn.MaxPool2d(3, stride=2)
self.conv3 = nn.Conv2d(192,384,3,1,1)
self.conv4 = nn.Conv2d(384,256,3,1,1)
self.conv5 = nn.Conv2d(256, 256, 3, 1, 1)
self.pool3 = nn.MaxPool2d(3, stride=2)
self.adapool = nn.AdaptiveAvgPool2d(output_size=6)
self.fc1 = nn.Linear(9216,4096)
self.fc2 = nn.Linear(4096,4096)
self.fc3 = nn.Linear(4096,1000)
def forward(self,x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool1(x)
x = self.conv2(x)
x = self.relu(x)
x = self.pool2(x)
x = self.conv3(x)
x = self.relu(x)
print(x.size())
x = self.conv4(x)
x = self.relu(x)
print(x.size())
x = self.conv5(x)
x = self.relu(x)
x = self.pool3(x)
print(x.size())
x= self.adapool(x)
x = x.view(x.size()[0], -1) #view变形 展平
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
x = self.relu(x)
x = self.fc3(x)
x = self.relu(x)
return x
import torch
myalexnet = MyAlexNet()
def get_parameter_number(model):
total_num = sum(p.numel() for p in model.parameters())
trainable_num = sum(p.numel() for p in model.parameters() if p.requires_grad)
return {'Total': total_num, 'Trainable': trainable_num}
print(get_parameter_number(myalexnet))
img = torch.zeros((4,3,224,224))
out = myalexnet(img)
print(out.size())
2、VGGNet
import torchvision.models as models
import torch.nn as nn
vgg = models.vgg13()
print(vgg)
class vggLayer(nn.Module):
def __init__(self,in_cha, mid_cha, out_cha):
super(vggLayer, self).__init__()
self.relu = nn.ReLU()
self.pool = nn.MaxPool2d(2)
self.conv1 = nn.Conv2d(in_cha, mid_cha, 3, 1, 1)
self.conv2 = nn.Conv2d(mid_cha, out_cha, 3, 1, 1)
def forward(self,x):
x = self.conv1(x)
x= self.relu(x)
x = self.conv2(x)
x = self.relu(x)
x = self.pool(x)
return x
class MyVgg(nn.Module):
def __init__(self):
super(MyVgg, self).__init__()
self.layer1 = vggLayer(3, 64, 64)
self.layer2 = vggLayer(64, 128, 128)
self.layer3 = vggLayer(128, 256, 256)
self.layer4 = vggLayer(256, 512, 512)
self.layer5 = vggLayer(512, 512, 512)
self.adapool = nn.AdaptiveAvgPool2d(7)
self.relu = nn.ReLU()
self.fc1 = nn.Linear(25088, 4096)
self.fc2 = nn.Linear(4096, 4096)
self.fc3 = nn.Linear(4096, 1000)
def forward(self,x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.layer5(x)
x = self.adapool(x)
x= self.adapool(x)
x = x.view(x.size()[0], -1)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
x = self.relu(x)
x = self.fc3(x)
x = self.relu(x)
return x
import torch
myVgg = MyVgg()
img = torch.zeros((1, 3, 224,224))
out = myVgg(img)
print(out.size())
def get_parameter_number(model):
total_num = sum(p.numel() for p in model.parameters())
trainable_num = sum(p.numel() for p in model.parameters() if p.requires_grad)
return {'Total': total_num, 'Trainable': trainable_num}
print(get_parameter_number(myVgg))
print(get_parameter_number(myVgg.layer1))
print(get_parameter_number(myVgg.layer1.conv1))
print(get_parameter_number(vgg))
3、ResNet
import torch
import torch.nn as nn
import torchvision.models as models
resNet = models.resnet18()
print(resNet)
class Residual_block(nn.Module): #@save
def __init__(self, input_channels, out_channels, down_sample=False, strides=1):
super().__init__()
self.conv1 = nn.Conv2d(input_channels, out_channels,
kernel_size=3, padding=1, stride=strides)
self.conv2 = nn.Conv2d(out_channels, out_channels,
kernel_size=3, padding=1, stride= 1)
if input_channels != out_channels:
self.conv3 = nn.Conv2d(input_channels, out_channels,
kernel_size=1, stride=strides)
else:
self.conv3 = None
self.bn1 = nn.BatchNorm2d(out_channels)
self.bn2 = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU()
def forward(self, X):
out = self.relu(self.bn1(self.conv1(X)))
out= self.bn2(self.conv2(out))
if self.conv3:
X = self.conv3(X)
out += X
return self.relu(out)
class MyResNet18(nn.Module):
def __init__(self):
super(MyResNet18, self).__init__()
self.conv1 = nn.Conv2d(3, 64, 7, 2, 3)
self.bn1 = nn.BatchNorm2d(64)
self.pool1 = nn.MaxPool2d(3, stride=2, padding=1)
self.relu = nn.ReLU()
self.layer1 = nn.Sequential(
Residual_block(64, 64),
Residual_block(64, 64)
)
self.layer2 = nn.Sequential(
Residual_block(64, 128, strides=2),
Residual_block(128, 128)
)
self.layer3 = nn.Sequential(
Residual_block(128, 256, strides=2),
Residual_block(256, 256)
)
self.layer4 = nn.Sequential(
Residual_block(256, 512, strides=2),
Residual_block(512, 512)
)
self.flatten = nn.Flatten()
self.adv_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Linear(512, 1000)
def forward(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.pool1(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.adv_pool(x)
x = self.flatten(x)
x = self.fc(x)
return x
myres = MyResNet18()
def get_parameter_number(model):
total_num = sum(p.numel() for p in model.parameters())
trainable_num = sum(p.numel() for p in model.parameters() if p.requires_grad)
return {'Total': total_num, 'Trainable': trainable_num}
print(get_parameter_number(myres.layer1))
print(get_parameter_number(myres.layer1[0].conv1))
print(get_parameter_number(resNet.layer1[0].conv1))
x = torch.rand((1,3,224,224))
out = resNet(x)
out = myres(x)
更多推荐
所有评论(0)