现在是2024年2月24日,13:59,从研一就开始断断续续说要过一遍框架,到现在博一下学期,还一直拖着呢,拖延症太可怕啦,决定好好做人,不拖了,就从现在开始,好好过一遍,呜呜呜呜呜呜呜呜,(罪该万死)。

看的教程是:《动手学深度学习》(PyTorch版),是把李沐老师的《动手学深度学习》原书中的MXNet实现改为PyTorch实现。

开始吧。

1.深度学习简介

1.通俗来说,机器学习是一门讨论各式各样的适用于不同问题的函数形式,以及如何使用数据来有效地获取函数参数具体值的学科。深度学习是指机器学习中的一类函数,它们的形式通常为多层神经网络。近年来,仰仗着大数据集和强大的硬件,深度学习已逐渐成为处理图像、文本语料和声音信号等复杂高维度数据的主要方法。

2.另一个对深度学习有重大影响的领域是神经科学与心理学。既然人类显然能够展现出智能,那么对于解释并逆向工程人类智能机理的探究也在情理之中。最早的算法之一是由唐纳德·赫布(1904--1985)正式提出的。在他开创性的著作《行为的组织》中,他提出神经是通过正向强化来学习的,即赫布理论 [2]。赫布理论是感知机学习算法的原型,并成为支撑今日深度学习的随机梯度下降算法的基石:强化合意的行为、惩罚不合意的行为,最终获得优良的神经网络参数。

3.随着时间发展,神经网络的生物学解释被稀释,但仍保留了这个名字。时至今日,绝大多数神经网络都包含以下的核心原则。

  • 交替使用线性处理单元与非线性处理单元,它们经常被称为“层”。
  • 使用链式法则(即反向传播)来更新网络的参数。

4.Q:

“很显然,存储容量没能跟上数据量增长的步伐。与此同时,计算力的增长又盖过了数据量的增长。这样的趋势使得统计模型可以在优化参数上投入更多的计算力,但同时需要提高存储的利用效率,例如使用非线性处理单元。”为什么说非线性处理单元有这样的优势

A:

ChatGPT:

提到非线性处理单元(比如神经网络中的非线性激活函数),它们能够带来一系列优势,特别是在处理复杂数据和优化存储效率方面。以下是一些关键点:

  1. 增加模型的表达能力:非线性处理单元可以帮助统计模型捕捉数据中的复杂模式和关系。线性模型仅能处理数据的线性关系,而非线性模型通过引入非线性处理单元,能够学习到更加复杂的数据结构,从而在相同或更少的参数下实现更高的准确度。
  2. 提高存储利用效率:通过使用非线性处理单元,模型能够以更紧凑的形式表示复杂函数。这意味着为了达到相同的性能,非线性模型可能需要更少的参数和存储空间。例如,深度学习模型通过堆叠非线性层来学习高级特征,而不是简单地增加模型的大小,这样不仅提升了模型的学习能力,也优化了参数的使用和存储。
  3. 使模型能够处理非线性问题:现实世界中的许多问题都是非线性的,使用非线性处理单元使得模型能够直接应对这些问题。比如在图像识别、语言处理等领域,非线性模型展现出了比线性模型更好的性能。
  4. 提高计算效率:虽然非线性计算在某些情况下可能比线性计算更为复杂,但通过智能的算法设计和硬件优化(如GPU加速),这种增加的复杂度可以得到有效管理。此外,由于非线性模型能够使用更少的参数解决问题,因此可以减少计算资源的消耗,从而在给定的计算能力下实现更高效的数据处理。

综上所述,非线性处理单元之所以在优化参数和提高存储利用效率方面具有优势,是因为它们提高了模型的表达能力,使得模型能以更紧凑、效率更高的方式学习和表示复杂数据模式。这对于处理大规模数据集、在计算资源受限的情况下优化性能尤为重要。

