- 博客(53)
- 收藏
- 关注
原创 pytorch模型部署基础知识
在深度学习研究和开发中,我们通常使用PyTorch这样的框架进行模型训练。在训练环境中,我们关注的是模型精度收敛速度和实验迭代效率。然而,当模型准备投入实际应用时,面临的挑战就完全不同了。1.1 训练环境是一个开放的深度学习模型表示格式。它类似于软件开发中的"中间语言"(IR),允许模型在不同的深度学习框架之间进行转换和共享。模型设计阶段考虑部署避免动态控制流(if/for)使用标准算子考虑量化友好性导出阶段注意事项始终使用model.eval()模式明确指定动态维度。
2025-12-01 21:53:36
509
原创 C++中的函数指针与指针函数:理解与运用
指针函数返回指针类型的函数。简单来说,就是一个返回值为指针的函数。函数指针是指向函数的指针变量,它存储的是函数的地址,可以通过该指针调用函数。指针函数是返回指针的函数,主要用于动态内存管理和资源创建。函数指针是指向函数的指针,主要用于回调函数和策略模式。在现代C++中,可以考虑使用std::function和lambda表达式作为函数指针的替代方案。使用时要注意内存管理和类型安全。
2025-10-24 21:21:38
217
原创 手撕注意力机制与多头注意力:核心原理与代码实现
在深度学习领域,尤其是自然语言处理中,注意力机制已经成为革命性的技术。今天,我们将深入理解注意力机制和多头注意力的核心原理,并用Python从零开始实现它们。多头注意力将输入投影到多个子空间,在每个子空间中独立计算注意力,最后将结果合并。这种设计允许模型同时关注来自不同表示子空间的信息。注意力机制模拟了人类大脑的注意力分配过程,让模型能够动态地关注输入中不同部分的重要性。
2025-10-19 20:42:57
225
原创 C++实现K-Means聚类算法
通过这个C++实现,我们完整地展示了K-Means聚类算法的核心思想和实现细节。K-Means虽然简单,但在实际应用中需要注意数据预处理、参数选择和算法优化等问题。核心思想:通过迭代优化质心位置来最小化簇内距离实现重点:质心初始化、数据点分配、质心更新。
2025-10-19 20:12:50
714
原创 C++从零实现KNN分类器
在机器学习领域,K最近邻(K-Nearest Neighbors,KNN)算法以其简单直观的特性,成为了很多初学者入门的第一课。今天,我将手把手教你如何使用C++实现一个完整的KNN分类器,不仅理解算法原理,还能掌握实际的编程技巧。KNN是一种基于实例的学习算法,它的核心思想可以用一句俗语概括:"近朱者赤,近墨者黑"。简单来说,一个样本的类别可以由它最接近的k个邻居的类别来决定。:在实际应用中,我们可以省略开方运算,因为距离的大小关系不变,这样可以提升计算速度。:选择距离最近的k个训练样本。
2025-10-19 19:13:18
420
原创 CNN参数量计算详解:为什么卷积神经网络如此高效?
但你是否曾好奇,为什么CNN能够在保持高精度的同时,参数量却远少于传统的全连接网络?”,当时脑子里只是知道卷积神经网路的卷积核参数是共享的,置于具体参数量怎么计算,还确实不记得了,因为这些基本知识只是在入门深度学习的时候才会学习,后续一直不怎么用,就忘了。惊人发现:仅仅一层全连接网络,就需要超过3千万个参数!,换言之,同一个卷积核在滑动提取输入数据不同区域特征时采用的权重是相同的。在理解CNN的优势之前,我们先看看全连接层面临的问题。为什么卷积神经网络参数量比全连接层少,以及参数量是怎么计算的。
2025-10-19 13:21:31
407
原创 Vision Transformer的双核引擎:注意力与位置编码原理解析
Vision Transformer的成功,深刻地揭示了深度学习的核心:通过构建可学习的关联结构,让模型自动从数据中发现复杂的模式与关系。自注意力机制提供了动态、全局的关联能力,而位置编码则确保了空间关系的正确注入。正是这对“双核引擎”的协同驱动,使得ViT能够“纵观全局”,在众多视觉任务中取得了突破性的成就。
2025-10-18 00:25:20
886
原创 transformer模型详解
从宏观上理解Transformer。它是一个编码器-解码器 结构,最初是为机器翻译任务设计的——编码器理解源语言句子,解码器生成目标语言句子。左侧:编码器。由N个(原论文中N=6)完全相同的层堆叠而成。右侧:解码器。同样由N个完全相同的层堆叠而成。中间:编码器和解码器之间通过注意力机制连接。接下来,我们像拆解精密仪器一样,深入每一个核心部件。
2025-10-16 23:25:11
810
原创 C++多态底层原理剖析
不知道有没有小伙伴跟我一样,网上去搜C++多态相关的解释时,一般出现的都是一下内容:C++ 多态是面向对象编程的核心特性之一,它允许不同的对象对同一消息做出不同的响应。多态通过运行时绑定(动态多态)和编译时绑定(静态多态)两种方式实现。静态多态(编译时多态)通过函数重载和模板实现,在编译阶段确定具体调用的函数。动态多态(运行时多态)通过虚函数和继承实现,在运行阶段根据对象的实际类型确定调用的函数。
2025-10-04 00:19:40
559
原创 原子操作与互斥锁:C++并发编程的利器
原子操作是指不可分割的操作,即在执行过程中不会被其他线程中断。C++11引入了<atomic>头文件,提供了模板类,用于对基本数据类型(如int、bool等)进行原子操作。原子操作通常由硬件支持(如CPU的lock指令或比较交换指令CAS),效率较高。原子操作的特点:不可中断:操作要么完成,要么未开始,不存在中间状态。轻量级:直接利用硬件指令,性能开销小。限制性:只适用于简单数据类型和特定操作(如增减、比较交换等)。// 原子变量i < n;++i) {// 原子递增。
2025-06-21 20:13:09
700
原创 ros-noetic中嵌入protobuf数据传输
由上面框架图可知,主要就是要重写一个适用于 protobuf 数据类型的偏特化 Serializer 结构体就行。至于什么是模板偏特化,见第4章的补充知识点。
2025-05-14 20:56:39
1036
原创 RRT-Star算法讲解
RRT全名叫做快速随机扩展树算法(Rapidly-exploring Random Tree, RRT),RRT算法是一种单查询(single-query)算法,目标是尽可能快的找到一条从起点到终点的可行路径。它的搜索过程类似于一棵树不断生长、向四周扩散的过程,它以起点作为根节点构建一棵搜索树T。它的算法流程如下:这里由于涉及到很多图片,并没有自己去画,而是参考知乎上一位大佬的。上述是基础的RRT算法流程,它的采样过程是完全随机的,还可以在采样时以一定的概率直接采样终点作为Xrand。
2025-04-18 21:01:19
1135
原创 KD树的建立与搜索
KD 树是一种二叉树,它将数据点在k 维空间中进行划分,每个内部节点对应于一个坐标轴上的划分。通过不断地将空间划分为更小的子空间,使得数据点在树中能够按照一定的规则分布,从而方便进行查找、插入和删除等操作。
2025-04-18 12:45:08
1195
2
原创 C++实现环形缓冲区
public:// 类型定义 (STL容器要求)提供STL容器标准接口所需的类型定义支持自定义分配器(默认使用std::allocator)template <typename T, typename Allocator = std::allocator<T>>:这是一个模板声明。T是一个模板类型参数,代表环形缓冲区中存储的元素类型。Allocator是另一个模板类型参数,它代表用于分配和释放内存的分配器类型,默认使用std::allocator<T>,这是标准库中提供的通用分配器。
2025-04-08 20:57:18
1223
原创 C++11内存池设计与实现深度解析
这里是因为直接调用默认拷贝构造会出现问题,因此重写拷贝构造的接口,实际上用的是委托的默认构造函数,这样即使不小心调用了拷贝构造,最后实际上执行的仍是默认构造,从而避免出现因浅拷贝而出现的问题。这里借助通俗的模型帮助大家理解内存池是怎么运作的。假设我们有一个快递站(内存池),里面有很多货架(Block),每个货架有很多格子(Slot)用于存放快递(要存储的对象),这里假设所有快递占用的空间一样。注意:一个内存池有很多个内存块(block),一个内存块有多个内存槽(slot),内存槽一般就可以用来存储对象。
2025-04-06 17:27:45
1088
原创 在 Ubuntu 中使用 pip 安装 Python 包时遇到 “no moudle named” 的问题,而改用 sudo pip 后正常
然后执行 source ~/.bashrc。系统中可能同时存在多个 Python 版本(如。),但某些系统级的 Python 环境(如。可能没有读取权限,导致代码运行时找不到模块。可能关联到不同的 Python 环境。运行,导致模块未安装到正确的环境。root 权限安装,包会被安装到。参数确保包安装到用户目录(,以减少系统污染和安全风险。统一安装到用户目录(推荐)所有用户和程序均可访问。),说明是权限问题。),则是多版本冲突。
2025-03-31 19:43:29
739
原创 arm架构ubuntu设置ibus中文输入法快捷键
死活没反应,搞了挺久就是不成功,不知为何,设置成其他的组合键是可以的,但其他的用不顺手。于是到处寻找其他的设置方法,终于找到了。最近在 jetson agx orin 上刷机,装上 ubuntu 后准备设置中文输入法,按照网上的操作安装。这里我是想把输入法快捷键设置成。按上图所示设置,点击“应用”, 点击“确定”单个 “shift” 键。单个 “shift”
2025-03-31 15:13:51
601
原创 34.C++11之异步线程池
在 C++11 中,虽然标准库没有直接提供线程池的实现,但借助新引入的多线程和异步编程特性,如 std::thread、std::mutex、std::condition_variable、std::future 等,能够轻松实现一个高效的异步线程池。线程池可以预先创建一定数量的线程,将任务添加到任务队列中,然后由线程池中的线程从队列中取出任务并执行,这样可以避免频繁创建和销毁线程带来的开销,提高程序的性能。
2025-03-18 19:16:35
449
原创 33.C++11之线程异步
C++11 引入了一系列用于线程异步编程的新特性,这些特性极大地简化了多线程和异步任务的管理,使得开发者能够更方便地编写并发程序。下面将从std::async、std::future、std::promise 和 std::packaged_task这几个核心组件详细介绍 C++11 的线程异步特性。
2025-03-18 18:59:36
1018
3
原创 32.C++11之线程同步原子变量
在 C++11 里,标准库引入了原子变量,这是线程同步的重要工具。原子变量能够让多个线程安全地访问和修改共享数据,避免数据竞争问题,且无需显式使用互斥锁,能提升程序的性能与并发能力。下面从多个方面详细介绍 C++11 的原子变量。
2025-03-18 16:55:38
1031
原创 31.C++11之线程同步条件变量
在 C++11 中,标准库引入了条件变量(),它是一种用于线程同步的工具,通常与互斥锁(如std::mutex)结合使用,用于实现线程间的等待 - 通知机制。下面将从多个方面详细介绍 C++11 中的条件变量。
2025-03-18 16:30:55
665
原创 30.C++11之线程同步互斥锁mutex
在 C++11 中引入了标准的线程库,其中互斥锁(mutex)是线程同步的重要工具,用于保护共享资源,防止多个线程同时访问和修改这些资源而导致的数据竞争问题。下面从多个方面详细介绍 C++11 中的互斥锁。
2025-03-18 16:09:05
1024
原创 29.C++11之 call_once 函数
std::call_once 是 C++11 引入的一个非常实用的函数,它位于<mutex>头文件中,用于确保某个函数在多线程环境下只被调用一次。这在需要进行一次性初始化操作时非常有用,比如单例模式的初始化、资源的一次性加载等。下面从多个方面详细介绍 std::call_once 函数。
2025-03-18 15:27:54
649
原创 28.C++11之命名空间 - this_thread
在 C++11 中,std::this_thread 是一个命名空间,它位于 <thread> 头文件中,提供了一组用于操作当前线程的实用函数。这些函数允许开发者对当前正在执行的线程进行控制和查询,增强了多线程编程的灵活性和可控性。下面详细介绍 std::this_thread 命名空间中的主要函数。
2025-03-18 15:07:55
477
原创 27.C++11之线程类 thread
C++11 引入了标准线程库,其中类是该库的核心部分,它为开发者提供了一种跨平台的方式来创建和管理线程。下面将从多个方面详细介绍 std::thread 类。
2025-03-18 14:30:45
892
原创 26.C++11之处理日期和时间的chrono库
C++11 引入的<chrono>库为处理日期和时间提供了一套全面且灵活的工具,它将时间相关的操作进行了抽象和封装,使得代码更加简洁、安全且易于维护。下面从几个关键方面详细介绍 <chrono> 库。
2025-03-18 13:42:15
859
原创 25.C++11之智能指针
在某些情况下,默认的删除器(使用delete操作符)可能不满足需求,这时可以自定义删除器。delete p;return 0;在上述代码中,customDeleter是自定义的删除器,当ptr的引用计数变为 0 时,会调用该删除器来释放对象。std::unique_ptr允许使用自定义删除器,当所管理的对象需要特殊的释放方式时非常有用。delete p;return 0;在上述代码中,customDeleter是自定义的删除器,当ptr被销毁时,会调用该删除器来释放对象。
2025-03-18 10:48:39
903
1
原创 24.C++11之非受限联合体
非受限联合体的定义和传统联合体基本相同,只是放宽了对成员类型的限制,允许包含具有非平凡特殊成员函数的类型。// 非受限联合体定义int i;
2025-03-18 09:54:44
834
原创 23.C++11之强类型枚举
Value1,Value2,// ...其中,EnumName 是枚举的名称,UnderlyingType 是可选的底层类型,用于指定枚举值的实际存储类型,默认情况下是 int。
2025-03-17 22:38:58
373
原创 22.C++11之扩展的 friend 语法
在 C++11 之前,friend 关键字主要用于授予类或者函数访问另一个类的私有和受保护成员的权限。C++11 对 friend 语法进行了扩展,主要体现在允许 friend 声明一个模板实例化,这一特性增强了代码的灵活性和可维护性。下面将详细介绍 C++11 扩展的 friend 语法。
2025-03-17 22:21:30
665
原创 21.C++11之默认函数控制 =default 与 =delete
在 C++11 中,=default 和 =delete 是两个非常有用的特性,它们允许程序员对类的特殊成员函数的生成和使用进行更精细的控制,增强了代码的可读性和可维护性。下面分别详细介绍这两个特性。
2025-03-17 22:04:14
822
原创 20.C++11之POD类型
在 C++ 里,POD 是 “Plain Old Data” 的缩写,意思是普通旧数据。在 C++11 之前,POD 类型就已存在,不过 C++11 对其定义和规则进行了更为细致的划分和明确。POD 类型旨在和 C 语言中的数据类型保持兼容,保证数据在内存中的布局和 C 语言里的一致,这有利于在 C++ 和 C 代码之间进行数据交互,同时也能确保对象在内存中的存储形式简单且可预测。
2025-03-17 21:42:28
791
原创 19.C++11之可调用对象包装器、绑定器
在 C++11 中,可调用对象包装器和绑定器是两个非常实用的特性,它们增强了 C++ 在处理可调用对象(如函数、函数指针、成员函数指针、lambda 表达式等)时的灵活性和可复用性。
2025-03-17 21:08:38
799
原创 18.C++11之using的使用
在C++中using用于声明命名空间,使用命名空间也可以防止命名冲突。在程序中声明了命名空间之后,就可以直接使用命名空间中的定义的类了。在C++11中赋予了using新的功能,让C++变得更年轻,更灵活。
2025-03-17 19:40:04
531
原创 17.C++11之列表初始化
在 C++11 之前,初始化对象的方式多种多样,不同的类型和场景可能需要不同的初始化语法,这使得代码的一致性和可读性受到影响。例如,数组可以使用花括号初始化,而对于类对象,可能需要使用构造函数调用的方式进行初始化。C++11 引入了列表初始化(也称为统一初始化),提供了一种统一的初始化语法,能够应用于各种类型和场景。
2025-03-17 19:20:26
754
原创 16.C++11之完美转发
在 C++ 编程中,我们经常会编写函数模板,用于处理不同类型的参数。有时候,我们希望在函数模板中把接收到的参数原封不动地转发给另一个函数,这里的 “原封不动” 不仅指参数的值,还包括参数的左值 / 右值属性以及 const 属性等。在 C++11 之前,很难实现这种精确的参数转发。在这个 forwarding 函数模板中,无论传入的是左值还是右值,arg 都会被当作左值处理,因为它是一个具名变量。这就导致无法根据传入参数的原始值类别(左值或右值)来调用合适的 process 重载版本。
2025-03-17 17:12:44
818
原创 15.C++11之右值引用
右值引用是一种新的引用类型,使用双引号&&来表示。右值引用只能绑定到右值,不能绑定到左值。// 右值引用绑定到字面量(右值)在这个例子中,10 是一个右值,rvalueRef 是一个右值引用,它绑定到了这个右值。
2025-03-17 16:27:48
674
原创 14.C++11之委托构造函数和继承构造函数
如果基类有默认构造函数,派生类继承构造函数后,派生类不会因为继承构造函数而失去自己的默认构造函数(如果没有显式定义)。在上述代码中,派生类 Derived 为了使用基类 Base 的构造函数,需要在自己的构造函数中显式调用,当基类的构造函数较多时,派生类的代码会变得冗长。在修改之后的代码中可以看到,重复的代码全部没有了,并且在一个构造函数中调用了其他的构造函数用于相关数据的初始化,相当于是一个链式调用。:如果基类和派生类都定义了相同签名的构造函数,派生类的构造函数会隐藏基类的构造函数。
2025-03-17 15:37:46
417
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