如何训练有多个输出层的神经网络

各位大神们好!我最近尝试搭建了一个具有三个输出层的混合神经网络,其中两个输出层用softmax、另一个输出层用sigmoid。当我开始训练时,matlab就一直给我报错:损失函数必须为字符向量、字符串标量、函数句柄、AcceleratedFunction 对象或 deep.DifferentiableFunction 对象。因此我想知道这怎么解决,希望能得到大神们的解答!原代码如下:
%% ===================================================================
% 第1部分:PCSTA-Net 网络结构构建
clear, clc;
disp('正在构建并初始化网络...');
net = dlnetwork;
tempNet = [
sequenceInputLayer(18,"Name","Input","MinLength",25)
convolution1dLayer(1,64,"Name","Conv1D","Padding","causal")
batchNormalizationLayer("Name","BN")
clippedReluLayer(1.5,"Name","C-ReLU")];
net = addLayers(net,tempNet);
tempNet = identityLayer("Name","Residual Shortcut");
net = addLayers(net,tempNet);
tempNet = [
convolution1dLayer(3,32,"Name","Conv1D_1","Padding","causal")
batchNormalizationLayer("Name","BN_1")
leakyReluLayer(0.01,"Name","L-ReLU")];
net = addLayers(net,tempNet);
tempNet = [
convolution1dLayer(5,32,"Name","Conv1D_2","Padding","causal")
batchNormalizationLayer("Name","BN_2")
leakyReluLayer(0.01,"Name","L-ReLU_1")];
net = addLayers(net,tempNet);
tempNet = [
convolution1dLayer(3,32,"Name","Conv1D_3","DilationFactor",3,"Padding","causal")
batchNormalizationLayer("Name","BN_3")
leakyReluLayer(0.01,"Name","L-ReLU_2")];
net = addLayers(net,tempNet);
tempNet = [
convolution1dLayer(3,32,"Name","Conv1D_4","DilationFactor",4,"Padding","causal")
batchNormalizationLayer("Name","BN_4")
leakyReluLayer(0.01,"Name","L-ReLU_3")];
net = addLayers(net,tempNet);
tempNet = [
concatenationLayer(1,4,"Name","Concat")
convolution1dLayer(1,64,"Name","Conv1D_5","Padding","causal")
batchNormalizationLayer("Name","BN_5")
spatialDropoutLayer("Name","Spatial Dropout","Probability",0.3)];
net = addLayers(net,tempNet);
tempNet = [
additionLayer(2,"Name","Add")
leakyReluLayer(0.01,"Name","L-ReLU_4")];
net = addLayers(net,tempNet);
tempNet = [
selfAttentionLayer(4,64,"Name","Self-Attention","NumValueChannels",64,"OutputSize",64)
layerNormalizationLayer("Name","LN")
gruLayer(64,"Name","GRU")];
net = addLayers(net,tempNet);
tempNet = [
globalAveragePooling1dLayer("Name","GAP")
dropoutLayer(0.4,"Name","Dropout")];
net = addLayers(net,tempNet);
tempNet = [
fullyConnectedLayer(6,"Name","FC")
softmaxLayer("Name","Gait Output")];
net = addLayers(net,tempNet);
tempNet = [
fullyConnectedLayer(7,"Name","FC_1")
softmaxLayer("Name","Slope Output")];
net = addLayers(net,tempNet);
tempNet = indexing1dLayer("last","Name","Index Extract");
net = addLayers(net,tempNet);
tempNet = [
identityLayer("Name","Skip Connection")
indexing1dLayer("last","Name","Index Extract_1")];
net = addLayers(net,tempNet);
tempNet = [
concatenationLayer(1,2,"Name","Concat_1")
fullyConnectedLayer(1,"Name","FC_2")
sigmoidLayer("Name","Phase Output")];
net = addLayers(net,tempNet);
% 清理辅助变量
clear tempNet;
net = connectLayers(net,"C-ReLU","Residual Shortcut");
net = connectLayers(net,"C-ReLU","Conv1D_1");
net = connectLayers(net,"C-ReLU","Conv1D_2");
net = connectLayers(net,"C-ReLU","Conv1D_3");
net = connectLayers(net,"C-ReLU","Conv1D_4");
net = connectLayers(net,"Residual Shortcut","Add/in2");
net = connectLayers(net,"L-ReLU","Concat/in1");
net = connectLayers(net,"L-ReLU_1","Concat/in2");
net = connectLayers(net,"L-ReLU_2","Concat/in3");
net = connectLayers(net,"L-ReLU_3","Concat/in4");
net = connectLayers(net,"Spatial Dropout","Add/in1");
net = connectLayers(net,"L-ReLU_4","Self-Attention");
net = connectLayers(net,"L-ReLU_4","Skip Connection");
net = connectLayers(net,"GRU","GAP");
net = connectLayers(net,"GRU","Index Extract");
net = connectLayers(net,"Dropout","FC");
net = connectLayers(net,"Dropout","FC_1");
net = connectLayers(net,"Index Extract","Concat_1/in1");
net = connectLayers(net,"Index Extract_1","Concat_1/in2");
% 初始化网络权重
net = initialize(net);
disp('网络初始化完成。');
%% ===================================================================
% 第2部分:核心训练循环
% 1. 加载数据
load('Simulated_Gait_Dataset_6_7_2.mat', 'X', 'Y_gait', 'Y_incline', 'Y_phase');
% 2. 将数据封装为 Datastore 对象
dsX = arrayDatastore(X, 'OutputType', 'same');
dsY_gait = arrayDatastore(Y_gait);
dsY_incline = arrayDatastore(Y_incline);
dsY_phase = arrayDatastore(Y_phase);
% 3. 组合 Datastore (顺序必须与网络输出层顺序一致)
dsCombined = combine(dsX, dsY_gait, dsY_incline, dsY_phase);
% 4. 配置训练参数
options = trainingOptions("adam", ...
"MaxEpochs", 50, ...
"MiniBatchSize", 32, ...
"InitialLearnRate", 1e-3, ...
"Plots", "training-progress", ...
"Metrics", "accuracy");
% 5. 指定三个输出分支的损失函数
lossFcn = ["crossentropy", "crossentropy", "binary-crossentropy"];
% 6. 启动标准训练
disp('启动标准多任务训练...');
[trainedNet, info] = trainnet(dsCombined, net, lossFcn, options);
disp('训练完成。');

Réponses (1)

Adarsh
Adarsh le 9 Avr 2026 à 6:30

0 votes

From my understanding, you are building a multi‑output network using a "dlnetwork" object with two Softmax output branches and one Sigmoid output branch, and you encounter an error when starting training that indicates the loss function specification is not valid.
The issue is not related to the network architecture itself, which is consistent with a multi‑task design, but rather to how the loss functions are specified when calling "trainnet".
In your script, the loss functions are defined as a string array:
lossFcn = ["crossentropy", "crossentropy", "binary-crossentropy"];
However, "trainnet" does not accept a string array for multiple losses. LossFcn must be provided as an individual loss definition, such as a function handle or a supported differentiable function object in this case.
For more information on how to use the lossFcn correctly in case of multi output models, the following documentation link can be referred:
I hope this helps!

Catégories

En savoir plus sur Deep Learning Toolbox dans Centre d'aide et File Exchange

Produits

Version

R2025b

Question posée :

le 6 Avr 2026 à 14:15

Réponse apportée :

le 9 Avr 2026 à 6:30

Community Treasure Hunt

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

Start Hunting!