增减网络20220101

现代c++有任意层数和每层任意结点数的全连接神经网络.代码包括了基本的梯度下降,要求输入数据有两组{1,0}、{1,1},训练目标数据target也有两个{1}、{0}......程序运行开始读取一个文本文件"s1.txt",而文本文件中如果有字符串,"{2,4,3,1}"则网络结构就是{2,4,3,1}(即输入层2个Nodes,输出层有1个node,第1个隐藏层有4个nodes,第2个隐藏层有3nodes! 之后程序再读取文本文件"s2.txt"读取文本文件中的第二个字符串,比如:"{2,4,1}"又重新重构神经网络,这次输入层有2个nodes,输出层有1个node,隐藏层有4个nodes,并且再次反向传播训练!

cpp 复制代码
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cmath>
#include <random>

using namespace std;

// Sigmoid 函数和它的导数
double sigmoid(double x) {
    return 1 / (1 + exp(-x));
}

double sigmoid_derivative(double x) {
    return x * (1 - x);
}

// 全连接神经网络
class NeuralNetwork {
public:
    vector<int> layers;
    vector<vector<double>> weights;
    vector<vector<double>> outputs;

    NeuralNetwork(vector<int> layers) : layers(layers) {
        random_device rd;
        mt19937 gen(rd());
        uniform_real_distribution<> dis(0, 1);

        for (int i = 1; i < layers.size(); ++i) {
            vector<double> weightLayer;
            for (int j = 0; j < layers[i - 1] * layers[i]; ++j) {
                weightLayer.push_back(dis(gen));
            }
            weights.push_back(weightLayer);
        }
    }

    vector<double> forward(vector<double> input) {
        outputs.clear();
        outputs.push_back(input);

        for (int i = 1; i < layers.size(); ++i) {
            vector<double> output(layers[i]);
            int k = 0;
            for (int j = 0; j < layers[i]; ++j) {
                double sum = 0;
                for (int l = 0; l < layers[i - 1]; ++l) {
                    sum += outputs[i - 1][l] * weights[i - 1][k++];
                }
                output[j] = sigmoid(sum);
            }
            outputs.push_back(output);
        }
        return outputs.back();
    }

    vector<double> forwarOut(vector<double> input) {
        outputs.clear();
        outputs.push_back(input);

        cout << endl<<" [";
        for (int jj = 0; jj < input.size(); ++jj) { cout << input[jj]; }
        cout << "]; " << endl;
        for (int i = 1; i < layers.size(); ++i) {
            vector<double> output(layers[i]);
            int k = 0;
            for (int j = 0; j < layers[i]; ++j) {
                double sum = 0;
                for (int l = 0; l < layers[i - 1]; ++l) {
                    sum += outputs[i - 1][l] * weights[i - 1][k++];
                }
                output[j] = sigmoid(sum);
                cout << output[j] << "], ";
            }
            outputs.push_back(output);
            cout << output[0] << "}; " << endl;
            cout << "}};  " << endl;
        }//for110i
        return outputs.back();
    }//forwarOut
    //---------------------------------------------------------------------

    void train(vector<double> input, vector<double> target, double lr) {
        forward(input);
        vector<vector<double>> deltas(layers.size());
        for (int i = layers.size() - 1; i >= 0; --i) {
            deltas[i].resize(layers[i]);
            if (i == layers.size() - 1) {
                for (int j = 0; j < layers[i]; ++j) {
                    double error = target[j] - outputs[i][j];
                    deltas[i][j] = error * sigmoid_derivative(outputs[i][j]);
                }
            }
            else {
                int k = 0;
                for (int j = 0; j < layers[i]; ++j) {
                    double error = 0;
                    for (int l = 0; l < layers[i + 1]; ++l) {
                        error += weights[i][k++] * deltas[i + 1][l];
                    }
                    deltas[i][j] = error * sigmoid_derivative(outputs[i][j]);
                }
            }
        }

        for (int i = layers.size() - 1; i > 0; --i) {
            int k = 0;
            for (int j = 0; j < layers[i]; ++j) {
                for (int l = 0; l < layers[i - 1]; ++l) {
                    weights[i - 1][k++] += lr * deltas[i][j] * outputs[i - 1][l];
                }
            }
        }
    }
};

// 从文件读取层信息
vector<int> readLayersFromFile(const string& filename) {
    ifstream file(filename);
    string str;
    if (file) {
        getline(file, str);
    }
    stringstream ss(str.substr(1, str.length() - 2));
    string token;
    vector<int> layers;
    while (getline(ss, token, ',')) {
        layers.push_back(stoi(token));
    }
    return layers;
}

int main() {
    // 第一次从文件s1.txt读取网络结构并构建网络
    vector<int> layers1 = readLayersFromFile("\/s1.txt");
    NeuralNetwork nn1(layers1);

    // 使用{1, 0} 和 {1, 1}训练
    vector<vector<double>> inputs1 = { {1, 0}, {1, 1},{0,1},{0,0} };    //{ {1, 0}, {1, 1} };
    vector<vector<double>> targets1 = { {1}, {0},{1},{0} };

    for (int epoch = 0; epoch < 1000; ++epoch) {
        for (int i = 0; i < inputs1.size(); ++i) {
            nn1.train(inputs1[i], targets1[i], 0.5);
        }
    }

    // 第二次从文件s2.txt读取网络结构并构建网络
    vector<int> layers2 = readLayersFromFile("\/s2.txt");
    NeuralNetwork nn2(layers2);

    // 再次使用{1, 0} 和 {1, 1}训练
    for (int epoch = 0; epoch < 5000; ++epoch) {
        for (int i = 0; i < inputs1.size(); ++i) {
            nn2.train(inputs1[i], targets1[i], 0.5);
        }
    }

    nn2.forwarOut( {0,1}  );

    cout << endl;
    nn2.forwarOut({ 1,1 });

    cout << endl;
    nn2.forwarOut({ 1,0 });

    cout << endl;
    nn2.forwarOut({ 0,0 });

    return 0;
}
相关推荐
世洋Blog3 分钟前
算法导论-分治法和合并(Merge)排序
算法
源代码•宸8 分钟前
Golang基础语法(go语言结构体、go语言数组与切片、go语言条件句、go语言循环)
开发语言·经验分享·后端·算法·golang·go
l1t15 分钟前
快速加载CSV文件到数据库的工具pg_csv_loader
数据库·算法
yugi98783822 分钟前
基于Matlab的晴空指数计算实现
开发语言·算法·matlab
ADI_OP38 分钟前
ADAU1452的开发教程3:常规音频算法的开发(2)
算法·dsp开发·adi dsp中文资料·adi dsp·adi音频dsp·adi dsp开发教程
666HZ66640 分钟前
数据结构1.0 数据结构在学什么
数据结构·算法
君义_noip1 小时前
信息学奥赛一本通 1951:【10NOIP普及组】导弹拦截 | 洛谷 P1158 [NOIP 2010 普及组] 导弹拦截
c++·算法·csp-j·信息学奥赛
环黄金线HHJX.1 小时前
《QuantumTuan ⇆ QT:Qt》
人工智能·qt·算法·编辑器·量子计算
jz_ddk1 小时前
[实战] 射频相位噪声单位转换:从dBc/Hz到rad
算法·rf·射频·相位噪声·相噪
zl_vslam1 小时前
SLAM中的非线性优-3D图优化之地平面约束(十五)
人工智能·算法·计算机视觉·3d