5.在描述深度学习的特点之前,我们先回顾并概括一下机器学习和深度学习的关系。机器学习研究如何使计算机系统利用经验改善性能。它是人工智能领域的分支,也是实现人工智能的一种手段。在机器学习的众多研究方向中,表征学习关注如何自动找出表示数据的合适方式,以便更好地将输入变换为正确的输出,而本书要重点探讨的深度学习是具有多级表示的表征学习方法。在每一级(从原始数据开始),深度学习通过简单的函数将该级的表示变换为更高级的表示。因此,深度学习模型也可以看作是由许多简单函数复合而成的函数。当这些复合的函数足够多时,深度学习模型就可以表达非常复杂的变换。

6.深度学习可以逐级表示越来越抽象的概念或模式。以图像为例,它的输入是一堆原始像素值。深度学习模型中,图像可以逐级表示为特定位置和角度的边缘、由边缘组合得出的花纹、由多种花纹进一步汇合得到的特定部位的模式等。最终,模型能够较容易根据更高级的表示完成给定的任务,如识别图像中的物体。值得一提的是,作为表征学习的一种,深度学习将自动找出每一级表示数据的合适方式。

7.因此,深度学习的一个外在特点是端到端的训练。也就是说,并不是将单独调试的部分拼凑起来组成一个系统,而是将整个系统组建好之后一起训练。比如说,计算机视觉科学家之前曾一度将特征抽取与机器学习模型的构建分开处理,像是Canny边缘探测 [20] 和SIFT特征提取 [21] 曾占据统治性地位达10年以上,但这也就是人类能找到的最好方法了。当深度学习进入这个领域后,这些特征提取方法就被性能更强的自动优化的逐级过滤器替代了。

8.除端到端的训练以外,我们也正在经历从含参数统计模型转向完全无参数的模型。当数据非常稀缺时,我们需要通过简化对现实的假设来得到实用的模型。当数据充足时,我们就可以用能更好地拟合现实的无参数模型来替代这些含参数模型。这也使我们可以得到更精确的模型,尽管需要牺牲一些可解释性。

9.相对其它经典的机器学习方法而言,深度学习的不同在于:对非最优解的包容、对非凸非线性优化的使用,以及勇于尝试没有被证明过的方法。这种在处理统计问题上的新经验主义吸引了大量人才的涌入,使得大量实际问题有了更好的解决方案。尽管大部分情况下需要为深度学习修改甚至重新发明已经存在数十年的工具,但是这绝对是一件非常有意义并令人兴奋的事。

小结

  • 机器学习研究如何使计算机系统利用经验改善性能。它是人工智能领域的分支,也是实现人工智能的一种手段。
  • 作为机器学习的一类,表征学习关注如何自动找出表示数据的合适方式。
  • 深度学习是具有多级表示的表征学习方法。它可以逐级表示越来越抽象的概念或模式。
  • 深度学习所基于的神经网络模型和用数据编程的核心思想实际上已经被研究了数百年。
  • 深度学习已经逐渐演变成一个工程师和科学家皆可使用的普适工具。

(15:03,结束第一节,休息一下~)

2. 预备知识

(15:09,继续)

2.2 数据操作

1.在PyTorch中,torch.Tensor是存储和变换数据的主要工具。如果你之前用过NumPy,你会发现Tensor和NumPy的多维数组非常类似。然而,Tensor提供GPU计算和自动求梯度等更多功能,这些使Tensor更加适合深度学习。

"tensor"这个单词一般可译作“张量”,张量可以看作是一个多维数组。标量可以看作是0维张量,向量可以看作1维张量,矩阵可以看作是二维张量。

2.2.1 创建Tensor

 1 ### 2.2.1 创建Tensor
