- 博客(37)
- 收藏
- 关注
原创 nvidia-container-toolkit安装与配置
nvidia-container-toolkit是Docker与NVIDIA GPU之间的桥梁,也就是只有安装了nvidia-container-toolkit,Docker才能使用本机的GPU;
2025-05-19 11:00:30
184
原创 C++中,前++和后++的区别
大概前++和后++的过程就是这样,所以(a++)这里返回一个临时对象的值,该值等于原来a的值,但其实a本身的值已经加了1,所以后面再乘以a的时候,a的值已经等于5;由于int类型的前++和后++的具体实现要去查看汇编代码,比较麻烦,所以这里定义一个新的类型来描述前++和后++的行为;本来想着b应该等于16,但结果等于20;
2025-05-15 11:26:20
144
原创 C++中六个特殊成员函数的关系
4、如果显式声明了析构函数,但是编译器仍然会自动提供默认的复制构造函数和复制赋值运算符,所以需要用到移动构造函数或移动赋值运算符的地方会自动使用复制构造函数和复制赋值运算符;默认构造函数、复制构造函数、复制赋值运算符、析构函数、移动构造函数、移动赋值运算符。2、如果显式声明了默认构造函数,编译器仍将自动提供其他五种特殊成员函数的默认定义;1、如果显式声明了任何构造函数,那么编译器不再自动提供默认构造函数;复制赋值运算符,那么编译器则不会自动提供移动构造函数。3、如果显式声明了析构函数、复制构造函数。
2025-05-09 16:06:50
244
原创 关于string类的构造函数
一、string(const char* s, size_type n, const Allocator & a=Allocator());这个构造函数接受一个C风格字符串,并指定复制这个C风格字符串的n个字符作为该string对象的内部数据成员;这里就是需要注意一下,当n大于s的长度的时候,string对象会继续获取s后面的内存区域的值,所以这里调用该string的size()方法的时候会返回n;二、string(const string & st, size_type pos, size_type
2025-05-05 17:46:22
182
原创 C++中一些关于何时何处定义类或函数的问题
因为只有在编译器编译过程中遇到模板的实例化(也就是指定了模板使用的具体类型)的时候,编译器才会按照模板定义来生成对应的实现代码,当模板在头文件中定义的时候,在预处理阶段,编译器会把代码文件中包含的头文件内容引入进来,这样在遇到模板实例化的时候,编译器就知道如何根据通用模板类的定义来生成对应的实现,而加入模板的定义放在其他代码文件中,那么本代码文件在遇到模板实例化的语句的时候就找不到模板的定义,就无法生成对应具体类的实现代码;2、内联函数➔必须头文件或者当前代码文件中定义,不能在其他的代码文件中定义。
2025-04-29 16:39:54
265
原创 问题:windows上用vscode远程连接wsl2 ubuntu运行opencv代码时, 如何调用windows机器的摄像头;
问题一:由于wsl2无法直接调用本机的摄像头,所以首先想要调用windows机器上的摄像头,要使用rtsp服务,在windows系统上建立一个rtsp服务器(使用easydarwin来建立),通过ffmpeg将本机(windows)的视频流推送到rtsp服务器上,然后在wsl ubuntu系统中使用ffmpeg去拉取rtsp服务器上面的视频流进行处理;简单来说,就是建立一个rtsp服务器,将wsl无法直接读取的视频流放在这个服务器上,然后通过这个rtsp服务器作为中转站,让wsl可以去拉去到视频流;
2025-04-23 18:02:39
229
原创 浅谈类的复制构造函数和赋值运算符
对于第二行和第三行代码,有用到=,但是不一定会调用赋值运算符(如果编译器的实现方式是:首先使用复制构造函数创建一个临时变量,然后将该临时变量的值赋给新对象,这种情况就会调用赋值运算符),这去取决于编译器,我用的g++编译器并不会调用赋值运算符;对于第一种按引用传递的函数,并不会调用复制构造函数,因为并不涉及创建临时对象,也就是整个过程并没有创建新的对象,所以并不会调用复制构造函数;默认的复制构造函数逐个复制非静态成员,复制的是成员的值,也就是浅复制,对于含有指针类型的成员数据,这种浅复制是不行的;
2025-04-08 16:12:00
263
原创 C++中的浅拷贝和深拷贝
浅拷贝只是将变量的值赋予给另外一个变量,在遇到指针类型时,浅拷贝只会把当前指针的值,也就是该指针指向的地址赋予给另外一个指针,深拷贝在遇到指针类型时,会先将当前指针指向地址包含的值复制一份,然后new一个新的内存空间,然后把复制的值放到该内存空间中,,只是两个不同地址包含的值是相同的;
2025-04-06 11:36:23
222
原创 C++中,应尽可能将引用形参声明为const
我们的目的是交换传入参数的值,如果不使用引入形参,如swap(int a,int b),那么该函数将按值传递,并不会实际改变传入参数的值,所以这种情况需要使用引用形参;2、节约内存和加快速度,对于基本类型可以不用使用引用参数,但是对于结构、数组或者较为复杂的类对象,使用引用参数可以避免传参时创建值相同的临时变量,而是直接使用引用的变量;,然后做Add类的加法运算,但是由于前面提到的引用形参没有使用const ,所以这里的临时变量没法传给函数;1、需要改变传入参数的值的时候,不能声明为const;
2025-04-04 10:59:29
308
原创 Clip原理及应用
数据集要求,读取出图片和对应的类别名,注意这里是要读取真实的类别名以交给tokenizer进行词元化,而不是像以前的图像分类任务读取类别编号import os# 自定义训练函数"""微调 CLIP 的映射层 (self.proj 和 self.text_projection)。Args:train_dataset (Dataset): 训练集。val_dataset (Dataset): 验证集。device (torch.device): 训练设备(CPU 或 GPU)。
2025-02-15 15:50:54
477
原创 Dropout的实际是如何运作的
虽然我们在学习dropout时,说的是将某些神经元置为0,但是实际上是将该神经元的输出置为0,从而在反向传播中,该神经元的梯度就会为0(同时也会让经过dropout的输出整体乘以1/(1-p),使得该层输出的整体期望不变)达到阻止该神经元不更新的目的,提高模型的泛化能力。而在模型推理时,也就是model.eval()时,则会自动组织nn.Dropout层将会自动失效。Dropout通过将该层的输出部分置为0的操作来使得该输出对应的神经元在反向传播中梯度等于0,从而达到阻止该神经元更新的目的。
2025-01-15 17:55:57
108
原创 关于python中的解包操作符,**和*,以及压缩zip
*是python用于解包(unpacking)字典的语法,这里inputs是一个字典,使用**后,会自动将inputs字典中的键值对转换为模型参入参数和对应值的形式。然后模型就按照forward的方法进行传参,如果inputs字典中包含了forward函数中未设置的参数怎么办?这种情况下,模型会忽略未定义的参数,不会报错。这里遇到了**的传参形式,顺便记录一下。如果传入未定义的参数,会报。
2025-01-15 16:55:31
197
原创 常见的Tokenizer算法
Tokenizer过程以how are you 为例子step1:首先利用分词器对文本数据进行分词,how are you–> [how] [are] [you]step2:构建词表或者利用现成的词表,将第一步的分词结果映射到对应在词表中的id,[how] [are] [you]–>[18465] [345] [33]step3:会根据序列长度进行填充或者截断,使得输入嵌入层的所有序列长度都是一致的。
2025-01-12 15:40:28
780
原创 不同参数量的模型推理和训练所需的显存
对于优化器所占用的显存,这个要根据优化器的类型来判断,以常用的Adam优化器为例子,需要用显存存储每个参数的动量和二阶矩,所以Adam优化器的显存占用为模型参数的两倍。如果只做推理的话,显存的占用就只用考虑模型的参数、一个批次数据的大小以及一些用于前向传播计算的中间值,这里主要考虑模型的参数和一个批次数据的显存占用。为例,模型本身占用的显存和一个批次数据所占用的显存上面已经讲过了,这里说一下反向传播所需要的梯度占用的显存,这个显存占用基本等于模型参数,以1B(10亿)大小的模型为例。
2025-01-11 20:33:29
377
原创 关于tensor计算中的维度问题
dim=-1时指运算沿着该对应维度编号增长的方向进行运算,比如在一个二维tensor中,如果想要计算每一行中最大的数值是什么,则需要令dim=-1,让运算按着列号增长的方向进行运算。在遇到张量计算中对于dim=-1时,计算的结果产生了疑惑,故因此记录。
2024-12-11 10:39:31
190
原创 神经网络学习
首先数据经过前向传播(经过隐藏层和输出层)得到一个预测结果,然后预测结果和数据标签做损失,然后损失通过反向传播算法来更新模型的参数,直至收敛。
2024-10-29 15:14:20
919
原创 决策树——DecisionTree
就是不断确定分裂点,将数据分开的过程。这个过程通过找到使得信息增益最大的数据特征及其特征值来确定分裂点,将数据分别左子树和右子树,然后不断对左右子树递归这个过程,直至达到我们对决策树的要求(比如限定了决策树的层数,限制了叶子节点的最小数据量之类的),叶子节点中样本数最多的类别就为这个叶子节点所属的类别。由于机器学习中,研究的都是一大堆数据,所以这里举一个包含多个数据的系统的信息熵,比如,这个系统中,我有100个数据,其中80个数据的标签为1,20个数据的标签为0,那么这个系统的信息熵该如何计算呢?
2024-10-28 16:01:47
1173
原创 机器学习常见概念理解
正则化为什么有效?答:正则化减小了或者去除了模型中某些特征对于预测值的影响,这些特征往往是我们不需要的特征,甚至是和预测值不相关的特征,比如噪声特征,降低了这种特征对预测值的影响后,模型的泛化能力就能得到进一步的提高;正则化是可以减小参数大小,可是为什么减少了参数大小就可以降低模型复杂度呢?答:参数大小减小后,导致在特征空间中,参数小的特征影响力降低,使得拟合曲线变得更为平滑,平滑后,模型看起来就不那么复杂了,实际参数数量可能并没有改变。# 加载波士顿房屋数据集# 不使用正则化。
2024-10-22 22:49:17
749
原创 特征归一化
因为不同特征之间量纲不一样,如果不进行归一化,特别又采用诸如欧式距离来衡量样本之间的距离的方法,那么量纲大的特征就会起决定性作用,这显然对于模型判断是不利的。
2024-10-09 19:02:19
464
原创 C++中的指针1
如果声明指针的时候,没有确切的地址可以赋值,最好为这个指针赋为NULL,这样指针指向内存地址为0的地址,内存地址为0是不可被访问的,可以避免一些难以预料的错误。
2024-09-11 23:07:16
198
原创 在 C++ 中,当 static 用在类数据成员上时,会导致仅有一个该成员的副本被类的所有对象共享
无论创捷多少个T数据类型的对象,这个类中的静态数据类型成员shareValue都是共享的。
2024-09-11 23:06:22
235
原创 浮点数在内存中的存储方式
以单精度浮点数(float)为例子(-1)* M * 2单精度浮点数中,S占1位,M占23位,E占8位双精度浮点数中,S占1位,M占52位,E占11位。
2024-09-11 23:05:24
252
原创 C++中的Lambda表达式
在Lambda函数定义时,捕获变量前面加上&,表示捕获对应变量的内存地址,这样捕获变量的值在函数调用时才会确定。在捕获变量中不使用具体的变量名,而只使用=或者&,表示捕获函数所需的所有外部变量的值或引用,这样可以避免遗漏。注意:不能同时使用=和&,因为这样会造成冲突,导致函数无法理解到底是捕获值还是捕获引用,编译也会报错。值捕获的变量在Lambda表达式定义时就已经确定。
2024-09-11 23:04:13
239
原创 前端入门——HTML和CSS
一、什么是HTML?HTML是用来描述网页的一种语言·HTML指的是超文本语言(Hyper Text Makedown Language);·HTML是一种标记语言,而不是一种编程语言;·标记语言是一套标记标签二、网页的组成部分HTML(结构)、CSS(表现)、JS(行为);三、HTML的基本语法1、常规标记,也叫双标记;格式:<标记 属性=“属性值” 属性=“属性值”><标记/>例如:<head><head/>2.
2022-01-26 13:55:05
719
原创 Avoid passing null as the view root ;Android
警告提示:Avoid passing null as the view root (needed to resolve layout parameters on the inflated layout's root element)View view = LayoutInflater.from(getActivity()).inflate(R.layout.keyboard,null);当这样使用时会报警告;改为:View view = LayoutInflater.from(getAct
2021-10-30 11:41:24
1197
原创 IDEA 部分快捷键
Ctrl+D:复制当前行;Ctrl+Y:删除当前行;Ctrl+H:查看当前类的层级关系;Ctrl+B:将光标放在方法名上,定位方法;、Ctrl+Alt+L:格式化代码;Alert+insert:构造器和getter和setter方法等;Alert+R:运行当前程序;Ctrl+Shift+R:全局查找;在类的后面加.var:自动分配变量名;...
2021-10-26 15:58:47
119
原创 数据结构——稀疏数组
一、稀疏数组:1、存储原数组有几行几列,以及原数组有多少个不同的值;2、存储原数组不同值所在的行列,以及数值。二、二维数组转稀疏数组1.遍历原始二维数组,得到有效数据的个数sum;2.创建稀疏数组sparseArray[sum+1][3];3、将二维数组中的有效数据存入稀疏数组中。三、稀疏数组转二维数组1、先读取稀疏数组第一行数据,根据该数据创建二维数组;2、再读取稀疏数组后几行数据,赋给二维数组即可。四、代码实现package com.ling.sparsea
2021-10-17 16:41:28
99
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人