Neural network 卷积神经网络,使用MatConvNet工具箱实现。如何处理过度装修?

Neural network 卷积神经网络,使用MatConvNet工具箱实现。如何处理过度装修?,neural-network,deep-learning,conv-neural-network,matconvnet,Neural Network,Deep Learning,Conv Neural Network,Matconvnet,我目前一直在与CNN合作,我认为这是一个很难处理的问题。具体来说,即使我的训练数据收敛到最小误差,我的验证数据仍然拒绝因误差而下降。我使用的输入数据是512 x 650 x 1 x 4000(2D数据,4000个样本),我试图区分的数据只有两个类(A类和B类)。我知道我将来需要更多的样本,但现在,我只希望在我投资生成更多数据之前,我的验证错误会下降一点 我的网络都有60-70层,包括以下类型的层: 块示例 卷积层[3 x 3]滤波器大小,跨距[1 x 1],填充[1] ReLU层(非线性) 批量

我目前一直在与CNN合作,我认为这是一个很难处理的问题。具体来说,即使我的训练数据收敛到最小误差,我的验证数据仍然拒绝因误差而下降。我使用的输入数据是512 x 650 x 1 x 4000(2D数据,4000个样本),我试图区分的数据只有两个类(A类和B类)。我知道我将来需要更多的样本,但现在,我只希望在我投资生成更多数据之前,我的验证错误会下降一点

我的网络都有60-70层,包括以下类型的层:

块示例 卷积层[3 x 3]滤波器大小,跨距[1 x 1],填充[1]

ReLU层(非线性)

批量规范化(极大地帮助培训数据收敛和实现速度)

最大池层[2 x 2]过滤器大小、跨距[2 x 2],填充[0]

然后我重复这个“块”,直到我的输入数据是1 x 1 x N大小,然后我将它运行到几个完全连接的层,然后运行到softmax中

下面是我的实际MatConvNet代码,以供检查,并附上输出图。对于图,蓝色表示我的训练错误,橙色表示我的验证错误。我正在从下面的代码链接我的最新版本

我的问题是:

1) 人们如何知道他们的数据要使用什么大小的过滤器?我知道这是一个经验过程,但这背后肯定有某种直觉?我读过关于使用[3x3]小型过滤器和使用大量过滤器的论文(VGG.net等),但即使考虑到这一点设计了70层网络,仍然没有验证错误下降

2) 我已经尝试了退出层,因为他们的流行减少过度装修。。。我将整个网络中的退出层放在上面显示的“块”中的ReLU和池层之后,但放在所有卷积层之间。不幸的是,它对我的验证数据没有影响,错误仍然是一样的。接下来,我尝试只在完全连接的层之后使用它,因为在我的架构中,大部分神经元(或特征图)都是在这个层中创建的,但仍然没有成功。我读过关于辍学的报纸。我应该放弃使用它吗?这又是一个“把戏”吗

3) 如果我尝试更小的网络(我读过这是一种处理过度拟合的下降方式),我如何有效地减少数据的大小?只是max pooling

任何建议都很好

再次感谢大家阅读这个长长的问题。我向你保证,我已经做了研究,并发现从长远来看,在这里提问可能会对我有更多帮助

MatConvNet代码(用于CNN设计的Matlab工具箱)


首先,我觉得你的网络对于数据来说太复杂了,你还需要两个数量级的样本才能在如此复杂的网络上看到任何结果。如果问题本身如此复杂。试着用更小的网络看看结果是否有所改善。回答您的问题:

1) 滤波器尺寸是经验的,但通常使用1x1,3x3,5x5滤波器。一个70层的网络是没有意义的,除非问题非常复杂,并且你有大量的数据。此外,为了成功地进行培训,您可能需要研究resnet

2) 辍学最常用于完全连接的层。您可以查看dropconnect。通常不需要在conv层之间使用它们

3) 通过conv+maxpooling堆栈可以很容易地减少中间映射的大小。在使用MLP之前,您不必将其缩小到1x1大小。例如,当网络中的贴图达到8x8大小时,您可以直接使用它。尝试使用多个FC层。同时减少网络宽度以降低模型复杂性(每层过滤器的数量)


