MATLAB Answers

cui
0

How to pass 3D data to the deep neural network for training (image3dInputLayer)?

Asked by cui
on 12 Aug 2019
Latest activity Edited by cui
on 14 Aug 2019
I am trying to train a 3D convolutional network for motion recognition, but I don't know how to correctly pass the image sequence set to the network. The input size is 320*320*16*3, corresponding to h*w*d*c, respectively. The custom dataset class is:
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.12 cuixingxing
% email:cuixingxing150@gmail.com
%
properties
Folders
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);
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 = read(ds)
% Read one mini-batch batch of data
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}));
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.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
when i successfully load my data,it can read , like this,
my net structure is,
Then I train my network, it errors:
ThreeDs = My3DFolderDatastore('E:\ActivityDataBase',[320,320,3],16,30);
ThreeDs = shuffle(ThreeDs);
%%
% 训练网络
miniBatchSize = 30;
options = trainingOptions('adam', ...
'ExecutionEnvironment','gpu', ...
'MaxEpochs',75, ...
'MiniBatchSize',miniBatchSize, ...
'GradientThreshold',1, ...
'Verbose',1, ...
'VerboseFrequency',1,...
'Plots','training-progress');
net = trainNetwork(ThreeDs,lgraph,options);
error means "too many outputs",can somebody help me,thanks!

  1 Comment

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?
reference here, here2
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

Sign in to comment.

0 Answers