You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于PyTorch的时间序列曲线多标签分类问题求助

Hey there! Let's dive into your curve shape multi-label classification problem and address each of your questions with practical fixes and insights:

1. Is RNN a suitable choice for this task?

Short answer: It's not the most optimal, but it can work if implemented correctly. Here's why:

  • Your task focuses on shape-based pattern recognition (e.g., convex/concave curves, initial value magnitude) rather than capturing sequential dependencies (like predicting the next time step in a time series). These patterns are often better captured by:
    • Handcrafted features + MLP: Extract stats directly tied to your categories (more on this later) — this is simple, fast, and highly interpretable.
    • 1D CNN: Convolutional layers excel at local pattern detection (e.g., convex segments) and global feature aggregation for signal data, which aligns perfectly with your curve shape goals.
  • If you still want to use RNN, you need to fix how you're feeding data into it (more on that in the next section) — your current setup isn't leveraging the RNN's sequential modeling capability at all.

2. Why isn't the loss decreasing, and how to fix it?

Your code has several critical issues that are blocking training progress. Let's break them down with fixes:

a. RNN Input Dimension Misconfiguration

Your current model sets input_dim=1500 and reshapes input to (1, batch_size, 1500) — this treats the entire 1500-length curve as a single time-step input, which makes the RNN act like a fancy linear layer. RNNs expect sequential input where each time step is one data point:

  • Set input_dim=1 (each time step feeds one scalar value from the curve)
  • Reshape your input to (1500, batch_size, 1) (sequence length first, then batch, then feature dimension)
  • Simplify RNN layers: 20 layers is way too many for this task — RNNs suffer from gradient vanishing with deep stacks. Stick to 1-2 layers max.

Fixed RNN model example:

class Net(nn.Module):
    def __init__(self, input_dim=1, hidden_dim=32, layer_dim=1, output_dim=7):
        super(Net, self).__init__()
        self.hidden_dim = hidden_dim
        self.layer_dim = layer_dim
        self.rnn = nn.RNN(input_dim, hidden_dim, layer_dim)
        self.fc = nn.Linear(self.hidden_dim, output_dim)

    def forward(self, x):
        # x shape: (seq_len, batch_size, input_dim) = (1500, batch_size, 1)
        h0 = torch.zeros(self.layer_dim, x.size(1), self.hidden_dim, device=x.device)
        out, _ = self.rnn(x, h0)
        # Use the final time-step output or average all steps for global context
        out = out[-1, :, :]  # (batch_size, hidden_dim)
        out = self.fc(out)
        return out

b. Wrong Loss Function for Multi-Label Classification

F.l1_loss is a regression loss — it's not designed for binary multi-label tasks where each output is an independent 0/1 prediction. Use BCEWithLogitsLoss instead:

  • It combines sigmoid activation and binary cross-entropy, which is stable and ideal for multi-label problems.
  • Ensure your target tensor is float-type, matching the output's dtype.

c. Target Tensor is Incorrectly Generated

Your current code assigns the same label (from the last sample in the batch) to the entire batch — this means your model is learning garbage labels! Fix this by creating a label vector for each sample:

# Inside your training loop, generate target correctly
target = np.zeros((batch_size, 7))
for idx, d in enumerate(data[index:index+batch_size]):
    for class_idx in np.array(d['classifier']):
        target[idx, class_idx-1] = 1
target = torch.from_numpy(target).float()

d. Data Preprocessing Bug

You have a line y = np.multiply(y, y.max()) that reverses your 0-1 normalization — remove this to keep inputs in the 0-1 range, which helps model training stability.

e. Suboptimal Optimizer Choice

SGD with momentum can be slow to converge for RNNs. Switch to Adam optimizer for faster, more stable training:

optimizer = optim.Adam(network.parameters(), lr=1e-3)

3. Reference Cases & Alternative Approaches

Since your task is unique but related to 1D signal pattern recognition, here are two practical approaches you can explore:

Approach 1: Handcrafted Features + MLP

This is the simplest and most interpretable method. Extract features directly mapped to your categories:

  • Initial value偏高: y[0] (threshold e.g., >0.8)
  • 类正弦曲线: FFT peak count, autocorrelation coefficient (to detect periodicity)
  • 凸曲线: Proportion of intervals where second derivative (via finite difference) is negative
  • 凹曲线: Proportion of intervals where second derivative is positive
  • Add other stats: mean, variance, peak-to-trough ratio, etc.

Feed these features into a small MLP — this will train in minutes and give you clear insight into which features drive each classification.

1D CNNs are far more efficient than RNNs for signal pattern tasks. Here's a minimal example:

class CNNNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv_layers = nn.Sequential(
            nn.Conv1d(1, 16, kernel_size=5, padding=2),
            nn.ReLU(),
            nn.MaxPool1d(2),
            nn.Conv1d(16, 32, kernel_size=5, padding=2),
            nn.ReLU(),
            nn.MaxPool1d(2)
        )
        self.fc_layers = nn.Sequential(
            nn.Linear(32 * 375, 128),  # 1500 / 2 / 2 = 375
            nn.ReLU(),
            nn.Linear(128, 7)
        )
    
    def forward(self, x):
        # x shape: (batch_size, 1, 1500)
        x = self.conv_layers(x)
        x = x.flatten(1)
        x = self.fc_layers(x)
        return x

Input shape here is (batch_size, 1, 1500) (channels first for CNNs), and you'll still use BCEWithLogitsLoss for multi-label training.


内容的提问来源于stack exchange,提问作者rst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 14:08:16