THIS IS B3c0me

记录生活中的点点滴滴

0%

卷积神经网络

什么是卷积神经网络

卷积网络一般由卷积层、汇聚层和全连接层构成

和全连接网络对比来看,卷积层中的每个神经元都之和前一层中某个局部窗口内的神经元相连,构成一个局部连接网络

卷积层

卷积层的作用是提取一个局部区域的特征,不同的卷积核相当于不同的特征提取器

卷积网络主要应用在图像处理上,图像是二维结构,因此为了更充分地利用图像的局部信息,通常将神经元组织委员三维结构的神经层,其规格为M * N * D,分别为长、宽和深度

假设一个卷积层的结构如下:

  • 输入特征映射组(三维张量)
  • 输出特征映射组(三维张量)
  • 卷积核(四维张量)

计算过程如下:

汇聚层

也叫池化层,作用是进行特征选择,降低特征数量

常用的池化函数有两种:

  • 最大池化
  • 平均池化

构建基本的神经网络结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#定义卷积神经网络:4和8为人为指定的两个卷积层的厚度(feature map的数量)
depth = [4, 8]
class ConvNet(nn.Module):
def __init__(self):
# 该函数在创建一个ConvNet对象的时候,即调用如下语句:net=ConvNet(),就会被调用
# 首先调用父类相应的构造函数
super(ConvNet, self).__init__()

# 其次构造ConvNet需要用到的各个神经模块。
'''注意,定义组件并没有真正搭建这些组件,只是把基本建筑砖块先找好'''
self.conv1 = nn.Conv2d(1, 4, 5, padding = 2) #定义一个卷积层,输入通道为1,输出通道为4,窗口大小为5,padding为2
self.pool = nn.MaxPool2d(2, 2) #定义一个Pooling层,一个窗口为2*2的pooling运算
self.conv2 = nn.Conv2d(depth[0], depth[1], 5, padding = 2) #第二层卷积,输入通道为depth[0],
#输出通道为depth[1],窗口为5,padding为2
self.fc1 = nn.Linear(image_size // 4 * image_size // 4 * depth[1] , 512)
#一个线性连接层,输入尺寸为最后一层立方体的平铺,输出层512个节点
self.fc2 = nn.Linear(512, num_classes) #最后一层线性分类单元,输入为512,输出为要做分类的类别数

def forward(self, x):
#该函数完成神经网络真正的前向运算,我们会在这里把各个组件进行实际的拼装
#x的尺寸:(batch_size, image_channels, image_width, image_height)
x = F.relu(self.conv1(x)) #第一层卷积,激活函数用ReLu,为了防止过拟合
#x的尺寸:(batch_size, num_filters, image_width, image_height)
x = self.pool(x) #第二层pooling,将图片变小
#x的尺寸:(batch_size, depth[0], image_width/2, image_height/2)
x = F.relu(self.conv2(x)) #第三层又是卷积,窗口为5,输入输出通道分别为depth[0]=4, depth[1]=8
#x的尺寸:(batch_size, depth[1], image_width/2, image_height/2)
x = self.pool(x) #第四层pooling,将图片缩小到原大小的1/4
#x的尺寸:(batch_size, depth[1], image_width/4, image_height/4)

# 将立体的特征图Tensor,压成一个一维的向量
# view这个函数可以将一个tensor按指定的方式重新排布。
# 下面这个命令就是要让x按照batch_size * (image_size//4)^2*depth[1]的方式来排布向量
x = x.view(-1, image_size // 4 * image_size // 4 * depth[1])
#x的尺寸:(batch_size, depth[1]*image_width/4*image_height/4)

x = F.relu(self.fc1(x)) #第五层为全链接,ReLu激活函数
#x的尺寸:(batch_size, 512)

x = F.dropout(x, training=self.training) #以默认为0.5的概率对这一层进行dropout操作,为了防止过拟合
x = self.fc2(x) #全链接
#x的尺寸:(batch_size, num_classes)

x = F.log_softmax(x, dim = 0) #输出层为log_softmax,即概率对数值log(p(x))。采用log_softmax可以使得后面的交叉熵计算更快
return x

def retrieve_features(self, x):
#该函数专门用于提取卷积神经网络的特征图的功能,返回feature_map1, feature_map2为前两层卷积层的特征图
feature_map1 = F.relu(self.conv1(x)) #完成第一层卷积
x = self.pool(feature_map1) # 完成第一层pooling
feature_map2 = F.relu(self.conv2(x)) #第二层卷积,两层特征图都存储到了feature_map1, feature_map2中
return (feature_map1, feature_map2)

欢迎关注我的其它发布渠道