NagumoYoichi 2024-03-09 15:15 采纳率: 60%
浏览 27
已结题

MATLAB深度神经网络的问题

基于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
无效网络。
原因:
    网络: 缺少输入层。网络必须有至少一个输入层。
    层 1: 未连接的输入。每个层输入必须连接到另一个层的输出。

代码第2部分


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

% 构建DNN模型
layers = [
    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', categorical(selected_clusters), layers, options);

%%%%%%%%%%%%%%%%%%% 使用DNN进行分类 %%%%%%%%%%%%%%%%%%%%%%
% 假设新的24维数据样本存储在名为 new_data 的向量中
new_data = [    ];

% 预处理新数据,确保与训练数据相同的处理
% 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);
  • 写回答

8条回答 默认 最新

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

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

    根据您的描述,MATLAB中DNN预测部分的错误提示指出网络缺少输入层。在您提供的代码中,trainNetwork函数的输入参数不完整或格式有误,导致MATLAB无法识别输入数据和目标类别。

    为了解决这个问题,请确保正确构建了DNN模型并提供正确的训练数据。以下是修正后的代码第2部分:

    %%%%%%%%%%%%%%%%%%% 构建和训练DNN模型 %%%%%%%%%%%%%%%%%%%%%%%
    % 确保输入层大小与预处理后的数据维度一致
    input_size = size(x, 2); % 输入层大小等于数据维度
    
    % 根据聚类结果调整输出层大小
    output_size = final_clusters; % 输出层大小等于聚类数目
    
    % 构建DNN模型,注意将x作为输入数据,selected_clusters作为分类标签
    layers = [
        fullyConnectedLayer(input_size)
        reluLayer
        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模型,这里需要将x'(转置后的特征矩阵)和categorical(selected_clusters)作为输入
    dnn_model = trainNetwork(x', categorical(selected_clusters), layers, options);
    
    %%%%%%%%%%%%%%%%%%% 使用DNN进行分类 %%%%%%%%%%%%%%%%%%%%%%
    % 假设新的24维数据样本存储在名为 new_data 的向量中
    new_data = [ ]; % 需要替换为实际的新数据
    
    % 对新数据执行与原始数据相同的预处理步骤
    new_data_preprocessed = zscore(new_data');
    
    % 在使用knnimpute之前,检查是否有必要对新数据应用KNN插补
    % 如果新数据中存在全零行,可以跳过KNN预处理
    for i = 1:size(new_data_preprocessed, 1)
        currentRow = new_data_preprocessed(i, :);
        if all(currentRow == 0)
            disp(['第', num2str(i), '行数据全为0,跳过KNN算法']);
            continue;
        end
        % 因为之前的预处理已经包含了zscore,此处是否需要KNN插补请根据实际情况决定
        % 如果确实需要KNN插补,则执行以下代码
        % newData = knnimpute(new_data_preprocessed, k);
    end
    
    % 使用训练好的 DNN 模型进行分类
    predicted_labels = classify(dnn_model, new_data_preprocessed');
    
    % 输出预测结果
    disp('预测结果:');
    disp(predicted_labels);
    

    请注意:

    1. 确保在构建DNN模型时,输入层大小与预处理后数据维度一致。
    2. 在调用trainNetwork函数时,第二个参数应为经过one-hot编码的分类标签,这里我们使用categorical(selected_clusters)
    3. 在对新数据进行分类前,同样需要先完成与训练数据相同的预处理步骤,包括z-score标准化等操作。不过,在这段代码中,对于新数据的KNN预处理可能并不必要,因为原始代码中并未对所有新数据执行此操作,而是仅针对非全零行。如果新数据也需要KNN插补,请取消注释相应的代码行。
    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月9日
  • 创建了问题 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 微信的店铺小程序如何修改背景图