2 import torch
3
4 # 创建一个5x3的未初始化的Tensor:
5 x = torch.empty(5,3)
6 # print(x)
7
8 # 创建一个5x3的随机初始化的Tensor:
9 x = torch.rand(5,3)
10 # print(x)
11
12 # 创建一个5x3的long型全0的Tensor:
13 x = torch.zeros(5,3, dtype = torch.long)
14 # print(x)
15
16 # 还可以直接根据数据创建:
17 x = torch.tensor([5,5,3])
18 # print(x)
19
20 # 还可以通过现有的Tensor来创建,此方法会默认重用输入Tensor的一些属性,例如数据类型,除非自定义数据类型
21 x = x.new_ones(5,3, dtype = torch.float64) # 返回的tensor默认具有相同的torch.dtype和torch.device
22 # print(x)
23
24 x = torch.randn_like(x, dtype = torch.float) # 指定新的数据类型
25 # print(x)
26
27 # 可以通过shape或者size()来获取Tensor的形状:
28 print(x.size())
29 print(x.shape)
30 # 注意:返回的torch.Size其实就是一个tuple, 支持所有tuple的操作。

还有很多函数可以创建Tensor,去翻翻官方API就知道了,下表给了一些常用的作参考。

函数 功能
Tensor(*sizes) 基础构造函数
tensor(data,) 类似np.array的构造函数
ones(*sizes) 全1Tensor
zeros(*sizes) 全0Tensor
eye(*sizes) 对角线为1,其他为0
arange(s,e,step) 从s到e,步长为step
linspace(s,e,steps) 从s到e,均匀切分成steps份
rand/randn(*sizes) 均匀/标准分布
normal(mean,std)/uniform(from,to) 正态分布/均匀分布
randperm(m) 随机排列

这些创建方法都可以在创建的时候指定数据类型dtype和存放device(cpu/gpu)。

2.2.2 操作

 1 ### 2.2.2 操作
2 # 介绍Tensor的各种操作
3
4 ## 算数操作
5 # 在PyTorch中,同一种操作可能有很多中形式,下面用加法作为例子。
6 # 加法形式一
7 y = torch.rand(5,3)
8 # print(x + y)
9
10 # 加法形式二
11 # print(torch.add(x,y))
12 # 还可指定输出:
13 result = torch.empty(5,3)
14 torch.add(x,y, out = result)
15 # print(result)
16
17 # 加法形式三、inplace 原地
18 # adds x to y
19 y.add_(x)
20 # print(y)
21 # 注:PyTorch操作inplace版本都有后缀_, 例如x.copy_(y), x.t_()
22
23 ## 索引
24 # 还可以使用类似Numpy的索引操作来访问Tensor的一部分,需要注意的是:索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。
25 y = x[0,:] # 选择x的第一行,所有列,第一行的一个完整切片
26 print(x)
27 y += 1
28 print(y)
29 print(x[0,:]) # 源tensor也被修改了

除了常用的索引选择数据之外,PyTorch还提供了一些高级的选择函数:

函数 功能
index_select(input, dim, index) 在指定维度dim上选取,比如选取某些行、某些列
masked_select(input, mask) 例子如上,a[a>0],使用ByteTensor进行选取
nonzero(input) 非0元素的下标
gather(input, dim, index) 根据index,在dim维度上选取数据,输出的size与index一样

这里不详细介绍,用到了再查官方文档。

 1 ## 改变形状
