一、视频学习

1. 深度学习的数学基础

(一)机器学习中的数学基础
矩阵线性变换、线性代数:秩、机器学习:数据降维、机器学习:低秩近似
(二)机器学习三要素:模型、策略、算法
概率/函数形式的统一
策略设计:训练误差->泛化误差——机器学习目的是获得小的泛化误差(训练误差要小、训练误差与泛化误差足够接近)
策略设计:无免费午餐定理
策略设计:奥卡姆剃刀原理
欠拟合、过拟合解决方案:
欠拟合:提高模型复杂度(决策树:拓展分支;神经网络:增加训练轮数)
过拟合:降低模型复杂度(决策树:剪枝;神经网路:early stop、dropout)
损失函数
(三)频率学派&贝叶斯学派
频率学派:关注可独立重复的随机试验中单个事件发生的频率 ->统计机器学习
贝叶斯学派:关注随机事件的“可信程度” ->概率图模型
(四)Beyond深度学习
(1)因果推断:(联结主义vs贝叶斯——相关性vs因果性)
统计机器学习:寻找相关性(相关性不可靠:Yule-Simpson悖论)
因果性=相关性+被忽略的因素
(2)群体智能
验证码
五)总结
数学基础许多涉及到线性代数和概率论的知识,要好好回顾

2.卷积神经网络CNN

(一)绪论
CNN基本应用:分类、检索、检测、分割;人脸识别、表情识别、图像生成、图像风格转化、自动驾驶

深度学习三部曲:1。搭建神经网络 2。找到一个合适的损失函数 3。找到一个合适的优化函数,更新参数
传统神经网络——全连接网络处理图像的问题:参数太多->过拟合
卷积神经网络——解决方式:局部关联,参数共享
(二)基本组成结构
1、卷积:
input、kernel/filter、weights、receptive field、actibvation map/feature map、padding、depth/channel、output
特征图大小:(N + padding 2 - F) / stride + 1
2、池化
保留了主要特征的同时减少参数和计算量,防止过拟合,提高模型泛化能力
最大值池化、平均池化
3、全连接
通常全连接层在卷积神经网络尾部
(三)卷积神经网络典型结构
1、AlexNet
ReLU函数优点:解决了梯度消失的问题(在正区间)、计算速度特别快,只需要判断输入是否大于零、收敛速度远快于sigmoid
数据增强
DropOut(随机失活):训练时随机关闭部分神经元,测试时整合所有神经元
2、ZFNet
3、VGG
4、GoogleNet:V1-V2-V3降低参数量
Stem: 卷积-池化-卷积-卷积-池化
多个Inception结构堆叠
输出:没有额外的全连接层(除了最后的类别输出层)
辅助分类器:解决由于模型深度过深导致的梯度消失的问题
5、ResNet
对输入数据和中间层的数据进行归一化操作,这种方法可以保证网络在反向传播中采用随机梯度下降(SGD),从而让网络达到收敛。
残差思想:去掉相同的主体部分,从而突出微小的变化
可以被用来训练非常深的网络
(四)代码实战
(五)总结
理论要结合代码学习,才学的懂。
*各类卷积神经网络之间的关系要好好研究。

3.(扩展学习)京东专家结合 pytorch 代码讲解 ResNet

Notes:
1.如果层数足够深,CNN可以拟合任何一个函数
2.50层+/50层-的ResNet组成结构最大差异是什么?——BottleNeck
3.图像识别、目标检测、语义分割、卷积神经网络组成结构、如何训练、优化函数
总结:需要看懂ResNet代码实现,最好能自己敲代码(。。)

二、代码练习

(1)MNIST 数据集分类

构建简单的CNN对 mnist 数据集进行分类。同时,还会在实验中学习池化与卷积操作的基本作用。
图像形态:
image.png
在小型全连接网络上训练
image.pngimage.png

在卷积神经网络上训练
image.pngimage.png
momentum (float, 可选) – 动量因子取0.9时候貌似有更高准确率(95%VS97%)(不知道是否普遍适应)
**
通过上面的测试结果,可以发现,含有相同参数的 CNN 效果要明显优于简单的全连接网络,是因为 CNN 能够更好的挖掘图像中的信息,主要通过两个手段:

  • 卷积:Locality and stationarity in images
  • 池化:Builds in some translation invariance

打乱像素顺序再次在两个网络上训练与测试
图像形态:
image.png
在小型全连接网络上训练
image.png
在卷积神经网络上训练(这里两处momentum都调为0.9)
image.png
从打乱像素顺序的实验结果来看,全连接网络的性能基本上没有发生变化,但是卷积神经网络的性能明显下降。
这是因为对于卷积神经网络,会利用像素的局部关系,但是打乱顺序以后,这些像素间的关系将无法得到利用。

(2)CIFAR10 数据集分类

