在MATLAB中,trimws
对象的方法splitEachLabel
将图像数据存储分成每个类别标签的比例。如何使用交叉验证和使用imageDatastore
类来拆分图像数据存储以进行培训?
即。很容易将其拆分为N个分区,但是需要某种trainImageCategoryCalssifier
功能才能使用交叉验证来训练分类器。
还是有另一种方法可以达到这个目的吗?
此致 埃琳娜
答案 0 :(得分:0)
我最近偶然发现了同样的问题。不确定是否有人仍在寻找可能的解决方案。
我最终创建了一个函数,将多个imds组合成一个(类似于_mergeEachLabel_
建议)。
根据MATLAB documentation,imageDatastore
是一个包含4个字段的结构
因此,此函数只创建一个新的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