类型体系与基本数据类型(第三节)

news/2025/2/12 12:03:52/

目录

前言

一、标量

1.1 类模板的声明

1.2 基于CPU的特化版本

1.3 标量的主体类型


前言

一个深度学习框架的初步实现为例,讨论如何在一个相对较大的项目中深入应用元编程,为系统优化提供更多的可能。

以下内容结合书中原文阅读最佳!!!


一、标量

在深度学习框架中,标量(scalar)是指只有一个数值的数据,它在框架中的地位确实相对特殊。这是因为深度学习模型通常处理的是大规模的数据集,其中包含了许多张量(tensors),而张量是标量的扩展形式。

标量在深度学习框架中的特殊地位有以下几个原因:

1. 表示损失或成本函数:在深度学习中,我们通常使用损失函数或成本函数来衡量模型预测与实际结果之间的差异。这些函数通常计算一个标量值,它表示了模型的性能指标,比如交叉熵损失、均方误差等。标量的特点使得我们可以方便地将这些函数的结果用作优化算法的目标函数,进一步优化模型参数。

2. 提供反向传播的梯度:深度学习中的优化算法通常使用梯度下降法来更新模型参数。反向传播算法用于计算损失函数对于模型中各个参数的梯度,从而确定优化的方向。由于标量只有一个值,相对于向量或矩阵来说,它的梯度计算比较简单和高效。

3. 监督学习中的目标标签:在监督学习任务中,训练样本通常包括输入数据和对应的目标标签。目标标签通常是一个标量,如分类任务中的类别索引、回归任务中的实际值等。标量的便利性在于可以直接与模型的预测结果进行对比,从而计算出损失函数。

4. 简化计算图:在深度学习中,通常使用计算图(computational graph)来描述模型的运算过程。计算图中的节点表示运算操作,边表示数据流向。标量的特点使得计算图变得更简单和清晰,因为它减少了在不同形状的张量之间执行操作的复杂性。

总结来说,标量在深度学习框架中的特殊地位可以归结为它在表示损失函数、计算梯度、定义目标标签和简化计算图等方面的方便性。这些特点使得标量在深度学习模型的训练和优化过程中起到了重要的作用。

1.1 类模板的声明

MetaNN为标量引入了专门的类模板,示例如下

template <typename, TElem, typename TDevice = DeviceTags::CPU>struct Scalar;template <typename TElem, typename TDevice>
constexpr bool IsScalar<Scalar<TElem, TDevice>> = true;

声明了一个类模板 Scalar,它有两个模板参数:typename TElem 和 typename TDevice。这个结构体的作用是表示标量数据。TElem 表示标量的类型,TDevice 表示标量所在的设备(默认为 CPU)。这样设计的好处是可以方便地适配不同类型和设备的标量数据。

接下来,constexpr bool IsScalar<Scalar<TElem, TDevice>> = true; 是一个模板特化,用于判断一个给定类型是否为 Scalar 类型的实例。使用 IsScalar 模板变量可以在编译期确定一个类型是否是 Scalar 类型,如果是,则该模板变量的值为 true,否则为 false。

总结来说,这段代码通过引入类模板 Scalar,为标量数据引入了一个统一的表示方式。这样可以更灵活地处理不同类型和设备上的标量数据,并通过 IsScalar 模板特化来判断一个给定类型是否为 Scalar 类型的实例。这种设计模式能够提高代码的可扩展性和复用性。

1.2 基于CPU的特化版本

Scalar的CPU特化版本

template <typename TElem, typename TDevice = DeviceTags::CPU>
class Scalar
{
public:using ElementType = TElem;using DeviceType = TDevice;public:Scalar(ElementType elem = ElementType()): m_elem(elem) {}auto& Value() { return m_elem; }auto Value() const { return m_elem; }// 求值相关接口bool operator == (const Scalar& val) const;template <typename TOtherType>bool operator == (const TOtherType&) const;template <typename TData>bool operator!= (const TData& val) const;auto EvalRegister() const;private:ElementType m_elem;
};

这段代码实现了一个名为 Scalar 的类模板,用于表示标量数据。

代码的详细解释:

1. 类模板定义:Scalar 是一个类模板,其中包括两个模板参数:typename TElem 和 typename TDevice。TElem 表示标量的数据类型,TDevice 表示标量所在的设备,默认为 CPU。

2. 类型别名:在类模板中定义了两个类型别名,用于方便使用 Scalar 类的成员类型。ElementType 用于表示标量的数据类型,DeviceType 用于表示标量所在的设备。

3. 构造函数:Scalar 类具有一个构造函数,它可以用于初始化 Scalar 对象。构造函数采用了一个默认参数 elem,用于指定初始的标量值,默认为 ElementType()。

4. Value() 成员函数:Value() 函数是一个重载函数,用于获取标量值。它包括了一个非常量版本 auto& Value() { return m_elem; } 和一个常量版本 auto Value() const { return m_elem; }。

5. 比较操作符:Scalar 类重载了相等和不相等操作符。具体包括 operator==() 和 operator!=() 的重载,允许对 Scalar 对象进行比较操作。

