C++最易读手撸神经网络两隐藏层(任意Nodes每层)梯度下降230821a

// c++神经网络手撸20梯度下降22_230820a.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include<iostream>
#include<vector>
#include<iomanip> // setprecision
#include<sstream> // getline  stof()
#include<fstream>

using namespace std;
//
float Loss误差损失之和001 = 0.0;

class NN神经网络NN {

private:
    const int inputNode输入层之节点数s, hidden01Node隐藏层01结点数s, hidden22Nodes, outputNode输出层结点数s;

    /*
       vector<vector<float>> 输入层到第1隐藏层之权重矩阵, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏22到输出层de权重矩阵; //这些变量为矩阵
       vector<float> 隐藏层1偏置1, 隐藏层2偏置2, O输出层偏置;
       vector<float>隐藏层1数据1, 隐藏层2数据2, 输出数据output; */

       void initLayer每一层的WeightsAndBiases(vector<vector<float>>& weights权重, vector<float>& biases偏置)
       {
           for (size_t i = 0; i < weights权重.size(); ++i) {//for110i
               for (size_t j = 0; j < weights权重[0].size(); ++j) { weights权重[i][j] = ((rand() % 2) - 1) / 1.0; }
               biases偏置[i] = ((rand() % 2) - 1) / 1.0;

           }//for110i
       }//void initLayerWeightsAndBiases(

       void initWeightsAndBiases初始化权重和偏置矩阵() {
           initLayer每一层的WeightsAndBiases(输入层到第1隐藏层之权重矩阵, 隐藏层1偏置1);
           initLayer每一层的WeightsAndBiases(隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏层2偏置2);
           initLayer每一层的WeightsAndBiases(隐藏22到输出层de权重矩阵 , O输出层偏置);
       }

       //激活函数-激活的过程
        vector<float> activate(const  vector<float>& inputs, const  vector< vector<float>>& weights, const  vector<float>& biases) {
            vector<float> layer_output(weights.size(), 0.0);
               for (size_t i = 0; i < weights.size(); i++) {
                       for (size_t j = 0; j < inputs.size(); j++) {
                           layer_output[i] += inputs[j] * weights[i][j];
                       }//for220j
                   layer_output[i] += biases[i];
                   layer_output[i] = sigmoid(layer_output[i]);
               }//for110i
           return layer_output;
       }//vector<float> activate

        //subtract求差:两个 向量的差
         vector<float> subtract(const  vector<float>& a, const  vector<float>& b) {
             vector<float> result(a.size(), 0.0);
            for (size_t i = 0; i < a.size(); i++) {
                result[i] = a[i] - b[i];
            }
            return result;
        }//vector<float>subtract

         //dotT点乘
         vector<float> dotT(const  vector<float>& a, const  vector< vector<float>>& b) {
             vector<float> result(b[0].size(), 0.0);
            for (size_t i = 0; i < b[0].size(); i++) {
                for (size_t j = 0; j < a.size(); j++) {
                    result[i] += a[j] * b[j][i];
                }
            }
            return result;
        }

        //更新权重矩阵s(们), 和偏置(向量)S们
        void updateWeights(const  vector<float>& inputs, const  vector<float>& errors, const  vector<float>& outputs,
             vector< vector<float>>& weights,  vector<float>& biases, float lr) {
            for (size_t i = 0; i < weights.size(); i++) {
                for (size_t j = 0; j < weights[0].size(); j++) {
                    weights[i][j] += lr * errors[i] * sigmoid导函数prime(outputs[i]) * inputs[j];
                }
                biases[i] += lr * errors[i] * sigmoid导函数prime(outputs[i]);
            }
        }//void updateWeights(


public:

    vector<vector<float>> 输入层到第1隐藏层之权重矩阵, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏22到输出层de权重矩阵; //这些变量为矩阵
    vector<float> 隐藏层1偏置1, 隐藏层2偏置2, O输出层偏置;
    vector<float>隐藏层1数据1, 隐藏层2数据2, 输出数据output;

