一、视频学习
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 数据集进行分类。同时,还会在实验中学习池化与卷积操作的基本作用。
图像形态:
在小型全连接网络上训练

在卷积神经网络上训练

momentum (float, 可选) – 动量因子取0.9时候貌似有更高准确率(95%VS97%)(不知道是否普遍适应)
**
通过上面的测试结果,可以发现,含有相同参数的 CNN 效果要明显优于简单的全连接网络,是因为 CNN 能够更好的挖掘图像中的信息,主要通过两个手段:
- 卷积:Locality and stationarity in images
- 池化:Builds in some translation invariance
打乱像素顺序再次在两个网络上训练与测试
图像形态:
在小型全连接网络上训练
在卷积神经网络上训练(这里两处momentum都调为0.9)
从打乱像素顺序的实验结果来看,全连接网络的性能基本上没有发生变化,但是卷积神经网络的性能明显下降。
这是因为对于卷积神经网络,会利用像素的局部关系,但是打乱顺序以后,这些像素间的关系将无法得到利用。
(2)CIFAR10 数据集分类
归一化CIFAR10使用torchvision,torchvision 数据集的输出是范围在[0,1]之间的 PILImage,我们将他们转换成归一化范围为[-1,1]之间的张量 Tensors。
transform = transforms.Compose([transforms.ToTensor(),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)。
定义网络,损失函数和优化器:
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# 网络放到GPU上net = Net().to(device)criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(net.parameters(), lr=0.001)
训练网络
for epoch in range(10): # 重复多轮训练for i, (inputs, labels) in enumerate(trainloader):inputs = inputs.to(device)labels = labels.to(device)# 优化器梯度归零optimizer.zero_grad()# 正向传播 + 反向传播 + 优化outputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 输出统计信息if i % 100 == 0:print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))
从测试集中取出8张图片,把图片输入模型,看看CNN把这些图片识别成什么:
有几个识别错误
在整个数据集上:
成功率在62%
猜测原因可能是训练集不够大,或者网络深度不够(注意避免过拟合)
(3)使用 VGG16 对 CIFAR10 分类
RandomCrop——随机裁剪
图像分类中,在深度学习的训练时将图片的随机剪裁(random crop)已经成为很普遍的数据扩充(data augmentation)方法,随机剪裁(缩写为:IRC)不但提高了模型精度,也增强了模型稳定性。
随机裁剪相当于建立每个因子特征与相应类别的权重关系,减弱背景(或噪音)因子的权重,且使模型面对缺失值不敏感,也就可以产生更好的学习效果,增加模型稳定性。
RandomHorizontalFlip——水平翻转(此处为了增加特征(?))
定义网络:
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(self.cfg)self.classifier = nn.Linear(512, 10)def forward(self, x):out = self.features(x)out = out.view(out.size(0), -1)out = self.classifier(out)return outdef _make_layers(self, cfg):layers = []in_channels = 3for 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 = xlayers += [nn.AvgPool2d(kernel_size=1, stride=1)]return nn.Sequential(*layers)
这里平均池化卷积核为什么设为1*1,不会无作用吗?
训练:
net = VGG().to(device)criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(net.parameters(), lr=0.001)for epoch in range(10): # 重复多轮训练for i, (inputs, labels) in enumerate(trainloader):inputs = inputs.to(device)labels = labels.to(device)# 优化器梯度归零optimizer.zero_grad()# 正向传播 + 反向传播 + 优化outputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 输出统计信息if i % 100 == 0:print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))print('Finished Training')

验证准确率:
correct = 0total = 0for data in testloader:images, labels = dataimages, 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))

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