总的来说,您的数据非常少,这对于深度模型来说肯定不起作用。微调预训练模型可能会获得更好的结果。这完全取决于数据本身和手头的任务。还要记住,像VGG这样的网络是为1000个不同的类和数百万张图像而训练的,这是一个非常复杂的问题

好的,这是有用的信息!谢谢你,先生。因此,对于较小的网络,您建议的层数是多少?我知道这最终取决于我的数据,但也许30层左右就足够了?而且,我所看到的所有例子都将尺寸减小到了1 x 1,所以我只是假设它背后有一些理论。最后,平均数量是多少个数据样本?50,000? 100000?还有一个问题:一个复杂度较低的小型网络是否会遵循简单、conv、relu、批处理规范、池格式迭代?对于conv过滤器,我是否仍然可以使用[5 x 5]大小的过滤器?或者我应该看看更大的吗?例如[15 x 15]。最后,你评论说我应该缩小我的网络宽度。你说的宽度是指每层的神经元吗?这与图层生成的要素图的数量相同,在我看来是“宽度”。你是这么说的吗?既然你刚开始学习,我建议你学习LeNet、AlexNet、VGNets、Inception GoogleNet和Resnets的体系结构。查看他们处理了哪些数据集,以及关于问题的复杂性有多少层。还可以显式地手动计算每个层的大小,并查看其缩小到什么大小。例如,AlexNet在第一个完全连接的层之前就有大小为13x13x128的功能图,数据量没有平均值。这个答案也许有用。也可以随意尝试过滤器大小,但我还没有看到任何成功的网络使用这种大型过滤器。通常最好堆叠几个3x3或5x5,而不是一个较大的过滤器。是的
opts.train.batchSize = 25;                                          
opts.train.numEpochs = 200 ;                                        
opts.train.continue = true ;                                        
opts.train.gpus = [1] ;                                             
opts.train.learningRate = 1e-3;                                     
opts.train.weightDecay  = 0.04;                                     
opts.train.momentum = 0.9;                                      
opts.train.expDir = 'epoch_data';                                   
opts.train.numSubBatches = 1;                                       

bopts.useGpu = numel(opts.train.gpus) >  0 ;                        

load('imdb4k.mat');                                                 
net = dagnn.DagNN() ;                                               

% Block #1

net.addLayer('conv1', dagnn.Conv('size', [3 3 1 64], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'input'}, {'conv1'},  {'conv1f'  'conv1b'});

net.addLayer('relu1', dagnn.ReLU(), {'conv1'}, {'relu1'}, {});

net.addLayer('bn1', dagnn.BatchNorm('numChannels', 64), {'relu1'}, {'bn1'}, {'bn1f', 'bn1b', 'bn1m'});