    NN神经网络NN(int inputNode输入层之节点数s, int hidden01Node隐藏层01结点数s, int hidden22Nodes, int outputNode输出层结点数s)
        :inputNode输入层之节点数s(inputNode输入层之节点数s), hidden01Node隐藏层01结点数s(hidden01Node隐藏层01结点数s), hidden22Nodes(hidden22Nodes), outputNode输出层结点数s(outputNode输出层结点数s)
    {
                srand(time(NULL));

                //初始换权重矩阵
                输入层到第1隐藏层之权重矩阵.resize(hidden01Node隐藏层01结点数s, vector<float>(inputNode输入层之节点数s));
                隐藏层1到第二隐藏层2之权重矩阵1to2.resize(hidden22Nodes, vector<float>(hidden01Node隐藏层01结点数s));
                隐藏22到输出层de权重矩阵.resize(outputNode输出层结点数s, vector<float>(hidden22Nodes));//

                隐藏层1偏置1.resize(hidden01Node隐藏层01结点数s);
                隐藏层2偏置2.resize(hidden22Nodes);
                O输出层偏置.resize(outputNode输出层结点数s);

                initWeightsAndBiases初始化权重和偏置矩阵();

    }//NN神经网络NN(i

        //sigmoid激活函数及导数
        float sigmoid(float x){ return 1.0 / (1.0 + exp(-x)); }
        float sigmoid导函数prime(float x) { return x * (1 - x); }

        //Forward前向传播
        vector<float> predict(const vector<float>& input输入数据) {

            //用激活函数sigmoid-激活的过程
            隐藏层1数据1 = activate(input输入数据, 输入层到第1隐藏层之权重矩阵, 隐藏层1偏置1); //激活函数
            // 第一隐藏层到第二隐藏层
            隐藏层2数据2 = activate(隐藏层1数据1, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏层2偏置2);//hidden1, wh1h2, bias_h2);

            // 第二隐藏层到输出层
            输出数据output = activate(隐藏层2数据2, 隐藏22到输出层de权重矩阵, O输出层偏置);// , wh2o, bias_o);

            return 输出数据output;

        }//vector<float>predict(


         // 反向传播//Backpropagation
        void train(const  vector<float>& inputs, const  vector<float>& target目标数据s, float lr学习率) {
             vector<float> output尝试的输出数据s = predict(inputs);

            // 输出层误差
             vector<float> output_error输出误差s = subtract(target目标数据s, output尝试的输出数据s);//
             Loss误差损失之和001 = 0.0;
            for (int ii = 0; ii < outputNode输出层结点数s; ++ii) { Loss误差损失之和001 += fabs(output_error输出误差s[ii]); }
            //=========================================================================

            // 隐藏层2误差
             vector<float> hidden2_errors = dotT(output_error输出误差s, 隐藏22到输出层de权重矩阵);

            // 隐藏层1误差
             vector<float> hidden1_errors = dotT(hidden2_errors, 隐藏层1到第二隐藏层2之权重矩阵1to2);

            // 更新权重: 隐藏层2到输出层(的权重矩阵
            updateWeights(隐藏层2数据2,   output_error输出误差s, output尝试的输出数据s, 隐藏22到输出层de权重矩阵, O输出层偏置, lr学习率);

            // 更新权重: 隐藏层1到隐藏层2
            updateWeights(隐藏层1数据1,   hidden2_errors, 隐藏层2数据2, 隐藏层1到第二隐藏层2之权重矩阵1to2, 隐藏层2偏置2, lr学习率);

            // 更新权重: 输入层到隐藏层1的权重矩阵)
            updateWeights(inputs,   hidden1_errors, 隐藏层1数据1, 输入层到第1隐藏层之权重矩阵, 隐藏层1偏置1, lr学习率);
        }// void train(
    // // 反向传播//Backpropagation

};//class NN神经网络NN {


//----------------------------------------------------------------------------------------
void writeVectorToFile(const std::vector<float>& A, const std::string& fileName) {
    std::ofstream outFile(fileName);
    if (outFile.is_open()) {
        for (float value : A) {
            outFile << value << std::endl;
        }
        outFile.close();
    }
    else {
        std::cerr << "Unable to open file for writing: " << fileName << std::endl;
    }
}//writeVectorToFile

void readVectorFromFile(std::vector<float>& B, const std::string& fileName) {
    std::ifstream inFile(fileName);
    float value;
    if (inFile.is_open()) {
        while (inFile >> value) {
            B.push_back(value);
        }
        inFile.close();
    }
    else {
        std::cerr << "Unable to open file for reading: " << fileName << std::endl;
    }
}//readVectorFromFile

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>

void writeToFile( const std::vector<std::vector<float>>& A , const std::string& filename) {
    std::ofstream file(filename);
    if (!file) {
        std::cerr << "Error opening file for writing: " << filename << std::endl;
        return;
    }

    for (const auto& row : A) {
        for (size_t i = 0; i < row.size(); ++i) {
            file << row[i];
            if (i != row.size() - 1) {
                file << ",";
            }
        }
        file << "\n";
    }

    file.close();
}//void writeToFile

