在看SiamFC中的Alexnet网络层的源码时,初始化网络时,在初始化匹配模板和weights涉及到高维数据的扩展与组合操作,用到了numpy内部的一些操作函数,这里将自己不熟悉的一些函数通过一个小的demo来进行可视化的理解,深入高维度数组的内部去探索高维数组的内部结构与操作。
首先,我们定义两个1维数组,并通过numpy中的meshgrid函数进行扩展操作,具体代码如下:
import numpy as np
y = np.arange(15, dtype=np.float32) - (15-1) / 2. # -7:7
x = np.arange(15, dtype=np.float32) - (15-1) / 2. # -7:7
print(y)
print(x)
y, x = np.meshgrid(y, x) #形成一个15*15的矩阵
print(y)
print(x)
具体输出如下:
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]
[-7. -6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7.]]
[[-7. -7. -7. -7. -7. -7. -7. -7. -7. -7. -7. -7. -7. -7. -7.]
[-6. -6. -6. -6. -6. -6. -6. -6. -6. -6. -6. -6. -6. -6. -6.]
[-5. -5. -5. -5. -5. -5. -5. -5. -5. -5. -5. -5. -5. -5. -5.]
[-4. -4. -4. -4. -4. -4. -4. -4. -4. -4. -4. -4. -4. -4. -4.]
[-3. -3. -3. -3. -3. -3. -3. -3. -3. -3. -3. -3. -3. -3. -3.]
[-2. -2. -2. -2. -2. -2. -2. -2. -2. -2. -2. -2. -2. -2. -2.]
[-1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]
[ 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.]
[ 4. 4. 4. 4. 4. 4. 4. 4. 4. 4. 4. 4. 4. 4. 4.]
[ 5. 5. 5. 5. 5. 5. 5. 5. 5. 5. 5. 5. 5. 5. 5.]
[ 6. 6. 6. 6. 6. 6. 6. 6. 6. 6. 6. 6. 6. 6. 6.]
[ 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.]]
具体的输出结果前两个为-7:7的15个元素的一维数组,通过meshgrid函数进行了维度的扩展,y和x都变成了15*15的二维数组。实际上y和x的坐标是一一对应上的,可以通过plot函数进行展示,即对应位置的y和x组成一个坐标的对应点。
我们也可以通过如下求距离的公式进行求解,
dist = np.sqrt(x**2 + y**2) #每个点的距离
mask=np.zeros((15,15))
#print(mask)
mask[dist <= 2] = 1
print(mask)
print(dist)
具体输出如下:
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
[[9.899495 9.219544 8.602325 8.062258 7.615773 7.28011 7.071068
7. 7.071068 7.28011 7.615773 8.062258 8.602325 9.219544
9.899495 ]
[9.219544 8.485281 7.81025 7.2111025 6.708204 6.3245554 6.0827627
6. 6.0827627 6.3245554 6.708204 7.2111025 7.81025 8.485281
9.219544 ]
[8.602325 7.81025 7.071068 6.4031243 5.8309517 5.3851647 5.0990195
5. 5.0990195 5.3851647 5.8309517 6.4031243 7.071068 7.81025
8.602325 ]
[8.062258 7.2111025 6.4031243 5.656854 5. 4.472136 4.1231055
4. 4.1231055 4.472136 5. 5.656854 6.4031243 7.2111025
8.062258 ]
[7.615773 6.708204 5.8309517 5. 4.2426405 3.6055512 3.1622777
3. 3.1622777 3.6055512 4.2426405 5. 5.8309517 6.708204
7.615773 ]
[7.28011 6.3245554 5.3851647 4.472136 3.6055512 2.828427 2.236068
2. 2.236068 2.828427 3.6055512 4.472136 5.3851647 6.3245554
7.28011 ]
[7.071068 6.0827627 5.0990195 4.1231055 3.1622777 2.236068 1.4142135
1. 1.4142135 2.236068 3.1622777 4.1231055 5.0990195 6.0827627
7.071068 ]
[7. 6. 5. 4. 3. 2. 1.
0. 1. 2. 3. 4. 5. 6.
7. ]
[7.071068 6.0827627 5.0990195 4.1231055 3.1622777 2.236068 1.4142135
1. 1.4142135 2.236068 3.1622777 4.1231055 5.0990195 6.0827627
7.071068 ]
[7.28011 6.3245554 5.3851647 4.472136 3.6055512 2.828427 2.236068
2. 2.236068 2.828427 3.6055512 4.472136 5.3851647 6.3245554
7.28011 ]
[7.615773 6.708204 5.8309517 5. 4.2426405 3.6055512 3.1622777
3. 3.1622777 3.6055512 4.2426405 5. 5.8309517 6.708204
7.615773 ]
[8.062258 7.2111025 6.4031243 5.656854 5. 4.472136 4.1231055
4. 4.1231055 4.472136 5. 5.656854 6.4031243 7.2111025
8.062258 ]
[8.602325 7.81025 7.071068 6.4031243 5.8309517 5.3851647 5.0990195
5. 5.0990195 5.3851647 5.8309517 6.4031243 7.071068 7.81025
8.602325 ]
[9.219544 8.485281 7.81025 7.2111025 6.708204 6.3245554 6.0827627
6. 6.0827627 6.3245554 6.708204 7.2111025 7.81025 8.485281
9.219544 ]
[9.899495 9.219544 8.602325 8.062258 7.615773 7.28011 7.071068
7. 7.071068 7.28011 7.615773 8.062258 8.602325 9.219544
9.899495 ]]
mask是一个15*15的二维矩阵,dist是一个15*15的二维矩阵,每个点的信息表示点的距离信息。
之后通过np.newaxis对二维矩阵进行维度增加处理,并通过repeat函数对内部进行数据的扩展,通俗的理解为二维数据进行维度扩展后变成三维数据,但是三维数据内部只有一个二维的数据,可以通过维度扩展,扩展多个二维的数据元素,通过以下代码显示:
mask = mask[np.newaxis, :, :]
print(mask)
mask=np.repeat(mask, 8, axis=0) #在第0维重复8次,表示8个二维矩阵
print(mask)
mask:
[[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]]
repeat8次之后显示为:
[[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]]
[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
共8个15*15的二维元素的三维数据
在进行一次np.newaxis维度扩展,扩展为一个四维的数据,具体代码如下:
mask = mask[:, np.newaxis, :, :] #在增加一维数据 8个三维数据,三维数据内只有1个15*15的二维数据
print(mask.astype(np.float32))
print('====================================')
print(mask.shape)
在第二个维度进行维度扩展,相当于之前的8个15*15的二维元素变成的8个1*15*15的三维元素,即外部是一个四维的数据,内部包含了8个1*15*15的三维数据,每个三维数据内部是一个15*15的二维数据,具体显示结果如下:
[[[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]]]
[[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
共8个1*15*15三维数据的四维数据
====================================
(8, 1, 15, 15)
通过shape函数显示具体的维度信息。虽然很抽象,但是可以一步步进行数据输出理解。要想做好深度学习cv这一行,数据的抽象化理解很重要,一定要自己手动去实现去思考理解。