C++.神经网络与深度学习(二次修改)

神经网络与深度学习

  • 1. 神经网络基础
    • 1.1 神经元模型与激活函数
    • 1.2 神经网络结构与前向传播
    • 2.1 损失函数与优化算法
      • 均方误差损失函数
      • 交叉熵损失函数
      • 梯度下降优化算法
    • 2.2 反向传播与梯度计算
      • 神经元的反向传播
    • 3.1 神经元类设计与实现
      • 神经元类代码实现
      • 代码思路
    • 3.2 神经网络类构建
      • 神经网络类代码实现
      • 代码思路
    • 4.1 神经元模型与激活函数
    • 4.2 神经网络结构与前向传播
    • 4.3 深度学习框架中的关键组件
    • 4.4 反向传播与梯度计算
    • 4.5 神经网络类的构建与实现
    • 4.6 神经网络的训练过程
      • 代码思路

1. 神经网络基础

1.1 神经元模型与激活函数

神经元是神经网络的基本单元,其模型可以类比为生物神经元。一个神经元接收多个输入信号,对这些信号进行加权求和,然后通过一个激活函数进行非线性变换,最终输出一个信号。以下是用 C++ 实现一个简单神经元的代码示例:

#include <iostream>
#include <vector>
#include <cmath>// 定义激活函数
double sigmoid(double x) {return 1.0 / (1.0 + exp(-x));
}// 神经元类
class Neuron {
private:std::vector<double> weights; // 权重double bias; // 偏置public:// 构造函数Neuron(int input_size) {weights.resize(input_size, 0.0); // 初始化权重为0bias = 0.0; // 初始化偏置为0}// 设置权重和偏置void set_weights(const std::vector<double>& w, double b) {weights = w;bias = b;}// 前向传播,计算输出double forward(const std::vector<double>& inputs) {double sum = bias;for (size_t i = 0; i < inputs.size(); ++i) {sum += inputs[i] * weights[i];}return sigmoid(sum); // 使用Sigmoid激活函数}
};int main() {// 创建一个输入大小为2的神经元Neuron neuron(2);// 设置权重和偏置std::vector<double> weights = {0.5, -0.3};double bias = 0.1;neuron.set_weights(weights, bias);// 输入信号std::vector<double> inputs = {1.0, -2.0};// 计算输出double output = neuron.forward(inputs);std::cout << "Neuron output: " << output << std::endl;return 0;
}

代码思路:

  • 激活函数:Sigmoid 函数是一个常用的激活函数,它将输入映射到 (0, 1) 区间,具有平滑的梯度,适用于神经元的非线性变换。
  • 神经元类
    • 成员变量weights 存储输入信号的权重,bias 是偏置项。
    • 构造函数:根据输入信号的数量初始化权重和偏置。
    • 设置权重和偏置:通过 set_weights 函数设置权重和偏置。
    • 前向传播forward 函数计算输入信号的加权和,加上偏置后通过激活函数输出结果。
  • 主函数
    • 创建一个神经元实例,设置权重和偏置。
    • 提供输入信号,调用 forward 函数计算输出。

1.2 神经网络结构与前向传播

神经网络由多个神经元组成,通常分为输入层、隐藏层和输出层。前向传播是指从输入层到输出层逐层计算的过程。以下是一个简单的两层神经网络的 C++ 实现:

