Matlab 为什么MatConvNet说数据和衍生品不';你没有匹配的格式吗?

Matlab 为什么MatConvNet说数据和衍生品不';你没有匹配的格式吗?,matlab,machine-learning,neural-network,conv-neural-network,Matlab,Machine Learning,Neural Network,Conv Neural Network,问题陈述 我使用MatConvNet构建了一个非常简单的1D示例,并使用示例库附带的函数cnn_train构建了一个小型网络。按照他们的示例,我构建了一个小型CNN示例,如下所示: clc;clear;clc;clear; %% prepare Data M = 32; %batch size X_train = zeros(1,1,1,M); % (1 1 1 2) = (1 1 1 M) for m=1:M, X_train(:,:,:,m) = m; %training e

问题陈述

我使用MatConvNet构建了一个非常简单的1D示例,并使用示例库附带的函数cnn_train构建了一个小型网络。按照他们的示例,我构建了一个小型CNN示例,如下所示:

    clc;clear;clc;clear;
%% prepare Data
M = 32; %batch size
X_train = zeros(1,1,1,M); % (1 1 1 2) = (1 1 1 M)
for m=1:M,
    X_train(:,:,:,m) = m; %training example value
end
Y_test = 10*X_train;
split = ones(1,M);
split(floor(M*0.75):end) = 2;
% load image dadabase (imgdb)
imdb.images.data = X_train;
imdb.images.label = Y_test;
imdb.images.set = split;
%% prepare parameters
L1=3;
w1 = randn(1,1,1,L1); %1st layer weights
w2 = randn(1,1,1,L1); %2nd layer weights
b1 = randn(1,1,1,L1); %1st layer biases
b2 = randn(1,1,1,L1); %2nd layer biases
G1 = ones(1,1,1,L1); % (1 1 1 3) = (1 1 1 L1) BN scale, one per  dimension
B1 = zeros(1,1,1,L1); % (1 1 1 3) = (1 1 1 L1) BN shift, one per  dimension
EPS = 1e-4;
%% make CNN layers: conv, BN, relu, conv, pdist, l2-loss
net.layers = {} ;
net.layers{end+1} = struct('type', 'conv', ...
                           'name', 'conv1', ...
                           'weights', {{w1, b1}}, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'bnorm', ...
                           'weights', {{G1, B1}}, ...
                           'EPSILON', EPS, ...
                           'learningRate', [1 1 0.05], ...
                           'weightDecay', [0 0]) ;                       
net.layers{end+1} = struct('type', 'relu', ...
                           'name', 'relu1' ) ;
net.layers{end+1} = struct('type', 'conv', ...
                           'name', 'conv2', ...
                           'weights', {{w2, b2}}, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pdist', ...
                           'name', 'averageing1', ...
                           'class', 0, ...
                           'p', 1) ;
%% add L2-loss                   
fwfun = @l2LossForward;
bwfun = @l2LossBackward;
net = addCustomLossLayer(net, fwfun, bwfun) ;
net.layers{end}.class = Y_test; % its the test set
net = vl_simplenn_tidy(net) ;
res = vl_simplenn(net, X_train);
%% prepare train options
trainOpts.expDir = 'results/' ; %save results/trained cnn
trainOpts.gpus = [] ;
trainOpts.batchSize = 2 ;
trainOpts.learningRate = 0.02 ;
trainOpts.plotDiagnostics = false ;
%trainOpts.plotDiagnostics = true ; % Uncomment to plot diagnostics
trainOpts.numEpochs = 20 ; % number of training epochs
trainOpts.errorFunction = 'none' ;
%% CNN TRAIN
vl_simplenn_display(net) ;
net = cnn_train(net, imdb, @getBatch, trainOpts) ;
我根据创建了此示例,每当我运行该示例时,都会出现以下错误:

Error using vl_nnconv
DATA and DEROUTPUT do not have compatible formats.

Error in vl_simplenn (line 397)
          [res(i).dzdx, dzdw{1}, dzdw{2}] = vl_nnconv(res(i).x, l.weights{1},
          l.weights{2}, res(i+1).dzdx)

