如何在MATLAB中拆分图像数据存储区以进行交叉验证?

时间:2017-02-10 10:24:09

标签: image matlab cross-validation

在MATLAB中,trimws对象的方法splitEachLabel将图像数据存储分成每个类别标签的比例。如何使用交叉验证和使用imageDatastore类来拆分图像数据存储以进行培训?

即。很容易将其拆分为N个分区,但是需要某种trainImageCategoryCalssifier功能才能使用交叉验证来训练分类器。

还是有另一种方法可以达到这个目的吗?

此致 埃琳娜

2 个答案:

答案 0 :(得分:0)

我最近偶然发现了同样的问题。不确定是否有人仍在寻找可能的解决方案。

我最终创建了一个函数,将多个imds组合成一个(类似于_mergeEachLabel_建议)。

根据MATLAB documentationimageDatastore是一个包含4个字段的结构

  1. 包含图像路径的单元格数组
  2. 带有每个图像标签的单元格数组
  3. 一个整数,指定读者每次调用时要读取的图像数量
  4. 读取图像数据的功能
  5. 因此,此函数只创建一个新的IMDS,将N个不同imds的第一个和第二个字段连接到这个新的IMDS中。

    然后您可以使用此功能运行交叉验证。如果你有5个折叠(5个不同的imds)你可以运行一个调用trainImageCategoryClassifier的循环,它将4个折叠组合成一个训练集,并在剩下的imds上运行evaluate

    一个警告:使用后我意识到以这种方式工作是非常低效的,因为你会在每次CV循环迭代时将图像重新编码到你的特征包中。将整个IMDS编码一次到X矩阵然后直接使用fitsvm会更有效,它们内置了CV功能。

    无论如何,如果有人仍然对这个问题感兴趣,这是我的功能:

    function [newimds] = combineimds(cell_imds)
    % COMBINEIMDS  Merges a set of IMDS together and returns the combined IMDS
    %     CELL_IMDS is a 1xn cell array where each cell is a different IMDS object
    %%
    n = size(cell_imds, 2);      % assumes that cell_imds is 1xn
    
    %%
    % use function splitEachLabel to copy first fold to new imds
    [newimds dummy] = splitEachLabel(cell_imds{1}, 1);
    a = [newimds.Files; dummy.Files];
    b = [newimds.Labels; dummy.Labels];
    newimds.Files = a;
    newimds.Labels = b;
    %%
    % concatenate cells in the new imds
    for i = 2:n
      a = [newimds.Files; cell_imds{i}.Files];
      b = [newimds.Labels; cell_imds{i}.Labels];
      newimds.Files = a;
      newimds.Labels = b;
    end
    
    end
    

    希望它有所帮助。

答案 1 :(得分:0)

以下代码应该适用于基本的交叉验证,当然您需要适当地更改 k 的值和数据存储区选项。

k = 5; % number of folds
datastore = imageDatastore(fullfile('.'), 'IncludeSubfolders', true, 'LabelSource', 'foldernames');

partStores{k} = [];
for i = 1:k
   temp = partition(datastore, k, i);
   partStores{i} = temp.Files;
end

% this will give us some randomization
% though it is still advisable to randomize the data before hand
idx = crossvalind('Kfold', k, k);

for i = 1:k
    test_idx = (idx == i);
    train_idx = ~test_idx;

    test_Store = imageDatastore(partStores{test_idx}, 'IncludeSubfolders', true, 'LabelSource', 'foldernames');
    train_Store = imageDatastore(cat(1, partStores{train_idx}), 'IncludeSubfolders', true, 'LabelSource', 'foldernames');

    % do your training and predictions here, maybe pre-allocate them before the loop, too
    %net{i} = trainNetwork(train_Store, layers options);
    %pred{i} = classify(net, test_Store);
end