您现在的位置是:首页 >学无止境 >c++神经网络算法实现网站首页学无止境

c++神经网络算法实现

风语情 2024-06-21 18:01:02
简介c++神经网络算法实现

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;

// 定义常量
const int INPUT_NUM = 784; // 输入层节点数
const int HIDDEN_NUM = 100; // 隐藏层节点数
const int OUTPUT_NUM = 10; // 输出层节点数
const double LEARNING_RATE = 0.1; // 学习率
const int EPOCH_NUM = 20; // 迭代次数
const int BATCH_SIZE = 100; // 批量大小

// 定义神经网络类
class NeuralNetwork {
public:
    NeuralNetwork(int inputNum, int hiddenNum, int outputNum) {
        inputNum_ = inputNum;
        hiddenNum_ = hiddenNum;
        outputNum_ = outputNum;

        // 初始化权重和偏置
        srand(time(NULL));
        for (int i = 0; i < inputNum_; i++) {
            for (int j = 0; j < hiddenNum_; j++) {
                w1_(i, j) = (rand() / double(RAND_MAX)) * 2 - 1;
            }
        }
        for (int i = 0; i < hiddenNum_; i++) {
            for (int j = 0; j < outputNum_; j++) {
                w2_(i, j) = (rand() / double(RAND_MAX)) * 2 - 1;
            }
        }
        for (int i = 0; i < hiddenNum_; i++) {
            b1_[i] = (rand() / double(RAND_MAX)) * 2 - 1;
        }
        for (int i = 0; i < outputNum_; i++) {
            b2_[i] = (rand() / double(RAND_MAX)) * 2 - 1;
        }
    }

    // 前向传播
    void forwardPropagation(MatrixXd& x) {
        for (int i = 0; i < hiddenNum_; i++) {
            double z = 0;
            for (int j = 0; j < inputNum_; j++) {
                z += x(j, 0) * w1_(j, i);
            }
            z += b1_[i];
            h_(i, 0) = sigmoid(z);
        }
        for (int i = 0; i < outputNum_; i++) {
            double z = 0;
            for (int j = 0; j < hiddenNum_; j++) {
                z += h_(j, 0) * w2_(j, i);
            }
            z += b2_[i];
            y_(i, 0) = softmax(z);
        }
    }

    // 反向传播
    void backwardPropagation(MatrixXd& x, int t) {
        MatrixXd delta2 = y_ - oneHot(t);
        MatrixXd delta1 = (w2_ * delta2).cwiseProduct(h_.array() * (1 - h_.array())).matrix();
        w2_ -= LEARNING_RATE * h_ * delta2.transpose();
        w1_ -= LEARNING_RATE * x * delta1.transpose();
        b2_ -= LEARNING_RATE * delta2;
        b1_ -= LEARNING_RATE * delta1.col(0);
    }

    // 训练
    void train(vector<MatrixXd>& xTrain, vector<int>& tTrain) {
        for (int epoch = 0; epoch < EPOCH_NUM; epoch++) {
            shuffle(xTrain, tTrain); // 打乱训练集
            for (int i = 0; i < xTrain.size(); i += BATCH_SIZE) {
                int batchSize = min(BATCH_SIZE, int(xTrain.size() - i));
                for (int j = 0; j < batchSize; j++) {
                    forwardPropagation(xTrain[i + j]);
                    backwardPropagation(xTrain[i + j], tTrain[i + j]);
                }
            }
            double accuracy = test(xTrain, tTrain); // 计算准确率
            cout << "Epoch: " << epoch + 1 << ", Accuracy: " << accuracy << endl;
        }
    }

    // 预测
    int predict(MatrixXd& x) {
        forwardPropagation(x);
        int maxIndex = 0;
        double maxValue = y_(0, 0);
        for (int i = 1; i < outputNum_; i++) {
            if (y_(i, 0) > maxValue) {
                maxIndex = i;
                maxValue = y_(i, 0);
            }
        }
        return maxIndex;
    }

private:
    int inputNum_, hiddenNum_, outputNum_;
    MatrixXd w1_ = MatrixXd::Zero(INPUT_NUM, HIDDEN_NUM), w2_ = MatrixXd::Zero(HIDDEN_NUM, OUTPUT_NUM);
    VectorXd b1_ = VectorXd::Zero(HIDDEN_NUM), b2_ = VectorXd::Zero(OUTPUT_NUM);
    MatrixXd h_ = MatrixXd::Zero(HIDDEN_NUM, 1), y_ = MatrixXd::Zero(OUTPUT_NUM, 1);

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

    // 激活函数 softmax
    double softmax(double x) {
        return exp(x) / exp(1);
    }

    // 打乱训练集
    void shuffle(vector<MatrixXd>& xTrain, vector<int>& tTrain) {
        for (int i = 0; i < xTrain.size(); i++) {
            int j = rand() % xTrain.size();
            swap(xTrain[i], xTrain[j]);
            swap(tTrain[i], tTrain[j]);
        }
    }

    // 测试
    double test(vector<MatrixXd>& xTest, vector<int>& tTest) {
        int correctCount = 0;
        for (int i = 0; i < xTest.size(); i++) {
            if (predict(xTest[i]) == tTest[i]) {
                correctCount++;
            }
        }
        return double(correctCount) / xTest.size();
    }

    // one-hot编码
    MatrixXd oneHot(int t) {
        MatrixXd oneHotVec = MatrixXd::Zero(outputNum_, 1);
        oneHotVec(t, 0) = 1;
        return oneHotVec;
    }
};

// 测试函数
void test() {
    vector<MatrixXd> xTrain, xTest;
    vector<int> tTrain, tTest;
    int row, col;
    cin >> row >> col;
    MatrixXd input(row, col);
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++)

{
 cin >> input(i, j);
 } 
} 
xTrain.push_back(input.col(col - 1));
 // 将最后一列作为训练数据
 tTrain.push_back(0); 
// 标签为0
 NeuralNetwork nn(INPUT_NUM, HIDDEN_NUM, OUTPUT_NUM); nn.train(xTrain, tTrain); int prediction = nn.predict(xTrain[0]); cout << "Prediction: " << prediction << endl; }

int main() {

test();

return 0;

}

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。