程序的设计思路是基于神经网络的二分类模型。主要包括一个'Network'类和一些辅助函数。

'Network'类中包含了训练次数(epoches)和学习率(learning_rate)作为超参数,并初始化了权重(w1, w2, w3, w4, w5, w6)和参数(b1, b2, b3)。在构造函数中对这些参数进行初始化。

'Network'类中定义了激活函数'sigmoid'和激活函数的导数'deriv_sigmoid'。'sigmoid'函数将输入的值压缩到0和1之间,而'deriv_sigmoid'函数则是'sigmoid'函数的导数。

'Network'类中的'forward'函数实现了前向传播的计算过程。它接收一个数据向量作为输入,通过一系列的线性变换和激活函数得到最终的输出值。

'Network'类中的'train'函数用于训练模型。它接收训练数据和标签作为输入,并通过反向传播算法更新神经网络的参数。在每个训练周期内,遍历所有的训练样本,计算预测值和损失,并根据损失和梯度下降算法更新参数。同时,每隔一定的训练周期,输出当前训练次数和损失值。

'Network'类中的'predict'函数用于预测模型的输出。它接收测试数据和标签作为输入,通过前向传播得到预测值,并与标签进行对比,计算正确率。

在'main'函数中,定义了训练数据和标签,创建了一个'Network'对象,并调用'train'函数进行训练。然后定义了测试数据和标签,调用'predict'函数进行预测。

整个程序的目的是训练一个二分类模型,通过训练数据学习到合适的参数和权重,并在测试数据上进行预测,计算预测的正确率。

#include<iostream>
#include<vector>
#include<cmath>

using namespace std;
//获取误差:
double getMSEloss(double x1, double x2)
{
    return (x1 - x2) * (x1 - x2);
}
class Network{
private:
    int epoches;//训练次数。
    double learning_rate;//学习率。
    double w1, w2, w3, w4, w5, w6;//权重。
    double b1, b2, b3;//参数。
public:
    // 超参数、参数初始化:
    Network(int es, double lr) :epoches(es), learning_rate(lr)
    {
        w1 = w2 = w3 = w4 = w5 = w6 = 0;
        b1 = b2 = b3 = 0;
    }
    // 激活函数:
    double sigmoid(double x)
    {
        return 1 / (1 + exp(-x));
    }
    // 激活函数求导:
    double deriv_sigmoid(double x)
    {
        double y = sigmoid(x);
        return y * (1 - y);
    }
    // 前向传播:
    double forward(vector<double> data)
    {
        double sum_h1 = w1 * data[0] + w2 * data[1] + b1;
        double h1 = sigmoid(sum_h1);
        double sum_h2 = w3 * data[0] + w4 * data[1] + b2;
        double h2 = sigmoid(sum_h2);
        double sum_o1 = w5 * h1 + w6 * h2 + b3;
        return sigmoid(sum_o1);
    }
    //训练数据数组:
    void train(vector<vector<double>> data, vector<double> label)
    {
        for (int epoch = 0; epoch < epoches; ++epoch)
        {
            int total_n = data.size();
            for (int i = 0; i < total_n; ++i)
            {
                vector<double> x = data[i];
                double sum_h1 = w1 * x[0] + w2 * x[1] + b1;
                double h1 = sigmoid(sum_h1);
                double sum_h2 = w3 * x[0] + w4 * x[1] + b2;
                double h2 = sigmoid(sum_h2);
                double sum_o1 = w5 * h1 + w6 * h2 + b3;
                double o1 = sigmoid(sum_o1);
                double pred = o1;
                //反向算法更新神经网络参数:
                double d_loss_pred = -2 * (label[i] - pred);
                double d_pred_w5 = h1 * deriv_sigmoid(sum_o1);
                double d_pred_w6 = h2 * deriv_sigmoid(sum_o1);
                double d_pred_b3 = deriv_sigmoid(sum_o1);
                double d_pred_h1 = w5 * deriv_sigmoid(sum_o1);
                double d_pred_h2 = w6 * deriv_sigmoid(sum_o1);
                double d_h1_w1 = x[0] * deriv_sigmoid(sum_h1);
                double d_h1_w2 = x[1] * deriv_sigmoid(sum_h1);
                double d_h1_b1 = deriv_sigmoid(sum_h1);
                double d_h2_w3 = x[0] * deriv_sigmoid(sum_h2);
                double d_h2_w4 = x[1] * deriv_sigmoid(sum_h2);
                double d_h2_b2 = deriv_sigmoid(sum_h2);

                w1 -= learning_rate * d_loss_pred * d_pred_h1 * d_h1_w1;
                w2 -= learning_rate * d_loss_pred * d_pred_h1 * d_h1_w2;
                b1 -= learning_rate * d_loss_pred * d_pred_h1 * d_h1_b1;
                w3 -= learning_rate * d_loss_pred * d_pred_h2 * d_h2_w3;
                w4 -= learning_rate * d_loss_pred * d_pred_h2 * d_h2_w4;
                b2 -= learning_rate * d_loss_pred * d_pred_h2 * d_h2_b2;
                w5 -= learning_rate * d_loss_pred * d_pred_w5;
                w6 -= learning_rate * d_loss_pred * d_pred_w6;
                b3 -= learning_rate * d_loss_pred * d_pred_b3;
            }
            if (epoch % 10 == 0)
            {
                double loss = 0;
                for (int i = 0; i < total_n; ++i)
                {
                    double pred = forward(data[i]);
                    loss += getMSEloss(pred, label[i]);
                }
                //输出训练次数与误差:
                cout << 'Epoch:' << epoch << '  Loss: ' << loss << endl;
            }
        }
    }
    //预测数据数组:
    void predict(vector<vector<double>> testdata, vector<double> testlabel)
    {
        int n = testdata.size();
        double temp = 0;
        for (int i = 0; i < n; ++i)
        {
            double pred = forward(testdata[i]);
            pred = pred > 0.5 ? 1 : 0;
            temp += (testlabel[i] == pred);
        }
        //输出判断的正确率:
        cout << '正确率:' << temp / n *100<<'%' << endl;
    }
};

int main()
{
    //训练:
    vector<vector<double>> data = { {1,2},{3,4},{5,6},{-7,-8} };
    vector<double> label = { 0,0,0,1 };
    Network network = Network(2000, 0.1);
    network.train(data, label);
    //得出预测结论:
    vector<vector<double>> testdata = { {8,7},{-5,-6},{-2,-5},{6,8},{-5,-1} };
    vector<double> testlabel = { 0,1,1,0,1 };
    network.predict(testdata, testlabel);
    return 0;
}
基于神经网络的二分类模型代码解析:结构、算法与训练过程

原文地址: https://www.cveoy.top/t/topic/qwJg 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录