std::vector<std::vector<float>> readFromFile(const std::string& filename) {
    std::vector<std::vector<float>> B;
    std::ifstream file(filename);
    if (!file) {
        std::cerr << "Error opening file for reading: " << filename << std::endl;
        return B;
    }

    std::string line;
    while (std::getline(file, line)) {
        std::vector<float> row;
        std::stringstream ss(line);
        std::string value;
        while (std::getline(ss, value, ',')) {
            row.push_back(std::stof(value));
        }
        B.push_back(row);
    }

    file.close();
    return B;
}//readFromFile(


//----------------------------------------------------------------------------------------

#define Num训练数据的个数s 4
int main()
{
    NN神经网络NN nn(2, 4, 3, 1);// 2, 3, 2, 1);// 11, 10, 4);
    // Example

    int 训练数据的个数s = Num训练数据的个数s;
     vector<float> input[Num训练数据的个数s];

/*  input[0] = {0,1,0, 0,1,0, 0,1,0};      //1“竖线”或 “1”字{ 1.0, 0.5, 0.25, 0.125 };
    input[1] = { 0,0,0, 1,1,1,0,0,0 };      //-“横线”或 “-”减号{ 1.0, 0.5, 0.25, 0.125 };
    input[2] = { 0,1,0, 1,1,1, 0,1,0 };      //+“+”加号{ 1.0, 0.5, 0.25, 0.125 };
    input[3] = { 0,1,0, 0,1.2, 0,  0,1, 0 };   // '1'或 '|'字型{ 1.0, 0.5, 0.25, 0.125 };
    input[4] = { 1,1,0, 1,0,1.2,  1,1,1 };      //“口”字型+{ 1.0, 0.5, 0.25, 0.125 };
     vector<float> target[Num训练数据的个数s];
    target[0] = { 1.0, 0,0,0 };// , 0};//1 , 0}; //0.0, 1.0, 0.5};      //{ 0.0, 1.0 };
    target[1] = { 0, 1.0 ,0,0 };// , 0};//- 91.0, 0};// , 0, 0}; //
    target[2] = { 0,0,1.0,0 };// , 0};//+ 1.0, 0.5};
    target[3] = { 1.0 ,0,0, 0.5 };// , 0}; //1
    target[4] = { 0,0,0,0 };// , 1.0}; //“口”
    */

    vector<float> target[Num训练数据的个数s];
    input[0] = { 0,0 };     target[0] = { 0 };   //"-"
    input[1] = { 1,0 };     target[1] = { 1 };
    input[2] = { 1,1};     target[2] = { 0};
    input[3] = { 0,1 };     target[3] = { 1 };


    for (int i = 0; i < 900000; ++i) {//for110i
        for (int jj = 0; jj < Num训练数据的个数s - 1;  ++jj) {
        //for (auto& val: input ) {
            nn.train(input[jj], target[jj], 0.001);
            if (0 ==i % 100000) { std::cout << "[Lost:" << Loss误差损失之和001 << endl; }
        
        }//for220jj

    }//for110i

//    writeToFile( nn.输入层到第1隐藏层之权重矩阵 , "/file输入层到第1隐藏层之权重矩阵Name220101.txt");
    writeToFile(nn.输入层到第1隐藏层之权重矩阵, "/file输入层到第1隐藏层之权重矩阵Name220101.txt");
    writeToFile(nn.隐藏22到输出层de权重矩阵, "/file隐藏22到输出层de权重矩阵Name220101.txt");
    writeToFile(nn.隐藏层1到第二隐藏层2之权重矩阵1to2, "file隐藏层1到第二隐藏层2之权重矩阵1to2Name220101.txt");

    writeVectorToFile( nn.隐藏层1偏置1, "/file隐藏层1偏置1.txt");
    writeVectorToFile(nn.隐藏层2偏置2, "/file隐藏层2偏置2.txt");
    writeVectorToFile(nn.O输出层偏置, "/fileO输出层偏置.txt");
   
    std::cout << endl;

    //--------------------------------------
    input[1] = { 0,1 };// 0, 0, 1, 1, 0.98, 0, 0, 0};      //1/
     vector<float> outpu输出数据001t = nn.predict(input[0]);

    for (auto& val : outpu输出数据001t)
         std::cout <<  fixed <<  setprecision(9) << val << " ";
    std::cout << endl;

    //-------------------------------------------------------------

     string str0001;
    do {
         std::cout <<  endl << "请输入一个字符串(要求字符串是包含9个由逗号分隔的数字的字符串,如 1,2,0,0,5,0,0,8,9等): " <<  endl;
         getline( cin, str0001);

         stringstream s01s001(str0001);
         for (int i = 0; i < 2;++i) {//
             //9; ++i) {
             string temp;
             getline(s01s001, temp, ',');

            input[1][i] = (float) stof(temp); // 将字符串转化为整数
        }

         std::cout << "数字数组为: ";
         for (int i = 0; i < 2;++i) {// 9; ++i) {
             std::cout << input[1][i] << " ";
        }

         //
         readVectorFromFile(nn.隐藏层1偏置1, "/file隐藏层1偏置1.txt");

         nn.输入层到第1隐藏层之权重矩阵 = readFromFile("/file输入层到第1隐藏层之权重矩阵Name220101.txt");

         //
        outpu输出数据001t = nn.predict(input[1]);
         std::cout <<  endl;
        for (auto& val : outpu输出数据001t)
             std::cout <<  fixed <<  setprecision(9) << val << " ";

    } while (true);// 1 == 1);

    //======================================
     std::cout << "Hello World!\n";
}//

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/48585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于打包多模块SpringBoot项目并通过宝塔上传服务器

