2019.12.05
1.绝对路径和相对路径,除了从根目录开始写得路径以外,其他的都是相对路径。
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))这句话就是说去出当前所写的文件的绝对路径地址,然后加入到sys系统路径中,然后就会找到后面的操作的路径了。
2.DataLoader介绍:
DataLoader的函数定义如下:
DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
num_workers=0, collate_fn=default_collate, pin_memory=False,
drop_last=False)
1. dataset:加载的数据集(Dataset对象)
2. batch_size:batch size
3. shuffle::是否将数据打乱
4. sampler: 样本抽样,后续会详细介绍
5. num_workers:使用多进程并行加载的工作进程数,同一时间多个worker去寻找多个batch数据,0代表不使用多进程
6. collate_fn: 如何将多个样本数据拼接成一个batch,一般使用默认的拼接方式即可
7. pin_memory:是否将数据保存在pin memory区,pin memory中的数据转到GPU会快一些
8. drop_last:dataset中的数据个数可能不是batch_size的整数倍,drop_last为True会将多出来不足一个batch的数据丢弃
也可以参考:【Q&A】pytorch中的worker如何工作的 - 小塞 - 博客园
PyTorch源码解读(一)torch.utils.data.DataLoader_sinat_42239797的博客-CSDN博客
聊聊Pytorch中的dataloader - 知乎
3.__all__ :
__all__
是一个列表,可使表外成员全体私有化,表内指定的可以被其他导入from xxx import *
有用单下划线、双下划线、头尾双下划线说明:
__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
4.if __name__ == '__main__':
一个python的文件有两种使用的方法:
作用一,直接作为脚本执行。
作用二,import到其他的python脚本中被调用(模块重用)执行。
if __name__ == '__main__': 的作用就是控制这两种情况执行代码的过程,在if __name__ == '__main__': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而import到其他脚本中是不会被执行的。
5.TypeError: 'module' object is not callable:这个bug的原因很有可能是因为在文件名和在__init__.py中的“from x x import *”中有重名,且导入时,程序先遇到这个文件名,然后程序以为是这个想要调用的成员,但发现不可调用,其实是个文件。修改重名的文件名和__init__.py中的相关代码。
6.python import 其他文件夹下的文件
一般情况下,import的文件和被import的文件在同一个路径下面,import也比较方便。如果这两个文件不在一个路径下面,import就比较麻烦了,需要在被import的文件路径下面新建一个__init__.py文件,可以是一个没有代码的空文件。比如被import的文件路径是../A/B/b.py下面,那么在在文件夹A、B下面分别新建一个__init__.py文件,然后按照下面的语句引用:import A.B.b
7.nn.Sequential(*layers)
layers列表应该是包含各个层的列表,nn.Sequential的参数是各个层,不是列表;加上*会把layers列表拆成各个元素作为nn.Sequential的输入
Sequential与ModuleList的区别:Pytorch中nn.ModuleList和nn.Sequential的用法和区别_watermelon1123的博客-CSDN博客_nn.modulelist和nn.sequential
nn.ModuleList是一个无序性的序列,他并没有实现forward()方法,需要自己具体实现。
nn.Sequential定义的网络中各层会按照定义的顺序进行级联,因此需要保证各层的输入和输出之间要衔接。并且nn.Sequential实现了farward()方法,因此可以直接通过类似于x=self.combine(x)的方式实现forward
PyTorch 中的 ModuleList 和 Sequential: 区别和使用场景 - 知乎
8.全局平均池化GAP和平均池化:
全局:pytorch 学习 | 全局平均池化 global average pooling 实现 和作用优点解析_湫一-CSDN博客
平局:torch之AvgPool2d_Nicola.Zhang-CSDN博客_avg_pool2d
9.Python的程序有两中退出方式:os._exit(), sys.exit():
os._exit()会直接将python程序终止,之后的所有代码都不会继续执行。
sys.exit()会引发一个异常:SystemExit,如果这个异常没有被捕获,那么python解释器将会退出。如果有捕获此异常的代码,那么这些代码还是会执行。捕获这个异常可以做一些额外的清理工作。0为正常退出,其他数值(1-127)为不正常,可抛异常事件供捕获。
2019.12.11
10.理解交叉熵(cross_entropy)作为损失函数在神经网络中的作用
为什么分类如LR使用交叉熵而不使用均方误差:主要是因为在分类中MSE作为二元分类的损失函数求梯度时会有梯度消失
在自变量非常大或者非常小,sigmoid的导数接近0,交叉熵也不适用于回归问题,从公式可以看出,交叉熵的损失函数只和分类正确的预测结果有关系。
二元分类为什么不能用MSE做为损失函数?-SofaSofa
交叉熵与均方差_DawnRanger的专栏-CSDN博客(注意使用的是sigmoid函数,sigmoid求导,均方误差的求导比交叉熵求导会多乘一个小数),pytorch中由于需要预测分布概率,交叉熵会自己调用softmax。
CrossEntropyLoss()
是 softmax
和 负对数损失的结合,因此使用交叉熵后不用在模型最后使用softmax。softmax反向传播:简单易懂的softmax交叉熵损失函数求导_绝望的乐园-CSDN博客_softmax损失函数
11.python的argparse模块add_argument详解
https://www.baidu.com/link?url=vFC3gjUL2JEbq3bkNIMnTLEcex0nmMApCJYglntLbj64bwbpDzQEBREQIbXe8jV2bi_ULyEDJjRnAxPzrDanlZBeYHraguqB3kXel-q6wMO&wd=&eqid=9738f8a500017452000000035df1a810
12.pytorch 基本函数中的 dim与torch.norm的理解
pytorch 基本函数中的 dim【详细说明】:以torch.argmax为例_月下花弄影-CSDN博客
一个矩阵的维度为(d0,d1,d2,...,dn-1),那么dim=0就表示对应到d0,依次类推,一般方法中运用到dim 时都是按照dim这个维度缩减。比如二维矩阵,按照dim=0缩减,则缩减后变成了一行原来的数据大小。
torch.norm的理解_goodxin_ie的博客-CSDN博客
13.pytorch model.named_parameters() ,model.parameters() ,model.state_dict().items()
pytorch model.named_parameters() ,model.parameters() ,model.state_dict().items()_u013548568的博客-CSDN博客
14.__init__()方法和__init__.py
__iniy__()方法的第一参数永远是self
,self表示创建的类实例本身。默认会有一个无参的__init__()方法,加“__”都为私有的python中带有下划线的变量和函数 - helloTerry1998 - 博客园。
不是实例中的普通独立的函数不需要self,但直接定义在实例中的方法第一个参数默认为self,不可以省略。调用时,s.print_s()其实已经给print_s()函数传入了一个参数对象,即s这个实例。
Python中__init__的用法和理解 - DuKe渡客 - 博客园
__init__.py:用于不同层级的调用,同一层级的文件可以直接from XX import xx,但不同层级需要在当前层级建立一个__init__.py文件,在文件中写入引用的代码(from XX(文件名) import xx)即为当前层级向外提供的接口目录,外部层级的文件可以通过from XXX(层级名) import xx引用。(本质把一个层级当作是一个class,__init__.py作用就如同__init__()函数)。
python 中的__init__.py的用法与个人理解 - clemente - 博客园
15.enumerate的用法以及Pytorch 的常用数据模块库介绍
for i, data in enumerate(trainloader, 0):
#data里面包含图像数据(inputs)(tensor类型的)和标签(labels)(tensor类型)。
inputs, labels = dataenumerate()
用于可迭代\可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标.上面代码的0表示从索引从0开始,假如为1的话,那索引就从1开始。
较全常用模块:Pytorch:常用工具模块 - 纯洁的小兄弟 - 博客园
较常见的pytorch问题:Pytorch在训练过程中常见的问题 - Oldpan的个人博客
16.CUB2011数据集的下载,处理运用
下载:https://github.com/TDeVries/cub2011_dataset/blob/master/cub2011.py
处理与运用:下载后要把数据集分为训练集和测试集。然后做成dataloader:CUB200-2011鸟类细粒度数据集训练集和测试集划分python代码_CV-小生的博客-CSDN博客_cub数据集
17.torchvision.datasets.ImageFolder()的理解
这是一个通用的数据加载器,默认你的数据集已经自觉按照要分配的类型分成了不同的文件夹,一种类型的文件夹下面只存放一种类型的图片。只要按照上述分开存放,在加载时标签就已经加载进去了。使用如下,详细如下:pytorch torchvision.ImageFolder的使用 - 慢行厚积 - 博客园
test_dataset = torchvision.datasets.ImageFolder(root_test,transform=test_transform)
testloader = torch.utils.data.DataLoader(test_dataset,batch_size=train_BATCH_SIZE,shuffle=True,num_workers=2, pin_memory=True)
18.防止过拟合和学习率调整
防止过拟合:regularization方式(L1/L2),在优化器中添加动量,学习率衰减方式,earlystopping,dropout,SGD,BN等。
如何降低神经网络模型的过拟合和欠拟合? - The-Chosen-One - 博客园
学习率调整:pytorch中的学习率调整函数 - 慢行厚积 - 博客园scheduler的step_size表示scheduler.step()每调用step_size次,对应的学习率就会按照策略调整一次。因此一般放在一个epoch结束。
19.BN层的分析和优缺点
【Normalization】深度学习中的Normalization模型
详解深度学习中的Normalization,BN/LN/WN - 知乎
20.GD,SGD以及mini-batch SGD
GD:在GD中,每次迭代都要用到全部训练数据。batchsize=n,把所有样本一次放进网络,占用太多内存。
SGD:在SGD中,每次迭代可以只用一个训练数据来更新参数。batchsize=1
mini-batch SGD:每次迭代可以同时使用batachsize个数据来更新参数。batchsize=1~n
GD训练的每次迭代一定是向着最优方向前进,但SGD和mini-batch SGD不一定,可能会”震荡“。SGD其实可以算作是一种online-learning。另外SGD收敛会比GD快,但是对于代价函数求最小值还是GD做的比较好。折中的办法就是mini-batch SGD
21.list取出一列不能直接切片,但list和numpy里面的array一样也可以使用切片。
>>> a=[[1,2,3], [4,5,6]]
>>> a[:, 0] # 尝试用数组的方法读取一列失败,这种写法是array的,list是a[][]
TypeError: list indices must be integers or slices, not tuple
需要使用列表解析的方法来读取一列
>>> b = [i[0] for i in a] # 从a中的每一行取第一个元素。
>>> print(b)
[1, 4]
想要切片取出一列的话,可以先将list转为numpy.array,就可以了
同时,对于list,去某一个list中的元素,假设为二维。list[i][j],切片也是在每一维的[]中,而numpy中array()产生的数组,a[i,j]为某个元素,同时对每个维度的切片也在这一个[]中,只是用逗号隔开。Python-数组切片_Focus-CSDN博客_数组切片(数组切片)
22.Residual Block和Depth-Separable Convolutional Layer
残差块:在具体实现残差网络时,对于其中的输入、输出通道数目不同的情况作者使用了两种可能的选择。A)shortcut直接使用identity mapping,不足的通道通同补零来对齐;B)使用1x1的Conv来表示Ws映射,从而使得输入、输出通道数目相同。后面为了实际计算的考虑,作者提出了一种bottleneck的结构块来代替常规的Resedual block,它像Inception网络那样通过使用1x1 conv来巧妙地缩减或扩张feature map维度。
深度分离卷积:一个大小为64×64像素、三通道彩色图片首先经过第一次卷积运算,与通常的不同之处在于此次的卷积完全是在二维平面内进行即Filter的厚度为1,且Filter的数量与上一层的Depth相同。所以一个三通道的图像经过运算后生成了3个特征图。Depthwise Convolution完成后的Feature map数量与输入层的depth相同,但是这种运算对输入层的每个channel独立进行卷积运算后就结束了,没有有效的利用不同map在相同空间位置上的信息。因此需要增加另外一步操作来将这些map进行组合生成新的Feature map,即接下来的Pointwise Convolution。Depthwise Separable Convolution详解_在路上的咸鱼的博客-CSDN博客
23.K近邻(KNN)、K-means以及其他聚类算法
knn与k-means:KNN与K-Means的区别_天下对手教会少林武僧-CSDN博客_knn和kmeans
总结:聚类算法和分类算法_蔡艺君小朋友的博客-CSDN博客_分类算法和聚类算法 总结2
24.面向对象编程中的深浅拷贝和赋值
在编程语言中,包括C(结构体),C++,java,python等,在复制对象的操作时,都存在深浅拷贝之分。在对象的赋值中,一般的赋值=语句都是浅拷贝,只是复制内存地址(指针),并没有开辟新的内存空间。此处讨论的是对象赋值而不是属性变量赋值。如student a = b或int b[2] = {1,2}; int *a = b,b的任何变化都会引起a的变化。并不是a[1] = b[1]这种变量的赋值。变量赋值直接赋了,对象赋值赋的是指向该对象的地址。包括python的赋值“=”也是如此。
>> a = [1, 2, 3]
>>> b = a //对象赋值,赋值的是指向该对象的地址。
>>> a = [4, 5, 6] //赋新的值给 a,让a指向了其他对象
>>> a
[4, 5, 6]
>>> b
[1, 2, 3]
# a 的值改变后,b 并没有随着 a 变
>>> a = [1, 2, 3]
>>> b = a
>>> a[0], a[1], a[2] = 4, 5, 6 //a和b仍然指向[1,2,3]对象,但此处元素值被改变。
>>> a
[4, 5, 6]
>>> b
[4, 5, 6]
# a 的值改变后,b 随着 a 变了
python中的copy模块有copy()方法和deepcopy()方法。copy模块是为了实现数据的复制的,实现真正的copy,都会开辟新的内存空间,因此理论上都是深拷贝,通过a is b也可以判断,只不过copy的程度有区别。python为每个列表list都开辟了内存空间,但list的内存空间没有存放元素,而是存放了元素的地址。通过id()看出,list中的每个元素的地址并不是连续的,同时由于列表的元素可以是任何对象,因此推断list的每个内存中放置的是指向元素的地址。pyhton的copy()开辟的新空间中只拷贝了第一级元素的内存地址。deepcopy()才是拷贝所有级元素。
深浅拷贝的区别就是在于有没有开辟新的内存空间。
25.python全局变量和局部变量
在某类的方法中申请全局变量可以使用self,没有加self的是局部变量。
一般来说,在函数外边定义的变量叫做全局变量,全局变量能够在所有的函数中被访问读取。
修改时:对于不可变型(数字、字符、字符串、元祖)必须使用global 变量名进行声明;对于可变型(列表,字典等能增删的变量)不需要global直接可以被修改。
全局变量可以和定义在函数里面的局部变量重名,但是是两个不同的变量,在方法中此时使用的是局部变量。
字符串中的每个元素不能被直接修改,并不是字符串数组,可以使用replace()方法。
26.机器学习中的判别模型和生成模型
在机器学习中任务是从属性X预测标记Y,判别模型求的是P(Y|X),即后验概率;而生成模型最后求的是P(X,Y),即联合概率。从本质上来说:判别模型之所以称为“判别”模型,是因为其根据X“判别”Y;
而生成模型之所以称为“生成”模型,是因为其预测的根据是联合概率P(X,Y),而联合概率可以理解为“生成”(X,Y)样本的概率分布(或称为 依据);具体来说,机器学习已知X,从Y的候选集合中选出一个来,可能的样本有(X,Y_1), (X,Y_2), (X,Y_3),……,(X,Y_n),实际数据是如何“生成”的依赖于P(X,Y),那么最后的预测结果选哪一个Y呢?那就选“生成”概率最大的那个吧~
27.Python 类中__init__函数以及参数self
__init__函数即为类的构造函数,创建类时用于初始化该类对象的属性。不过注意:init函数(方法)的第一个参数必须是self(self为习惯用法,也可以用别的名字),后面的参数则可以自由定义,和定义函数没有任何区别。Python 中__init__函数以及参数self_程存淦-CSDN博客
28.尾调用和尾递归优化
尾调用即一个函数中最后return只执行调用另外一个函数,如在f(x)中return g(x)。由于这样不会保留调用记录,省去调用栈的内存,可以减少内存的消耗。达到O(1)的空间复杂度。尾递归即是在return时递归调用自己,并不减少递归的次数【转载】尾调用与尾递归优化 - J1ac - 博客园
29.海量数据排序——如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?
外排序:归并排序,内排序:任意高效的排序方法
海量数据排序——如果有1TB的数据需要排序,但只有32GB的内存如何排序处理?_无鞋童鞋的博客-CSDN博客
30.python中numpy的stack、vstack、hstack、concatenate
stack是将数组自身实现重新堆叠,其余三个都是将两个数组实现连结。python中numpy的stack、vstack、hstack、concatenate、_Zamirquito的博客-CSDN博客
stack与cat的区别:torch.cat()对tensors沿指定维度拼接,但返回的Tensor的维数不会变
torch.stack()同样是对tensors沿指定维度拼接,但返回的Tensor会多一维
31.对resnet的理解和relu的优点
在网络层数越来越多,但准确率却不增加反而降低的情况下提出了resnet结构,这个方法是为了解决这种梯度消失或爆炸的情况。对输入数据和中间层的数据进行归一化操作,这种方法可以保证网络在反向传播中采用随机梯度下降(SGD),从而让网络达到收敛。但是,这个方法仅对几十层的网络有用,当网络再往深处走的时候,这种方法就无用武之地了。
为什么引入Relu呢?
第一,采用sigmoid等函数,算激活函数时(指数运算),计算量大
第二,对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失的情况(在sigmoid接近饱和区时,变换太缓慢,导数趋于0,这种情况会造成信息丢失),从而无法完成深层网络的训练。
第三,Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
非线性激活函数relu反向传播实现:优化网络的原理与方法(番外篇)--激活函数层的反向传播实现_学习随笔-CSDN博客
32.python中的*和**
作为中缀操作符时,分别为乘法和指数为2的幂运算。
作为前缀操作符时,用于指定函数传入参数的类型。*参数名,表示传入的多个参数将按照元组的形式存储,是一个元组。**参数名,表示传入的多个参数将按照字典的形式存储。另外一种情况,变量本身是一个元组或者字典时,在函数调用时,*变量或者**变量可以进行解引用,将元组或者字典的元素赋值给函数定义的各个形参。Python3 * 和 ** 运算符_极客点儿-CSDN博客
33.torch.nn与torch.nn.functional之间的区别和联系
nn.functional.xxx
是函数接口,而nn.Xxx
是nn.functional.xxx
的类封装,在nn.xxx定义时最后调用了nn.functiona.xxx。并且nn.Xxx
都继承于一个共同祖先nn.Module。
PyTorch(1) torch.nn与torch.nn.functional之间的区别和联系_GZHermit的博客-CSDN博客 PyTorch 中,nn 与 nn.functional 有什么区别? - 知乎
34.pytorch提示CUDA不足,显存不足
35.lambda
lambda常用于map(lambda x:操作,序列),返回对序列中每个元素操作后的迭代器,与filter(lambda x:操作,序列)返回满足条件的元素的迭代器。
#numpy中一般都是将对象的每一个元素分别进行处理
import numpy as np
arr = np.array([1, 2, 3])
scale = lambda x: x * 3
scale(arr) # Gives array([3, 6, 9])
#普通的python中,是将对象进行处理
arr = [1, 2, 3]
scale = lambda x: x * 3
scale(arr) # Gives [1, 2, 3, 1, 2, 3, 1, 2, 3]
36.append的浅拷贝
当 list 类型的对象进行 append 操作时,实际上追加的是该对象的引用。
alist = []
num = [2]
alist.append( num )
id( num ) == id( alist[0] )
->True alist[0]与num共同指向一个对象
当num指向另外一个对象时,alist[0]仍然不变
当num并没有指向另外一个对象,而是自身发生了变化,如num.append([3]),也即它们共同指向的对象变化,alist[0]会变化。
37.max()输入对象为strs
>>> s1
['acc', 'axc', 'abc', 'acy']
>>> max(s1) # 进行字典序比较,对每个元素的相应字母进行字典序比较。直到比较出来大小
'axc'
>>> min(s1)
'abc'
38.向量和矩阵的点乘和叉乘
numpy库的对象有数组和矩阵,两者看起来长得差不多,但在性质、运算上有很大不同。可通过array函数和mat函数相互转化。参考
39.迁移学习
参考 参考
迁移学习往往还和你的任务中的数据关系密切,可以考虑以下几种情况:参考
40.KL散度(相对熵)
当P(x)和Q(x)的相似度越高,KL散度越小。
KL散度主要有两个性质:
(1)不对称性:尽管KL散度从直观上是个度量或距离函数,但它并不是一个真正的度量或者距离,因为它不具有对称性,即D(P||Q)!=D(Q||P)。
(2)非负性:相对熵的值是非负值,即D(P||Q)>0。
互信息:信息论(1)——熵、互信息、相对熵 - 知乎
41.交叉验证
留一交叉验证:现在有n个数据组成的数据集,那么LOOCV的方法就是每次取出一个数据作为测试集的唯一元素,而其他n-1个数据都作为训练集用于训练模型和调参。结果就是我们最终训练了n个模型,每次都能得到一个MSE。而计算最终test MSE则就是将这n个MSE取平均。
K折交叉验证:
如果K=5,那么我们利用五折交叉验证的步骤就是:
1.将所有数据集分成5份
2.不重复地每次取其中一份做测试集,用其他四份做训练集训练模型,之后计算该模型在测试集上的MSE
3.将5次的MSE取平均得到最后的MSE
不难理解,其实LOOCV是一种特殊的K-fold Cross Validation(K=N)。
42.collections.defaultdict()的使用
Python中通过Key访问字典,当Key不存在时,会引发‘KeyError’异常。为了避免这种情况的发生,可以使用collections类中的defaultdict()方法来为字典提供默认值。
collections.defaultdict()的使用_净的博客-CSDN博客
43.pytorch中的normal_()和fill_()都是in_place操作,不会开辟新的空间进行复制。
pytorch normal_(), fill_() - Picassooo - 博客园
44.backbone、head、neck等深度学习中的术语解释
目标检测网络构成部分,backbone + neck + head?分别代表什么意思,都有哪些网络_weixin_48780159的博客-CSDN博客
45.nn.BCELoss与nn.CrossEntropyLoss的区别
YOLOV3中使用的BCELoss,即对每个类别都进行预测是否为该类,然后累加损失。是因为有的物体会符合多个类别。
46.将小图变成大图使用上采样等
反卷积(Deconvolution)、上采样(UNSampling)与上池化(UnPooling)加入自己的思考(tensorflow函数)(一)_镜中隐的博客-CSDN博客_unsampling
47.linux中的-和--参数
linux中的-和--参数_torresergio的博客-CSDN博客_- -- linux 参数
48.linux中"cd /" ,"cd ~","cd /home"
linux中"cd /" ,"cd ~","cd /home",家目录的区别_CSDN-CSDN博客
49.python中super().__init__()
子类继承父类的方法,子类B继承父类A后重写了add(),但是重写中只继承了父类的add()。可以通过B.__mro__方法查看B的继承顺序python中super().__init__()_java/python知识分享-CSDN博客_super().__init__()
class A:
def add(self, x):
y = x+1
print(y)
class B(A):
def add(self, x):
#super().add(x)
super(B,self).add(x) # python 3两种方式都可以,python2只支持这一种
b = B()
b.add(2) # 3
50.pytorch中的自定义Module和datasets:
首先,我们在定义自已的网络的时候,需要继承nn.Module类,并重新实现构造函数__init__构造函数和forward这两个方法。参考
Dataset类是Pytorch中图像数据集中最为重要的一个类,也是Pytorch中所有数据集加载类中应该继承的父类。其中父类中的两个私有成员函数必须被重载,__len__应该返回数据集的大小,而__getitem__应该编写支持数据集索引的函数。参考
import torch.utils.data as data
自己定义的数据集要去继承data.Dataset,Datasets就是构建Dataloader函数的实例参数之一。
加载自己定义的数据集:参考
51.python中的迭代器:Python 迭代器(Iterator) - 吴吃辣 - 博客园
__iter__()
方法必须始终返回迭代器对象本身。
__next__()
方法必须返回序列中的下一项,效果上类似for循环。
52.回调函数 回调函数(callback)是什么? - 知乎
回调函数提供不同的具体功能,供不完整的中间函数(登记回调函数)去通过传参的形式调用,这样的话在程序中调用中间函数就可以根据回调函数提供的功能而实现不同的功能。实现更加的灵活,耦合度低。
53.CUDA_VISIBLE_DEVICES=0,2,3 # 只有编号为0,2,3的GPU对程序是可见的,但并不是程序使用这三个gpu,一般在cfg文件中有配置。
54.python @property的介绍与使用:是python的一种装饰器,是用来修饰方法的。
python @property的介绍与使用 - 知乎 callable(可调用)对象是指一个后面可以加 ‘( ) ’的对象
加了@property后,可以用调用属性的形式来调用方法,即后面不需要加(),类似创建了和方法同名的只读属性。
装饰器:即是函数的嵌套,调用被装饰的函数时a(),首先会执行装饰器函数A(),然后再执行a()。类似A(a())。
55.vscode 调试python代码时添加参数(args)
vscode 调试python代码时添加参数(args)_zk0272的博客-CSDN博客
注意“program”即为你要运行的文件。
56.PyTorch中的model.modules(), model.children(), model.parameters()
pytorch model.named_parameters() ,model.parameters() ,model.state_dict().items()_u013548568的博客-CSDN博客
57.torchvision的介绍:
torchvision.datasets: 参考
torchvision.transforms: 参考
torchvision.models: 参考
58.python 的代码执行顺序
参考
所以python中的main使用和c++中main有一点区别,c++中main表示程序的入口,而python当中是顺序执行的,并且顺序执行的是一些非类定义和非函数定义的没有缩进的代码段,我的理解是这里的main函数就没有c++当中那么重要了
若是文件需要主动执行(脚本),main之前不要有可执行代码,这样做到程序从main()开始,流程逻辑性强,若是文件作为模块被调用,则可以不用写main(),从上而下顺序执行。
59.pytorch中数据采样方法Sampler
取样器是在某一个数据集合上,按照某种策略进行取样,将采样交给dataloader。常见的策略包括顺序取样,随机取样(个样本等概率),随机取样(赋予个样本不同的概率)。参考
60.np.array与np.ndarray的区别
np.ndarray是一个类,其默认构造函数是ndarray()。np.array()是一个函数,便于创建一个ndarray对象,通常使用这些上层一点的函数来构造ndarray对象会更方便一些。参考
61.python读取图片、保存图片的方法
python读取图片、保存图片的方法_sduati的专栏-CSDN博客_python保存图片
62.pickle和json的区别:参考
我们把对象(变量)包括整型字符串列表字典等等都叫对象,从内存中变成可存储或传输的过程称之为序列化,在python中叫pickling,在其他语言中serialization、marshalling、flattening等等,都是一个意思,序列化之后的内容可以写入磁盘或者通过网络传输到别的机器上。
相反,把变量内容从序列化对象重新读到内存里称之为反序列化,python叫unpickling
注意:将json转化为Pickle:将array或者json文件转化为pkl文件保存_Raywit的博客-CSDN博客
63.判断两个list/array中的元素是否相等
注意:观察两个list/array中是否为多个元素,如果只有一个元素,则不需要加all()或则any()
完全相等:all(),有一个相等就行any()
学习随笔-ValueError: The truth value of an array with more than one element is ambiguous_Evan的日常blog-CSDN博客
64.PyTorch JIT
PyTorch JIT - 知乎
首先要知道 JIT 是一种概念,全称是 Just In Time Compilation,中文译为「即时编译」,是一种程序优化的方法,一种常见的使用场景是「正则表达式」。
如果多次使用到某一个正则表达式,则建议先对其进行 compile,然后再通过 compile 之后得到的对象来做正则匹配。而这个 compile 的过程,就可以理解为 JIT(即时编译)。
65.Numpy/Pytorch之数据类型与强制转换 总结_球场书生的博客-CSDN博客
66.python创建字典多种方式_Ydoing的专栏-CSDN博客_python 创建字典并赋值
67.神经网络中 warmup 策略为什么有效;有什么理论解释么? - 知乎
68.PyTorch中的is_contiguous:用来判断当前数据是否被transpose、permute等操作
PyTorch中的contiguous - 知乎
tensor.is_contiguous()
69.class numpy.errstate(**kwargs) 它允许该上下文中的语句以已知的错误处理行为执行。
python numpy errstate用法及代码示例 - 纯净天空
70.np.nansum()、np.nanmean() 函数用法:对数组中含有nan的情况进行求和,求均值。
np.nansum()、np.nanmean() 函数用法_java_pythons的博客-CSDN博客_np.nansum
71.目标检测中bbox回归中class-agnostic和class-specific的区别在哪? - 知乎
72.Python:pip 和pip3的区别_去向前方的博客-CSDN博客_pip和pip3的区别
73.condarc的替换,就是conda install时去找的网址:https://www.jb51.net/article/212362.htm
74.循环删除列表中元素时千万别用正序遍历,一定要用反序遍历!https://www.baidu.com/link?url=Mrz6XHwCVB-CFMjn_lPg6c2wUkjaJI77iMBKpNh4-VtMUh5GrYl8XCzFrj4DvreCB3otUpua3UC4KoB_Dr2oO_&wd=&eqid=82382ccd0001c50100000003620b5fcfhttps://www.baidu.com/link?url=Mrz6XHwCVB-CFMjn_lPg6c2wUkjaJI77iMBKpNh4-VtMUh5GrYl8XCzFrj4DvreCB3otUpua3UC4KoB_Dr2oO_&wd=&eqid=82382ccd0001c50100000003620b5fcf
75. TP,FP,FN的正确认识:
在模型收敛的情况下,我们认为模型的预测,模型都认为是正样本,其中肯定有真正的正样本,和假的正样本。
TN是无法计算的,因为你无法定义一个图像中有多少个negative样本,但可以计算FN,这就比较简单了:没有被任何pred匹配上的GT就是一个FN
目标检测中,gt没有框,但是预测出了一个目标框,那么算是FP还是FN? - 知乎
76.转置卷积,反卷积
抽丝剥茧,带你理解转置卷积(反卷积)_史丹利复合田的博客-CSDN博客_转置卷积和反卷积
首先,卷积的底层实现可能并不是滑动窗口去实现的,而是文档中描述的两个矩阵相乘,卷积核的weight变成了一定大小的矩阵,然后与展平的输入矩阵相乘,获得和滑动相同指的结果。
1. 卷积的底层实现通过两个矩阵相乘,避免滑动窗口的实现。
2. 转置卷积即是将展平的输出O,乘以shape为普通卷积的转置的weight矩阵(weight值并不是前面普通矩阵的,为可学习参数),得到原输入大小的矩阵。
3. 上述的转置卷积操作,可以通过将一个普通的卷积核旋转180°,然后与padding后得O`卷积来等效替换实现。
其次,反卷积核uppooling和upsampling操作的可视化区别:
反卷积(deconvolution)的理解 +上采样(UNSampling)与上池化(UnPooling)_Snoopy_Dream的博客-CSDN博客_逆卷积
最后,对于反卷积的stride 大于1,反卷积的padding大于1的实现:
Deconvolution(逆卷积)_玄云飘风的博客-CSDN博客_deconvolution
77. Python @property装饰器详解Python @property装饰器详解_NickTheRock的博客-CSDN博客
@property 装饰器的应用和直接使用python 内置函数 property() 函数创建托管属性其实没啥区别。
创建托管属性的意义:可以对class类的私有属性进行重新命名(可以取名为规范易懂的名字),如果没有创建对应的setter,deleter方法,托管属性为只读属性,同时也方便对读取,修改,删除属性增加筛选和过滤条件,比如达到什么条件才能修改,读取,删除该属性值。
78.numba.jit 介绍 (超级详细)jit的介绍和用法(python加速)_python jit_音程的博客-CSDN博客
使用@jit(nopython=True)装饰器去装饰某个数学计算较多的函数, jit第一次运行函数不会加速,因为这一次在摸清函数内部的套路,但第后续的话会脱离python解释器,编译为机器码快速运行。
79.python中list,dict为可变数据类型,同时,python中创建的形参实参其实都是指针,指向同一块list/dict的数据,因此形参和实参的处理都会改变这一块数据内容。
Python中实参随形参改变而改变的问题_python形参改变实参_长命百岁️的博客-CSDN博客
80.迭代器和生成器的区别和联系:生成器是特殊的迭代器,同样都支持next()方法,__iter__()。但生成器每次next都是调用时才生成的,配合yield方法,并不会占过多内存。
python中生成器与迭代器到底有什么区别?一文带你彻底搞清楚_python迭代器和生成器的区别_达达爱吃肉的博客-CSDN博客
Python迭代器基本方法iter()及其魔法方法__iter__()原理详解_涛涛ALG的博客-CSDN博客
81.python中的@classmethod的作用_謹言的博客-CSDN博客
@classmethod修饰的函数在没有初始化类的情况下就可以被调用,直接返回被调用后产生的实例,实现除了__init__()以外的其他初始化类的方式。