一些问题
是 2019-04-03 看书时写下的
关于展开为二维数组后转置规律的探究(p208-p221)
对输入数据展开后,其维度情况是$(行数=数据个数\times 单个数据卷积次数, 列数=输入通道数\times 卷积核的宽\times 卷积核的高)$
若把输入数据维度情况记为$(N, C, H, W)$,卷积核维度情况记为$(FN, C, FH, FW)$,输出数据维度情况记为$(ON, OC, OH, OW)$,则有以下关系:
$N$个输入数据展开的二维数组形状为$(N\times OH\times OW, C\times FH\times FW)$
其中,行数中$(OW\times OH)$为单个输出数据的维度情况,亦即对单个输入数据需要卷积的次数;而$N$则是输入数据的个数,也是输出数据的个数。完整的行数表示只有一个卷积核时,$N$个输入数据对应的输出元素个数。
列数中,$C$为输入数据的通道数;而$(FH\times FW)$则代表卷积核的维度情况,其值是卷积核的元素个数。完整的列数表示对具有$C$个输入通道的输入图像,一次卷积运算需要运算的区域对应的输入元素个数。$FN$个卷积核展开的二维数组形状为$(C\times FH\times FW, FN)$
其中,行数$(C\times FH\times FW)$的解释如上的列数。
列数$FN$则为卷积核的个数,也就是输出数据的通道数。按照数组的排列规则,其排列顺序是优先排最低维度。比如对二维数组(5, 3),其排完一行的元素个数为 3 ,排完一行再排第二行,也就是说,离首元素最近的元素首先是第一行的其他元素,而不是下一行的首元素。在reshape的时候必须要考虑到元素的顺序问题。
数组维度规律是越靠前维度越高,新增的更高维因此也必须加在数组维度的最左边。比如从$Width$维度开始,增加了一个$Height$维度,则数组变为$(Height, Width)$,再增加一个通道维度$Channel$,则数组维度变为$(Channel, Height, Width)$,以此类推。输出数据在进行
reshape
操作前,维度情况是$(行数=数据个数\times 单个数据卷积次数, 列数=卷积核个数=输出通道数)$输出数据的维度情况用字母表达则为$(N\times OH\times OW, FN)$
对应为最终需要的输出,可以表示为$(ON\times OH\times OW, OC)$,经过reshape
调整之后维度情况为$(ON, OH, OW, OC)$而需要的输出是$(ON, OC, OH, OW)$,以便作为下一次的输入。
所以对reshape
的结果,还需要通过transpose
更改轴的顺序,把原先的(0,1,2,3)转换为(0,3,1,2)
突然想到一个类比:数组的高维、低维就像数制中的高位、低位一样,数先在低位排,排满一个低位之后,则向高位进1,然后继续排列下一个高位的一系列低位。并且数制的进位也是让高位在左,低位在右。十分有趣。数制也可以理解为维度的一种特殊形式,其各维具有相同的元素个数。数组的高维和低维之间也存在一种类似的“进位”关系。
关于“为什么二维数组的第0轴是列方向”
从上面的分析可以看出来,多维数组对轴的编号是从左往右的,也就是说,对二维数组(y, x)来说,x方向是第0轴,y方向是第1轴;对三维数组(z, y, x)来说,第0轴则是z轴,第1轴是y轴,第2轴是x轴。
图书链接
《深度学习入门:基于Python的理论与实现》(图灵社区)