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

基础机器学习:二分类感知机无法正确学习问题求助

问题分析与修复方案

你的感知机模型无法正确学习主要有几个关键问题,我逐一拆解并给出修复建议:

1. 缺少偏置项(Bias),模型表达能力不足

标准感知机的决策边界公式是 w·x + b > 0(或类似带阈值的形式),其中b是偏置项,用来调整决策边界的偏移。你的代码里没有偏置,仅用w·x > threshold,这会导致模型无法灵活调整决策边界的位置——比如当sum(x)=0时,你需要模型输出1,但没有偏置的话,权重的线性组合很难刚好匹配这个阈值要求。

2. 错误计数逻辑完全错误

在train方法里,你把error_count作为参数传入train_observation,并且在外部又累加返回值,这会导致错误计数被重复计算:

# 错误的逻辑:
error_count += self.train_observation(x, y, error_count)

比如第一次出现错误时,train_observation里把传入的0加1变成1并返回,外部error_count变成0+1=1;第二次出现错误时,传入1,内部加1变成2返回,外部error_count变成1+2=3——实际只有2个错误,但计数变成了3,这会让训练的终止条件(error_count == 0)判断混乱,甚至可能提前终止训练。

3. 阈值设置与任务不匹配

你的任务是sum(x)≥0输出1,对应的理想决策边界是sum(x) ≥ 0,也就是w·x + b ≥ 0(当w全为1,b=0时正好匹配)。但你设置的threshold=0.5,加上没有偏置,模型很难学到正确的权重来匹配这个任务。


修复后的完整代码

我把这些问题都修复了,你可以直接运行测试:

import numpy as np

class Perceptron():
    def __init__(self, x, y, learning_rate=0.1, max_epochs=10):
        self.learning_rate = learning_rate
        self.x = x
        self.y = y
        self.max_epochs = max_epochs
        # 初始化权重和偏置
        self.weights = None
        self.bias = None

    def initialize(self):
        # 权重初始化为小随机数,偏置初始化为0
        self.weights = np.random.randn(len(self.x[0])) * 0.1
        self.bias = 0.0

    def train(self):
        epoch = 0
        while True:
            error_count = 0
            epoch += 1
            for x_i, y_true in zip(self.x, self.y):
                # 计算预测值:w·x + b > 0 则为1,否则为0
                y_pred = 1 if (np.dot(x_i, self.weights) + self.bias) > 0 else 0
                error = y_true - y_pred
                if error != 0:
                    error_count += 1
                    # 更新权重和偏置
                    self.weights += self.learning_rate * error * x_i
                    self.bias += self.learning_rate * error
            print(f'Epoch: {epoch} Error count: {error_count}')
            if error_count == 0:
                print('Training successful')
                break
            if epoch >= self.max_epochs:
                print('Reached max epochs')
                break

    def predict(self, x):
        return 1 if (np.dot(x, self.weights) + self.bias) > 0 else 0

# 任务函数:sum(x)≥0返回1,否则0
def sum01(x):
    return 1 if sum(x) >= 0 else 0

# 生成训练数据
np.random.seed(42)  # 设置随机种子方便复现
x_train = np.random.randint(low=-3, high=3, size=(50,10))
y_train = [sum01(z) for z in x_train]

# 训练模型
p = Perceptron(x_train, y_train)
p.initialize()
p.train()

# 测试预测
x_test = np.random.randint(low=-3, high=3, size=(10,10))
predics = [(p.predict(i), sum01(i)) for i in x_test]
print("\n预测结果(预测值, 真实值):")
print(predics)

修复说明

  • 新增了偏置项self.bias,让模型可以调整决策边界的偏移,匹配任务要求
  • 修正了错误计数逻辑,现在每次错误只累加1次,计数准确
  • 去掉了冗余的threshold参数,改用w·x + b > 0的标准感知机形式,更贴合你的任务
  • 权重初始化改用小的正态分布随机数,避免初始值过大影响训练
  • 设置了随机种子np.random.seed(42),方便你复现结果

运行这段代码后,你会看到训练很快就能达到error_count=0,预测结果也会基本正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:07:54