打包 —— 如何打包多模块项目&#xff0c;参考b站up主&#xff1a;[喜欢编程的代先生] 的视频 总结&#xff1a;1. 对着视频里看一下父模块和各个子模块pom.xml文件关于打包工具的依赖是否正确。2. 从最底层开始打包&#xff0c;逐层向上&#xff0c;最后再合并打包。 部署 …

【计算机网络篇】TCP协议

✅作者简介&#xff1a;大家好&#xff0c;我是小杨 &#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; TCP协议 1&#xff0c;TCP 简介 TCP&#xff08;Transmission Control Protocol&#xff09;是…

uniapp,使用canvas制作一个签名版

先看效果图 我把这个做成了页面&#xff0c;没有做成组件&#xff0c;因为之前我是配合uview-plus的popup弹出层使用的&#xff0c;这种组件好像是没有生命周期的&#xff0c;第一次打开弹出层可以正常写字&#xff0c;但是关闭之后再打开就不会显示绘制的线条了&#xff0c;还…

【C语言进阶(4)】指针和数组笔试题

文章目录 Ⅰ 一维数组Ⅱ 字符数组题型 1题型 2题型 3 Ⅲ 二维数组 数组名的意义 sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小。&数组名&#xff0c;这里的数组名表示的是整个数组&#xff0c;取出的是整个数组的地址。除了上述…

2023年03月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;和数 给定一个正整数序列&#xff0c;判断其中有多少个数&#xff0c;等于数列中其他两个数的和。 比如&#xff0c;对于数列1 2 3 4, 这个问题的答案就是2, 因为3 2 1, 4 1 3。 时间限制&#xff1a;10000 内存限制&#xff1a;65536 输入 共两行&#x…

TCP-消息队列模型

#include "main.h" fd_win_set setSockets;VOID Server_write_error() {}int cteateserver(HWND hwnd) {WORD wVersionRequested;WSADATA wsaData;int err;/* 使用Windef.h中声明的MAKEWORD&#xff08;低字节、高字节&#xff09;宏 */wVersionRequested MAKEWORD(…

AMBA总线协议(6)——AHB(四):传输细节

一、前言 在之前的文章中&#xff0c;我们已经讲述了AHB传输中的两种情况&#xff0c;基本传输和猝发传输。我们进行一个简单的回顾&#xff0c;首先&#xff0c;开始一次传输之前主机需要向仲裁器申请获得总线的使用权限&#xff0c;然后主机给出地址和控制信号&#xff0c;根…

非计算机科班如何丝滑转码

近年来&#xff0c;很多人想要从其他行业跳槽转入计算机领域。非计算机科班如何丝滑转码&#xff1f; 方向一&#xff1a;如何规划才能实现转码&#xff1f; 对于非计算机科班的人来说&#xff0c;想要在计算机领域实现顺利的转码并不是一件容易的事情&#xff0c;但也并非不…

【JavaEE进阶】SpringMVC

