im2col解析3
前面实现了图像转列向量,在之前推导过程中使用的是行向量,所以修改im2col.py
,实现im2row
的功能
卷积核大小为\(2\times 2\),步长为1
,零填充为0
- field_height = 2
- field_width = 2
- stride = 1
- padding = 0
2
维图像大小为\(3\times 3\),3维图像大小为\(2\times 3\times 3\),4维图像大小为\(2\times 2\times 3\times 3\)
所以输出数据体的空间尺寸为\(2\times 2\),深度为2
,数量为2
- out_height = 2
- out_width = 2
- depth = 2
- N = 2
图像转行向量
2维图像
1 | >>> a = np.arange(9).reshape(3,3) |
行坐标矩阵
对于行坐标矩阵而言,每一行表示一个局部连接矩阵
局部连接矩阵中同一行的行坐标相等,相邻行的行坐标加1
1 | # i1 = np.repeat(np.arange(field_height), field_width) |
行坐标矩阵的列数表示局部连接的个数
图像中同一行局部连接的行坐标相等,相邻行之间的局部连接行坐标相差stride
1 | # i0 = stride * np.repeat(np.arange(out_height), out_width) |
计算行坐标矩阵
1 | # i = i0.reshape(-1, 1) + i1.reshape(1, -1) |
列坐标矩阵
对于列坐标矩阵而言,每一行表示一个局部连接矩阵
局部连接矩阵中同一列的列坐标相等,相邻列的列坐标加1
1 | # j1 = np.tile(np.arange(field_width), field_height) |
列坐标矩阵的列数表示局部连接的个数
图像中同一行的相邻局部连接相差stride
距离,同一列的局部连接距离该行最左端的距离相等
1 | # j0 = stride * np.tile(np.arange(out_width), out_height) |
计算列坐标矩阵
1 | # j = j0.reshape(-1, 1) + j1.reshape(1, -1) |
行向量
1 | >>> a[i,j] |
3维图像
1 | >>> a = np.arange(18).reshape(2,3,3) |
行坐标矩阵
多通道图像仅改变单个局部连接矩阵大小,不改变数量
并且单个局部连接在每个通道的行坐标相同
1 | # i1 = np.repeat(np.arange(field_height), field_width) |
计算行坐标矩阵
1 | >>> i0 = 1 * np.repeat(np.arange(2), 2) |
列坐标矩阵
多通道图像仅改变单个局部连接矩阵大小,不改变数量
并且单个局部连接在每个通道的列坐标相同
1 | # j1 = np.tile(np.arange(field_width), field_height * C) |
计算列坐标矩阵
1 | >>> j0 = 1 * np.tile(np.arange(2), 2) |
通道向量
需要指定哪个通道图像进行数据提取
1 | # k = np.repeat(np.arange(C), field_width * field_height).reshape(-1, 1) |
行向量
1 | >>> a[k,i,j] |
4维图像
1 | >>> a = np.arange(36).reshape(2,2,3,3) |
对于批量图像进行行向量转换
1 | >>> rows = a[:,k,i,j] |
还需要进一步变形
1 | >>> rows.shape |
最终实现结果的采样方式:逐图像按照从左到右、从上到下的顺序采集局部连接矩阵
如果要实现逐坐标的采集局部连接矩阵,需要先进行维数转换,再完成变形
1 | >>> rows = np.transpose(rows, (1,0,2)) |
行向量转图像
2维图像
已知图像大小,行/列坐标矩阵和行向量矩阵,用numpy.add.at
就能完成映射
1 | >>> b = np.zeros(a.shape) |
计算叠加倍数,得到原始图像
1 | c = np.ones(a.shape) |
1 | >>> b/d |
3维图像
已知图像大小,行/列坐标矩阵、深度向量和行向量矩阵,用numpy.add.at
就能完成映射
1 | >>> b = np.zeros(a.shape) |
计算叠加倍数,得到原始图像
1 | >>> c = np.ones(a.shape) |
1 | >>> b/d |
4维图像
已知图像大小,行/列坐标矩阵、深度向量和行向量矩阵,用numpy.add.at
就能完成映射
1 | >>> rows |
计算叠加倍数,得到原始图像
1 | >>> c = np.ones(a.shape) |
1 | >>> b/d |
im2row
仿照im2col.py
,im2row
实现如下:
1 | # -*- coding: utf-8 -*- |
修改如下:
- 实现图像转行向量
- 实现逐图像的行向量转换(
im2cols.py
实现的是逐坐标的列向量转换) - 添加行向量转换回原图功能(符号位
isstinct
)
卷积层和全连接层相互转换
批量图像数据大小为\(2\times 3\times 4\times 4\),卷积核大小为\(3\times 3\),步长为\(1\),零填充为0
单个局部连接矩阵大小为\(3\times 3\times 3=27\),共有8个
行向量矩阵大小为\(8\times 27\)
1 | x = np.arange(96).reshape(2, 3, 4, 4) |
1 | [[ 0 1 2 4 5 6 8 9 10 16 17 18 20 21 22 24 25 26 32 33 34 36 37 38 |