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

7 views (last 30 days)
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
cui,xingxing
cui,xingxing on 13 Aug 2019
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.

Answers (0)

Products


Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!