#include #include // 导入数学函数库 #include // 导入向量库 using namespace std;

class Network { private: int epoches; // 训练次数 double learning_rate; // 学习率 double w1, w2, w3, w4, w5, w6; // 网络参数 double b1, b2, b3;

public: Network(int epoches, double learning_rate) // 初始化网络参数 : epoches(epoches), learning_rate(learning_rate), w1(0.2), w2(0.4), w3(0.5), w4(0.7), w5(0.3), w6(0.6), b1(0.4), b2(0.5), b3(0.3) {}

// Sigmoid激活函数
double sigmoid(double x) {
    return 1 / (1 + exp(-x));
}

// Sigmoid函数的导数
double deriv_sigmoid(double x) {
    return sigmoid(x) * (1 - sigmoid(x));
}

// 前向传播,计算输出值
double forward(double x, double y) {
    double h1 = sigmoid(w1 * x + w2 * y + b1); // 计算隐藏层节点1的值
    double h2 = sigmoid(w3 * x + w4 * y + b2); // 计算隐藏层节点2的值
    double output = sigmoid(w5 * h1 + w6 * h2 + b3); // 计算输出层节点的值
    return output;
}

// 训练网络
void train(vector<pair<double, double>> data) {
    for (int i = 0; i < epoches; ++i) { // 循环训练epoches次
        double total_loss = 0;
        for (auto point : data) { // 遍历训练数据
            double x = point.first;
            double y = point.second;
            double target = (x > 0 && y > 0) ? 0 : 1; // 根据数据点位置确定目标标签

            // 前向传播
            double h1 = sigmoid(w1 * x + w2 * y + b1);
            double h2 = sigmoid(w3 * x + w4 * y + b2);
            double output = sigmoid(w5 * h1 + w6 * h2 + b3);

            // 计算损失和梯度
            double loss = pow(output - target, 2); // 计算均方误差
            double dloss_doutput = 2 * (output - target); // 损失函数对输出值的导数
            double doutput_dw5 = h1 * deriv_sigmoid(w5 * h1 + w6 * h2 + b3); // 输出层权重w5的梯度
            double doutput_dw6 = h2 * deriv_sigmoid(w5 * h1 + w6 * h2 + b3); // 输出层权重w6的梯度
            double doutput_db3 = deriv_sigmoid(w5 * h1 + w6 * h2 + b3); // 输出层偏置b3的梯度
            double dh1_dw1 = x * deriv_sigmoid(w1 * x + w2 * y + b1); // 隐藏层节点1权重w1的梯度
            double dh1_dw2 = y * deriv_sigmoid(w1 * x + w2 * y + b1); // 隐藏层节点1权重w2的梯度
            double dh2_dw3 = x * deriv_sigmoid(w3 * x + w4 * y + b2); // 隐藏层节点2权重w3的梯度
            double dh2_dw4 = y * deriv_sigmoid(w3 * x + w4 * y + b2); // 隐藏层节点2权重w4的梯度
            double dh1_db1 = deriv_sigmoid(w1 * x + w2 * y + b1); // 隐藏层节点1偏置b1的梯度
            double dh2_db2 = deriv_sigmoid(w3 * x + w4 * y + b2); // 隐藏层节点2偏置b2的梯度

            // 更新参数
            w5 -= learning_rate * dloss_doutput * doutput_dw5; // 更新输出层权重w5
            w6 -= learning_rate * dloss_doutput * doutput_dw6; // 更新输出层权重w6
            b3 -= learning_rate * dloss_doutput * doutput_db3; // 更新输出层偏置b3
            w1 -= learning_rate * dloss_doutput * doutput_dw5 * dh1_dw1; // 更新隐藏层节点1权重w1
            w2 -= learning_rate * dloss_doutput * doutput_dw5 * dh1_dw2; // 更新隐藏层节点1权重w2
            w3 -= learning_rate * dloss_doutput * doutput_dw6 * dh2_dw3; // 更新隐藏层节点2权重w3
            w4 -= learning_rate * dloss_doutput * doutput_dw6 * dh2_dw4; // 更新隐藏层节点2权重w4
            b1 -= learning_rate * dloss_doutput * doutput_dw5 * dh1_db1; // 更新隐藏层节点1偏置b1
            b2 -= learning_rate * dloss_doutput * doutput_dw6 * dh2_db2; // 更新隐藏层节点2偏置b2

            total_loss += loss;
        }
        cout << "Epoch " << i + 1 << ", Loss: " << total_loss << endl;
    }
}

// 预测
int predict(double x, double y) {
    double output = forward(x, y);
    return (output >= 0.5) ? 1 : 0; // 根据输出值判断分类结果
}

};

int main() { vector<pair<double, double>> data = {{1, 2}, {-1, -2}, {3, 4}, {-3, -4}}; // 初始化训练数据 Network network(1000, 0.1); // 创建网络对象 network.train(data); // 训练网络 double x, y;

cout << "请输入点的坐标(x, y): ";
cin >> x >> y; // 输入待预测点的坐标
int label = network.predict(x, y); // 预测点的标签
cout << "预测标签: " << label << endl;

return 0;

}

C++实现简单的二分类神经网络

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

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