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

目录

前言

一、标量

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.mzph.cn/news/153839.shtml

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

相关文章

centos7安装mysql8

打开Mysql下载页面 https://downloads.mysql.com/archives/community/ 选择版本号&#xff1a; centos选择Red Hat版本&#xff0c;复制地址 复制地址后&#xff0c;链接ssh&#xff0c;添加储存库 yum install 粘贴地址&#xff1b; yum install https://downloads.mysql…

人工智能基础_机器学习044_使用逻辑回归模型计算逻辑回归概率_以及_逻辑回归代码实现与手动计算概率对比---人工智能工作笔记0084

上面我们已经把逻辑回归的公式,以及,公式对应的图形都画画出来了,然后我们再来看看 如何用代码实现 可以看到上面是代码,咱们自己去写一下 import numpy as np from sklearn.linear_model import LogistieRegression from sklearn import datasets # 训练数据和测试数据拆分…

人工智能时代下的程序员核心竞争力:构建专属护城河

选题建议&#xff1a;《人工智能时代下的程序员核心竞争力&#xff1a;构建你的护城河》 大纲&#xff1a; I. 引言 A. 人工智能时代的发展趋势B. 程序员面临的挑战与机遇 I. 引言 A. 人工智能时代的发展趋势 随着科技的飞速进步&#xff0c;我们已经踏入了一个日新月异的人工…

Leetcode—2216.美化数组的最少删除数【中等】

2023每日刷题&#xff08;三十六&#xff09; Leetcode—2216.美化数组的最少删除数 实现代码 int minDeletion(int* nums, int numsSize) {int last nums[0], flag 1, ans 0;for(int i 1; i < numsSize; i) {if(flag) { // 前一个下标为偶数if(nums[i] last) {…

【CSS】min 和 max 函数(设置最大最小值)

文章目录 min() 函数&#xff1a;允许你从逗号分隔符表达式中选择一个最小值作为 CSS 的属性值 width: min(1vw, 4em, 80px);max() 函数&#xff1a;让你可以从一个逗号分隔的表达式列表中选择最大&#xff08;正方向&#xff09;的值作为属性的值 width: max(10vw, 4em, 80p…

Linux C 线程

线程 概述线程和进程的异同如何选择使用进程还是线程 函数获取进程自身ID  pthread_self创建线程  pthread_create退出线程  pthread_exit线程等待  pthread_join 四种线程模型1 &#xff09;单线程2 &#xff09;单线程3 &#xff09;双线程4 &#xff09;三线程 概述…

【HarmonyOS】低代码平台组件拖拽使用技巧之列表

【关键字】 HarmonyOS、低代码平台、组件拖拽、列表、列表项 1、写在前面 我们在日常开发中使用最多的组件可能就是列表组件了&#xff0c;现在几乎所有的应用都离不开列表&#xff0c;那么今天我们就来介绍一下如何利用低代码平台来实现列表的展示&#xff0c;列表实际上也是…

律师网站开发实战案例

最近关于律师的电视剧很火爆&#xff0c;各大卫视也相继播出关于律师类的电视剧&#xff0c;在互联网领域律师也不再是那种遥不可攀&#xff0c;不能触达的领域。今天我们要介绍的是律师行业网站的制作过程&#xff0c;他到底有什么功能点和用处。 律师网站的功能主要包括&…

kettle官网和中文网地址

整理的kettle相关的网站地址&#xff1a; github 地址&#xff1a; https://github.com/pentaho/pentaho-kettle kettle下载目录&#xff1a; https://sourceforge/projects/pentaho/files/ kettle9.2下载地址&#xff1a; https://sourceforge/projects/pentaho/files/Penta…

HALCON根据需要创建自定义函数

任务要求&#xff1a; 创建函数myfun(a,b,c)&#xff0c;输入浮点数a&#xff0c;b的值&#xff0c;计算c a b&#xff0c;将计算结果返回。 操作步骤&#xff1a; 1&#xff09;打开HDevelop程序 2&#xff09;打开函数菜单&#xff0c;选择“创建新函数”&#xff0c…