Error in cnn_train>process_epoch (line 323)
    res = vl_simplenn(net, im, dzdy, res, ...

Error in cnn_train (line 139)
    [net,stats.train,prof] = process_epoch(opts, getBatch, epoch, train, learningRate,
    imdb, net) ;

Error in main_1D_1layer_hard_coded_example (line 64)
net = cnn_train(net, imdb, @getBatch, trainOpts) ;
有人知道发生了什么吗?这个例子实际上被认为很简单,所以它让我困惑什么可能是错的


我试图解决的问题的补充部分

关于我试图解决这个问题的更多细节,请阅读

我找到了导致错误的文件中的那一行,并打印了该函数的输入,以确保我给出的参数是有意义的,并且在这方面似乎一切正常:

  case 'conv'
      size(res(i).x)
      size(res(i+1).dzdx)
      size(l.weights{1})
      size(l.weights{2})
      [res(i).dzdx, dzdw{1}, dzdw{2}] = vl_nnconv(res(i).x, l.weights{1}, l.weights{2}, res(i+1).dzdx)
    [res(i).dzdx, dzdw{1}, dzdw{2}] = ...
      vl_nnconv(res(i).x, l.weights{1}, l.weights{2}, res(i+1).dzdx, ...
      'pad', l.pad, ...
      'stride', l.stride, ...
      l.opts{:}, ...
      cudnn{:}) ;
印刷品:

ans =

     1     1     3    16


ans =

     1     1     3    16


ans =

     1     1     1     3


ans =

     1     1     1     3
我所期望的

我甚至继续手动硬编码网络应该计算的衍生品链,该文件似乎工作正常:

clc;clear;clc;clear;
%% prepare Data
M = 3;
x = zeros(1,1,1,M); % (1 1 1 2) = (1 1 1 M)
for m=1:M,
    x(:,:,:,m) = m;
end
Y = 5;
r=Y;
%% parameters
L1 = 3;
w1 = randn(1,1,1,L1); % (1 1 1 L1) = (1 1 1 3)
b1 = ones(1,L1);
w2 = randn(1,1,1,L1); % (1 1 1 L1) = (1 1 1 3)
b2 = ones(1,L1);
G1 = ones(1,1,1,L1); % (1 1 1 3) = (1 1 1 L1) BN scale, one per  dimension
B1 = zeros(1,1,1,L1); % (1 1 1 3) = (1 1 1 L1) BN shift, one per  dimension
EPS = 1e-4;
%% Forward Pass
z1 = vl_nnconv(x,w1,b1); % (1 1 3 2) = (1 1 L1 M)
%bn1 = z1;
bn1 = vl_nnbnorm(z1,G1,B1,'EPSILON',EPS); % (1 1 3 2) = (1 1 L1 M)
a1 = vl_nnrelu(bn1); % (1 1 3 2) = (1 1 L1 M) 
z2 = vl_nnconv(a1,w2,b2);
y1 = vl_nnpdist(z2, 0, 1);
loss_forward = l2LossForward(y1,Y);
%%
net.layers = {} ;
net.layers{end+1} = struct('type', 'conv', ...
                           'name', 'conv1', ...
                           'weights', {{w1, b1}}, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'bnorm', ...
                           'weights', {{G1, B1}}, ...
                           'EPSILON', EPS, ...
                           'learningRate', [1 1 0.05], ...
                           'weightDecay', [0 0]) ;                       
net.layers{end+1} = struct('type', 'relu', ...
                           'name', 'relu1' ) ;
net.layers{end+1} = struct('type', 'conv', ...
                           'name', 'conv2', ...
                           'weights', {{w2, b2}}, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pdist', ...
                           'name', 'averageing1', ...
                           'class', 0, ...
                           'p', 1) ;
fwfun = @l2LossForward;
bwfun = @l2LossBackward;
net = addCustomLossLayer(net, fwfun, bwfun) ;
net.layers{end}.class = Y;
net = vl_simplenn_tidy(net) ;
res = vl_simplenn(net, x);
%%
loss_forward = squeeze( loss_forward ) % (1 1)
loss_res = squeeze( res(end).x ) % (1 1)
%% Backward Pass
p = 1;
dldx = l2LossBackward(y1,r,p);
dy1dx = vl_nnpdist(z2, 0, 1, dldx);
[dz2dx, dz2dw2] = vl_nnconv(a1, w2, b2, dy1dx);
da1dx = vl_nnrelu(bn1, dz2dx);
[dbn1dx,dbn1dG1,dbn1dB1] = vl_nnbnorm(z1,G1,B1,da1dx);
[dz1dx, dz1dw1] = vl_nnconv(x, w1, b1, dbn1dx);
%%
dzdy = 1;
res = vl_simplenn(net, x, dzdy, res);
%%
% func = @(x) proj(p, forward(x, x0)) ;
% err = checkDerivativeNumerically(f, x, dx)
% %%
dz1dx = squeeze(dz1dx)
dz1dx_vl_simplenn = squeeze(res(1).dzdx)
导数似乎是数学上的,所以我假设文件中的所有内容都是有效的。它不会抛出错误,所以它甚至没有运行这一事实让我非常困惑。有人知道发生了什么吗


我加载CNN的方式是基于他们提供的教程。我将粘贴该文件重要方面的摘要(cnn_train功能运行良好,而我的功能运行不正常)


w2的尺寸应为1x1x3

此外,通常情况下,偏差会被给出为1x3,因为它们只有一个维度(或权重为1x1xn,对应偏差为1xN,其中N为过滤器数量),B1和G1也是如此(这里是1xM,其中M为前一层中的过滤器数量)。但这两种方法都可能奏效

在您的示例中,x的尺寸在第一次卷积后为1x1x16。这意味着一批中有16个元素,其中每个元素的宽度和高度为1,深度为3。深度3,因为第一次卷积是用3个滤波器完成的(w1的尺寸为1x1x3)


在您的示例中,w2的尺寸为1x1x3,表示宽度、高度和深度为1的3个过滤器。因此,过滤器的深度与输入的深度不匹配。

通过创建自定义层,我遇到了相同的问题。通过跟踪matconvnet实现,我最终找到了解决方案。希望以后能对其他人有所帮助

简而言之,您需要确保这两个数据不为空,不为null,并且具有相同的设备类型(GPU或CPU)和相同的数据类型(float、single或char)

在我的例子中,两个数据必须具有相同的“gpuArray”和“single”

======详情================== 首先是错误

数据和筛选器没有兼容的格式

数据和偏差没有兼容的格式

数据和输出没有兼容的格式

确切地说,这两个变量没有兼容的格式。 那么,“兼容格式”是什么意思呢? 它在vl_nnconv.cu第269~278行中实现

 /* check for GPU/data class consistency */


if (hasFilters && ! vl::areCompatible(data, filters)) {
    vlmxError(VLMXE_IllegalArgument, "DATA and FILTERS do not have compatible formats.") ;
  }
  if (hasBiases && ! vl::areCompatible(data, biases)) {
    vlmxError(VLMXE_IllegalArgument, "DATA and BIASES do not have compatible formats.") ;
  }
  if (backMode && ! vl::areCompatible(data, derOutput)) {
    vlmxError(VLMXE_IllegalArgument, "DATA and DEROUTPUT do not have compatible formats.") ;
  }
错误来自函数vl::areCompatible,该函数实现为

inline bool areCompatible(Tensor const & a, Tensor const & b)
  {
    return
    (a.isEmpty() || a.isNull()) ||
    (b.isEmpty() || b.isNull()) ||
    ((a.getDeviceType() == b.getDeviceType()) & (a.getDataType() == b.getDataType())) ;
  }
因此,基本上,它检查任何输入是空的还是空的,并确保两个输入具有相同的数据类型(double、single、vs char)和设备类型(GPU、CPU)


你能想出一个不太……的例子吗。。。。“非最小值?”安德拉斯达克当然,你是说它太复杂了吗?假设它是一个简单的网络,我只是提供了一些我试图修复它的东西。我试着对这个例子进行更多的评论,让它相信它非常简单。希望有帮助。你应该简化你的例子,它太长了,我需要一个小时来阅读你写的东西。提供一个较短的示例将增加答案的数量,并让您有机会自己发现问题。您是否在@Pinocchio解决了此问题?两条评论,1)我确实制作了w2 1x1x3,但不幸的是,它仍然没有运行。2) 你的推理从逻辑上讲是有道理的,但我仍然感到困惑的是,如果你的论点是正确的,那么为什么我可以在模型中成功地运行正向传递?如果你注意到我给出的代码中有一行
res=vl\u simplenn(net,X\u train)对模型进行评估,让我惊讶的是,它实际运行。如果尺寸不匹配,那么为什么向前传球会跑呢?我还不知道,但似乎回传球是错误输出的问题。我会试着检查一下。我一定是忽略了这一点。真奇怪。也许在接下来的几天里我会有时间亲自尝试你的代码。
inline bool areCompatible(Tensor const & a, Tensor const & b)
  {
    return
    (a.isEmpty() || a.isNull()) ||
    (b.isEmpty() || b.isNull()) ||
    ((a.getDeviceType() == b.getDeviceType()) & (a.getDataType() == b.getDataType())) ;
  }
 /// Type of device: CPU or GPU
  enum DeviceType {
    VLDT_CPU = 0,
    VLDT_GPU
  }  ;

  /// Type of data (char, float, double, ...)
  enum DataType {
    VLDT_Char,
    VLDT_Float,
    VLDT_Double
  } ;