2 # 用view()来改变Tensor的形状:
3 y = x.view(15)
4 z = x.view(-1,5) # -1所指的维度可以根据其他维度的值推出来
5 # print(x)
6 # print(y)
7 # print(z)
8 # print(x.size(), y.size(), z.size())
9 # 输出:看形状
10 # tensor([[ 1.3107, 0.0693, 3.4263],
11 # [-0.7560, 1.2920, -0.5012],
12 # [ 1.4238, -1.1785, 0.7892],
13 # [ 0.3062, -0.9667, 1.1572],
14 # [ 0.3245, 1.3990, 0.0399]])
15 # tensor([ 1.3107, 0.0693, 3.4263, -0.7560, 1.2920, -0.5012, 1.4238, -1.1785,
16 # 0.7892, 0.3062, -0.9667, 1.1572, 0.3245, 1.3990, 0.0399])
17 # tensor([[ 1.3107, 0.0693, 3.4263, -0.7560, 1.2920],
18 # [-0.5012, 1.4238, -1.1785, 0.7892, 0.3062],
19 # [-0.9667, 1.1572, 0.3245, 1.3990, 0.0399]])
20 # torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
21
22 # 注意view()返回的新Tensor与源Tensor虽然可能有不同的size,但是是共享data的,也即更改其中的一个,另外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察角度,内部数据并未改变)
23 # print(x)
24 x += 1
25 # print(x)
26 # print(y) # 也加了1
27
28 # 所以如果我们想返回一个真正新的副本(即不共享data内存)该怎么办呢?Pytorch还提供了一个reshape()可以改变形状,但是此函数并不能保证返回的是其拷贝,所以不推荐使用。推荐先用clone创造一个副本然后再使用view。
29 x_cp = x.clone().view(15)
30 # print(x)
31 x -= 1
32 # print(x)
33 # print(x_cp)
34 # 输出
35 # tensor([[ 0.2564, 3.6559, 3.9383],
36 # [ 0.3162, -0.7308, 0.6828],
37 # [-0.3874, 2.2831, 0.4981],
38 # [ 1.2237, 0.5300, 0.5792],
39 # [ 1.5834, 1.8099, -0.2272]])
40 # tensor([[-0.7436, 2.6559, 2.9383],
41 # [-0.6838, -1.7308, -0.3172],
42 # [-1.3874, 1.2831, -0.5019],
43 # [ 0.2237, -0.4700, -0.4208],
44 # [ 0.5834, 0.8099, -1.2272]])
45 # tensor([ 0.2564, 3.6559, 3.9383, 0.3162, -0.7308, 0.6828, -0.3874, 2.2831,
46 # 0.4981, 1.2237, 0.5300, 0.5792, 1.5834, 1.8099, -0.2272])
47 # 使用clone还有一个好处是会被记录在计算图中,即梯度回传到副本时也会传到源Tensor。
48
49 # 另外一个常用的函数就是item(),它可以将一个标量Tensor转换成一个Python number:
50 x= torch.randn(1)
51 print(x)
52 print(x.item())
53 # 现在16:40,累了
54
55 ## 线性代数

另外,PyTorch还支持一些线性函数,这里提一下,免得用起来的时候自己造轮子,具体用法参考官方文档。如下表所示:

函数 功能
trace 对角线元素之和(矩阵的迹)
diag 对角线元素
triu/tril 矩阵的上三角/下三角,可指定偏移量
mm/bmm 矩阵乘法,batch的矩阵乘法
addmm/addbmm/addmv/addr/baddbmm.. 矩阵运算
t 转置
dot/cross 内积/外积
inverse 求逆矩阵
svd 奇异值分解

PyTorch中的Tensor支持超过一百种操作,包括转置、索引、切片、数学运算、线性代数、随机数等等,可参考官方文档

2.2.3 广播机制

前面我们看到如何对两个形状相同的Tensor做按元素运算。当对两个形状不同的Tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个Tensor形状相同后再按元素运算。例如:

 1 ### 2.2.3 广播机制
2 # 前面我们看到如何对两个形状相同的Tensor做按元素运算。当对两个形状不同的Tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个Tensor形状相同后再按元素运算。例如:
3 x = torch.arange(1,3).view(1,2)
4 print(x)
5 y = torch.arange(1,4).view(3,1)
6 print(y)
7 print(x + y)
8 # 输出
9 # tensor([[1, 2]])
10 # tensor([[1],
11 # [2],
12 # [3]])
13 # tensor([[2, 3],
14 # [3, 4],
15 # [4, 5]])

由于xy分别是1行2列和3行1列的矩阵,如果要计算x + y,那么x中第一行的2个元素被广播(复制)到了第二行和第三行,而y中第一列的3个元素被广播(复制)到了第二列。如此,就可以对2个3行2列的矩阵按元素相加。

(唉,一把年纪了,还要重新想一下之前矩阵分析学的东西)

2.2.4 运算的内存开销

 1 ### 2.2.4 运算的内存开销