#include <iostream>
#include <vector>
#include <cmath>// 激活函数
double sigmoid(double x) {return 1.0 / (1.0 + exp(-x));
}// 神经元类
class Neuron {
private:std::vector<double> weights;double bias;public:Neuron(int input_size) {weights.resize(input_size, 0.0);bias = 0.0;}void set_weights(const std::vector<double>& w, double b) {weights = w;bias = b;}double forward(const std::vector<double>& inputs) {double sum = bias;for (size_t i = 0; i < inputs.size(); ++i) {sum += inputs[i] * weights[i];}return sigmoid(sum);}
};// 神经网络类
class NeuralNetwork {
private:std::vector<Neuron> hidden_layer; // 隐藏层Neuron output_neuron; // 输出层public:NeuralNetwork(int input_size, int hidden_size) {hidden_layer.resize(hidden_size, Neuron(input_size));output_neuron = Neuron(hidden_size);}void set_weights(const std::vector<std::vector<double>>& hidden_weights,const std::vector<double>& hidden_biases,const std::vector<double>& output_weights,double output_bias) {for (size_t i = 0; i < hidden_layer.size(); ++i) {hidden_layer[i].set_weights(hidden_weights[i], hidden_biases[i]);}output_neuron.set_weights(output_weights, output_bias);}double forward(const std::vector<double>& inputs) {std::vector<double> hidden_outputs(hidden_layer.size());for (size_t i = 0; i < hidden_layer.size(); ++i) {hidden_outputs[i] = hidden_layer[i].forward(inputs);}return output_neuron.forward(hidden_outputs);}
};int main() {// 创建一个输入大小为2,隐藏层大小为2的神经网络NeuralNetwork nn(2, 2);// 设置权重和偏置std::vector<std::vector<double>> hidden_weights = {{0.5, -0.3}, {0.2, 0.1}};std::vector<double> hidden_biases = {0.1, -0.2};std::vector<double> output_weights = {0.4, -0.5};double output_bias = 0.3;nn.set_weights(hidden_weights, hidden_biases, output_weights, output_bias);// 输入信号std::vector<double> inputs = {1.0, -2.0};// 计算输出double output = nn.forward(inputs);std::cout << "Neural Network output: " << output << std::endl;return 0;
}

代码思路:

  • 神经网络类
    • 成员变量hidden_layer 存储隐藏层的神经元,output_neuron 是输出层的神经元。
    • 构造函数:根据输入层大小和隐藏层大小初始化神经网络。
    • 设置权重和偏置:通过 set_weights 函数设置隐藏层和输出层的权重和偏置。
    • 前向传播
      • 隐藏层的每个神经元对输入信号进行前向传播,计算隐藏层的输出。
      • 将隐藏层的输出作为输出层神经元的输入,计算最终输出。
  • 主函数
    • 创建一个神经网络实例,设置权重和偏置。
    • 提供输入信号,调用 forward 函数计算输出。# 2. 深度学习框架

2.1 损失函数与优化算法

在深度学习中,损失函数用于衡量模型的预测值与真实值之间的差异,优化算法则用于调整模型的参数以最小化损失函数。以下是几种常见的损失函数和优化算法的实现及讲解。

均方误差损失函数

均方误差(MSE)损失函数是回归任务中常用的损失函数,它计算预测值与真实值之间差的平方的均值。

#include <iostream>
#include <vector>
#include <cmath>// 均方误差损失函数
double mse_loss(const std::vector<double>& predictions, const std::vector<double>& targets) {double loss = 0.0;for (size_t i = 0; i < predictions.size(); ++i) {loss += std::pow(predictions[i] - targets[i], 2);}return loss / predictions.size();
}int main() {// 示例:预测值和真实值std::vector<double> predictions = {0.5, 1.2, -0.3};std::vector<double> targets = {0.4, 1.0, -0.5};// 计算损失double loss = mse_loss(predictions, targets);std::cout << "MSE Loss: " << loss << std::endl;return 0;
}

代码思路:

  • 损失计算:遍历预测值和真实值,计算每个样本的预测值与真实值之差的平方。将所有样本的损失值求和后除以样本总数,得到均方误差损失。

交叉熵损失函数

