NagumoYoichi 2024-03-09 17:24 采纳率: 60%
浏览 89
已结题

关于MATLAB深度神经网络DNN的问题

基于SOM-层次聚类结果的新数据类别预测

整个MATLAB代码的背景:

  • 有一组数据,几百行,每一行为一个样本,有24列,即24维。

  • 现在对这份数据进行聚类处理,先通过SOM聚类得到100个神经元,再用层次聚类把100个神经元进一步聚类得到5类,最终把数据分为了5类。

  • 以上聚类模型结束后,需要进行预测模型,用DNN深度神经网络,输入一条新的数据样本(同样24维),判断它属于之前聚类得到的5类中的哪一类。

  • 预测模型需要对这个无监督学习分类的模型(就是聚类模型)进行输入,最后输出预测的类别。

问题
聚类模型已经没有问题,可以运行,但是DNN预测的代码(代码第2部分)有问题,代码在后面部分。如何修改?

代码第一部分

clc;
clear;
%%%%%%%%%%%%%%%%%% 数据预处理 %%%%%%%%%%%%%%%%%%
% 指定Excel文件
excelFileName = '123.xlsx';
sheetName = '第一份';
dataRange = 'C2:Z366';
data = xlsread(excelFileName, sheetName, dataRange);

% knn预处理
k = 5;
% 遍历每一行数据
for i = 1:size(data, 1)
    % 获取当前行数据
    currentRow = data(i, :);  
    % 判断当前行数据是否全为0
    if all(currentRow == 0)
        disp(['第', num2str(i), '行数据全为0,跳过KNN算法']);
        continue; % 跳过当前循环,继续下一行数据的处理
    end    
    % 执行KNN算法
    % 使用 knnimpute 进行预处理
    data_preprocessed = knnimpute(data, k);    
end