2 # 前面说了,索引操作是不会开辟新内存的,而像y = x + y这样的运算是会新开内存的,然后将y指向新内存。为了演示这一点,我们可以使用Python自带的id函数:如果两个实例的ID一致,那么它们所对应的内存地址相同;反之则不同。
3 x = torch.tensor([1,2])
4 y = torch.tensor([3,4])
5 id_before = id(y)
6 y = y + x
7 # print(id_before)
8 # print(id(y))
9 # print(id(y) == id_before) # False
10
11 # 如果想指定结果到原来的y的内存,我们可以使用前面介绍的索引来进行替换操作。在下面的例子中,我们把x + y的结果通过[:]写进y对应的内存中。
12 x = torch.tensor([1,2])
13 y = torch.tensor([3,4])
14 id_before = id(y)
15 y[:] = y + x
16 # print(id(y) == id_before) # True
17 # print(y)
18
19 # 我们还可以使用运算符全名函数中的out参数或者自加运算符+=(也即add_())达到上述效果,例如torch.add(x,y, out = y)和y += x(y.add_(x))
20 x = torch.tensor([1,2])
21 y = torch.tensor([3,4])
22 id_before = id(y)
23 torch.add(x,y, out = y) # y += x, y.add_(x)
24 print(id(y) == id_before) # True

注:虽然view返回的Tensor与源Tensor是共享data的,但是依然是一个新的Tensor(因为Tensor除了包含data外还有一些其他属性),二者id(内存地址)并不一致。

2.2.5 Tensor和NumPy相互转换

我们很容易用numpy()from_numpy()Tensor和NumPy中的数组相互转换。但是需要注意的一点是: 这两个函数所产生的的Tensor和NumPy中的数组共享相同的内存(所以他们之间的转换很快),改变其中一个时另一个也会改变!!!

还有一个常用的将NumPy中的array转换成Tensor的方法就是torch.tensor(), 需要注意的是,此方法总是会进行数据拷贝(就会消耗更多的时间和空间),所以返回的Tensor和原来的数据不再共享内存。

 1 ### 2.2.5 Tensor和NumPy相互转换
2 ## Tensor转NumPy
3 # 使用numpy()将Tensor转换成NumPy数组:
4 a = torch.ones(5)
5 b = a.numpy()
6 # print(a,b)
7
8 a += 1
9 # print(a,b)
10 b += 1
11 # print(a,b)
12
13 ## NumPy数组转Tensor
14 # 使用from_numpy()将NumPy数组转换成Tensor:
15 import numpy as np
16 a = np.ones(5)
17 b = torch.from_numpy(a)
18 # print(a,b)
19
20 a += 1
21 # print(a,b)
22 b += 1
23 # print(a,b)
24
25 # 所有在CPU上的Tensor(除了CharTensor)都支持与NumPy数组相互转换。
26 # 此外上面提到还有一个常用的方法就是直接用torch.tensor()将NumPy数组转换成Tensor,需要注意的是该方法总是会进行数据拷贝,返回的Tensor和原来的数据不再共享内存。
27 c = torch.tensor(a)
28 a += 1
29 print(a,c)

2.2.6 Tensor on GPU

 1 ### 2.2.6 Tensor on GPU
2 # 用方法to()可以将Tensor在CPU和GPU(需要硬件支持)之间相互移动。
3 # 以下代码只有在PyTorch GPU版本上才会执行
4 if torch.cuda.is_available():
5 device = torch.device("cuda") # GPU
6 y = torch.ones_like(x, device = device) # 直接创建一个在GPU上的Tensor
7 x = x.to(device) # 等价于 .to("cuda")
8 z = x + y
9 print(z)
10 print(z.device)
11 print(z.to("cpu", torch.double)) # to()还可以同时更改数据类型
12 print(z.device) # 有问题,我的电脑切换不到cpu上
13 z = z.to("cpu", torch.double) # 这个可以切换成功,原因:data.to(device)后需要赋值给另一变量,可以是data本身,否则无法真正实现迁移。
14 print(z.device)

现在是18:02,好饿,溜了,今天元宵节,打算去快乐一会了.

现在是20:51,没买到汤圆,刚刚改了一下之前写的代码,然后现在贴一下这篇里用到的所有代码的汇总:

结束,准备开启下一章内容。(21:26,突然发现还有2.3节,哈哈哈哈哈哈)

(2024年2月26日,21:04继续)

2.3 自动求梯度

1.在深度学习中,我们经常需要对函数求梯度(gradient)。PyTorch提供的autograd包能够根据输入和前向传播过程自动构建计算图,并执行反向传播。本节将介绍如何使用autograd包来进行自动求梯度的有关操作。

2.3.1 概念

上一节介绍的Tensor是这个包的核心类,如果将其属性.requires_grad设置为True,它将开始追踪(track)在其上的所有操作(这样就可以利用链式法则进行梯度传播了)。完成计算后,可以调用.backward()来完成所有梯度计算。此Tensor的梯度将累积到.grad属性中。

注意在y.backward()时,如果y是标量,则不需要为backward()传入任何参数;否则,需要传入一个与y同形的Tensor。解释见 2.3.2 节。

如果不想要被继续追踪,可以调用.detach()将其从追踪记录中分离出来,这样就可以防止将来的计算被追踪,这样梯度就传不过去了。此外,还可以用with torch.no_grad()将不想被追踪的操作代码块包裹起来,这种方法在评估模型的时候很常用,因为在评估模型时,我们并不需要计算可训练参数(requires_grad=True)的梯度。

Function是另外一个很重要的类。TensorFunction互相结合就可以构建一个记录有整个计算过程的有向无环图(DAG)。每个Tensor都有一个.grad_fn属性,该属性即创建该TensorFunction, 就是说该Tensor是不是通过某些运算得到的,若是,则grad_fn返回一个与这些运算相关的对象,否则是None。

下面通过一些例子来理解这些概念。

2.3.2 Tensor

痛定思痛,好好做人,从头过一遍PyTorch框架(一)(1.深度学习简介、2.预备知识)的更多相关文章

  1. [Pytorch框架] 2.2 深度学习基础及数学原理

    文章目录 2.2 深度学习基础及数学原理 2.2.1 监督学习和无监督学习 2.2.2 线性回归 (Linear Regreesion) 2.2.3 损失函数(Loss Function) nn.L1 ...

  2. 分别基于TensorFlow、PyTorch、Keras的深度学习动手练习项目

    ×下面资源个人全都跑了一遍,不会出现仅是字符而无法运行的状况,运行环境: Geoffrey Hinton在多次访谈中讲到深度学习研究人员不要仅仅只停留在理论上,要多编程.个人在学习中也体会到单单的看理 ...

  3. [Pytorch框架] 2.4 卷积神经网络简介

    文章目录 2.4 卷积神经网络简介 2.4.1 为什么要用卷积神经网络 2.4.2结构组成 卷积层 卷积计算 卷积核大小 f 边界填充 (p)adding 步长 (s)tride 计算公式 卷积层 激 ...

  4. 从TensorFlow到PyTorch:九大深度学习框架哪款最适合你?

    开源的深度学习神经网络正步入成熟,而现在有许多框架具备为个性化方案提供先进的机器学习和人工智能的能力.那么如何决定哪个开源框架最适合你呢?本文试图通过对比深度学习各大框架的优缺点,从而为各位读者提供一 ...

  5. win10+MX350显卡+CUDA10.2+PyTorch 安装过程记录 深度学习环境配置

    https://blog.csdn.net/m0_37867091/article/details/105788637

  6. 【PyTorch深度学习】学习笔记之PyTorch与深度学习

    第1章 PyTorch与深度学习 深度学习的应用 接近人类水平的图像分类 接近人类水平的语音识别 机器翻译 自动驾驶汽车 Siri.Google语音和Alexa在最近几年更加准确 日本农民的黄瓜智能分 ...

  7. 参考《深度学习之PyTorch实战计算机视觉》PDF

    计算机视觉.自然语言处理和语音识别是目前深度学习领域很热门的三大应用方向. 计算机视觉学习,推荐阅读<深度学习之PyTorch实战计算机视觉>.学到人工智能的基础概念及Python 编程技 ...

  8. 【PyTorch】深度学习与PyTorch资料链接整理

    欢迎来到我的博客! 以下链接均是日常学习,偶然得之,并加以收集整理,感兴趣的朋友可以多多访问和学习.如果以下内容对你有所帮助,不妨转载和分享.(Update on 5,November,2019) 1 ...

  9. 深度学习调用TensorFlow、PyTorch等框架

    深度学习调用TensorFlow.PyTorch等框架 一.开发目标目标 提供统一接口的库,它可以从C++和Python中的多个框架中运行深度学习模型.欧米诺使研究人员能够在自己选择的框架内轻松建立模 ...

  10. [Pytorch框架] 4.1 Fine tuning 模型微调

    文章目录 4.1 Fine tuning 模型微调 4.1.1 什么是微调 为什么要微调 迁移学习 Transfer Learning 二者关系 4.1.2 如何微调 4.1.3 注意事项 4.1.3 ...