Spring 定时任务如何到达某一指定时间点后,触发任务机制

在Spring框架中&#xff0c;可以使用Spring Task来实现定时任务。以下是使用Spring Task触发定时任务的步骤&#xff1a; 添加依赖&#xff1a;首先&#xff0c;在你的项目中添加Spring Task的依赖。如果使用Maven管理项目&#xff0c;可以在pom.xml文件中添加以下依赖项&#…

中间件安全:Apache Tomcat 文件上传.(CVE-2017-12615)

中间件安全&#xff1a;Apache Tomcat 文件上传. 当存在漏洞的 Tomcat 运行在 Windows / Linux 主机上&#xff0c;且启用了 HTTP PUT 请求方法(例如&#xff0c;将 readonly 初始化参数由默认值设置为ialse) &#xff0c; 攻击者将有可能可通过精心构造的攻击请求数据包向服务…

java算法学习索引之数组矩阵问题

一 将正方形矩阵顺时针转动90 给定一个NN的矩阵matrix&#xff0c;把这个矩阵调整成顺时针转动90后的形式。 顺时针转动90后为&#xff1a; 【要求】额外空间复杂度为O&#xff08;1&#xff09;。 public void rotate(int[][] matrix) {int tR 0; // 左上角行坐标int tC 0;…

常用系统函数

$clog2 clogb2 系统函数 $clog2 应返回参数以 2 为底的对数的上限&#xff08;对数四舍五入为整数值&#xff09;。参数可以是整数或任意大小的向量值。参数应被视为无符号值&#xff0c;参数值为 0 将产生结果 0。 该系统函数可用于计算对给定大小的存储器进行寻址所…

使用过去20天测试未来7天,时间步是多少

在使用过去20天的数据预测未来7天时&#xff0c;时间步的设置通常取决于你对问题的理解以及模型的设计。时间步定义了每个样本中包含多少个时间步的数据。 在使用循环神经网络 (RNN) 或长短时记忆网络 (LSTM) 这样的模型时&#xff0c;你可以将时间步的选择视为一个超参数。这…

oracle 19c 创建物化视图并测试logminer进行日志挖掘

【赠送】IT技术视频教程&#xff0c;白拿不谢&#xff01;思科、华为、红帽、数据库、云计算等等https://xmws-it.blog.csdn.net/article/details/117297837?spm1001.2014.3001.5502【微/信/公/众/号&#xff1a;厦门微思网络】 1、创建物化视图 alter session set container…

解锁无限可能性:探索Amazon Lightsail的便捷云计算服务

解锁无限可能性&#xff1a;探索Amazon Lightsail的便捷云计算服务 在数字化时代&#xff0c;云计算成为推动创新和业务发展的关键驱动力。Amazon Lightsail 作为 Amazon Web Services&#xff08;亚马逊云科技&#xff09;家族中的一员&#xff0c;为小型企业和创业公司提供了…

Python-列表和元祖的区别

列表定义&#xff1a; list [1,3,"ceshi"] print(list) #输出&#xff1a;[1,3,"ceshi"] print(list[2]) #输出&#xff1a;ceshi 元祖定义&#xff1a; tuple&#xff08;1,3,"ceshi&#xff09; print(tuple) #输出&#xff1a;&#xf…

深度剖析倍增算法求解最近公共祖先(LCA)的细枝末节

1. LCA&#xff08;最近公共祖先&#xff09; 倍增算法的基本思想在前面的博文中有较详细的介绍&#xff0c;本文不再复述。此文仅讲解如何使用倍增算法求解多叉树中节点之间的最近公共祖先问题。 什么是最近公共祖先问题&#xff1f; 字面而言&#xff0c;指在树上查询两个…

linux CentOS7 安装git 配置秘钥公钥克隆代码

第一步&#xff1a;安装git yum -y install git #查看版本 git --version 第二步&#xff1a;配置git信息 git config --global user.name "username" git config --global user.email "XXXXX.com" 第三步&#xff1a;生成密钥和公钥&#xff0c; 后…