2018-11-01 21:42:46    397    0    0

1、mAP的计算

ReID 终归还是排序问题,Rank 是排序命中率核心指标。Rank1 是首位命中率,就是排在第一位的图有没有命中他本人,Rank5 是 1-5 张图有没有至少一张命中他本人。

title

这里放了两组图,图片 1 和图片 2 是检索图,第一组图在底库中有 5 张图,下面有 5 个数字,我们假设它的检索位置,排在第 1 位、第 3 位、第 4 位、第 8 位,第 20 位,第二张图第 1 位、第 3 位、第 5 位。

它的 mAP 是怎么算的?对于第一张图平均精度有一个公式在下面,就是 0.63 这个位置。第一张是 1 除以 1,第二张是除以排序实际位置,2 除以 3,第三个位置是 3 除以 4,第四个是 4 除以 8,第五张图是 5 除以 20,然后把它们的值求平均,再总除以总的图片量,最后得出的 mAP 值大概是 0.63。

同样的算法,算出图片 2 的精度是 0.756。最后把所有图片的 mAP 求一个平均值,最后得到的 mAP 大概是 69.45。从这个公式可以看到,这个检索图在底库中所有的图片都会去计算 mAP,所以最好的情况是这个人在底库中所有的图片都排在前面,没有任何其他人的照片插到他前面来,就相当于同一个人所有的照片距离都是最近的,这种情况最好,这种要求是非常高的,所以 mAP 是比较能够综合体现这个模型真实水平的指标。

参考:
https://www.cnblogs.com/gmhappy/p/11864020.html
2、rankn和mAP
title

3、P、R等

1、rank-n

搜索结果中最靠前(置信度最高)的n张图有正确结果的概率。

例如: lable为m1,在100个样本中搜索。

如果识别结果是m1、m2、m3、m4、m5……,则此时rank-1的正确率为100%;rank-2的正确率也为100%;rank-5的正确率也为100%;如果识别结果是m2、m1、m3、m4、m5……,则此时rank-1的正确率为0%;rank-2的正确率为100%;rank-5的正确率也为100%;如果识别结果是m2、m3、m4、m5、m1……,则此时rank-1的正确率为0%;rank-2的正确率为

2018-10-31 13:21:58    208    0    0

1.入门级简单使用
泡菜模块的简单使用,不止是列表对象,其他的比如字典,tuple等都可以保存为pkl文件,pkl是一种二进制文件:

  1. >>> import pickle
  2. >>>
  3. >>> my_list=[1,2,3,'loss']
  4. >>> pickle_file=open('mylist.pkl','wb')#默认地址,在windows下应该是python解释器的位置,ubuntu则直接放在了/home/lb
  5. #>>> pickle_file=open('/home/lb/安装包/second.pkl','wb')# 也可以这样,指定文件位置
  6. >>> pickle.dump(my_list,pickle_file)
  7. >>> pickle_file.close()
  8. >>>
  9. >>> pickle_file=open('mylist.pkl','rb')
  10. >>> my_list2=pickle.load(pickle_file)
  11. >>> print(my_list2)
  12. [1, 2, 3, 'loss']
  13. >>>

2.pkl文件实际应用
一种应用主要是保存深度学习网络的模型,或者只保存其参数parameters:
(1)保存模型:

  1. # 2 ways to save the net
  2. torch.save(net1, 'net.pkl') # save entire net
  3. torch.save(net1.state_dict(), 'net_params.pkl') # save only the parameters

(2)加载模型:
a)直接加载模型,缺点是占用较大空间:

  1. net2 = torch.load('net.pkl')#然后网络net2就可以正常使用了,比如prediction = net2(x)

