iron_man8 2024-04-09 19:37 采纳率: 0%
浏览 530
已结题

我运行这个代码就会报错,错误提示如下错误使用 trainNetworkX 和 Y 中的观测值数量不一致,如何解决?(语言-matlab)


clc;
close all;
clear;

%% 参数设置
excelFilePath = 'C:\Users\Desktop\心音数据\训练数据.xlsx'; % Excel文件的路径
dataFolder = 'C:\Users\Desktop\心音数据\处理心音'; % 心音文件的文件夹路径
desiredSamplesPerLabel = 100; % 您希望从每个标签中挑选的样本数量

%% 步骤1: 从Excel读取数据(指定没有列名)
dataTable = readtable(excelFilePath, 'ReadVariableNames', false);

%% 提取文件名和标签(使用列索引)
fileNames = dataTable.Var1; % 第一列为文件名
labels = dataTable.Var2; % 第二列为标签

%% 初始化存储所有文件路径和对应标签的数组
paths = {}; % 存储所有文件路径
labelsArray = []; % 存储与paths对应的标签

%% 计算每个标签可用的最大样本数,并确定实际的样本数
maxSamplesLabel0 = sum(labels == 0);
maxSamplesLabel1 = sum(labels == 1);
actualSamplesPerLabel = min([desiredSamplesPerLabel, maxSamplesLabel0, maxSamplesLabel1]);

%% 对每个标签进行处理
for label = [0, 1]
    % 筛选当前标签的所有文件名
    labelFileNames = fileNames(labels == label);
    
    % 随机选择实际的样本数
    idx = randperm(length(labelFileNames), actualSamplesPerLabel);
    selectedFileNames = labelFileNames(idx);
    
    % 步骤2: 生成完整路径
    fullPaths = fullfile(dataFolder, selectedFileNames);
    
    % 将当前标签的路径添加到总路径数组中
    paths = [paths; fullPaths];
    
    % 生成与当前路径匹配的标签数组
    currentLabels = repmat(label, length(fullPaths), 1);
    
    % 将当前标签添加到总标签数组中
    labelsArray = [labelsArray; currentLabels];
end

%% 验证结果
% disp(paths);
% disp(labelsArray);

%%
MFCCFeatures = collectMFCCFeatures(paths);


% 假设您的总数据集大小
totalSamples = size(MFCCFeatures, 1);

% 创建一个分区对象,指定分割比例
cv = cvpartition(totalSamples, 'HoldOut', 0.2); % 这里0.2意味着20%的数据将用作验证集

% 索引训练集和验证集
idxTrain = training(cv);
idxValidation = test(cv);

% 分割MFCC特征为训练集和验证集
XTrain = MFCCFeatures(idxTrain, :, :, :);
XValidation = MFCCFeatures(idxValidation, :, :, :);

% 分割标签为训练集和验证集,并转换为categorical类型
YTrain = categorical(labelsArray(idxTrain));
YValidation = categorical(labelsArray(idxValidation));
%%


layers = [
    imageInputLayer([13 249 3]) % 输入层,输入尺寸匹配MFCC特征尺寸

    convolution2dLayer(3, 8, 'Padding','same') % 卷积层
    batchNormalizationLayer % 批标准化层
    reluLayer % ReLU激活层

    maxPooling2dLayer(2, 'Stride',2) % 最大池化层

    convolution2dLayer(3, 16, 'Padding','same') % 另一个卷积层
    batchNormalizationLayer % 批标准化层
    reluLayer % ReLU激活层

    maxPooling2dLayer(2, 'Stride',2) % 最大池化层

    fullyConnectedLayer(64) % 全连接层
    reluLayer % ReLU激活层
    fullyConnectedLayer(2) % 全连接层,输出类别数量假设为2
    softmaxLayer % Softmax激活层
    classificationLayer]; % 分类输出层

% 设置训练选项
options = trainingOptions('sgdm', ...
    'InitialLearnRate',0.01, ...
    'MaxEpochs',10, ...
    'Shuffle','every-epoch', ...
    'ValidationData',{XValidation,YValidation}, ...
    'ValidationFrequency',20, ...
    'Verbose',false, ...
    'Plots','training-progress');

% 训练CNN模型
% 注意:你需要将XTrain和YTrain替换为你的实际训练数据和标签

model = trainNetwork(XTrain,YTrain,layers,options);

% 使用训练好的模型进行预测或评估
% YPred = classify(model, XTest);
% accuracy = sum(YPred == YTest)/numel(YTest); % 计算准确率

我运行这个代码就会报错,错误提示如下
错误使用 trainNetwork
X 和 Y 中的观测值数量不一致。

出错 yiweixunlian (第 110 行)
model = trainNetwork(XTrain,YTrain,layers,options);

当我运行这段代码时就会报错,可是我已经检查过XTrain和YTrain的大小了,请问各位问题出在了哪儿啊?这是我其中涉及到的函数

