Today i add a output argument "info" in read function, add Labels properties, and get a new error:
"Invalid training data. The output size (8) of the last layer does not match the number of classes (2)."
is that a matlab issue?
classdef My3DFolderDatastore < matlab.io.Datastore & ...
matlab.io.datastore.MiniBatchable &...
matlab.io.datastore.Shuffleable % 参考官方Develop Custom Mini-Batch Datastore文档
% 目的:解决3d卷积网络输入数据太大,导致out of
% memory的情况设计,例如输入320*320*16*3*NumObservations 5D数据(包含NumObservations维度)
%
% 本程序使用示例(example):
% folder = 'E:\ActivityDataBase';
% inputsize = [320,320,3];
% seqLen = 16;
% minibatchsize = 30;
% ThreeDs = My3DFolderDatastore(folder,inputsize,seqLen,minibatchsize);
% while hasdata(ThreeDs)
% data_label_table = read(ThreeDs);
% ...
% end
%
% 2019.8.13 cuixingxing
% email:cuixingxing150@gmail.com
%
properties
Folders
Labels
InputSize % [h,w,c],输入图像大小
SequenceLength % 为常数16
MiniBatchSize % 必须的
end
properties(SetAccess = protected)
NumObservations % 必须的
end
properties(Access = private)
% This property is inherited from Datastore
CurrentFolderIndex
CurrentFolder
end
methods
function ds = My3DFolderDatastore(folder,inputsize,seqLen,minibatchsize)
% Construct a MySequenceDatastore object
imds = imageDatastore(folder,...
'FileExtensions',{'.jpg','.png'}, ...
'labelsource','foldernames',...
'IncludeSubfolders',true);
[paths,~,~] = cellfun(@fileparts,imds.Files,...
'UniformOutput',false);
ds.Folders = unique(paths);
line = split(ds.Folders,'\');
labels = line(:,end-1);
ds.Labels = categorical(labels);
ds.InputSize = inputsize;
ds.NumObservations = length(ds.Folders);
ds.CurrentFolderIndex = 1;
ds.CurrentFolder = ds.Folders{1};
ds.SequenceLength = seqLen;
ds.MiniBatchSize = minibatchsize;
end
function tf = hasdata(ds)
% Return true if more data is available
tf = ds.CurrentFolderIndex + ds.MiniBatchSize - 1 ...
<= ds.NumObservations;
end
function [data_label_table,info] = read(ds)
% Read one mini-batch batch of data
info = struct;
miniBatchSize = ds.MiniBatchSize;
data = cell(miniBatchSize,1);
label = cell(miniBatchSize,1);
data_batch = zeros([ds.InputSize,ds.SequenceLength,miniBatchSize],'uint8');
label_batch = categorical(zeros(miniBatchSize,1));
for i = 1:miniBatchSize
ds.CurrentFolder = ds.Folders{ds.CurrentFolderIndex};
imds_data = imageDatastore(ds.CurrentFolder);
assert(length(imds_data.Files)==ds.SequenceLength);
for j = 1:ds.SequenceLength
data_batch(:,:,:,j,i) = imresize(imread(imds_data.Files{j}),ds.InputSize(1:2));
end
% label_path = strsplit(imds_data.Files{1},'\');
% label_batch(i,1) = categorical(string(label_path{end-2}));
label_batch(i,1) = ds.Labels(ds.CurrentFolderIndex);
ds.CurrentFolderIndex = ds.CurrentFolderIndex + 1;
end
data_batch = permute(data_batch,[1,2,4,3,5]); % 最终为h*w*d*c*b大小的数组
for i = 1:miniBatchSize
data{i,1} = data_batch(:,:,:,:,i);
label{i,1} = label_batch(i,1);
end
data_label_table = table(data,label);
end % end of read
function reset(ds)
ds.CurrentFolderIndex = 1;
end
function dsNew = shuffle(ds)
% dsNew = shuffle(ds) shuffles the files and the
% corresponding labels in the datastore.
% Create a copy of datastore
dsNew = copy(ds);
% Shuffle files and corresponding labels
numObservations = dsNew.NumObservations;
idx = randperm(numObservations);
dsNew.Folders = dsNew.Folders(idx);
dsNew.Labels = dsNew.Labels(idx);
dsNew.CurrentFolderIndex = 1;
dsNew.CurrentFolder = dsNew.Folders(dsNew.CurrentFolderIndex);
end
end
methods (Hidden = true)
function frac = progress(ds)
% Determine percentage of data read from datastore
frac = (ds.CurrentFolderIndex - 1) / ds.NumObservations;
end
end
end % end class definition