b)只加载网络权重参数,这种情况下,参数占用的空间比模型小,缺点就是加载时,需要自己先搭建一个跟需要加载的网络结构一样的网络,再加载网络参数:

  1. # restore only the parameters in net1 to net3
  2. net3 = torch.nn.Sequential(
  3. torch.nn.Linear(1, 1
2018-10-31 11:00:16    66    0    0

1.傅里叶变换及其性质

傅立叶级数:
任何周期函数都可以表示成为不同频率的正弦或者余弦之和的形式,每个正弦余弦的乘以不同的系数.
傅立叶变换
傅立叶变换,表示能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。定义为:
title
性质
(1)线性性质
title
(2)尺度变换性质
title
(3)对偶性质
title
(4)平移性质
title的傅立叶变换为:
title
(5)微分性质
title
(6)时域卷积
title
(7)频域卷积
title
(8)Parseval定理
title
(9)Plancherel定理
title

2.取样定理

p134
在进行模拟/数字信号的转换过程中,当采样频率fs.max大于信号中最高频率fmax的2倍时(fs.max>2fmax),采样之后的数字信号完整地保留了原始信号中的信息,一般实际应用中保证采样频率为信号最高频率的2.56~4倍;采样定理又称奈奎斯特定理

3.图像的频谱中,低频,高频的物理意义是什么?频率为0(F(0,0))处代表着什么?

图像的频率:灰度值变化剧烈程度的指标,是灰度在平面空间上的梯度。
(1)什么是低频?

  1. 低频就是颜色缓慢地变化,也就是灰度缓慢地变化,就代表着那是连续渐变的一块区域,这部分就是低频. 对于一幅图像来说,除去高频的就是低频了,也就是边缘以内的内容为低频,而边缘内的内容就是图像的大部分信息,即图像的大致概貌和轮廓,是图像的近似信息。

(2)什么是高频?

  1. 反过来, 高频就是频率变化快.图像中什么时候灰度变化快?就是相邻区域之间灰度相差很大,这就是变化得快.图像中,一个影像与背景的边缘部位,通常会有明显的差别,也就是说变化那条边线那里,灰度变化很快,也即是变化频率高的部位.因此,图像边缘的灰度值变化快,就对应着频率高,即高频显示图像边缘。图像的细节处也是属于灰度值急剧变化的区域,正是因为灰度值的急剧变化,才会出现细节。
  2. 另外噪声(即噪点)也是这样,在一个像素所在的位置,之所以是噪点,就是因为它与正常的点颜色不一样了,也就是说该像素点灰度值明显不一样了,,也就是灰度有快速地变化
2018-10-29 22:26:45    216    0    0

#1.自建模块

创建一个文件夹,在里面放入作为模块的py文件,这个文件夹可以作为一个包

当没有__init__.py文件时,这时可以直接import 包,但是不能通过先使用 import 包名 然后再包名.模块来访问包里的模块.因为这时认为包为一个模块,而包是一个文件夹,并不是模块。

可以通过 import pack.module或者 from pack import module来导入pack文件夹(也叫做包)中的模块(py文件),或者在__init__.py文件中加载相应的模块即可(from . import test1 #test1为包中的一个py文件)
后面就是这种情况.

#2.引入包,并调用里面的模块

import 包名.模块名

from 包名 import * ps:此时只能使用__init__.py__all__中允许调用的模块

from 包名 import 模块名

特别的,如果想导入模块中的类(或者函数,变量等),不能使用:

  1. import pack.module.class # 会提示没有相应的pack.module.class模块

应该使用:

  1. from pack.module import class
  2. #from pack.module import * #这种会导入module中所有的变量

总之,能直接import的是包和模块,能from ...import 的,是模块和类,变量
#3. 包中的__init__.py文件

__init__.py控制着包的导入行为,某个文件夹放入__init__.py,说明这个文件夹是个包

① 若__init__.py为空

仅仅导入包,并不导入模块

② __init__.py中的 __all__
__all__只控制from 包名 import *中导入的模块,它不仅在第一时间展现了模块的内容大纲,而且也更清晰的提供了外部访问接口。详细参考:https://blog.csdn.net/hang916/article/details/79474821

但是,实际上只要from . import test1就可以不用管__all__.

2018-10-29 16:24:05    226    0    0

(一)stack()
stack()实际上就是堆叠,拼接的意思,针对单个ndarray(torch.cat()函数也是拼接的意思,但是针对的两个tensor),它所做的工作就是将原来的元素,按照axis的值,取出来打包,重新堆叠形成新的ndarray,可以看下面的例子:
当执行np.stack(arrays, axis=0)时,取出第一维的1、2、3、4,打包,[1, 2, 3, 4],其余的类似,然后结果如下:

  1. >>> arrays = [[1,2,3,4], [5,6,7,8]]
  2. >>> arrays=np.array(arrays)
  3. >>> np.stack(arrays,axis=0)
  4. array([[1, 2, 3, 4],
  5. [5, 6, 7, 8]])

当执行np.stack(arrays, axis=1)时,先对arrays中的第二维进行“打包”,也即是将1、5打包成[1, 5],其余的类似,结果如下:

  1. >>> np.stack(arrays, axis=1)
  2. array([[1, 5],
  3. [2, 6],
  4. [3, 7],
  5. [4, 8]])

有这个“打包”的概念后,对于三维,或者更高维的数组堆叠也不难理解了.
理解stack的要点:(1)stack前后,对于堆叠的各部分来说,轴的数量相应的增加(2)特定axis轴上,索引相同的数据,打包在一起,因此在新增的特定轴上的索引数量(针对于原来stack()内的各个部分的维度来说的),也会相应的增加,如下

  1. >>> a = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
  2. >>> b = np.array([[4, 5, 6], [4, 5, 6], [4, 5, 6]])
  3. >>> a.shape
  4. (3, 3)
  5. >>> b.shape
  6. (3, 3)
  7. >>> np.stack((a, b), axis=0).shape #这是针对两个ndarray的情况,实际上与单个ndarray情况是一致的,单个ndarray也可以堪
  8. (2, 3, 3)
  9. >>> np.stack((a, b), axis=1
2018-10-25 23:32:20    201    0    0

第一次:
1.编程将一幅图像降质为多个低空间分辨率的图像;
2.编程将一幅256灰度级的灰度图像分解为不同灰度的分辨率(128,64,32,16,8,4,2)的图像;
3.编程实现图像差分,多幅图像相加去噪.

第二次:
1.编程统计任何一副图像的直方图并显示
2.编程实现图像均衡化和图像规格化
3.编程实现图像均值滤波,中值滤波

2018-10-24 16:51:46    101    0    0

参考资料:
https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/3-1-pd-intro/

https://blog.csdn.net/xiaodongxiexie/article/details/53108959

如果用 python 的列表和字典来作比较, 那么可以说 Numpy 是列表形式的,没有数值标签,而 Pandas 就是字典形式。Pandas是基于Numpy构建的,让Numpy为中心的应用变得更加简单。

要使用pandas,首先需要了解他主要两个数据结构:Series和DataFrame

1.Series的使用

Series的字符串表现形式为:索引在左边,值在右边。由于我们没有为数据指定索引。于是会自动创建一个0到N-1(N为长度)的整数型索引:

  1. import numpy as np
  2. import pandas as pd
  3. print(pd.Series([1,2,np.nan,'like']))

输出:

  1. 0 1
  2. 1 2
  3. 2 NaN
  4. 3 like
  5. dtype: object

2.DataFrame的使用

DataFrame的本质是行(index)列(column)索引+多列数据.

DataFrame 是有多个列的数据表,每个列拥有一个 label,当然,DataFrame 也有索引
DataFrame是一个表格型的数据结构,它包含有一组有序的列,每列可以是不同的值类型(数值,字符串,布尔值等)。DataFrame既有行索引也有列索引, 它可以被看做由Series组成的大字典。

  1. import numpy as np
  2. import pandas as pd
  3. #convert string to Timestamp
  4. date=pd.date_range('20181001',end='20181006',periods=6)
  5. data=pd.DataFrame(np.random.randn(6,4),index=date,columns=['a','b','c','d'])
  6. print(data)

结果

2018-10-24 11:16:44    442    0    0

1.前向传播
最大子采样函数取区域内所有神经元的最大值(max-pooling)。
以下图为例,输入数据X为4*4,input_width=4,采样核kernel_size为2,stride为2,padding=0。输出数据大小out_width类似卷积层的计算方法如下:

out_width=input_width+2paddingkernel_sizestride+1

前向传播中不仅要计算pool区域内的最大值,还要记录该最大值所在输入数据中的位置,目的是为了在反向传播中,需要把梯度值传到对应最大值所在的位置
title
2.反向传播
还是引用上图,通过前向传播已知,梯度值对应上一层输出的最大值位置。具体过程如下:
title

2018-10-23 17:43:24    7026    0    0

Cross Entropy(也就是交叉熵)Loss:交叉熵损失函数,通常用于多分类,其中yi是one_hot标签,pi是softmax层的输出结果,交叉熵损失E定义为:

E=1nyilog(Pi)

Negative Log Liklihood(NLL) Loss:负对数似然损失函数,X是log_softmax()的输出,label是对应的标签位置

loss(X,label)=Xlabel

损失函数NLLLoss() 的 输入 是一个对数概率向量和一个目标标签,并对应位置相乘相加,最后再取负(也就是说,这里的Xlabel,,对于独热码来说,实际上就是取的X中,对应于label中为1的那个x). 它不会为我们计算对数概率,适合最后一层是log_softmax()log_softmax也就是对softmax的输出取对数)的网络. 损失函数 CrossEntropyLoss()NLLLoss()类似, 唯一的不同是它为我们去做 softmax并取对数.可以理解为:

CrossEntropyLoss()=log_softmax() + NLLLoss()

代码则为:

  1. import t
2018-10-21 22:18:36    273    0    0

python作为一个动态语言其函数的参数也很“动态”。
参数可能有的情况:必选参数、默认参数、可变参数、关键字参数、命名关键字参数

function(a,b=1,*c,**d,*,e)

1.位置参数(正常传参)

就是固定的参数,函数中定义多少个参数,调用函数的时候后就传递多好个参数。

  1. #1.正常参数
  2. def power(x,n):
  3. sum=0
  4. while(n>1):
  5. sum=sum+x*x
  6. n=n-1
  7. return sum
  8. print(power(2,5))#输出16

2.默认参数(给定一个默认值)

首先注意:
(1)默认参数要放在最后面,不然会有误会,编译器不知道从哪个数开始算他不是默认参数
(2)默认参数必须指向不变对象
当函数中有部分参数的值在大部分时间是固定的时候,可以预先给它一个值。不用每一次都输入。当然有特殊情况的时候依然可以给它附一个新的值。

  1. #2.默认参数
  2. def power(x,n=5):
  3. sum=0
  4. while n>1:
  5. sum=sum+x*x
  6. n=n-1
  7. return sum
  8. print(power(2))#输出16

3.可变参数(*加参数名,表示此参数可变)

第1种方式:
可变的参数指的是列表(list),元组(tuple).因为其中的数据是可以改变的,将列表和元组作为参数传入函数中,所以函数的参数也是可变的。要定义可变参数,仅需在参数名之前添加一个星号(*)。在函数内部,这些参数被包装为一个 tuple
例如:power函数
使用 * 放在参数名前,作为可变参数的标志

  1. ## 3,可变参数,表示参数可以改变,比如下面的*number,相当于构成了一个tuple,这个tuple的名字是number
  2. def calc(*number):
  3. sum =0
  4. for n in number:
  5. print(n)
  6. print(number)
  7. return sum
  8. number1=[1,5,6,7]
  9. number2=[8,9,11,34]
  10. print(calc(numb