function [mfcc, mfcc_delta, mfcc_delta2] = extractMFCCFeatures(audioFilePath)
    % 读取音频文件
    [audio_data, Fs] = audioread(audioFilePath);
    
    % 计算MFCC特征
    n_mfcc = 13;
    % 提取MFCC特征
    mfcc = melcepst(audio_data, Fs, 'M', n_mfcc);

    % 计算一阶差分和二阶差分
    mfcc_delta = diff(mfcc, 1, 1);
    mfcc_delta2 = diff(mfcc, 2, 1);
    
    % 为了保持维度一致性,对差分结果进行零填充
    mfcc_delta = [zeros(1, size(mfcc, 2)); mfcc_delta];  % 在开始处填充零
    mfcc_delta2 = [zeros(2, size(mfcc, 2)); mfcc_delta2];  % 在开始处填充两行零
end


function [features] = collectMFCCFeatures(paths)
    numFiles = length(paths);
    n_mfcc = 13; % 假设MFCC系数数量为13
    maxFrames = 0; % 用于记录最大时间帧数

    
    % 假设最大时间帧数,用于测试
    maxFrames = 249; % 硬编码为249进行测试

    % 初始化特征数组
    features = zeros(numFiles, n_mfcc, maxFrames, 3); % [numSamples, n_mfcc, numFrames, 3]

    % 再次遍历以填充特征数组
    for i = 1:numFiles
        [mfcc, mfcc_delta, mfcc_delta2] = extractMFCCFeatures(paths{i});
        
        % 对差分结果进行零填充以匹配最大时间帧数
        numCurrentFrames = size(mfcc, 1); % 当前MFCC的时间帧数
        paddingSize = maxFrames - numCurrentFrames; % 需要填充的零的数量

        % 根据需要填充零
        paddedMFCC = [mfcc; zeros(paddingSize, n_mfcc)];
        paddedDelta = [mfcc_delta; zeros(paddingSize, n_mfcc)];
        paddedDelta2 = [mfcc_delta2; zeros(paddingSize, n_mfcc)];

        % 填充特征数组,注意转置
        features(i,:,1:maxFrames,1) = paddedMFCC';
        features(i,:,1:maxFrames,2) = paddedDelta';
        features(i,:,1:maxFrames,3) = paddedDelta2';
    end
end


img

  • 写回答

20条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-04-09 19:37
    关注
    获得0.60元问题酬金

    引自免费微信小程序:皆我百晓生

    针对您提供的MATLAB代码中遇到的trainNetwork错误提示“X 和 Y 中的观测值数量不一致”,经过分析,问题可能出在以下方面:

    1. 数据集大小不匹配:尽管您已经检查过XTrainYTrain的大小,但仍然出现此错误,可能是由于在数据预处理、特征提取或数据集划分过程中出现了导致两者大小不一致的问题。

    2. 特征维度问题trainNetwork要求输入数据XTrain是四维张量,而YTrain应为一维向量。确保XTrain的第四维表示通道数(如RGB颜色通道),且与网络结构中的输入层设定相符。

    针对上述可能性,建议您按照以下步骤排查并解决:

    步骤1:检查特征提取过程

    确认collectMFCCFeatures函数是否正确地为每个样本生成了相同维度的特征。特别关注maxFrames的计算方式,确保它能准确反映每个样本的实际时间帧数,而不是硬编码。目前您已硬编码为249,这可能导致某些样本在填充零后与实际帧数不符。

    步骤2:核实数据集划分

    确保在使用cvpartition进行数据集划分时,idxTrainidxValidation所对应的MFCCFeatureslabelsArray子集的大小是一致的。可以分别计算idxTrainidxValidation的长度,并与size(XTrain)size(YTrain)进行对比。

    步骤3:验证XTrainYTrain的大小

    在代码中添加以下检查语句,确保XTrainYTrain的样本数量(第一维大小)相等:

    if size(XTrain, 1) ~= size(YTrain, 1)
        error('XTrain and YTrain have different numbers of observations.');
    end
    

    步骤4:检查YTrain向量化

    确保YTrain已经被正确地转换为一维向量。虽然您使用了categorical函数,但在实际应用中,确保其维度为1。可以使用以下代码验证:

    if ndims(YTrain) > 2 || size(YTrain, 2) > 1
        error('YTrain should be a column vector.');
    end
    

    步骤5:重新运行代码

    完成以上检查和修改后,重新运行代码,看是否还会出现“X 和 Y 中的观测值数量不一致”的错误。

    综上所述,通过仔细检查特征提取过程、数据集划分、以及XTrainYTrain的大小和维度,应该能找到并解决导致trainNetwork报错的原因。如果按照上述步骤操作后问题依然存在,请提供详细的XTrainYTrain大小信息及代码运行时的错误详细输出,以便进一步诊断。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 4月17日
  • 创建了问题 4月9日