交叉熵损失函数常用于分类任务,它衡量模型输出的概率分布与真实标签的概率分布之间的差异。

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>// Softmax函数
std::vector<double> softmax(const std::vector<double>& logits) {double max_logit = *std::max_element(logits.begin(), logits.end());double sum = 0.0;std::vector<double> probabilities(logits.size());for (size_t i = 0; i < logits.size(); ++i) {probabilities[i] = std::exp(logits[i] - max_logit);sum += probabilities[i];}for (size_t i = 0; i < logits.size(); ++i) {probabilities[i] /= sum;}return probabilities;
}// 交叉熵损失函数
double cross_entropy_loss(const std::vector<double>& logits, int target_class) {std::vector<double> probabilities = softmax(logits);return -std::log(probabilities[target_class]);
}int main() {// 示例:模型输出的logits和目标类别std::vector<double> logits = {2.0, 1.0

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

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

相关文章

FPGA图像处理(六)------ 图像腐蚀and图像膨胀

默认迭代次数为1&#xff0c;只进行一次腐蚀、膨胀 一、图像腐蚀 1.相关定义 2.图像腐蚀效果图 3.fpga实现 彩色图像灰度化&#xff0c;灰度图像二值化&#xff0c;图像缓存生成滤波模块&#xff08;3*3&#xff09;&#xff0c;图像腐蚀算法 timescale 1ns / 1ps // // Des…

中国版Cursor:CodeBuddy腾讯云代码助手使用体验

我正在参加CodeBuddy「首席试玩官」内容创作大赛&#xff0c;本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴” 1.CodeBuddy简介 腾讯云代码助手CodeBuddy&#xff0c;这个是一款编程插件&#xff0c;我们可以在各个编程…

Go语言 GORM框架 使用指南

在 Go 语言社区中&#xff0c;数据库交互一直是开发者们关注的重点领域&#xff0c;不同开发者基于自身的需求和偏好&#xff0c;形成了两种主要的技术选型流派。一部分开发者钟情于像sqlx这类简洁的库&#xff0c;尽管其功能并非一应俱全&#xff0c;但它赋予开发者对 SQL 语句…

从零开始学习three.js(18):一文详解three.js中的着色器Shader

在WebGL和Three.js的3D图形渲染中&#xff0c;着色器&#xff08;Shader&#xff09; 是实现复杂视觉效果的核心工具。通过编写自定义的着色器代码&#xff0c;开发者可以直接操作GPU&#xff0c;实现从基础颜色渲染到动态光照、粒子效果等高级图形技术。本文将深入解析Three.j…

Python函数库调用实战:以数据分析为例

一、引言 Python之所以在编程领域广受欢迎&#xff0c;很大程度上得益于其丰富且强大的函数库。这些函数库涵盖了从数据分析、科学计算到Web开发、机器学习等众多领域&#xff0c;极大地提高了开发效率。本文将以数据分析为例&#xff0c;介绍如何调用Python的一些常用函数库。…

shell脚本之条件判断,循环控制,exit详解

if条件语句的语法及案例 一、基本语法结构 1. 单条件判断 if [ 条件 ]; then命令1命令2... fi2. 双分支&#xff08;if-else&#xff09; if [ 条件 ]; then条件为真时执行的命令 else条件为假时执行的命令 fi3. 多分支&#xff08;if-elif-else&#xff09; if [ 条件1 ]…

现代 Web 自动化测试框架对比:Playwright 与 Selenium 的深度剖析

现代 Web 自动化测试框架对比&#xff1a;Playwright 与 Selenium 的深度剖析 摘要&#xff1a;本文对 Playwright 与 Selenium 在开发适配性、使用难度、场景适用性及性能表现等方面进行了全面深入的对比分析。通过详细的技术实现细节阐述与实测数据支撑&#xff0c;为开发者…

系统架构设计(十):结构化编程

定义 结构化编程是一种遵循清晰逻辑结构、避免使用 goto 的编程方法。它强调使用有限的三种基本控制结构来组织程序&#xff0c;提高程序的可读性、可维护性和可测试性。 它是现代程序设计的基础&#xff0c;被广泛应用于命令式语言&#xff08;如 C、Pascal、Java&#xff0…

TC3xx学习笔记-UCB BMHD使用详解(二)

文章目录 前言Confirmation的定义Dual UCB: Confirmation StatesDual UCB: Errored State or ECC Error in the UCB Confirmation CodesECC Error in the UCB ContentDual Password UCB ORIG and COPY Re-programming UCB_BMHDx_ORIG and UCB_BMHDx_COPY (x 0-3)BMHD Protecti…

OTA与boot loader

OTA指的是无线升级&#xff0c;通常用于更新设备的固件或软件&#xff0c;用户不用手动操作&#xff0c;非常方便。而bootloader是启动时加载操作系统的程序&#xff0c;负责硬件初始化和启动流程。 首先&#xff0c;OTA是如何通过bootloader工作的。OTA下载更新包后&#xff0…

实验六:FPGA序列检测器实验

FPGA序列检测器实验(远程实验系统) 文章目录 FPGA序列检测器实验(远程实验系统)一、数字电路基础知识1. 时钟与同步2. 按键消抖原理代码讲解:分频与消抖3. 有限状态机(FSM)设计代码讲解:状态机编码与转移4. 边沿检测与信号同步5. 模块化设计二、实验数字电路整体思想三…

jenkins部署

开发者将代码push到git运维人员通过jenkins部署&#xff0c;自动到git上pull代码通过maven构建成jar包&#xff0c;并结合dockerfile打包成镜像&#xff0c;push docker镜像到docker registry通过k8s发起 发布/更新 服务 操作 通过Jenkins部署&#xff0c;自动到Git上PULL代码 …

BBR 的 buffer 动力学观感

这周很忙&#xff0c;今天还加了一天班&#xff0c;但还是抽空实现了五一在安徽泾县山区喝着一壶酒写的 BBR ProbeRTT 的想法&#xff0c;没多少行代码&#xff0c;它真就消除了带宽锯齿&#xff0c;皮了个鞋&#x1f45e;&#xff0c;昨天我还在群里说了今天再说说 BBR 的&…

第9讲、深入理解Scaled Dot-Product Attention

Scaled Dot-Product Attention是Transformer架构的核心组件&#xff0c;也是现代深度学习中最重要的注意力机制之一。本文将从原理、实现和应用三个方面深入剖析这一机制。 1. 基本原理 Scaled Dot-Product Attention的本质是一种加权求和机制&#xff0c;通过计算查询(Query…

el-tree结合checkbox实现数据回显

组件代码 <el-tree:data"vertiList"show-checkboxnode-key"id":props"defaultProps"ref"treeRefx"class"custom-tree"check-change"handleCheckChange"> </el-tree>获取选择的节点 handleCheckChan…

OpenResty 深度解析:构建高性能 Web 服务的终极方案

引言 openresty是什么&#xff1f;在我个人对它的理解来看相当于嵌入了lua的nginx; 我们在nginx中嵌入lua是为了不需要再重新编译,我们只需要重新修改lua脚本,随后重启即可; 一.lua指令序列 我们分别从初始化阶段&#xff0c;重写/访问阶段&#xff0c;内容阶段&#xff0c;日志…

多商户商城系统源码解析:开发直播电商APP的技术底层实战详解

随着直播电商的火爆&#xff0c;越来越多的创业者和企业都在寻求打造自己的多商户商城系统&#xff0c;以实现“人、货、场”三者的深度融合。然而&#xff0c;从一个简单的电商平台到一个功能完善的直播电商APP&#xff0c;其技术底层架构和实现过程并非一蹴而就。本文将从架构…

桌面端进程通信

以下是关于 Electron 桌面端进程通信的基本知识点总结: 一、Electron 进程模型基础 1. 进程类型与职责 进程类型职责权限主进程(Main)创建窗口、系统级操作、IPC中枢完全Node.js访问权限渲染进程(Renderer)展示Web内容、UI交互默认受限(可配置开启Node.js)预加载脚本(Prelo…

openEuler24.03 LTS下安装MySQL8.0.42

目录 前提步骤 删除原有mysql及maridb数据库 安装MySQL 启动MySQL 启动查看MySQL状态 设置MySQL开机自启动 查看登录密码 登录MySQL 修改密码及支持远程连接 远程连接MySQL 前提步骤 拥有openEuler24.03 LTS环境&#xff0c;可参考&#xff1a;Vmware下安装openEule…

idea 保证旧版本配置的同时,如何从低版本升到高版本

文章目录 前言idea 保证旧版本配置的同时,如何从低版本升到高版本1. 备份项目2. 下载最新的idea3. 安装安装包4. 导入idea2019旧配置5. 验证前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差,…