zoukankan      html  css  js  c++  java
  • 机器学习 —— 深度学习 —— 基于DAGNN的MNIST NET

      DAGNN 是Directed acyclic graph neural network 缩写,也就有向图非循环神经网络。我使用的是由MatConvNet 提供的DAGNN API。选择这套API作为工具的原因有三点,第一:这是matlab的API,相对其他语言我对Matlab比较熟悉;第二:有向图非循环的网络可以实现RPN,Network in Network 等较为复杂的功能,可以随意的引出各层的输入和输出,有利于针对三维视觉任务改造网络结构。MNIST 是手写数字的图片集,也是机器学习网络最简单的试金石。

    1、定义层

     1 conv_layer1 = dagnn.Conv('size',single([5,5,1,30]),'hasBias',true);
     2 relu_layer2 = dagnn.ReLU();
     3 
     4 conv_layer3 = dagnn.Conv('size',single([5,5,30,16]),'hasBias',true);
     5 relu_layer4 = dagnn.ReLU();
     6 pooling_layer5 = dagnn.Pooling('poolSize',[2,2],'stride',[2 2]);
     7 
     8 fullConnet_layer6 = dagnn.Conv('size',single([4,4,16,256]),'hasBias',true);
     9 relu_layer7 = dagnn.ReLU();
    10 fullConnet_layer8 = dagnn.Conv('size',single([1,1,256,10]),'hasBias',true);
    11 SoftMat_layer9 = dagnn.SoftMax();
    12 Loss_layer = dagnn.Loss();
    View Code

    首先是利用API构造各层网络,定义网络结构类型。所有的Layer 都继承自dagnn.Layer类,子类中定义了输入输出,前向传播,反向传播的行为。

    其中包括卷积层,激活层,池化层,Softmax 分类层,以及计算Loss层。值得注意的是全连接层是通过大卷积层来实现的。本质上全连接就是“输入的等尺寸卷积”。全连接层的作用是将卷积层提取的特征进行高度非线性的映射,将其映射到输出空间中。

    2、定义网络

     1 mynet = dagnn.DagNN();
     2 mynet.addLayer('conv1',conv_layer1,{'input'},{'x2'},{'filters_conv1','bias_conv1'});
     3 mynet.addLayer('relu1',relu_layer2,{'x2'},{'x3'});
     4 mynet.addLayer('pool1',pooling_layer5,{'x3'},{'x4'});
     5 
     6 mynet.addLayer('conv2',conv_layer3,{'x4'},{'x5'},{'filters_conv2','bias_conv2'});
     7 mynet.addLayer('relu2',relu_layer4,{'x5'},{'x6'});
     8 mynet.addLayer('pool2',pooling_layer5,{'x6'},{'x7'});
     9 
    10 mynet.addLayer('full1',fullConnet_layer6,{'x7'},{'x8'},{'filters_fc1','bias_fc1'});
    11 mynet.addLayer('relu3',relu_layer7,{'x8'},{'x9'});
    12 mynet.addLayer('full2',fullConnet_layer8,{'x9'},{'x10'},{'filters_fc2','bias_fc2'});
    13 mynet.addLayer('Cls1',SoftMat_layer9,{'x10'},{'pred'});
    14 mynet.addLayer('Loss',Loss_layer,{'pred','label'},{'loss'});
    15 mynet.initParams();
    16 mynet.meta.inputs = {'data',[28,28,1,1]};
    17 mynet.meta.classes.name = {1,2,3,4,5,6,7,8,9,10};
    18 mynet.meta.normalization.imageSize = [28,28,1,1];
    19 mynet.meta.interpolation = 'bicubic';
    View Code

    定义网络调用了addLayer方法,与其他API的网络构建方法不同的是,DAGNN的API需要针对每层定义输入和输出,以及网络中的待求得参数。当然,作为初学者我先实现了链式网络,在下周的工作中会尝试实现Faster R-CNN。

    net.addLayer('full1',fullConnet_layer6,{'x7'},{'x8'},{'filters_fc1','bias_fc1'});

    以此为例,代表该层的名字是full1 , 该层的结构是fullConnect_layer6,输入为x7、输出x8,参数名为filters_fc1 和 bias_fc1。其中loss 层最为特殊,其具有来自softmax层的pred 和 label (ground truth) 两种输入。

    最重要的是一定要initParams()!!!!这会生成初始参数。

    3、定义数据输入函数

    为了训练网络,我们需要定义一个输入函数。数据量小,可存在内存中,但当数据量大的时候全部存在内存里是不现实的,这就需要一个数据输入函数来对你定义的数据库进行操作。本例中我仅使用5000幅图片进行训练,所以可以把图片放在内存中。getBatch函数如下所示:

    1 function inputs = getBatch(imdb, batch)
    2 % --------------------------------------------------------------------
    3 images = imdb.images.data(:,:,:,batch) ;
    4 labels = imdb.images.labels(1,batch) ;
    5 
    6 %  images = gpuArray(images) ;
    7 
    8 inputs = {'input', images, 'label', labels} ;
    View Code

    其中 imdb 是image data base. 其中包括:

    imdb.images.data  图片 W*H*C*N 的4-D  single Array

    imdb.images.label  标签 N*1  的 single Array

    imdb.images.data_mean 图片平均值 用于预处理时去中心

    imdb.images.set    集合号 N*1 的 single Array, 其中1 代表训练集 2 代表测试集 3 代表验证集

    imdb.meta 存放类型名称等和训练关系不太密切的东西

    4、开始训练

    直接调用 cnn_train_dag 的API 开始对整个集合进行训练,注意getBatch 输入的是函数句柄。

    cnn_train_dag(mynet,imdb_sub,@getBatch);

      训练了30个epoch,但是learningRate好像给太高了,掉局部最小里了。。。。。。。不过结果不错,在验证集中拿到了4998/5000.

  • 相关阅读:
    今天面试一些程序员(新,老)手的体会
    UVA 10635 Prince and Princess
    poj 2240 Arbitrage
    poj 2253 Frogger
    poj 2485 Highways
    UVA 11258 String Partition
    UVA 11151 Longest Palindrome
    poj 1125 Stockbroker Grapevine
    poj 1789 Truck History
    poj 3259 Wormholes
  • 原文地址:https://www.cnblogs.com/ironstark/p/6058090.html
Copyright © 2011-2022 走看看