模型预测不准

这个模型当我[0.1358896, 0.59416669, 0.92579291, 0.41567412, 0.1358894]  [0.1358891, 0.59416669, 0.92579291, 0.41567412, 0.1358894] [0.1358892, 0.59416669, 0.92579291, 0.41567412, 0.1358894]  的时候他预测不准 他会认为 是1  实际为0怎么办

你遇到的是一个典型的模型泛化问题。根据你的数据生成规则,当向量的第一个元素小于等于第五个元素时,标签应为 0。但模型在边界值附近(如两个元素几乎相等时)预测错误,这可能是由以下原因导致的:

  1. 线性模型局限性:你的模型只有一个线性层,可能无法捕捉到如此细微的差异
  2. 边界值敏感度:当第一个元素和第五个元素非常接近时,模型可能无法准确区分
  3. 训练数据分布:随机生成的数据可能没有充分覆盖边界情况

解决方案

以下是几种可以提高模型在边界值附近预测准确性的方法:

1. 增加模型复杂度

python
 
运行
 
 
 
 
class TorchModel(nn.Module):
    def __init__(self, input_size, device):
        super(TorchModel, self).__init__()
        self.device = device
        # 增加隐藏层以提高模型表达能力
        self.layer1 = nn.Linear(input_size, 10).to(device)  # 第一个线性层
        self.layer2 = nn.Linear(10, 1).to(device)          # 第二个线性层
        self.relu = nn.ReLU()                              # 激活函数
        self.sigmoid = nn.Sigmoid()                        # 输出层激活
        self.loss = nn.functional.bce_loss                 # 使用二元交叉熵损失

    def forward(self, x, y=None):
        x = x.to(self.device)
        x = self.relu(self.layer1(x))  # 应用隐藏层和ReLU激活
        y_pred = self.sigmoid(self.layer2(x))  # 应用输出层和Sigmoid
        
        if y is not None:
            y = y.to(self.device)
            # 确保标签在[0,1]范围内
            return self.loss(y_pred, y)
        else:
            return y_pred
 

2. 调整阈值

对于边界值,你可以调整预测阈值,使其更加保守:

python
 
运行
 
 
 
 
def predict(model_path, input_vec, device, threshold=0.5):
    # ... 模型加载代码 ...
    
    with torch.no_grad():
        input_tensor = torch.FloatTensor(input_vec).to(device)
        result = model.forward(input_tensor)
        result_cpu = result.cpu().numpy()
    
    for vec, res in zip(input_vec, result_cpu):
        # 使用自定义阈值进行预测
        predicted_class = 1 if res >= threshold else 0
        print(f"输入:{vec}, 预测类别:{predicted_class}, 概率值:{res[0]:.6f}")
 

3. 增强训练数据

特别生成更多边界值样本,确保模型学习到这些情况:

python
 
运行
 
 
 
 
def build_dataset(total_sample_num, device, add_boundary_samples=True):
    X = np.zeros((total_sample_num, 5), dtype=np.float32)
    Y = np.zeros((total_sample_num, 1), dtype=np.float32)
    
    for i in range(total_sample_num):
        # 确保生成一些边界样本
        if add_boundary_samples and i % 5 == 0:  # 每5个样本中加入一个边界样本
            delta = np.random.uniform(-0.01, 0.01)  # 微小差异
            x = np.random.random(5)
            x[0] = x[4] + delta  # 第一个元素接近第五个元素
            y = 1 if x[0] > x[4] else 0
        else:
            x, y = build_sample()
        
        X[i] = x
        Y[i] = y
    
    return torch.from_numpy(X).to(device), torch.from_numpy(Y).to(device)
 

4. 增加训练轮数和样本量

python
 
运行
 
 
 
 
def main():
    # 增加训练样本量和轮数
    epoch_num = 50        # 增加训练轮数
    batch_size = 32       # 增大批次大小
    train_sample = 10000  # 增加训练样本数量
    
    # ... 其余代码保持不变 ...
 

5. 调整学习率和优化器

python
 
运行
 
 
 
 
# 使用学习率调度器动态调整学习率
def main():
    # ... 其他参数 ...
    
    model = TorchModel(input_size, device)
    optim = torch.optim.Adam(model.parameters(), lr=learning_rate)
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
        optim, mode='min', factor=0.5, patience=3, verbose=True
    )
    
    # 训练循环
    for epoch in range(epoch_num):
        # ... 训练代码 ...
        
        # 更新学习率
        scheduler.step(np.mean(watch_loss))
        
        # ... 其余代码 ...
 

综合解决方案

结合以上方法,你可以显著提高模型在边界值附近的预测准确性。特别注意,对于这种依赖于特定特征比较的问题,可能需要更复杂的模型结构或专门设计的特征工程来确保模型能够学习到这种精确的比较规则。
posted @ 2025-06-23 00:22  m516606428  阅读(45)  评论(0)    收藏  举报