活动介绍
file-type

深入解析matlab中的my_conv_2d二维卷积函数

ZIP文件

下载需积分: 50 | 2KB | 更新于2025-04-23 | 68 浏览量 | 5 下载量 举报 收藏
download 立即下载
在本节中,我们着重于介绍在MATLAB环境下开发的二维卷积函数`my_conv_2d`的相关知识点。这一过程涉及图像处理的核心概念和MATLAB编程技巧,以下是详细说明。 ### 二维卷积函数概述 二维卷积是一种图像处理技术,广泛应用于信号处理和图像分析领域。卷积操作涉及到两个矩阵:一个是输入的图片矩阵,另一个是过滤器矩阵(也称为核或滤波器)。在卷积过程中,过滤器在图片矩阵上滑动,计算重叠元素的加权和,从而产生一个新的二维矩阵,即卷积矩阵。 ### 关键知识点解析 #### 1. 图片矩阵与过滤矩阵 - **图片矩阵**:一般代表图像的像素值矩阵,其中矩阵的每个元素对应图像上的一个像素点,像素值可以是灰度值或者RGB颜色值等。 - **过滤矩阵**:通常是一个较小的矩阵,设计用来提取图像的特定特征,例如边缘、纹理等。在卷积过程中,过滤器通过在图片矩阵上移动来计算每个位置的卷积值。 #### 2. 边缘处理策略 在进行二维卷积时,需要处理图片边缘的像素,因为过滤器可能会超出图片矩阵的边界。有几种边缘处理策略,其中常见的包括零填充、镜像填充和边界复制等。在本函数`my_conv_2d`中,采用的是镜像原始数据的策略。这意味着当过滤器到达图片矩阵的边缘时,会使用图片矩阵边缘外侧像素值的镜像进行填充,这样可以减少边界效应,使边缘附近的像素也被合理地处理。 #### 3. 卷积矩阵的生成 - 卷积矩阵的大小:卷积后得到的新矩阵,其尺寸与原始图片矩阵相同。这是因为每个像素都对应了一个卷积结果。 - 卷积矩阵的值:卷积矩阵中的每个元素是通过将过滤器矩阵与图片矩阵中对应的局部区域进行点乘再求和得到的。整个卷积矩阵是通过在图片矩阵的每个像素位置重复此过程获得的。 - 卷积矩阵的格式:由于使用了镜像填充策略,卷积矩阵保留了与原图片矩阵相同的格式,保持了图像的颜色深度等信息。 #### 4. MATLAB编程实现 在MATLAB中,二维卷积函数可以使用内建函数`conv2`来实现,但本例中`my_conv_2d`函数可能是为了深入理解卷积过程或实现特定的算法改进而手动编写的。 - **函数定义**:`my_conv_2d`函数需要至少两个参数,即图片矩阵和过滤矩阵。 - **循环处理**:可能通过嵌套循环遍历图片矩阵的每个像素,并在每个位置应用过滤器。 - **边缘处理**:在卷积过程中,需要对边缘进行特殊处理,以确保过滤器可以应用于图片矩阵的边界。 - **输出结果**:函数最终返回一个与输入图片矩阵大小和格式相同的卷积矩阵。 ### 附录:使用`my_conv_2d`函数的示例代码 ```matlab % 示例代码未提供,因此此处基于知识点构建一段示例代码 % 假设有以下图片矩阵和过滤器矩阵 img_matrix = [ ... ]; % 图片矩阵的定义 filter_matrix = [ ... ]; % 过滤器矩阵的定义 % 调用my_conv_2d函数进行卷积 conv_matrix = my_conv_2d(img_matrix, filter_matrix); % 显示卷积结果 disp(conv_matrix); ``` 通过以上分析,我们可以看出`my_conv_2d`函数的实现和使用涉及到信号处理中的核心算法、图像处理的基本概念以及MATLAB编程的技巧。掌握这些知识点对于进行图像处理和开发相关算法具有重要意义。

相关推荐

filetype

