我们在看一些关于深度学习的教材或者视频时,作者(讲解者)总是喜欢使用MNIST数据集进行讲解,不仅是因为MNIST数据集小,还因为MNSIT数据集图片是单色的。在讲解时很的容易达到深度学习的效果。
但是学习不能只止于此,接下来我们就使用彩色图片去训练一个模型。
最初我在设置网络结构去训练时,准确率才40%的样子,同时不能够收敛。后来结合着一些论文对神经网络有了一定的了解,接着就开始对网络进行优化,使得准确率逐渐的到了60%、70%、80%、90%……(最终训练准确率为99%,测试准确率为85%)

  1. 数据集介绍:

    我相信接触过深度学习的小伙伴对这个数据集一定不陌生吧,这个就是CIFAR-10CIFAR-10数据集由 ‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’ 组成的共10类32x32的彩色图片,一共包含60000张图片,每一类包含6000图片。其中50000张图片作为训练集,10000张图片作为测试集。
    下面就开始我们的训练:(说明:训练框架是pytorch

  2. 第一步:加载数据集
    如何加载呢:
    1 . 导入必要的第三方库

    import torch
    from torch import nn
    import torch.optim as optim
    import torch.nn.functional as F
    from torch.autograd import Variable
    import matplotlib.pyplot as plt
    from torchvision import transforms,datasets
    from torch.utils.data import DataLoader
    
    1. 下载数据集 (pytorch或者tensorflow都是预留了下载数据集的接口的,所以不需要我们再另外去下载)
    def plot_curve(data):   fig = plt.figure()plt.plot(range(len(data)), data, color='blue')plt.legend(['value'], loc='upper right')plt.xlabel('step')plt.ylabel('value')plt.show()
    transTrain=transforms.Compose([transforms.RandomHorizontalFlip(),  transforms.RandomGrayscale(),transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
    transTest=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
    

    上述的代码中transforms是对数据进行预处理
    plot_curve函数是对后面的loss和acc进行简单的可视化处理

    # 这行代码是对数据进行加强
    transforms.RandomHorizontalFlip()
    transforms.RandomGrayscale()
    

    3.定义网络结构
    首先我们使用Lenet-5网络结构

    class Lenet5(nn.Module):def __init__(self):super(Lenet5, self).__init__()self.conv_unit = nn.Sequential(nn.Conv2d(3, 16, kernel_size=5, stride=1, padding=0),nn.MaxPool2d(kernel_size=2, stride=2, padding=0),nn.Conv2d(16, 32, kernel_size=5, stride=1, padding=0),nn.MaxPool2d(kernel_size=2, stride=2, padding=0),)self.fc_unit = nn.Sequential(nn.Linear(32*5*5, 32),nn.ReLU(),nn.Linear(32, 10))tmp = torch.randn(2, 3, 32, 32)out = self.conv_unit(tmp)print('conv out:', out.shape)def forward(self, x):batchsz = x.size(0)x = self.conv_unit(x)x = x.view(batchsz, 32*5*5)logits = self.fc_unit(x)return logits
    

    在 PyTorch 中可以通过继承 nn.Module 来自定义神经网络,在 init() 中设定结构,在 forward() 中设定前向传播的流程。 因为 PyTorch 可以自动计算梯度,所以不需要特别定义 backward 反向传播。

  3. 定义 Loss 函数和优化器
    Loss使用CrossEntropyLoss (交叉熵损失函数)
    优化器使用Adam,当然使用SGD也可以

    loss = nn.CrossEntropyLoss()
    #optimizer = optim.SGD(self.parameters(),lr=0.01)
    optimizer = optim.Adam(self.parameters(), lr=0.0001)
    
  4. 训练

    for epoch in range(100):for i, (x, label) in enumerate(train_data_load):x, label = x.to(device), label.to(device)logits = net(x)loss = name(logits, label)optimizer.zero_grad()loss.backward()optimizer.step()trans_loss.append(loss.item())net.eval()with torch.no_grad():# testtotal_correct = 0total_num = 0for x, label in test_data_load:# [b, 3, 32, 32]# [b]x, label = x.to(device), label.to(device)# [b, 10]logits = net(x)# [b]pred = logits.argmax(dim=1)# [b] vs [b] => scalar tensorcorrect = torch.eq(pred, label).float().sum().item()total_correct += correcttotal_num += x.size(0)# print(correct)acc = total_correct / total_numtest_acc.append(acc)print(epoch+1,'loss:',loss.item(),'test acc:',acc)
    plot_curve(trans_loss)
    plot_curve(test_acc)
    
    程序设定训练过程要经过 100 个 epoch,然后结束。
    结束之后我们来查看训练结果:
    


    可以看到训练结果并不是很理想,所以接下来我们就需要对网络结构进行调整

  5. 调整方案一
    下面是笔者手动建立的三层卷积网络结构

    class CNN(nn.Module):def __init__(self):super(CNN,self).__init__()self.conv1=nn.Sequential(nn.Conv2d(3,16,kernel_size=3,stride=1,padding=1),nn.ReLU(True),)self.conv2=nn.Sequential(nn.Conv2d(16,32,kernel_size=5,stride=1,padding=2),nn.ReLU(True),)self.conv3=nn.Sequential(nn.Conv2d(32,64,kernel_size=5,stride=1,padding=2),nn.ReLU(True),nn.MaxPool2d(kernel_size=2,stride=2),nn.BatchNorm2d(64))self.function=nn.Linear(15*15*64,10)def forward(self, x):out = self.conv1(x)out = self.conv2(out)out = self.conv3(out)out = out.view(out.size(0), -1)out = self.function(out)return out
    
    我们再来看看训练结果:
    



    可以看出来这个网络结构和上一个相比好了一点,但是不是很明显。

  6. 方案二
    开始是想着使用牛津大学VGG-16网络模型的,但是显存不够,只能自己去写一个了

    class CNN(nn.Module):def __init__(self):super(CNN,self).__init__()self.conv1 = nn.Conv2d(3, 64, 3, padding=1)self.conv2 = nn.Conv2d(64, 64, 3, padding=1)self.pool1 = nn.MaxPool2d(2, 2)self.bn1 = nn.BatchNorm2d(64)self.relu1 = nn.ReLU()self.conv3 = nn.Conv2d(64, 128, 3, padding=1)self.conv4 = nn.Conv2d(128, 128, 3, padding=1)self.pool2 = nn.MaxPool2d(2, 2, padding=1)self.bn2 = nn.BatchNorm2d(128)self.relu2 = nn.ReLU()self.conv5 = nn.Conv2d(128, 128, 3, padding=1)self.conv6 = nn.Conv2d(128, 128, 3, padding=1)self.conv7 = nn.Conv2d(128, 128, 1, padding=1)self.pool3 = nn.MaxPool2d(2, 2, padding=1)self.bn3 = nn.BatchNorm2d(128)self.relu3 = nn.ReLU()self.conv8 = nn.Conv2d(128, 256, 3, padding=1)self.conv9 = nn.Conv2d(256, 256, 3, padding=1)self.conv10 = nn.Conv2d(256, 256, 1, padding=1)self.pool4 = nn.MaxPool2d(2, 2, padding=1)self.bn4 = nn.BatchNorm2d(256)self.relu4 = nn.ReLU()self.conv11 = nn.Conv2d(256, 512, 3, padding=1)self.conv12 = nn.Conv2d(512, 512, 3, padding=1)self.conv13 = nn.Conv2d(512, 512, 1, padding=1)self.pool5 = nn.MaxPool2d(2, 2, padding=1)self.bn5 = nn.BatchNorm2d(512)self.relu5 = nn.ReLU()self.fc14 = nn.Linear(512 * 4 * 4, 1024)self.drop1 = nn.Dropout2d()self.fc15 = nn.Linear(1024, 1024)self.drop2 = nn.Dropout2d()self.fc16 = nn.Linear(1024, 10)def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.pool1(x)x = self.bn1(x)x = self.relu1(x)x = self.conv3(x)x = self.conv4(x)x = self.pool2(x)x = self.bn2(x)x = self.relu2(x)x = self.conv5(x)x = self.conv6(x)x = self.conv7(x)x = self.pool3(x)x = self.bn3(x)x = self.relu3(x)x = self.conv8(x)x = self.conv9(x)x = self.conv10(x)x = self.pool4(x)x = self.bn4(x)x = self.relu4(x)x = self.conv11(x)x = self.conv12(x)x = self.conv13(x)x = self.pool5(x)x = self.bn5(x)x = self.relu5(x)x = x.view(-1, 512 * 4 * 4)x = F.relu(self.fc14(x))x = self.drop1(x)x = F.relu(self.fc15(x))x = self.drop2(x)x = self.fc16(x)return x
    
  7. 方案二的训练结果
    方案二只训练了25个epoch,比较无奈显卡不好,GTX1050训练尽然用了45分钟,给我等死了,而且显卡温度还很高,哎,都是穷呀~~~~
    看看我的显卡温度,我都害怕

    得让我的电脑降降温才行,咳咳,好了温度降下来了

    不废话了,上最终的运行结果


    可以看到这个结果比前两个有了很大的提升,test acc已近到了83%,这仅仅只训练了25个epoch

  8. 最终代码如下

    import torch
    from torch import nn
    import torch.optim as optim
    import torch.nn.functional as F
    from torch.autograd import Variable
    import matplotlib.pyplot as plt
    from torchvision import transforms,datasets
    from torch.utils.data import DataLoaderdef plot_curve(data):fig = plt.figure()plt.plot(range(len(data)), data, color='blue')plt.legend(['value'], loc='upper right')plt.xlabel('step')plt.ylabel('value')plt.show()
    transTrain=transforms.Compose([transforms.RandomHorizontalFlip(),transforms.RandomGrayscale(),transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
    transTest=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
    # download data
    train_data=datasets.CIFAR10(root='./CIFAR',train=True,transform=transTrain,download=True)
    test_data=datasets.CIFAR10(root='./CIFAR',train=False,transform=transTest,download=True)
    train_data_load=DataLoader(train_data,batch_size=100,shuffle=True,num_workers=2)
    test_data_load=DataLoader(test_data,batch_size=100,shuffle=False,num_workers=2)
    # definde CNN
    class CNN(nn.Module):def __init__(self):super(CNN,self).__init__()self.conv1 = nn.Conv2d(3, 64, 3, padding=1)self.conv2 = nn.Conv2d(64, 64, 3, padding=1)self.pool1 = nn.MaxPool2d(2, 2)self.bn1 = nn.BatchNorm2d(64)self.relu1 = nn.ReLU()self.conv3 = nn.Conv2d(64, 128, 3, padding=1)self.conv4 = nn.Conv2d(128, 128, 3, padding=1)self.pool2 = nn.MaxPool2d(2, 2, padding=1)self.bn2 = nn.BatchNorm2d(128)self.relu2 = nn.ReLU()self.conv5 = nn.Conv2d(128, 128, 3, padding=1)self.conv6 = nn.Conv2d(128, 128, 3, padding=1)self.conv7 = nn.Conv2d(128, 128, 1, padding=1)self.pool3 = nn.MaxPool2d(2, 2, padding=1)self.bn3 = nn.BatchNorm2d(128)self.relu3 = nn.ReLU()self.conv8 = nn.Conv2d(128, 256, 3, padding=1)self.conv9 = nn.Conv2d(256, 256, 3, padding=1)self.conv10 = nn.Conv2d(256, 256, 1, padding=1)self.pool4 = nn.MaxPool2d(2, 2, padding=1)self.bn4 = nn.BatchNorm2d(256)self.relu4 = nn.ReLU()self.conv11 = nn.Conv2d(256, 512, 3, padding=1)self.conv12 = nn.Conv2d(512, 512, 3, padding=1)self.conv13 = nn.Conv2d(512, 512, 1, padding=1)self.pool5 = nn.MaxPool2d(2, 2, padding=1)self.bn5 = nn.BatchNorm2d(512)self.relu5 = nn.ReLU()self.fc14 = nn.Linear(512 * 4 * 4, 1024)self.drop1 = nn.Dropout2d()self.fc15 = nn.Linear(1024, 1024)self.drop2 = nn.Dropout2d()self.fc16 = nn.Linear(1024, 10)def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.pool1(x)x = self.bn1(x)x = self.relu1(x)x = self.conv3(x)x = self.conv4(x)x = self.pool2(x)x = self.bn2(x)x = self.relu2(x)x = self.conv5(x)x = self.conv6(x)x = self.conv7(x)x = self.pool3(x)x = self.bn3(x)x = self.relu3(x)x = self.conv8(x)x = self.conv9(x)x = self.conv10(x)x = self.pool4(x)x = self.bn4(x)x = self.relu4(x)x = self.conv11(x)x = self.conv12(x)x = self.conv13(x)x = self.pool5(x)x = self.bn5(x)x = self.relu5(x)x = x.view(-1, 512 * 4 * 4)x = F.relu(self.fc14(x))x = self.drop1(x)x = F.relu(self.fc15(x))x = self.drop2(x)x = self.fc16(x)return xdevice = torch.device('cuda')
    net=CNN().to(device)
    name = nn.CrossEntropyLoss().to(device)
    optimizer = optim.Adam(net.parameters(), lr=0.001)
    loss_num=0.0
    trans_loss=[]
    test_acc=[]
    for epoch in range(25):for i, (x, label) in enumerate(train_data_load):x, label = x.to(device), label.to(device)logits = net(x)loss = name(logits, label)optimizer.zero_grad()loss.backward()optimizer.step()trans_loss.append(loss.item())net.eval()with torch.no_grad():total_correct = 0total_num = 0for x, label in test_data_load:x, label = x.to(device), label.to(device)logits = net(x)pred = logits.argmax(dim=1)# [b] vs [b] => scalar tensorcorrect = torch.eq(pred, label).float().sum().item()total_correct += correcttotal_num += x.size(0)acc = total_correct / total_numtest_acc.append(acc)print(epoch+1,'loss:',loss.item(),'test acc:',acc)
    plot_curve(trans_loss)
    plot_curve(test_acc)
    
  9. 总结
    由于笔者的设备问题(显卡太low)
    所以笔者优化的网络结构最终准确率能达到多少我也知道,我这里仅仅训练了25个epoch,有兴趣的小伙伴可以在自己的设备上运行运行,可以把最终的结果告诉我一下,万分感谢!!!!(后来在云端运行了一下,训练准确率为99%、 测试准确率为85.4%)也还不错,哈哈~~~
    这样一个神经网络的搭建和优化就结束了,由于笔者能力有限,也许上述阐述有误,请多多包含,有错误的地方欢迎指正,谢谢~~~~
    希望大家可以动手实践实践

从零开始搭建神经网络并将准确率提升至85%相关推荐

  1. 从零开始搭建神经网络(五)卷积神经网络(CNN)

    目录 1.基础介绍 2.网络结构 2.1卷积层 2.1.1 Padding 2.1.2 Stride 2.1.3 多通道计算 2.2池化层 2.2.1 最大池化 2.2.2 平均池化 2.3全连接层 ...

  2. 项目准时交付率提升至91% 鼎捷助力金石机器人击破经营困局

    服务型制造是制造与服务融合发展的新型制造模式和产业形态,是先进制造业和现代服务业深度融合的重要方向.这一发展趋势在装备制造行业尤为突出.如何成功摆脱单机制造,快速形成"设计+制造+服务&qu ...

  3. 阿里开源新一代人机对话模型 ESIM:准确率打破世界纪录,提升至 94.1%!

    近日,阿里 AI 开源了新一代人机对话模型 Enhanced Sequential Inference Model(ESIM).ESIM 是一种专为自然语言推断而生的加强版 LSTM,据阿里介绍,该算 ...

  4. 从零开始搭建深度学习验证码识别模型

    文章目录 从零开始搭建深度学习验证码识别模型 CNN模型与图像识别 验证码数据集介绍 生成数据集 生成EasyCaptcha 生成Kcaptcha 搭建模型 EasyNet模型 KCapNet模型 模 ...

  5. 如何从零开始搭建知识图谱?

    导读: 从一开始的 Google 搜索,到现在的聊天机器人.大数据风控.证券投资.智能医疗.自适应教育.推荐系统,无一不跟知识图谱相关.它在技术领域的热度也在逐年上升. 本文以通俗易懂的方式来讲解知识 ...

  6. 科大讯飞语音识别率从97%提升至98% 用AI赋能方言保护

    原标题:科大讯飞语音识别率从97%提升至98% 用AI赋能方言保护 6月12日,讯飞输入法在北京启动"AI方言发音人招募"公益行动.在人工智能一天天渗透并改变我们生活的今天,科大讯 ...

  7. 由浅入深搭建神经网络

    一.从零搭建神经网络 1.利用numpy来搭建网络模型 import numpy as np import torch""" 热身: 用numpy实现两层神经网络 一个全 ...

  8. 如何从零开始搭建智能外呼系统

    前言:本文作者是咱们"AI产品经理大本营"团员@何静 ,她用非常接地气的文字介绍了智能外呼系统的必备入门信息,对于不是这个细分领域的AI从业者来说,非常值得一看. 1 序言 随着人 ...

  9. 从零开始搭建智能Ai外呼系统?

    前言:本文作者是咱们"AI产品经理大本营"团员@何静 ,她用非常接地气的文字介绍了智能外呼系统的必备入门信息,对于不是这个细分领域的AI从业者来说,非常值得一看. 1--序言 随着 ...

最新文章

  1. 由Python历史「解密」Python底层逻辑
  2. LSTM之父撰文,纪念这位图灵奖遗珠、“AI理论之父”
  3. static_cast与c风格的强制类型转换比较
  4. Matlab语音信号频谱分析代码实现
  5. How to install MinGW-w64 and MSYS2?
  6. vba excel 退出编辑状态_VBA小常识(15)—Application对象
  7. CV模型,全目标检测等
  8. (10)js操作符(运算符)
  9. Maven知识- repositories
  10. 东京大学计算机专业研究生好吗,东北大学计算机类研究生个人考研经历以及感受...
  11. Halcon自定义直线卡尺rake
  12. 如何在M1 Mac上安装iPhone或iPad应用程序?
  13. vscode好用的扩展及常用的快捷键
  14. oAuth2.0店铺订单接口,获取单笔交易的详细信息api接口
  15. 注册表改win 7更新服务器,uefi安装win7卡在更新注册表设置解决新方法(完美解决)...
  16. 读史使人明智,二混子带你漫画学历史~
  17. 妈妈再也不用担心我的博客访问量了(一个可以刷博客访问量的小程序java)
  18. CM201-1广东移动盒子YS版(易视腾代工)TTL方式保留原系统 或不保留原系统方法
  19. C#(OpenGL MathNet)处理Gauss光斑图像
  20. STATA 和 SAS 输入输出示范

热门文章

  1. 在Myeclipse中创建自定义用户类库
  2. NetBeans 时事通讯(刊号 # 51 - Apr 07, 2009)
  3. Mesa 3D 计算机图形库
  4. SpringBoot --thymeleaf(资源文件css、js的引入)
  5. 基于物品的协同过滤mysql_百万用户,八十万商品,如何计算基于物品的协同过滤...
  6. python 数据框按行拼接_使用python进行数据分析
  7. c与指针 从一个字符串中提取子串_利用双指针解LeetCode第1297题:子串的最大出现次数
  8. a星算法python_Python-加速A星寻路算法
  9. android edittext inputfilter,android – EditText和InputFilter会导致重复的文本
  10. QGIS+GH + MapServer