归一化CIFAR10使用torchvision,torchvision 数据集的输出是范围在[0,1]之间的 PILImage,我们将他们转换成归一化范围为[-1,1]之间的张量 Tensors。

  1. transform = transforms.Compose(
  2. [transforms.ToTensor(),
  3. transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

PyTorch源码中是这么写的:
input[channel] = (input[channel] - mean[channel]) / std[channel]
这样就是:((0,1)-0.5)/0.5=(-1,1)。
定义网络,损失函数和优化器:

  1. class Net(nn.Module):
  2. def __init__(self):
  3. super(Net, self).__init__()
  4. self.conv1 = nn.Conv2d(3, 6, 5)
  5. self.pool = nn.MaxPool2d(2, 2)
  6. self.conv2 = nn.Conv2d(6, 16, 5)
  7. self.fc1 = nn.Linear(16 * 5 * 5, 120)
  8. self.fc2 = nn.Linear(120, 84)
  9. self.fc3 = nn.Linear(84, 10)
  10. def forward(self, x):
  11. x = self.pool(F.relu(self.conv1(x)))
  12. x = self.pool(F.relu(self.conv2(x)))
  13. x = x.view(-1, 16 * 5 * 5)
  14. x = F.relu(self.fc1(x))
  15. x = F.relu(self.fc2(x))
  16. x = self.fc3(x)
  17. return x
  18. # 网络放到GPU上
  19. net = Net().to(device)
  20. criterion = nn.CrossEntropyLoss()
  21. optimizer = optim.Adam(net.parameters(), lr=0.001)

训练网络

  1. for epoch in range(10): # 重复多轮训练
  2. for i, (inputs, labels) in enumerate(trainloader):
  3. inputs = inputs.to(device)
  4. labels = labels.to(device)
  5. # 优化器梯度归零
  6. optimizer.zero_grad()
  7. # 正向传播 + 反向传播 + 优化
  8. outputs = net(inputs)
  9. loss = criterion(outputs, labels)
  10. loss.backward()
  11. optimizer.step()
  12. # 输出统计信息
  13. if i % 100 == 0:
  14. print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))

从测试集中取出8张图片,把图片输入模型,看看CNN把这些图片识别成什么:
image.png
有几个识别错误
在整个数据集上:
image.png
成功率在62%
猜测原因可能是训练集不够大,或者网络深度不够(注意避免过拟合)

(3)使用 VGG16 对 CIFAR10 分类

RandomCrop——随机裁剪
图像分类中,在深度学习的训练时将图片的随机剪裁(random crop)已经成为很普遍的数据扩充(data augmentation)方法,随机剪裁(缩写为:IRC)不但提高了模型精度,也增强了模型稳定性。
随机裁剪相当于建立每个因子特征与相应类别的权重关系,减弱背景(或噪音)因子的权重,且使模型面对缺失值不敏感,也就可以产生更好的学习效果,增加模型稳定性。
RandomHorizontalFlip——水平翻转(此处为了增加特征(?))
定义网络:

  1. class VGG(nn.Module):
  2. def __init__(self):
  3. super(VGG, self).__init__()
  4. self.cfg = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M']
  5. self.features = self._make_layers(self.cfg)
  6. self.classifier = nn.Linear(512, 10)
  7. def forward(self, x):
  8. out = self.features(x)
  9. out = out.view(out.size(0), -1)
  10. out = self.classifier(out)
  11. return out
  12. def _make_layers(self, cfg):
  13. layers = []
  14. in_channels = 3
  15. for x in cfg:
  16. if x == 'M':
  17. layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
  18. else:
  19. layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),
  20. nn.BatchNorm2d(x),
  21. nn.ReLU(inplace=True)]
  22. in_channels = x
  23. layers += [nn.AvgPool2d(kernel_size=1, stride=1)]
  24. return nn.Sequential(*layers)

这里平均池化卷积核为什么设为1*1,不会无作用吗?
训练:

  1. net = VGG().to(device)
  2. criterion = nn.CrossEntropyLoss()
  3. optimizer = optim.Adam(net.parameters(), lr=0.001)
  4. for epoch in range(10): # 重复多轮训练
  5. for i, (inputs, labels) in enumerate(trainloader):
  6. inputs = inputs.to(device)
  7. labels = labels.to(device)
  8. # 优化器梯度归零
  9. optimizer.zero_grad()
  10. # 正向传播 + 反向传播 + 优化
  11. outputs = net(inputs)
  12. loss = criterion(outputs, labels)
  13. loss.backward()
  14. optimizer.step()
  15. # 输出统计信息
  16. if i % 100 == 0:
  17. print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))
  18. print('Finished Training')

image.png

验证准确率:

  1. correct = 0
  2. total = 0
  3. for data in testloader:
  4. images, labels = data
  5. images, labels = images.to(device), labels.to(device)
  6. outputs = net(images)
  7. _, predicted = torch.max(outputs.data, 1)
  8. total += labels.size(0)
  9. correct += (predicted == labels).sum().item()
  10. print('Accuracy of the network on the 10000 test images: %.2f %%' % (
  11. 100 * correct / total))

image.png

三、总结

深度学习涉及到好多线代、概率、统计等数学知识,看视频的时候确实有点看不懂。光看理论是不够的,还是要结合代码才能理解网络的构造。