%% 初始化环境 clear; clc; close all; rng(42); % 固定随机种子确保可复现性 %% 参数设置 fs = 3200; % 采样频率 (Hz) N = 640; % 采样点数 t = (0:N-1)/fs; % 时间向量 f0 = 50; % 基频 (Hz) numSamples = 100; % 总样本数 noiseSNR = 40; % 信噪比 (dB) %% 生成PQD电压暂升信号数据集 X_signals = zeros(numSamples, N); % 存储时序信号 X_spectrograms = zeros(numSamples, 64, 64); % 存储时频图 labels = zeros(numSamples, 1); % 存储标签 (0:正常, 1:暂升) for i = 1:numSamples % 生成纯净正弦波 Vm = 1 + 0.1*randn(); % 幅值 (1±0.1 pu) phi = 2*pi*rand(); % 随机相位 cleanSignal = Vm * sin(2*pi*f0*t + phi); % 50%概率生成暂升扰动 if rand() > 0.5 labels(i) = 1; % 随机扰动参数 startTime = 0.04 + 0.12*rand(); % 起始时间 (0.04-0.16s) duration = 0.02 + 0.06*rand(); % 持续时间 (0.02-0.08s) k = 0.1 + 0.8*rand(); % 暂升幅度 (0.1-0.9 pu) % 创建暂升扰动 disturbance = zeros(1, N); idx = find(t >= startTime & t <= startTime + duration); disturbance(idx) = k; % 添加扰动 cleanSignal = cleanSignal .* (1 + disturbance); end % 添加高斯白噪声 noisySignal = awgn(cleanSignal, noiseSNR, 'measured'); X_signals(i, :) = noisySignal; % 计算S变换时频图 st_mag = st_transform(noisySignal, fs); % 归一化并调整大小 st_mag = st_mag / max(st_mag(:)); X_spectrograms(i, :, :) = imresize(st_mag, [64, 64]); end %% 数据集划分 rng(42); % 重置随机种子 splitRatio = [0.8, 0.1, 0.1]; % 训练:验证:测试 numTrain = round(splitRatio(1)*numSamples); numVal = round(splitRatio(2)*numSamples); numTest = numSamples - numTrain - numVal; % 随机索引 idx = randperm(numSamples); trainIdx = idx(1:numTrain); valIdx = idx(numTrain+1:numTrain+numVal); testIdx = idx(numTrain+numVal+1:end); % 时序信号数据集 - 重塑为正确的维度 [1, 序列长度, 1, 样本数] X_train_signal = reshape(X_signals(trainIdx, :)', [1, N, 1, numTrain]); X_val_signal = reshape(X_signals(valIdx, :)', [1, N, 1, numVal]); X_test_signal = reshape(X_signals(testIdx, :)', [1, N, 1, numTest]); % 时频图数据集 - 重塑为 [高度, 宽度, 通道, 样本数] % 先提取训练、验证和测试集的时频图 X_train_spec = X_spectrograms(trainIdx, :, :); X_val_spec = X_spectrograms(valIdx, :, :); X_test_spec = X_spectrograms(testIdx, :, :); % 然后重塑维度 X_train_spec = permute(X_train_spec, [2, 3, 4, 1]); % [64, 64, 1, numTrain] X_val_spec = permute(X_val_spec, [2, 3, 4, 1]); % [64, 64, 1, numVal] X_test_spec = permute(X_test_spec, [2, 3, 4, 1]); % [64, 64, 1, numTest] % 标签数据集 Y_train = categorical(labels(trainIdx)); Y_val = categorical(labels(valIdx)); Y_test = categorical(labels(testIdx)); %% 构建TCN-CNN融合模型 (修复语法错误) input_signal = imageInputLayer([1, N, 1], 'Name', 'signal_input', 'Normalization', 'none'); input_spec = imageInputLayer([64, 64, 1], 'Name', 'spec_input', 'Normalization', 'none'); % TCN分支 (时序特征提取) - 使用sequenceFoldingLayer解决维度问题 tcnLayers = [ sequenceFoldingLayer('Name', 'fold') % 将3D输入转换为2D序列 convolution2dLayer([1, 3], 16, 'Padding', 'same', 'Name', 'tcn_conv1') % 使用2D卷积处理1D序列 reluLayer('Name', 'tcn_relu1') convolution2dLayer([1, 3], 32, 'DilationFactor', [1, 2], 'Padding', 'same', 'Name', 'tcn_conv2') reluLayer('Name', 'tcn_relu2') convolution2dLayer([1, 3], 64, 'DilationFactor', [1, 4], 'Padding', 'same', 'Name', 'tcn_conv3') reluLayer('Name', 'tcn_relu3') sequenceUnfoldingLayer('Name', 'unfold') flattenLayer('Name', 'tcn_flatten') fullyConnectedLayer(32, 'Name', 'tcn_fc') ]; % CNN分支 (时频特征提取) cnnLayers = [ convolution2dLayer(3, 16, 'Padding', 'same', 'Name', 'cnn_conv1') batchNormalizationLayer('Name', 'cnn_bn1') reluLayer('Name', 'cnn_relu1') maxPooling2dLayer(2, 'Stride', 2, 'Name', 'cnn_pool1') % 64x64 -> 32x32 convolution2dLayer(3, 32, 'Padding', 'same', 'Name', 'cnn_conv2') batchNormalizationLayer('Name', 'cnn_bn2') reluLayer('Name', 'cnn_relu2') maxPooling2dLayer(2, 'Stride', 2, 'Name', 'cnn_pool2') % 32x32 -> 16x16 convolution2dLayer(3, 64, 'Padding', 'same', 'Name', 'cnn_conv3') batchNormalizationLayer('Name', 'cnn_bn3') reluLayer('Name', 'cnn_relu3') convolution2dLayer(1, 128, 'Padding', 'same', 'Name', 'cnn_conv4') % 1x1卷积增加通道数 batchNormalizationLayer('Name', 'cnn_bn4') reluLayer('Name', 'cnn_relu4') globalAveragePooling2dLayer('Name', 'cnn_gap') % 全局平均池化 fullyConnectedLayer(32, 'Name', 'cnn_fc') ]; % 特征融合与分类 - 修复语法错误 % 创建独立的reshape层 - 修复语法错误 reshape_tcn = functionLayer(@(X) dlarray(reshape(X, [1, 1, 32, size(X,2)]), ... 'Formattable', true, 'Name', 'reshape_tcn'); reshape_cnn = functionLayer(@(X) dlarray(reshape(X, [1, 1, 32, size(X,2)]), ... 'Formattable', true, 'Name', 'reshape_cnn'); % 创建深度连接层(沿通道维度连接) concat_layer = depthConcatenationLayer(2, 'Name', 'concat'); % 沿通道维度拼接,指定2个输入 % 分类层 fusion_fc1 = fullyConnectedLayer(64, 'Name', 'fusion_fc1'); fusion_relu = reluLayer('Name', 'fusion_relu'); fusion_dropout = dropoutLayer(0.5, 'Name', 'fusion_dropout'); fusion_fc2 = fullyConnectedLayer(32, 'Name', 'fusion_fc2'); fusion_relu2 = reluLayer('Name', 'fusion_relu2'); fc_final = fullyConnectedLayer(2, 'Name', 'fc_final'); softmax = softmaxLayer('Name', 'softmax'); output_layer = classificationLayer('Name', 'output'); % 组装完整模型 lgraph = layerGraph(); % 添加输入层 lgraph = addLayers(lgraph, input_signal); lgraph = addLayers(lgraph, input_spec); % 添加TCN分支 lgraph = addLayers(lgraph, tcnLayers); lgraph = connectLayers(lgraph, 'signal_input', 'fold'); % 添加CNN分支 lgraph = addLayers(lgraph, cnnLayers); lgraph = connectLayers(lgraph, 'spec_input', 'cnn_conv1'); % 添加reshape层 lgraph = addLayers(lgraph, reshape_tcn); lgraph = addLayers(lgraph, reshape_cnn); % 添加连接层 lgraph = addLayers(lgraph, concat_layer); % 添加分类层 lgraph = addLayers(lgraph, fusion_fc1); lgraph = addLayers(lgraph, fusion_relu); lgraph = addLayers(lgraph, fusion_dropout); lgraph = addLayers(lgraph, fusion_fc2); lgraph = addLayers(lgraph, fusion_relu2); lgraph = addLayers(lgraph, fc_final); lgraph = addLayers(lgraph, softmax); lgraph = addLayers(lgraph, output_layer); % 连接TCN分支 lgraph = connectLayers(lgraph, 'tcn_fc', 'reshape_tcn'); lgraph = connectLayers(lgraph, 'reshape_tcn', 'concat/in1'); % 连接到输入端口1 % 连接CNN分支 lgraph = connectLayers(lgraph, 'cnn_fc', 'reshape_cnn'); lgraph = connectLayers(lgraph, 'reshape_cnn', 'concat/in2'); % 连接到输入端口2 % 连接融合层 lgraph = connectLayers(lgraph, 'concat', 'fusion_fc1'); lgraph = connectLayers(lgraph, 'fusion_fc1', 'fusion_relu'); lgraph = connectLayers(lgraph, 'fusion_relu', 'fusion_dropout'); lgraph = connectLayers(lgraph, 'fusion_dropout', 'fusion_fc2'); lgraph = connectLayers(lgraph, 'fusion_fc2', 'fusion_relu2'); lgraph = connectLayers(lgraph, 'fusion_relu2', 'fc_final'); lgraph = connectLayers(lgraph, 'fc_final', 'softmax'); lgraph = connectLayers(lgraph, 'softmax', 'output'); % 添加最小连接以支持sequenceUnfoldingLayer lgraph = connectLayers(lgraph, 'fold/miniBatchSize', 'unfold/miniBatchSize'); % 显示网络结构 analyzeNetwork(lgraph); %% 训练配置 options = trainingOptions('adam', ... 'MaxEpochs', 50, ... 'MiniBatchSize', 16, ... 'InitialLearnRate', 1e-3, ... 'LearnRateSchedule', 'piecewise', ... 'LearnRateDropFactor', 0.5, ... 'LearnRateDropPeriod', 15, ... 'ValidationData', { {X_val_signal, X_val_spec}, Y_val }, ... 'ValidationFrequency', 30, ... 'Shuffle', 'every-epoch', ... 'Verbose', true, ... 'Plots', 'training-progress', ... 'ExecutionEnvironment', 'auto', ... 'OutputNetwork', 'best-validation-loss'); %% 训练模型 net = trainNetwork({X_train_signal, X_train_spec}, Y_train, lgraph, options); %% 测试集评估 [YPred, probs] = classify(net, {X_test_signal, X_test_spec}); accuracy = mean(YPred == Y_test); fprintf('测试集准确率: %.2f%%\n', accuracy*100); % 混淆矩阵 figure; confusionchart(Y_test, YPred); title('混淆矩阵'); % 绘制部分样本的原始信号和时频图 figure; for i = 1:4 % 原始信号 subplot(4, 2, 2*i-1); signal_data = squeeze(X_test_signal(1, :, 1, i)); plot(t, signal_data); title(['Test Sample ', num2str(i), ' - Label: ', char(Y_test(i))]); xlabel('Time (s)'); ylabel('Amplitude'); % 时频图 subplot(4, 2, 2*i); imagesc(squeeze(X_test_spec(:, :, 1, i))); title('S-transform Spectrogram'); xlabel('Time Index'); ylabel('Frequency Index'); axis xy; colorbar; end %% S变换实现函数 function st_mag = st_transform(signal, fs) N = length(signal); t = (0:N-1)/fs; f_min = 0; f_max = 1600; % 最高分析频率 nfreq = 64; % 频率点数 % 频率向量 freqs = linspace(f_min, f_max, nfreq); st_matrix = zeros(nfreq, N); % 傅里叶变换 F = fft(signal); % 计算S变换 for k = 1:nfreq f = freqs(k); if f == 0 % 对于0频率,使用简单的均值 st_matrix(k, :) = mean(signal)*ones(1,N); continue; end % 构造高斯窗 sigma = 1/(2*pi*f); window = exp(-((0:N-1) - N/2).^2 / (2*sigma^2)); window_shifted = circshift(window, -floor(N/2)); % 频域卷积 F_window = fft(window_shifted); F_convolved = F .* F_window; % 逆变换并存储 st_matrix(k, :) = ifft(F_convolved); end % 取幅度 st_mag = abs(st_matrix); end 分析代码是否有错误

filetype

%% 电压暂升信号检测系统 - 重构版 (确保样本一致性) clear; clc; close all; %% 参数设置 fs = 3200; % 采样频率 (Hz) N = 640; % 采样点数 numSignals = 50; % 总样本数 (小样本集用于调试) trainRatio = 0.8; % 训练集比例 valRatio = 0.1; % 验证集比例 testRatio = 0.1; % 测试集比例 numClasses = 2; % 类别数 (正常 vs 电压暂升) %% 1. 生成PQD电压暂升数据集 fprintf('生成PQD数据集...\n'); [signals, labels] = generatePQDDataset(fs, N, numSignals); fprintf('生成信号数量: %d, 标签数量: %d\n', size(signals, 1), numel(labels)); % 重塑信号数据为4D数组: [1, N, 1, numSignals] X1D_all = reshape(signals', [1, N, 1, size(signals, 1)]); fprintf('一维信号数据维度: %s\n', mat2str(size(X1D_all))); %% 2. 计算时频图 - 使用更可靠的STFT方法 fprintf('计算时频图...\n'); XTF_all = zeros(64, 64, 1, size(X1D_all, 4)); % 预分配内存 for i = 1:size(X1D_all, 4) sig = squeeze(X1D_all(1, :, 1, i))'; XTF_all(:, :, 1, i) = computeSpectrogram(sig, fs); end fprintf('时频图数据维度: %s\n', mat2str(size(XTF_all))); %% 3. 数据集划分 - 关键重构 fprintf('划分数据集...\n'); % 计算各集合样本数量 numTrain = floor(numSignals * trainRatio); numVal = floor(numSignals * valRatio); numTest = numSignals - numTrain - numVal; % 创建随机索引 indices = randperm(numSignals); trainIndices = indices(1:numTrain); valIndices = indices(numTrain+1:numTrain+numVal); testIndices = indices(numTrain+numVal+1:end); % 提取训练集 X1D_train = X1D_all(:, :, :, trainIndices); XTF_train = XTF_all(:, :, :, trainIndices); Y_train = categorical(labels(trainIndices))'; % 提取验证集 X1D_val = X1D_all(:, :, :, valIndices); XTF_val = XTF_all(:, :, :, valIndices); Y_val = categorical(labels(valIndices))'; % 提取测试集 X1D_test = X1D_all(:, :, :, testIndices); XTF_test = XTF_all(:, :, :, testIndices); Y_test = categorical(labels(testIndices))'; % 确保样本数量一致 fprintf('训练集: 一维信号=%d, 时频图=%d, 标签=%d\n', ... size(X1D_train, 4), size(XTF_train, 4), numel(Y_train)); fprintf('验证集: 一维信号=%d, 时频图=%d, 标签=%d\n', ... size(X1D_val, 4), size(XTF_val, 4), numel(Y_val)); fprintf('测试集: 一维信号=%d, 时频图=%d, 标签=%d\n', ... size(X1D_test, 4), size(XTF_test, 4), numel(Y_test)); % 样本数量一致性检查 assert(size(X1D_train, 4) == numel(Y_train), '训练集一维信号样本数量不一致'); assert(size(XTF_train, 4) == numel(Y_train), '训练集时频图样本数量不一致'); assert(size(X1D_val, 4) == numel(Y_val), '验证集一维信号样本数量不一致'); assert(size(XTF_val, 4) == numel(Y_val), '验证集时频图样本数量不一致'); assert(size(X1D_test, 4) == numel(Y_test), '测试集一维信号样本数量不一致'); assert(size(XTF_test, 4) == numel(Y_test), '测试集时频图样本数量不一致'); %% 4. 构建双分支深度学习模型 fprintf('构建双分支模型...\n'); % 创建输入层 input1 = imageInputLayer([1, N, 1], 'Name', '1D_Input'); input2 = imageInputLayer([64, 64, 1], 'Name', 'TF_Input'); % 一维信号分支 (简化) branch1 = [ convolution2dLayer([1, 5], 8, 'Padding', 'same', 'Name', 'Conv1D_1') reluLayer('Name', 'ReLU1D_1') maxPooling2dLayer([1, 2], 'Stride', [1, 2], 'Name', 'Pool1D_1') convolution2dLayer([1, 5], 16, 'Padding', 'same', 'Name', 'Conv1D_2') reluLayer('Name', 'ReLU1D_2') globalAveragePooling2dLayer('Name', 'GAP1D') fullyConnectedLayer(32, 'Name', 'FC1D') ]; % 时频图分支 (简化) branch2 = [ convolution2dLayer(3, 8, 'Padding', 'same', 'Name', 'Conv2D_1') reluLayer('Name', 'ReLU2D_1') maxPooling2dLayer(2, 'Stride', 2, 'Name', 'Pool2D_1') convolution2dLayer(3, 16, 'Padding', 'same', 'Name', 'Conv2D_2') reluLayer('Name', 'ReLU2D_2') globalAveragePooling2dLayer('Name', 'GAP2D') fullyConnectedLayer(32, 'Name', 'FC2D') ]; % 特征融合与分类 fusion = [ concatenationLayer(3, 2, 'Name', 'Concat') fullyConnectedLayer(64, 'Name', 'FC_Fusion') reluLayer('Name', 'ReLU_Fusion') fullyConnectedLayer(numClasses, 'Name', 'FC_Output') softmaxLayer('Name', 'Softmax') classificationLayer('Name', 'Output') ]; % 构建完整网络 lgraph = layerGraph(); % 添加输入分支 lgraph = addLayers(lgraph, input1); lgraph = addLayers(lgraph, input2); lgraph = addLayers(lgraph, branch1); lgraph = addLayers(lgraph, branch2); lgraph = addLayers(lgraph, fusion); % 连接层 lgraph = connectLayers(lgraph, '1D_Input', 'Conv1D_1'); lgraph = connectLayers(lgraph, 'TF_Input', 'Conv2D_1'); lgraph = connectLayers(lgraph, 'FC1D', 'Concat/in1'); lgraph = connectLayers(lgraph, 'FC2D', 'Concat/in2'); % 分析网络结构 analyzeNetwork(lgraph); %% 5. 模型训练 - 确保数据一致性 fprintf('开始训练模型...\n'); % 准备训练数据 trainData = {X1D_train, XTF_train}; valData = {X1D_val, XTF_val}; % 最终样本数量检查 fprintf('训练数据样本数: 输入1=%d, 输入2=%d, 标签=%d\n', ... size(trainData{1}, 4), size(trainData{2}, 4), numel(Y_train)); fprintf('验证数据样本数: 输入1=%d, 输入2=%d, 标签=%d\n', ... size(valData{1}, 4), size(valData{2}, 4), numel(Y_val)); % 确保样本数量一致 if size(trainData{1}, 4) ~= numel(Y_train) || size(trainData{2}, 4) ~= numel(Y_train) error('训练数据与标签样本数量不一致'); end if size(valData{1}, 4) ~= numel(Y_val) || size(valData{2}, 4) ~= numel(Y_val) error('验证数据与标签样本数量不一致'); end % 简化训练选项 options = trainingOptions('adam', ... 'InitialLearnRate', 0.001, ... 'MaxEpochs', 5, ... 'MiniBatchSize', 4, ... 'Shuffle', 'every-epoch', ... 'ValidationData', {valData, Y_val}, ... 'ValidationFrequency', 2, ... 'Verbose', true, ... 'Plots', 'training-progress'); % 训练模型 try [net, trainInfo] = trainNetwork(trainData, Y_train, lgraph, options); catch ME fprintf('训练出错: %s\n', ME.message); fprintf('错误发生在: %s (行号 %d)\n', ME.stack(1).name, ME.stack(1).line); % 显示详细维度信息 fprintf('\n===== 维度调试信息 =====\n'); fprintf('训练数据1维度: %s\n', mat2str(size(trainData{1}))); fprintf('训练数据2维度: %s\n', mat2str(size(trainData{2}))); fprintf('训练标签维度: %s\n', mat2str(size(Y_train))); % 重新抛出错误以进入调试模式 rethrow(ME); end %% 6. 模型评估 fprintf('评估模型性能...\n'); % 准备测试数据 testData = {X1D_test, XTF_test}; % 样本数量检查 fprintf('测试数据样本数: 输入1=%d, 输入2=%d, 标签=%d\n', ... size(testData{1}, 4), size(testData{2}, 4), numel(Y_test)); YPred = classify(net, testData, 'MiniBatchSize', 4); % 计算准确率 accuracy = sum(YPred == Y_test) / numel(Y_test); fprintf('测试集准确率: %.2f%%\n', accuracy * 100); % 混淆矩阵 figure; confusionchart(Y_test, YPred, 'Title', '电压暂升检测混淆矩阵'); %% 辅助函数定义 function [signals, labels] = generatePQDDataset(fs, N, numSignals) % 生成正常信号和电压暂升信号 t = (0:N-1)/fs; f0 = 50; % 基频 (Hz) signals = zeros(numSignals, N); labels = zeros(numSignals, 1); % 确保两类样本平衡 for i = 1:numSignals % 平衡两类样本 signalType = mod(i-1, 2); % 交替生成正常和暂升信号 labels(i) = signalType; % 生成基本信号 signal = sin(2*pi*f0*t); if signalType == 1 % 电压暂升 % 固定参数简化调试 startTime = 0.15; duration = 0.05; magnitude = 0.5; % 创建暂升 endTime = startTime + duration; idx = (t >= startTime) & (t <= endTime); signal(idx) = (1 + magnitude) * signal(idx); end % 添加固定噪声 noiseLevel = 0.03; signal = signal + noiseLevel * randn(1, N); signals(i, :) = signal; end fprintf('已生成%d个信号: %d个正常, %d个电压暂升\n', ... numSignals, sum(labels==0), sum(labels==1)); end function spect = computeSpectrogram(signal, fs) % 使用MATLAB内置的spectrogram函数 [s, ~, ~] = spectrogram(signal, 64, 60, 64, fs, 'yaxis'); % 取绝对值并调整方向 spect = abs(s); % 归一化 spect = spect / max(spect(:)); % 确保大小正确 if size(spect, 1) ~= 64 || size(spect, 2) ~= 64 spect = imresize(spect, [64, 64]); end end 运行后“ [net, trainInfo] = trainNetwork(trainData, Y_train, lgraph, options);”这一处出现错误原因是无效的训练数据。预测变量和响应必须有相同的观测值数目。请帮我修正

filetype

% 初始化 clear close all clc warning off %% 读取数据 res = xlsread('CRNR.xlsx'); %% 分析数据 num_class = 2; % 类别数(Excel最后一列放类别) num_dim = size(res, 2) - 1; % 特征维度 num_res = size(res, 1); % 样本数(每一行,是一个样本) num_size = 0.7; % 训练集占数据集的比例 res = res(randperm(num_res), :); % 打乱数据集(不打乱数据时,注释该行) flag_conusion = 1; % 标志位为1,打开混淆矩阵(要求2018版本及以上) %% 设置变量存储数据 P_train = []; P_test = []; T_train = []; T_test = []; %% 划分数据集 for i = 1 : num_class mid_res = res((res(:, end) == i), :); % 循环取出不同类别的样本 mid_size = size(mid_res, 1); % 得到不同类别样本个数 mid_tiran = round(num_size * mid_size); % 得到该类别的训练样本个数 P_train = [P_train; mid_res(1: mid_tiran, 1: end - 1)]; % 训练集输入 T_train = [T_train; mid_res(1: mid_tiran, end)]; % 训练集输出 P_test = [P_test; mid_res(mid_tiran + 1: end, 1: end - 1)]; % 测试集输入 T_test = [T_test; mid_res(mid_tiran + 1: end, end)]; % 测试集输出 end %% 数据转置 P_train = P_train'; P_test = P_test'; T_train = T_train'; T_test = T_test'; %% 得到训练集和测试样本个数 M = size(P_train, 2); N = size(P_test , 2); %% 数据归一化 [P_train, ps_input] = mapminmax(P_train, 0, 1); P_test = mapminmax('apply', P_test, ps_input); t_train = categorical(T_train)'; t_test = categorical(T_test )'; %% 数据平铺 % 将数据平铺成1维数据只是一种处理方式 % 也可以平铺成2维数据,以及3维数据,需要修改对应模型结构 % 但是应该始终和输入层数据结构保持一致 p_train = double(reshape(P_train, num_dim, 1, 1, M)); p_test = double(reshape(P_test , num_dim, 1, 1, N)); %% 构造网络结构 layers = [ imageInputLayer([num_dim, 1, 1]) % 输入层 convolution2dLayer([2, 1], 16, 'Padding', 'same') % 卷积核大小为 2*1 生成16个卷积 batchNormalizationLayer % 批归一化层 reluLayer % relu 激活层 maxPooling2dLayer([2, 1], 'Stride', [2, 1]) % 最大池化层 大小为 2*1 步长为 [2, 1] convolution2dLayer([2, 1], 32, 'Padding', 'same') % 卷积核大小为 2*1 生成32个卷积 batchNormalizationLayer % 批归一化层 reluLayer % relu 激活层 fullyConnectedLayer(num_class) % 全连接层(类别数) softmaxLayer % 损失函数层 classificationLayer]; % 分类层 %% 参数设置 options = trainingOptions('adam', ... % Adam 梯度下降算法 'MaxEpochs', 500, ... % 最大训练次数 500 'InitialLearnRate', 1e-3, ... % 初始学习率为 0.001 'L2Regularization', 1e-4, ... % L2正则化参数 'LearnRateSchedule', 'piecewise', ... % 学习率下降 'LearnRateDropFactor', 0.1, ... % 学习率下降因子 0.1 'LearnRateDropPeriod', 400, ... % 经过450次训练后 学习率为 0.001 * 0.1 'Shuffle', 'every-epoch', ... % 每次训练打乱数据集 'ValidationPatience', Inf, ... % 关闭验证 'Plots', 'training-progress', ... % 画出曲线 'Verbose', false); %% 训练模型 net = trainNetwork(p_train, t_train, layers, options); %% 预测模型 t_sim1 = predict(net, p_train); t_sim2 = predict(net, p_test ); %% 反归一化 T_sim1 = vec2ind(t_sim1'); T_sim2 = vec2ind(t_sim2'); %% 性能评价 error1 = sum((T_sim1 == T_train)) / M * 100 ; error2 = sum((T_sim2 == T_test )) / N * 100 ; %% 绘制网络分析图 analyzeNetwork(layers) %% 绘图 figure plot(1: M, T_train, 'r-*', 1: M, T_sim1, 'b-o', 'LineWidth', 1) legend('真实值', '预测值') xlabel('预测样本') ylabel('预测结果') string = {'训练集预测结果对比'; ['准确率=' num2str(error1) '%']}; title(string) grid figure plot(1: N, T_test, 'r-*', 1: N, T_sim2, 'b-o', 'LineWidth', 1) legend('真实值', '预测值') xlabel('预测样本') ylabel('预测结果') string = {'测试集预测结果对比'; ['准确率=' num2str(error2) '%']}; title(string) grid %% 混淆矩阵 if flag_conusion == 1 figure cm = confusionchart(T_train, T_sim1); cm.Title = 'Confusion Matrix for Train Data'; cm.ColumnSummary = 'column-normalized'; cm.RowSummary = 'row-normalized'; figure cm = confusionchart(T_test, T_sim2); cm.Title = 'Confusion Matrix for Test Data'; cm.ColumnSummary = 'column-normalized'; cm.RowSummary = 'row-normalized'; end %% Grad-CAM 可视化 % 获取最后一个卷积层 last_conv_layer = 'conv_2'; % 根据网络结构修改 gradcamMap = gradCAM(net, p_train, last_conv_layer); % 可视化 Grad-CAM figure; imagesc(gradcamMap); colorbar; title('Grad-CAM Heatmap'); %% 特征重要性分析 % 获取第一个卷积层的权重 first_conv_layer = net.Layers(2).Weights; feature_importance = squeeze(mean(abs(first_conv_layer), [1, 2, 3])); % 可视化特征重要性 figure; plot(feature_importance); xlabel('Raman Shift (cm⁻¹)'); ylabel('Feature Importance'); title('Feature Importance Analysis'); %% 遮挡分析 occlusion_sensitivity = occlusionSensitivity(net, p_train); % 可视化遮挡分析 figure; imagesc(occlusion_sensitivity); colorbar; title('Occlusion Sensitivity Map'); %% 显著性图 saliencyMap = saliency(net, p_train); % 可视化显著性图 figure; imagesc(saliencyMap); colorbar; title('Saliency Map'); %% 集成方法 % 训练多个模型并集成结果 num_models = 5; ensemble_predictions = zeros(num_class, N); for i = 1:num_models % 重新训练模型 net_ensemble = trainNetwork(p_train, t_train, layers, options); % 预测 t_sim_ensemble = predict(net_ensemble, p_test); ensemble_predictions = ensemble_predictions + t_sim_ensemble; end % 平均预测结果 ensemble_predictions = ensemble_predictions / num_models; T_sim_ensemble = vec2ind(ensemble_predictions'); % 计算集成模型的准确率 error_ensemble = sum((T_sim_ensemble == T_test)) / N * 100; disp(['集成模型的测试集准确率: ', num2str(error_ensemble), '%']); %% 结束 disp('分析完成!');按照这个CNN基本模型,修改代码,变成1D-CNN(一维卷积神经网络),拟进行高光谱二分类分析