% 计算 zscore
M11 = zscore(data_preprocessed');
x = M11;
%%%%%%%%%%%%%%%%%%%%%% S O M %%%%%%%%%%%%%%%%%%%%
% Create a Self-Organizing Map
dimension1 = 10;
dimension2 = 10;
net = selforgmap([dimension1 dimension2]);

% Choose Plot Functions
% For a list of all plot functions type: help nnplot
net.plotFcns = {'plotsomtop','plotsomnc','plotsomnd', ...
    'plotsomplanes', 'plotsomhits', 'plotsompos'};

% Train the Network
[net,tr] = train(net,x);

% Test the Network
y = net(x);

%%%%%%%%%%%%%%%%%%%%%% 层 次 聚 类 %%%%%%%%%%%%%%%%%%%%%%%%
% 获取 SOM 的输出(每个数据点对应的最终神经元索引)
som_output = vec2ind(y);

% 使用 SOM 输出作为 AGNES 的输入
agnes_input = net.IW{1};  % 获取 SOM 输出层的权重矩阵,每行对应一个样本

% 使用层次聚类(AGNES)进行进一步的聚类
Z = linkage(agnes_input, 'complete', 'euclidean');  % 使用complete linkage和欧氏距离

% 设置希望的最大簇的数量
max_clusters = 50;

% 显示 AGNES 的聚类结果
T = cluster(Z, 'maxclust', max_clusters);
% disp('AGNES聚类结果:');
% disp(T);

% 可视化层次聚类树
figure;
dendrogram(Z);

% 根据需要选择最终聚类结果,例如,选择前 k 个聚类
final_clusters = 5;
selected_clusters = cluster(Z, 'maxclust', final_clusters);

% 获取每个类别的数据
clustered_data = cell(final_clusters, 1);
for i = 1:final_clusters
    clustered_data{i} = data_preprocessed(selected_clusters == i, :);
end

% 计算每个聚类的平均曲线
cluster_center_curves = zeros(final_clusters, size(data_preprocessed, 2));
for i = 1:final_clusters
    cluster_center_curves(i, :) = mean(clustered_data{i}, 1);
end

以上代码都没有问题,可以运行

下面代码第2部分运行有问题,总是显示:

错误使用 trainNetwork
无效的训练数据。对于图像、序列到标签和特征分类任务,响应必须为分类响应。
dnn_model = trainNetwork(x, final_clusters, layers, options);

代码第2部分

%%%%%%%%%%%%%%%%%%% 构建和训练DNN模型 %%%%%%%%%%%%%%%%%%%%%%%%
% 假设你的DNN模型包含一个输入层,若干隐藏层,和一个输出层
input_size = size(x, 1); % 输入层大小等于数据维度,修改为 size(x, 1)
output_size = final_clusters; % 输出层大小等于聚类数目

% 构建DNN模型
layers = [
featureInputLayer(input_size) % 添加输入层
fullyConnectedLayer(50)
reluLayer
fullyConnectedLayer(20)
reluLayer
fullyConnectedLayer(output_size)
softmaxLayer
classificationLayer
];

% 设置训练选项
options = trainingOptions('adam', ...
'MaxEpochs', 100, ...
'MiniBatchSize', 32, ...
'InitialLearnRate', 0.001, ...
'LearnRateSchedule', 'piecewise', ...
'LearnRateDropPeriod', 50, ...
'LearnRateDropFactor', 0.1, ...
'Shuffle', 'every-epoch', ...
'Verbose', false);

% 训练DNN模型
dnn_model = trainNetwork(x, final_clusters, layers, options);
 
%%%%%%%%%%%%%%%%%%% 使用DNN进行分类 %%%%%%%%%%%%%%%%%%%%%%
% 假设新的24维数据样本存储在名为 new_data 的向量中
new_data = [43.52    38.56   37.2   33     35.52    40.72    43.32    35.16    35.04    43.24    38.16    56.68    38.28    27.44    26.44    39.12    43.76    37.68    27.56    34.88    35.44    31.96    35.4          32.24];
 
% 预处理新数据,确保与训练数据相同的处理
% knn预处理
k = 5;
% 遍历每一行数据
for i = 1:size(new_data, 1)
    % 获取当前行数据
    currentRow = new_data(i, :);  
    % 判断当前行数据是否全为0
    if all(currentRow == 0)
        disp(['第', num2str(i), '行数据全为0,跳过KNN算法']);
        continue; % 跳过当前循环,继续下一行数据的处理
    end    
    % 执行KNN算法
    % 使用 knnimpute 进行预处理
    newData = knnimpute(new_data, k);    
end
 
% 对新数据进行预处理,例如 zscore
newData_preprocessed = zscore(newData);
 
% 使用训练好的 DNN 模型进行分类
predicted_labels = classify(dnn_model, newData_preprocessed');
 
% 输出预测结果
disp('预测结果:');
disp(predicted_labels);


就是trainNetwork部分有问题,如何解决?

  • 写回答

11条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-09 17:25
    关注

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

    在上述代码中,问题出在使用 trainNetwork 函数训练深度神经网络 (DNN) 时的输入和目标响应参数上。对于分类任务,DNN 的输出层通常会接一个 softmaxLayer,而对应的训练数据标签应当是分类标签(即从 1 到类别数目的整数编码),而不是原始的聚类索引。

    要解决这个问题,请将以下步骤修改:

    1. 对最终聚类结果进行编码:将层次聚类得到的聚类索引转换为 one-hot 编码形式,作为 DNN 训练的目标响应。
    % 将 final_clusters 转换为 one-hot 编码
    y_encoded = zeros(size(x, 1), final_clusters);
    for i = 1:size(x, 1)
        y_encoded(i, selected_clusters(i)) = 1;
    end
    
    1. 用 one-hot 编码后的标签替换 final_clusters 在调用 trainNetwork 函数时:
    dnn_model = trainNetwork(x, y_encoded, layers, options);
    

    此外,针对新数据的预处理部分也需要注意,无需再次执行 KNN 预处理(因为这是在原始训练集上做的操作),直接对新样本做与训练集相同的 zscore 标准化即可。因此,可以简化新数据预处理部分的代码如下:

    % 假设新的24维数据样本存储在名为 new_data 的向量中
    new_data = [43.52    38.56   37.2   33     35.52    40.72    43.32    35.16    35.04    43.24    38.16    56.68    38.28    27.44    26.44    39.12    43.76    37.68    27.56    34.88    35.44    31.96    35.4      32.24];
    
    % 直接对新数据进行预处理,例如 zscore
    newData_preprocessed = zscore(new_data');
    
    % 使用训练好的 DNN 模型进行分类
    predicted_labels = classify(dnn_model, newData_preprocessed);
    
    % 输出预测结果
    disp('预测结果:');
    disp(predicted_labels);
    

    现在,整个流程应该能正确运行并训练一个用于分类的新数据点所属类别的 DNN 模型了。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月10日
  • 创建了问题 3月9日

悬赏问题

  • ¥15 Windows Script Host 无法找到脚本文件"C:\ProgramData\Player800\Cotrl.vbs”
  • ¥15 matlab自定义损失函数
  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图