6. EvalRegister() 函数:EvalRegister() 函数是一个成员函数,用于将 Scalar 对象注册到计算图中进行求值。

实现了以下功能:

1. 提供了一个通用的标量数据表示方式,可以用不同的数据类型和设备类型来实例化 Scalar 类。这使得该类模板在各种上下文中都可以使用并保持可扩展性。

2. 提供了获取标量值的接口,使得可以方便地获取标量对象的值,无论是作为左值还是右值使用。

3. 支持标量对象的比较操作,包括相等和不相等。这允许对 Scalar 对象进行逻辑条件判断和比较操作。

4. 提供了将 Scalar 对象注册到计算图中进行求值的接口,这在深度学习和计算图相关的领域中很有用。

因此,这段代码的功能在于提供了一个通用的、可扩展的标量数据表示类模板,同时提供了数据访问、比较操作和计算图注册等功能。

1.3 标量的主体类型

标量的主体类型指的是在编程领域中,标量数据所基于的计算单元与计算设备所实例化的类型。在实际编程中,标量数据通常需要在特定的计算单元(比如 CPU、GPU 等)上进行运算处理,因此标量数据的类型应当与计算单元和计算设备相匹配。

举例来说,如果我们有一个标量类模板 Scalar,它的实例化类型需要根据具体的计算设备来确定,比如可以是基于 CPU 或者 GPU 进行计算。这时候在实例化 Scalar 类时,需要指定具体的计算设备类型,以保证标量数据可以在指定的计算单元上进行处理。

在模板类 Scalar 中,模板参数 TDevice 代表计算设备(默认为 CPU),这样在实例化 Scalar 类时可以根据需要选择特定的计算设备类型,以确保标量数据可以在所需的计算环境中进行运算处理。

因此,标量的主体类型可以理解为在编程中,标量数据所依赖的计算单元与计算设备的类型,它是确保标量数据可以合适地被计算和处理的重要概念。


http://www.ppmy.cn/news/1224732.html

相关文章

网上申请的电信卡能用多长时间?可以长期使用吗?

我们在网上总能看到一些关于流量卡的广告&#xff0c;都是19元&#xff0c;29元100多g的套餐&#xff0c;乍一看这些套餐非常便宜&#xff0c;但是小编提醒大家一定要注意优惠期。 ​  网上的流量卡套餐&#xff0c;都是由基础套餐额外赠送充值送话费等内容组成&#xff0c;…

spring cloud openfeign 使用注意点

近期在做项目时给自己挖了一个坑&#xff0c;问题重现如下 使用的组件版本如下 spring boot 2.7.15&#xff0c;对应的 spring cloud 版本为 2021.0.5&#xff0c;其中 spring cloud 适配的 openfeign 版本是 3.1.5。 项目中使用的 feign 接口如下 public interface QueryApi…

一个UE无法注册的问题

问题场景是环境中只有一个小区&#xff0c;UE在找到这个小区&#xff0c;收到MIB SIB1后一直不发起注册。我想这大概是和S准则不满足有关系了&#xff0c;这个问题基本是又没啥好看的了&#xff0c;太简单了&#xff0c;在SIB1周围找找就解决了&#xff0c;于是我发现了以下log…

开源网安解决方案荣获四川数实融合创新实践优秀案例

​11月16日&#xff0c;2023天府数字经济峰会在成都圆满举行。本次峰会由四川省发展和改革委员会、中共四川省委网络安全和信息化委员会办公室、四川省经济和信息化厅等部门联合指导&#xff0c;聚焦数字经济与实体经济深度融合、数字赋能经济社会转型发展等话题展开交流研讨。…

ubuntu18.04 terminal打不开的解决方法

目录 现象解决 现象 打开terminal时,一直转圈,然后消失,总是打不开terminal. 解决 编辑文件sudo vim /etc/default/locale,修改为 # File generated by update-locale LANG"en_US.UTF-8" LANGUAGE"en_US:en"重启系统,问题解决.

4.2 Windows驱动开发:内核中进程线程与模块

内核进程线程和模块是操作系统内核中非常重要的概念。它们是操作系统的核心部分&#xff0c;用于管理系统资源和处理系统请求。在驱动安全开发中&#xff0c;理解内核进程线程和模块的概念对于编写安全的内核驱动程序至关重要。 内核进程是在操作系统内核中运行的程序。每个进…

OSI网络模型与TCP/IP协议

OSI&#xff0c; Open system Interconnection Reference Model 开放式系统互联通信参考模型。是国际标准化组织在1984年定义的一个概念框架&#xff0c;用于协调制定进程间通信标准。OSI作为一个协议规范集&#xff0c;定义了七个层次&#xff0c;包括层次之间的相互关系及各层…

基于Element-Plus动态配置Menu 菜单栏

文章目录 前言先看效果可兼容多级菜单栏&#xff08;顺便配置多少级&#xff09; 一、新建组件二、使用步骤总结如有启发&#xff0c;可点赞收藏哟~ 前言 菜单栏配置化 图标配置化参考vite动态配置svg图标及其他方式集合 先看效果 可兼容多级菜单栏&#xff08;顺便配置多少级…