随机推荐

  1. 效率工具RunFlow完全手册之进阶篇

    欢迎来到RunFlow手册的进阶篇,如果您还不了解RunFlow,建议先阅读我们的基础篇. (Solo 社区投稿) 搜索文件 按文件大小过滤,添加 len 参数,比如:len:1kb-2kb,len: ...

  2. Solo 开发者周刊 (第8期):Claude公司再度上新产品,成交额将超73亿美元

    这里会整合 Solo 社区每周推广内容.产品模块或活动投稿,每周五发布.在这期周刊中,我们将深入探讨开源软件产品的开发旅程,分享来自一线独立开发者的经验和见解.本杂志开源,欢迎投稿. 好文推荐 Cla ...

  3. odoo 给form表单视图内联列表添加按钮

    实践环境 Odoo 14.0-20221212 (Community Edition) 代码实现 模块文件组织结构 说明:为了更好的表达本文主题,一些和主题无关的文件.代码已略去 odoo14\cus ...

  4. Anaconda Navigator打不开

    问题描述:之前安装的Anaconda Navigator,好久不用了,今天却打不开了,只有那个绿色圆环图标出现在桌面中央,点一下就没了.但jupyter notebook和Spyder可以正常使用. ...

  5. cpu亲和性相关函数和宏 基础讲解[cpu_set_t]

    cpu亲和性相关函数和宏讲解: 写在前面: 我在查找关于linux cpu宏函数没看到有对宏函数基础的.详细的讲解,笔者便通过官方文档入手,对次进行的翻译和理解希望能帮到对这方面宏有疑惑的读者 exp ...

  6. 对比python学julia(第三章:游戏编程)--(第四节)捕鱼达人(5)

    4.3.    编程实现 (续上) 3. 实现射击捕鱼 在第 3 个阶段,将按照"编程思路"中介绍的射击捕鱼的算法进行编程,实现让玩家操控大炮射击捕鱼.在"bydr&qu ...

  7. 12、SpringMVC之拦截器

    12.1.环境搭建 创建名为spring_mvc_interceptor的新module,过程参考9.1节和9.5节 12.1.1.页面请求示例 <a th:href="@{/test ...

  8. 【微信小程序】 使用NPM包与VantWeapp

    小程序对npm的支持与限制 目前,小程序中已经支持使用npm安装第三方包,从而来提高小程序的开发效率. 但是,在小程序中使用npm包有如下3个限制: ① 不支持依赖于Node.js内置库的包② 不支持 ...

  9. Arm V8 - ADRP指令

    ADRP指令 作用 将当前指令所在页的基地址加/减去字节差,并写入目标寄存器 字节差:与目标地址页基地址的间隔字节数,其为PAGE_SIZE的整数倍 此时的字节差就是指令所操作的立即数 该指令通常配合 ...

  10. Efficientvit: Enhanced linear attention for high-resolution low-computation visual recognition

    GitHub地址: https://github.com/mit-han-lab/efficientvit#usage 相关: https://www.jetson-ai-lab.com/vit/tu ...