提示:文章完成后,目录可以自动生成,如何生成可以参考右边的帮助文档
目录
- 概念学习
- 与传统神经网络相比,卷积神经网络具有优势
-
- 1.连接方式
- 2.参数共享
- 二、卷积神经网络的结构
-
- 1.卷积层
- 2.池化层
- 3.全连接层
- 三、卷积神经网络典型结构
-
- 1.AlexNet
- 2.VGG
- 3.GoogleNet
- 4.ResNet
- 四、代码练习
-
- 1.构建简单CNN对 mnist 分类数据集。
- 2.构建简单CNN对 mnist 分类数据集。
- 3.使用 VGG16 对 CIFAR10 分类
- 五、问题
-
- 1.dataloader 里面 shuffle 取不同值有什么区别?
- 2.transform 里面,取了不同的值,这有什么区别?
- 3.epoch 和 batch 的区别
- 4.1x1的卷积和 FC 有什么区别?主要作用是什么?
- 5.residual leanring 为什么能提高准确率?
- 6.代码练习二里,网络和1989年 Lecun 提出的 LeNet 有什么区别?
- 7.代码练习两里,卷积后feature map 尺寸会变小,如何应用 Residual Learning?
- 8.有什么方法可以进一步提高准确性?
概念学习
一、卷积神经网络相对传统神经网络的优势
1.连接方式
:层间神经元完全连接,每个输出神经元可获得所有输入神经元的信息,有利于信息汇总,通常放置在网络末端;连接和连接之间的独立参数大大增加了模型的参数规模
:层间神经元只在局部范围内连接,在此范围内采用全连接,超过此范围的神经元不连接;与全连接相比,连接与连接之间的独立参数减少了感觉域外的连接,有效地减少了参数的规模
2.参数共享
在局部连接中,每个神经元的参数相同,即图像中共享相同的卷积核。卷积操作实际上是提取局部信息,局部信息的一些统计特征与其他部分相同,这意味着这部分学到的特征也可以用于另一部分。所以对图像上的所有位置,都能使用同样的学习特征。 对于一个100x如果我们用一个神经元来操作100像素的图像,这个神经元的大小是100x100=如果我们单独使用10000,x虽然我们需要多次计算10卷积核,但我们只需要10个参数x10=100个,加上一个偏差b,只需要101个参数。图像大小还是1000x100。
二、卷积神经网络的结构
1.卷积层
卷积层又称特征提取层,利用卷积核提取图像中的特征。 下图中的绿色矩阵是输入矩阵,例如在计算机中用图像的像素矩阵表示输入图像 下图中的黄色矩阵是卷积核,是训练过程中训练的权重参数。矩阵中的值可以随机初始化,矩阵的大小也可以自定义。 下图中的紫色部分是输出特征层,是输入图像和卷积层后的输出结果 第一步: 第二步: 第三步: 这里的卷积操作是从左到右检查每个通道的矩阵(卷积核一般为3x3矩阵)从上到下进行相关操作(从左到右,然后从上到下,所以积累操作也会保留位置信息),就像一个小窗口,从左上角滑到右下角,滑动的步长是一个超参数,相关操作意味着相应的位置相乘,最后加上三个通道的值
2.池化层
(1)概念 它实际上是一种降采样的形式。非线性池化函数有多种形式,其中最大池化最为常见。它将输入图像分为几个矩形区域,输出每个子区域的最大值。直觉上,这种机制之所以能有效地发现一个特征,是因为它的精确位置远不如它与其他特征的相对位置重要。池化层会不断降低数据的空间大小,因此参数的数量和计算量也会下降,这也在一定程度上控制了过拟合。通常来说,CNN池化层将定期插入卷积层之间。
(2)池化层的作用 1.特征不变性:池操作是模型更关注是否有某些特征,而不是特征的具体位置。不变形包括平移不变性、旋转不变性和尺度不变性。 2.特征降维(下采样):池化相当于在空间范围内降低维度,使模型能够提取更广泛的特征。同时,减少下一层的输入尺寸,然后减少计算量和参数数。 3.在一定程度上防止过拟合,优化更方便。 4.实现非线性。 5.扩大感觉野。
(3)池化层分类 ①最大池化,选择图像区域的最大值作为区域池化后的值
②平均池化:计算图像区域的平均值作为区域池化后的值。
3.全连接层
全连接层是将每个结点与上一层的所有结点连接起来,用于整合前面提取的特征。由于其全连接的特性,一般来说,全连接层的参数全连接层的目的是将网络学到的特征映射到样本的标记空间中。全连接层将卷积输出的二维特征图转化为一维向量。这个过程具体实现如下所示
三、卷积神经网络典型结构
1.AlexNet
(1)结构 (2)参数量 主要参数存在于全连接层
2.VGG
(1)和AlexNet结构对比 (2)参数量 主要参数也存在于全连接层
3.GoogleNet
(1)结构特征 因为没有那么多全连接层,所以参数只有AlexNet的1/12 (2)原始inception随着模型层数的增加,通道数量将继续增加 (3)引入1x1卷积可减少通道数 (4)inception V3.裂变卷积和,用小卷积核代替大卷积核
4.ResNet
残差思想: 随着网络层数的加深,目标函数越来越容易陷入局部最优解。同时,随着层数的增加,梯度消失问题越来越严重,原理输出层的网络参数无法有效学习。残留网络是缓解梯度消失问题的一种非常有效的网络,大大提高了可以有效训练的网络深度。残余单元可以跳层连接的形式实现,即单元输入直接与单元输出加在一起,然后激活。
四、代码练习
1.构建简单CNN对 mnist 分类数据集。
(1)加载并使用以下数据
input_size = 28*28 # MNIST上图像尺寸为 28x28 output_size = 10 # 类别为 0 到 9 的数,因此为十类
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=True, download=True,
transform=transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))])),
batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))])),
batch_size=1000, shuffle=True)
(2)在小型全连接网络上训练
n_hidden = 8 # number of hidden units
model_fnn = FC2Layer(input_size, n_hidden, output_size)
model_fnn.to(device)
optimizer = optim.SGD(model_fnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_fnn)))
train(model_fnn)
test(model_fnn)
(3)在卷积神经网络上训练
n_features = 6 # number of feature maps
model_cnn = CNN(input_size, n_features, output_size)
model_cnn.to(device)
optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_cnn)))
train(model_cnn)
test(model_cnn)
(4)在全连接网络上打乱像素顺序训练与测试
perm = torch.randperm(784)
n_hidden = 8 # number of hidden units
model_fnn = FC2Layer(input_size, n_hidden, output_size)
model_fnn.to(device)
optimizer = optim.SGD(model_fnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_fnn)))
train_perm(model_fnn, perm)
test_perm(model_fnn, perm)
(5)在卷积神经网络上打乱像素顺序训练与测试
perm = torch.randperm(784)
n_features = 6 # number of feature maps
model_cnn = CNN(input_size, n_features, output_size)
model_cnn.to(device)
optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_cnn)))
train_perm(model_cnn, perm)
test_perm(model_cnn, perm)
从打乱像素顺序的实验结果来看,全连接网络的性能基本上没有发生变化,但是 卷积神经网络的性能明显下降。这是因为对于卷积神经网络,会利用像素的局部关系,但是打乱顺序以后,这些像素间的关系将无法得到利用。
2.构建简单的CNN对 mnist 数据集进行分类。
(1)数据集里的部分图像 (2)定义网络
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
(3)经训练后,测试整个数据集
correct = 0
total = 0
for data in testloader:
images, labels = data
images, labels = images.to(device), labels.to(device)
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (
100 * correct / total))
经测试准确率达到了64%
3.使用 VGG16 对 CIFAR10 分类
(1)定义VGG网络
class VGG(nn.Module):
def __init__(self):
super(VGG, self).__init__()
self.cfg = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M']
self.features = self._make_layers(cfg)
self.classifier = nn.Linear(2048, 10)
def forward(self, x):
out = self.features(x)
out = out.view(out.size(0), -1)
out = self.classifier(out)
return out
def _make_layers(self, cfg):
layers = []
in_channels = 3
for x in cfg:
if x == 'M':
layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
else:
layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),
nn.BatchNorm2d(x),
nn.ReLU(inplace=True)]
in_channels = x
layers += [nn.AvgPool2d(kernel_size=1, stride=1)]
return nn.Sequential(*layers)
(2)经训练后验证准确率
correct = 0
total = 0
for data in testloader:
images, labels = data
images, labels = images.to(device), labels.to(device)
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %.2f %%' % (
100 * correct / total))
可以看到使用 VGG 网络后准确率提升到了 84.92%
五、问题
1.dataloader 里面 shuffle 取不同值有什么区别
在每次迭代训练时是否将数据重置。Ture将输入数据的顺序随机打乱,能使使数据更有独立性。Flase不打乱。默认是Flase。
2.transform 里,取了不同值,这个有什么区别
transforms.ToTensor()函数的作用是将原始的PILImage格式或者numpy.array格式的数据格式化为可被pytorch快速处理的张量类型。 transforms.Normalize()是数据标准化函数,可以逐channel的对图像进行标准化(均值变为0,标准差变为1),可以加快模型的收敛。
3.epoch 和 batch 的区别
Epoch由一个或多个Batch组成,整个训练样本分成若干个Batch。epoch是指将所有训练样本进入一次模型,batch大小是在更新模型以前处理的多个样本。
4.1x1的卷积和 FC 有什么区别?主要起什么作用
数学本质上一样,都是特征图中的元素乘以权重再求和。但使用场景不同,FC多用于卷积神经网络的输出,在整个卷积神经网络中起到“分类器”的作用。而1*1卷积可以减少或增加特征图的层数,可以用在多处进行增维降维。
5.residual leanring 为什么能够提升准确率
通过支路的设计在传递时加上本身,形成了Y=F(x)+x的结构,这样一来,无论经过多少层求导,梯度始终不会小于1,解决了梯度消失的问题,因此能够增加网络深度来提高准确率。
6.代码练习二里,网络和1989年 Lecun 提出的 LeNet 有什么区别?
激活函数不同:LeNet网络使用的是sigmoid激活函数,而AlexNet使用的是ReLU函数。ReLU函数可以有效避免梯度消失的问题
7.代码练习二里,卷积以后feature map 尺寸会变小,如何应用 Residual Learning?
可以利用1x1卷积改变channel个数,从而达成一致
8.有什么方法可以进一步提升准确率?
(1)对于residual leanring,可以增加深度与节点数 (2)增加训练轮数 (3)丰富数据集中的数据 (4)优化网络结构