C++实现单层感知机训练与预测

前言

感知机是最简单的一种神经网络模型,由Frank Rosenblatt在1958年提出。它是一种线性分类器,能够基于输入特征通过简单的线性决策边界来进行分类。在本篇博客中,我们将使用C++实现一个基础的单层感知机(Perceptron),并探讨其训练过程、预测机制以及学习算法的原理。

通过这段代码的实现,你将了解感知机的基本结构、训练过程、以及如何应用它来进行简单的二分类问题解决。

1. 感知机简介

感知机由输入层和输出层构成。每个输入值都对应一个权重,感知机的目标是学习这些权重值,使得它能够根据输入做出正确的输出。

感知机的工作原理:

  1. 输入值:感知机接受若干个输入,每个输入都有一个对应的权重。
  2. 加权求和:感知机通过加权求和(即输入值与权重的乘积之和)来计算一个加权总和。
  3. 激活函数:加权总和通过一个激活函数,通常是阶跃函数(step function),生成感知机的输出。

感知机使用的是二分类任务,输出为0或1。

2. C++实现单层感知机

下面我们来分析一下这段C++代码,该代码实现了一个简单的单层感知机,它通过训练数据来调整权重和偏置,从而能够做出正确的分类。

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;

// 阶跃函数(激活函数)
int stepFunction(double x) {
    return x >= 0 ? 1 : 0;  // 如果x大于或等于0,则输出1,否则输出0
}

// 预测函数:根据输入和权重计算预测结果
int predict(const vector<double>& inputs, const vector<double>& weights, double bias) {
    double sum = bias;  // 初始化加权和为偏置
    for (size_t i = 0; i < inputs.size(); ++i) {
        sum += inputs[i] * weights[i];  // 每个输入值与对应的权重相乘并加到加权和上
    }
    return stepFunction(sum);  // 通过阶跃函数得到预测结果
}

// 训练函数:调整权重和偏置使得模型输出正确
void train(vector<vector<double>>& inputs, vector<int>& labels, vector<double>& weights, double& bias, double learningRate, int epochs) {
    for (int epoch = 0; epoch < epochs; ++epoch) {  // 持续训练若干次(epochs次)
        bool hasError = false;  // 标志是否存在错误
        for (size_t i = 0; i < inputs.size(); ++i) {
            int prediction = predict(inputs[i], weights, bias);  // 获取预测结果
            int error = labels[i] - prediction;  // 计算误差

            if (error != 0) {  // 如果有误差,更新权重和偏置
                hasError = true;  // 标记有错误
                for (size_t j = 0; j < weights.size(); ++j) {
                    weights[j] += learningRate * error * inputs[i][j];  // 更新权重
                }
                bias += learningRate * error;  // 更新偏置
            }
        }

        if (!hasError) {
            break;  // 如果没有错误,训练可以提前结束
        }
    }
}

int main() {
    // 训练数据(输入)
    vector<vector<double>> inputs = {
        {1, 1}, {0, 1}, {1, 1}, {1, 0}  // 简单的2维输入数据
    };

    // 训练标签(对应的正确输出)
    vector<int> labels = { 1, 0, 1, 0 };  // 对应的标签(0或1)

    vector<double> weights(2, 0.0);  // 权重初始化为0
    double bias = 0.0;  // 偏置初始化为0
    double learningRate = 0.1;  // 学习率
    int epochs = 10;  // 训练次数

    // 训练过程
    train(inputs, labels, weights, bias, learningRate, epochs);

    // 训练完成后,模型已学习到了权重和偏置,可以用于预测
    // 在实际应用中,我们可以使用此模型对新的输入进行预测

    return 0;
}
3. 代码解释
  • stepFunction:这是感知机的激活函数,它决定了感知机的输出。通过判断输入值是否大于等于0,返回1或0,构成二分类。

  • predict:此函数使用输入值、权重和偏置进行加权求和,并通过激活函数决定输出。

  • train:这是感知机的训练函数。通过遍历输入数据,计算预测结果,比较预测值与实际标签的差异(误差),并根据误差调整权重和偏置。训练会持续多次(由epochs决定),直到没有误差为止。

4. 训练过程
  1. 初始化:权重和偏置被初始化为0,学习率设置为0.1。
  2. 输入数据:我们使用简单的二进制数据作为输入,输出标签也为0或1。
  3. 计算误差:每次预测后,计算实际标签与预测结果的误差。
  4. 更新权重:如果存在误差,则根据误差调整权重和偏置,逐步优化模型。
  5. 停止条件:当所有数据没有错误时,训练停止。
5. 总结

通过这段C++代码,我们成功实现了一个简单的单层感知机,它能够根据输入数据和标签通过训练调整权重和偏置,从而能够进行正确的预测。这是神经网络学习的基本原理之一,虽然非常简单,但它是更复杂的神经网络模型的基础。感知机的核心思想在于通过权重调整来逐渐优化预测结果,并且它采用了简单的阶跃函数作为激活函数。

对于初学者来说,理解单层感知机的工作原理非常重要,它能帮助我们更好地理解神经网络的学习机制,并为深入研究更复杂的神经网络架构打下基础。

希望通过这篇博客,你能够对感知机的实现、训练过程以及C++在机器学习中的应用有更深刻的理解。如果你对更复杂的神经网络模型感兴趣,欢迎继续深入探索!

猜你喜欢

转载自blog.csdn.net/m0_71043875/article/details/145633884