文章目录 一. 简单认识SpringMVC1. 什么是SpringMVC?2. SpringMVC与MVC的关系 二. SpringMVC1. SpringMVC创建和连接2. SpringMVC的简单使用2.1 RequestMapping 注解介绍2.2 RequestMapping支持的请求类型2.3 GetMapping 和 PostMapping 3. 获取参数3.1 传递单个参数3.2 传递对…

【linux】2 Linux编译器-gcc/g++和Linux调试器-gdb

文章目录 一、Linux编译器-gcc/g使用1.1 背景知识1.2 gcc如何完成1.3 函数库1.4 gcc选项 二、linux调试器-gdb使用2.1 背景2.2 开始使用 总结 ヾ(๑╹◡╹)&#xff89;" 人总要为过去的懒惰而付出代价ヾ(๑╹◡╹)&#xff89;" 一、Linux编译器-gcc/g使用 1.1 背景…

/root/.ssh/config line 2: Bad protocol 2 host key algorithms ‘+ssh-rsa‘.

文章目录 1、问题2、查看openssh版本3、解决问题4、重新生成密钥5、查看是否可连接工蜂 1、问题 ssh访问工蜂报错&#xff1a; [rootlocalhost .ssh]# ssh -T gitgit.code.tencent.com /root/.ssh/config line 2: Bad protocol 2 host key algorithms ‘ssh-rsa’. 2、查看o…

升级Qt后VS项目不能使用

错误场景&#xff1a; 如果你的QT卸载了装了新版,那么VS你原来设置的项目就不能跑了. 问题 升级Qt后&#xff36;&#xff33;项目不能使用 跟我一起开始挽救自己的项目 升级Qt后&#xff36;&#xff33;项目不能使用 假如你从5.14.6 升级到 Qt6.2并删除了原来的QT 你在VS里…

Unity 3d角色展示脚本(旋转 平移 缩放)展示界面

不考虑性能 很简陋的一个功能&#xff0c;主要是用于角色渲染的观察用&#xff0c;比simplecontroller要好用一点 using System; using UnityEngine;public class CharacterViewer : MonoBehaviour {public Transform target; // 人物模型的Transformpublic float rotationSpee…

Java网络编程(一)网络基础

概述 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递 网络分类 局域网(LAN) 局域网是一种在小区域内使用的,由多台计算机组成的网络,覆盖范围…

hive-sql

hive-常用SQL汇总 查看数据库 -- 查看所有的数据库 show databases; 使用默认的库 -- 下面的语句可以查看默认的库 use default ;查看某个库下的表 -- 查看所有的表 show tables ; -- 查看包含 stu的表 &#xff0c;这种是通配的方法来查看 show tables like *stu*; 查…

【深入理解jvm读书笔记】jvm如何进行内存分配

jvm如何进行内存分配 内存分配方式内存分配方式的选择并发场景下的内存分配内存空间的初始化构造函数 内存分配方式 指针碰撞空闲列表 指针碰撞法&#xff1a; 假设Java堆中内存是绝对规整的&#xff0c;所有被使用过的内存都被放在一边&#xff0c;空闲的内存被放在另一边&a…

春秋云镜 CVE-2019-16692

春秋云镜 CVE-2019-16692 phpIPAM 1.4 - SQL Injection 靶标介绍 phpIPAM 1.4后台存在SQL Injection。 启动场景 漏洞利用 后台SQL注入&#xff0c;admin/admin888登陆成功。 exp POST /app/admin/routing/edit-bgp-mapping-search.php HTTP/1.1 Host: xxx.com Content-Le…

mysql从传统模式切到GTID模式后启动主从,主从异常报错1236

一 前言 MySQL 的主从复制作为一项高可用特性&#xff0c;用于将主库的数据同步到从库&#xff0c;在维护主从复制数据库集群的时候&#xff0c;作为专职的MySQL DBA&#xff0c;笔者相信大多数人都会遇到“Got fatal error 1236 from master when reading data from binary …

MySQL数据库:内置函数

日期函数 规定&#xff1a;日期&#xff1a;年月日 时间&#xff1a;时分秒 函数名称作用描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳date(datetime)返回datetime参数的日期部分date_add(date,interval d_value_type)在date中添加…

jenkins自动部署微服务到docker

1、代码上传到git&#xff1b; 2、jenkins拉取git的代码&#xff0c;maven打包&#xff0c;使用插件生成镜像&#xff0c;自动上传docker&#xff1b; 两个插件&#xff0c;一个打包插件&#xff0c;一个创建镜像上传docker仓库.&#xff08;将dockerfile内容搬到插件配置&…