net.addLayer('pool1', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn1'}, {'pool1'}, {});

% Block #2

net.addLayer('conv2', dagnn.Conv('size', [3 3 64 64], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool1'}, {'conv2'},  {'conv2f'  'conv2b'});

net.addLayer('relu2', dagnn.ReLU(), {'conv2'}, {'relu2'}, {});

net.addLayer('bn2', dagnn.BatchNorm('numChannels', 64), {'relu2'}, {'bn2'}, {'bn2f', 'bn2b', 'bn2m'});

net.addLayer('pool2', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn2'}, {'pool2'}, {});

% Block #3

net.addLayer('conv3', dagnn.Conv('size', [3 3 64 128], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool2'}, {'conv3'},  {'conv3f'  'conv3b'}); 

net.addLayer('relu3', dagnn.ReLU(), {'conv3'}, {'relu3'}, {});

net.addLayer('bn3', dagnn.BatchNorm('numChannels', 128), {'relu3'}, {'bn3'}, 
{'bn3f', 'bn3b', 'bn3m'});

net.addLayer('pool3', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn3'}, {'pool3'}, {});

% Block #4

net.addLayer('conv4', dagnn.Conv('size', [3 3 128 128], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool3'}, {'conv4'},  {'conv4f'  'conv4b'}); 

net.addLayer('relu4', dagnn.ReLU(), {'conv4'}, {'relu4'}, {});

net.addLayer('bn4', dagnn.BatchNorm('numChannels', 128), {'relu4'}, {'bn4'}, {'bn4f', 'bn4b', 'bn4m'});

net.addLayer('pool4', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn4'}, {'pool4'}, {});

% Block #5

net.addLayer('conv5', dagnn.Conv('size', [3 3 128 256], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool4'}, {'conv5'},  {'conv5f'  'conv5b'});

net.addLayer('relu5', dagnn.ReLU(), {'conv5'}, {'relu5'}, {});

net.addLayer('bn5', dagnn.BatchNorm('numChannels', 256), {'relu5'}, {'bn5'}, {'bn5f', 'bn5b', 'bn5m'});

net.addLayer('pool5', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn5'}, {'pool5'}, {});

% Block #6

net.addLayer('conv6', dagnn.Conv('size', [3 3 256 256], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool5'}, {'conv6'},  {'conv6f'  'conv6b'}); 

net.addLayer('relu6', dagnn.ReLU(), {'conv6'}, {'relu6'}, {});

net.addLayer('bn6', dagnn.BatchNorm('numChannels', 256), {'relu6'}, {'bn6'}, {'bn6f', 'bn6b', 'bn6m'});

net.addLayer('pool6', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn6'}, {'pool6'}, {});

% Block #7

net.addLayer('conv7', dagnn.Conv('size', [3 3 256 512], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool6'}, {'conv7'},  {'conv7f'  'conv7b'});

net.addLayer('relu7', dagnn.ReLU(), {'conv7'}, {'relu7'}, {});

net.addLayer('bn7', dagnn.BatchNorm('numChannels', 512), {'relu7'}, {'bn7'}, {'bn7f', 'bn7b', 'bn7m'});

net.addLayer('pool7', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn7'}, {'pool7'}, {});

% Block #8

net.addLayer('conv8', dagnn.Conv('size', [3 3 512 512], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool7'}, {'conv8'},  {'conv8f'  'conv8b'}); 

net.addLayer('relu8', dagnn.ReLU(), {'conv8'}, {'relu8'}, {});

net.addLayer('bn8', dagnn.BatchNorm('numChannels', 512), {'relu8'}, {'bn8'}, {'bn8f', 'bn8b', 'bn8m'});

net.addLayer('pool8', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [1 2], 'pad', [0 0 0 0]), {'bn8'}, {'pool8'}, {});

% Block #9

net.addLayer('conv9', dagnn.Conv('size', [3 3 512 512], 'hasBias', true, 'stride', [1, 1], 'pad', [1 1 1 1]), {'pool8'}, {'conv9'},  {'conv9f'  'conv9b'});

net.addLayer('relu9', dagnn.ReLU(), {'conv9'}, {'relu9'}, {});

net.addLayer('bn9', dagnn.BatchNorm('numChannels', 512), {'relu9'}, {'bn9'}, {'bn9f', 'bn9b', 'bn9m'});

net.addLayer('pool9', dagnn.Pooling('method', 'max', 'poolSize', [2, 2], 'stride', [2 2], 'pad', [0 0 0 0]), {'bn9'}, {'pool9'}, {});

% Incorporate MLP

net.addLayer('fc1', dagnn.Conv('size', [1 1 512 1000], 'hasBias', true, 'stride', [1, 1], 'pad', [0 0 0 0]), {'pool9'}, {'fc1'},  {'conv15f'  'conv15b'});

net.addLayer('relu10', dagnn.ReLU(), {'fc1'}, {'relu10'}, {});

net.addLayer('bn10', dagnn.BatchNorm('numChannels', 1000), {'relu10'}, {'bn10'}, {'bn10f', 'bn10b', 'bn10m'});

net.addLayer('classifier', dagnn.Conv('size', [1 1 1000 2], 'hasBias', true, 'stride', [1, 1], 'pad', [0 0 0 0]), {'bn10'}, {'classifier'},  {'conv16f'  'conv16b'});

net.addLayer('prob', dagnn.SoftMax(), {'classifier'}, {'prob'}, {});

% The dagnn.Loss computes the loss incurred by the prediction scores X given the categorical labels

net.addLayer('objective', dagnn.Loss('loss', 'softmaxlog'), {'prob', 'label'}, {'objective'}, {});

net.addLayer('error', dagnn.Loss('loss', 'classerror'), {'prob','label'}, 'error') ;