Custom Vnet layer validation failed error
1 次查看(过去 30 天)
显示 更早的评论
I am trying to train a custom Vnet network it keeps giving me the following error
Layer 'en3_prelu1': Layer validation failed. Error using
'predict' in Layer prelu3dLayer. The function threw an error
and could not be executed.
Array dimensions must match for binary array op.
This is my class definition
classdef prelu3dLayer < nnet.layer.Layer
% Custom 3-D PReLU layer.
%
% Copyright 2019 The MathWorks, Inc.
properties (Learnable)
% Layer learnable parameters
% Scaling coefficient
Alpha
end
methods
function layer = prelu3dLayer(numChannels, name)
% layer = preluLayer(numChannels, name) creates a PReLU layer
% with numChannels channels and specifies the layer name.
% Set layer name.
layer.Name = name;
% Set layer description.
layer.Description = "PReLU with " + num2str(numChannels) + " channels";
% Initialize scaling coefficient.
layer.Alpha = rand(numChannels);
end
function Z = predict(layer, X)
% Z = predict(layer, X) forwards the input data X through the
% layer and outputs the result Z.
Z = max(0, X) + layer.Alpha .* min(0, X);
end
function [dLdX, dLdAlpha] = backward(layer, X, ~, dLdZ, memory)
% [dLdX, dLdAlpha] = backward(layer, X, Z, dLdZ, memory)
% backward propagates the derivative of the loss function
% through the layer.
% Inputs:
% layer - Layer to backward propagate through
% X - Input data
% Z - Output of layer forward function
% dLdZ - Gradient propagated from the deeper layer
% memory - Memory value which can be used in backward
% propagation
% Outputs:
% dLdX - Derivative of the loss with respect to the
% input data
% dLdAlpha - Derivative of the loss with respect to the
% learnable parameter Alpha
dLdX = layer.Alpha .* dLdZ;
dLdX(X>0) = dLdZ(X>0);
dLdAlpha = min(0,X) .* dLdZ;
%dLdAlpha = sum(sum(dLdAlpha,1),2);
% Sum over all observations in mini-batch.
dLdAlpha = sum(dLdAlpha,5);
end
end
end
And these are the network options
inputSize = [40 40 40];
numClasses = 2;
lgraph = createVnetBn(inputSize, numClasses);
figure;
lgraph.plot
maxEpochs = 250;
options = trainingOptions('adam', ...
'MaxEpochs',maxEpochs, ...
'InitialLearnRate',1e-3, ...
'LearnRateSchedule','piecewise', ...
'LearnRateDropPeriod',5, ...
'LearnRateDropFactor',0.97, ...
'ValidationData',dsVal, ...
'ValidationFrequency',400, ...
'Plots','training-progress', ...
'Verbose',false, ...
'MiniBatchSize',miniBatchSize);
doTraining = true;
if doTraining
modelDateTime = datestr(now,'dd-mmm-yyyy-HH-MM-SS');
[net,info] = trainNetwork(dsTrain,lgraph,options);
save(['trained3DUNet-' modelDateTime '-Epoch-' num2str(maxEpochs) '.mat'],'net');
end
0 个评论
回答(1 个)
Amanjit Dulai
2022-9-11
It's tricky to tell without the code for createVnetBn, but I would guess the problem is this line in prelu3dLayer:
% Initialize scaling coefficient
layer.Alpha = rand(numChannels);
This will initialize layer.Alpha to a numChannels-by-numChannels matrix, which is not what you would normally want for a 3D input. For a 3D input, you probably want something like this:
% Initialize scaling coefficient
layer.Alpha = rand([1 1 1 numChannels]);
7 个评论
Amanjit Dulai
2022-9-15
I've attached an edited version of createVnetBn.m which should work for an input size of 40x40x40. I have removed one of the downsampling and upsampling stages.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Image Data Workflows 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!