dmountain 2024-03-30 17:14 采纳率: 0%
浏览 987

无效的训练数据。序列响应必须与对应的预测变量具有相同的序列长度。哪里出了问题

无效的训练数据。序列响应必须与对应的预测变量具有相同的序列长度。哪里出了问题。


XrTrain = cell(size(pn_train,2),1);  %注意size是1还是2,tn_train是2*4095数组,pn_train是6*4095数组
YrTrain = zeros(size(tn_train,1),4095);%YrTrain是2*4095数组


for i=1:size(pn_train,2)%i是1到4095
    XrTrain{i,1} = pn_train(:,i);  %pn_train 是6*4095列.Xrtrain是6*1个胞元,
   YrTrain(:,i) = tn_train(:,i);
%     YrTrain(:,1)= tn_train(:,i); %每个tn_train是2*1列,tn_train是2*4095
end
numFeatures  = size(pn_train,1);
% 输出特征维度
numResponses = 2;
FiltZise = 10;
%  创建"CNN-LSTM"模型
    layers = [...
        % 输入特征
        sequenceInputLayer([numFeatures 1 1],'Name','input')
        sequenceFoldingLayer('Name','fold')
        % CNN特征提取
        convolution2dLayer([FiltZise 1],32,'Padding','same','WeightsInitializer','he','Name','conv','DilationFactor',1);
        batchNormalizationLayer('Name','bn')
        eluLayer('Name','elu')
        averagePooling2dLayer(1,'Stride',FiltZise,'Name','pool1')
        % 展开层
        sequenceUnfoldingLayer('Name','unfold')
        % 平滑层
        flattenLayer('Name','flatten')
        % LSTM特征学习
        lstmLayer(128,'Name','lstm1','RecurrentWeightsInitializer','He','InputWeightsInitializer','He')
        % LSTM输出
        lstmLayer(32,'OutputMode',"last",'Name','bil4','RecurrentWeightsInitializer','He','InputWeightsInitializer','He')
        dropoutLayer(0.25,'Name','drop3')
        % 全连接层
        fullyConnectedLayer(numResponses,'Name','fc')
        regressionLayer('Name','output')    ];

    layers = layerGraph(layers);
    layers = connectLayers(layers,'fold/miniBatchSize','unfold/miniBatchSize');
    analyzeNetwork(layers);   %补充分析

%% CNNLSTM训练选项
% 批处理样本
MiniBatchSize =24;
% 最大迭代次数
MaxEpochs = 60;
% 学习率
learningrate = 0.005;
% 一些参数调整
if gpuDeviceCount>0
    mydevice = 'gpu';
else
    mydevice = 'cpu';
end
    options = trainingOptions( 'adam', ...
        'MaxEpochs',100, ...
        'GradientThreshold',1, ...
        'InitialLearnRate',learningrate, ...
        'LearnRateSchedule','piecewise', ...
        'LearnRateDropPeriod',20, ...
        'LearnRateDropFactor',0.8, ...
        'L2Regularization',1e-3,...
        'Verbose',false, ...
        'ExecutionEnvironment',mydevice,...
        'Plots','training-progress');

%% 训练混合网络
% rng(0);
% 训练
net = trainNetwork(XrTrain,YrTrain,layers,options); 
  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-30 17:14
    关注

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

    在处理一个序列响应与预测变量具有相同序列长度的序列响应问题时,我们需要确保以下几点:

    1. 序列长度:序列响应通常包含一组连续的数字,其每个值都对应着一个预测变量(例如,'Y')的位置。如果我们尝试将这些值映射到原始的X输入矩阵(表示的是样本向量),我们可能会发现某些位置的X是空的或只包含有限个元素,导致length(XrTrain)小于length(YrTrain)

    2. 序列长度:根据上述步骤,序列响应的长度通常是预测变量的行数。如果序列响应的长度不等于预测变量的行数,则这可能意味着我们在构建CNN-LSTM模型时,序列响应被剪切或转换成了单个元素(即Z[i])。这就导致了sequenceLength为1或sequenceLength > length(YrTrain)的情况,从而使得训练数据中的预测变量位于一个序列长度较小的位置上,而序列响应中的其他部分则没有与其对应的需求。

    要解决这个问题,我们可以采取以下策略:

    解决方案一:预处理序列响应

    1. 缺失值填充: 如果序列响应中的某个位置上的所有元素都是空的或只有一个元素,我们可以使用填充技术(例如,零填充、随机填充等)来替换这些空值。在NumPy中,可以使用numpy.nanmean()函数或numpy.random.randn()函数实现这个任务。
    # 填充序列响应
    for i in range(len(XrTrain)):
        if np.isnan(XrTrain[i]):
            XrTrain[i] = np.random.randn()
    
    1. 进行数据缩放: 虽然通过填充已知或期望值可以填补缺失值,但可能对不同的数据集效果不同。因此,对于特征较少的数据集,我们可能希望将其缩放到一个更小的范围内,以便更好地适应模型结构和需求。这里,我们将设置shape(XrTrain),即XrTrain的形状为(XrTrain.shape[0], numFeatures),然后使用arraymap()函数应用一个固定的缩放系数:
    def scale_data(XrTrain):
        scaled_XrTrain = arraymap(lambda x: x / np.max(XrTrain), XrTrain)
        return scaled_XrTrain.reshape(shape(XrTrain))
    
    scaled_XrTrain = scale_data(XrTrain)
    

    解决方案二:正则化预处理

    在CNN-LSTM模型中,正则化是一种防止过拟合的技术,它通过对模型权重进行惩罚,降低复杂度,使模型更容易泛化到未见过的新数据上。在这种情况下,我们可以使用L1正则化或L2正则化来优化输入序列响应的权重,并减少预测变量之间的依赖性:

    1. L1正则化lambda_1 = 0.01:设置一个权重衰减项。在lr参数中设置 1e-4,以使用默认的学习率进行训练。
    options.L1Regularization = 1e-4
    
    # L1正则化训练
    net = trainNetwork(scaled_XrTrain,YrTrain,layers,options)
    
    1. L2正则化lambda_2 = 0.001:设置另一个权重衰减项。在lr参数中设置 1e-6,同样可以使用默认的学习率进行训练。
    options.L2Regularization = 1e-6
    
    # L2正则化训练
    net = trainNetwork(scaled_XrTrain,YrTrain,layers,options)
    

    解决方案三:截断多态解码器(MLP)

    考虑到CNN-LSTM模型结合了LSTM层和卷积神经网络(CNN),如果CNN层采用固定大小的卷积核和隐藏层,当预测变量的宽度不足以覆盖所有的特征时,可能会产生维度变高的情况,导致模型陷入局部最优解并影响性能。为此,我们可以使用多态解码器(MLP)进行数据切片,将序列响应分割成多个较小的片段,然后分别对其进行计算和更新。

    1. 多态解码器架构
      # 设定每个CNN模块的嵌套深度
      max_depth = 2
      
      # 使用递归方式创建多态解码器的嵌套结构
      for depth in range(max_depth):
          net_layers.append([
              feature_extractor_layer,
              recurrent_encoder_layer,
              decoder_layer,
          ])
          feature_extractor_layer = feature_extraction_layer + ('FC', (max_features, ))
          recurrent_encoder_layer = recurrent_encoder_layer + ('FC', (max_features, ))
          decoder_layer = decoder_layer + ('FC', (max_features, ))
          input_layer = sequence_input_layer
      
          for n_in, n_out in zip(input_layer.shape[1:], [
              n_in * feature_extractor_layer.n_features,  # 卷积层输入特征的通道数
              n_in * recurrent_encoder_layer.n_features,  # 隐藏层输入特征的通道数
              n_in * decoder_layer.n_features,  # 隐藏层输出特征的通道数
          ]):
              net_layers[-depth].append(
                  linear_classifier_layer(n_in * max_features, n_out),
              )
      
      # 应用多态解码器至整个模型
      net = multi_tensor_stack(net_layers)
      
      # 在最后一个非编码层添加批次大小校验层
      net = residual_block(net, 'batch_size', 16, activation='relu')
      
      # 构建多层馈送网络
      for n_in, n_out in zip(input_layer.shape[1:], [
          n_in * feature_extractor_layer.n_features,  # 卷积层输入特征的通道数
          n_in * recurrent_encoder_layer.n_features,  # 隐藏层输入特征的通道数
          n_in * decoder_layer.n_features,  # 隐藏层输出特征的通道数
          n_in * dense_layer_n_in,  # 卷积层隐藏层输出特征的通道数
      ]):
          net = add_twooutputs(inputs=[net_layers[-depth][n_in]], outputs=[net[-1][n_in]])
      
      
      # 编译模型
      optimizer = Adam(lr=learningrate)
      loss_function = nn.CrossEntropyLoss()
      criterion = nn.MSELoss()
      
      model = Model(inputs=input_layer, outputs=output_layer, losses=[criterion, loss_function])
      model.compile(optimizer=optimizer, loss=criterion)
      
    
    这段代码定义了一个多层的多态解码器架构,该架构首先使用递归方法(如`feature_extraction_layer`、`recurrent_encoder_layer`和`decoder_layer`)对输入序列响应进行切割,生成几个较小的片段,然后使用MPLP进行每个片段的计算和更新。最后,在编码层添加批次大小校验层,以便在每一帧的序列响应上进行平滑采样,从而得到单个像素级别的预测值。这与传统的CNN-LSTM架构不同,其中序列响应会被分块处理并一次性进行预测,而不是每次更新模型时才进行预测。
    
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月30日