Python 是否有可能延长;im2col";及;col2im“;到N-D图像?
“Im2col”已经在Python中高效地实现了二维图像。我想知道是否有可能将其扩展到任意N-D图像?许多应用程序都涉及高维数据(例如卷积、过滤、最大池等)。因此,这个问题的目的实际上只是公开发布我对这个问题的解决方案。我似乎在谷歌上找不到这样的解决方案,所以我决定自己尝试一下。事实证明,从我的问题中提到的帖子中的“方法2”扩展,实现实际上非常简单 有效实施N-D“im2col” 高效实施N-D“col2im” 验证它是否有效 让我们定义一个任意的三维输入:Python 是否有可能延长;im2col";及;col2im“;到N-D图像?,python,keras,convolution,max-pooling,Python,Keras,Convolution,Max Pooling,“Im2col”已经在Python中高效地实现了二维图像。我想知道是否有可能将其扩展到任意N-D图像?许多应用程序都涉及高维数据(例如卷积、过滤、最大池等)。因此,这个问题的目的实际上只是公开发布我对这个问题的解决方案。我似乎在谷歌上找不到这样的解决方案,所以我决定自己尝试一下。事实证明,从我的问题中提到的帖子中的“方法2”扩展,实现实际上非常简单 有效实施N-D“im2col” 高效实施N-D“col2im” 验证它是否有效 让我们定义一个任意的三维输入: x = np.arange(216)
x = np.arange(216).reshape(6, 6, 6)
print(x)
[[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[ 12 13 14 15 16 17]
[ 18 19 20 21 22 23]
[ 24 25 26 27 28 29]
[ 30 31 32 33 34 35]]
[[ 36 37 38 39 40 41]
[ 42 43 44 45 46 47]
[ 48 49 50 51 52 53]
[ 54 55 56 57 58 59]
[ 60 61 62 63 64 65]
[ 66 67 68 69 70 71]]
[[ 72 73 74 75 76 77]
[ 78 79 80 81 82 83]
[ 84 85 86 87 88 89]
[ 90 91 92 93 94 95]
[ 96 97 98 99 100 101]
[102 103 104 105 106 107]]
[[108 109 110 111 112 113]
[114 115 116 117 118 119]
[120 121 122 123 124 125]
[126 127 128 129 130 131]
[132 133 134 135 136 137]
[138 139 140 141 142 143]]
[[144 145 146 147 148 149]
[150 151 152 153 154 155]
[156 157 158 159 160 161]
[162 163 164 165 166 167]
[168 169 170 171 172 173]
[174 175 176 177 178 179]]
[[180 181 182 183 184 185]
[186 187 188 189 190 191]
[192 193 194 195 196 197]
[198 199 200 201 202 203]
[204 205 206 207 208 209]
[210 211 212 213 214 215]]]
让我们使用非均匀窗口和相等步幅提取所有面片:
y = im2col(x, [1, 3, 2], strides = [1, 3, 2])
print(y.T) # transposed for ease of visualization
[[ 0 1 6 7 12 13]
[ 2 3 8 9 14 15]
[ 4 5 10 11 16 17]
[ 18 19 24 25 30 31]
[ 20 21 26 27 32 33]
[ 22 23 28 29 34 35]
[ 36 37 42 43 48 49]
[ 38 39 44 45 50 51]
[ 40 41 46 47 52 53]
[ 54 55 60 61 66 67]
[ 56 57 62 63 68 69]
[ 58 59 64 65 70 71]
[ 72 73 78 79 84 85]
[ 74 75 80 81 86 87]
[ 76 77 82 83 88 89]
[ 90 91 96 97 102 103]
[ 92 93 98 99 104 105]
[ 94 95 100 101 106 107]
[108 109 114 115 120 121]
[110 111 116 117 122 123]
[112 113 118 119 124 125]
[126 127 132 133 138 139]
[128 129 134 135 140 141]
[130 131 136 137 142 143]
[144 145 150 151 156 157]
[146 147 152 153 158 159]
[148 149 154 155 160 161]
[162 163 168 169 174 175]
[164 165 170 171 176 177]
[166 167 172 173 178 179]
[180 181 186 187 192 193]
[182 183 188 189 194 195]
[184 185 190 191 196 197]
[198 199 204 205 210 211]
[200 201 206 207 212 213]
[202 203 208 209 214 215]]
让我们将其转换回(下采样)图像:
如您所见,最终输出确实是我们期望的下采样图像(您可以通过逐个值轻松检查)。我选择的维度和步幅纯粹是说明性的。没有理由说窗口大小必须与步幅相同,或者不能超过3维
应用程序
如果你想实际使用它,你所要做的就是截取im2col的输出,然后再将其转换回图像。例如,如果要进行池化,可以在第0个轴上取平均值或最大值。如果你想做卷积运算,你只需要把它乘以平坦的卷积滤波器
在Tensorflow等软件的保护下,可能会有比“im2col”更快的更有效的替代方案。这并不是最有效的实现。当然,您可以通过消除“im2col”中的中间重塑步骤来进一步优化我的代码,但这对我来说不是很明显,所以我就不说了。如果你有更好的解决方案,请告诉我。无论如何,希望这能帮助其他人寻找同样的答案 所以这个问题的目的实际上只是公开发布我对这个问题的解决方案。我似乎在谷歌上找不到这样的解决方案,所以我决定自己尝试一下。事实证明,从我的问题中提到的帖子中的“方法2”扩展,实现实际上非常简单 有效实施N-D“im2col” 高效实施N-D“col2im” 验证它是否有效 让我们定义一个任意的三维输入:
x = np.arange(216).reshape(6, 6, 6)
print(x)
[[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[ 12 13 14 15 16 17]
[ 18 19 20 21 22 23]
[ 24 25 26 27 28 29]
[ 30 31 32 33 34 35]]
[[ 36 37 38 39 40 41]
[ 42 43 44 45 46 47]
[ 48 49 50 51 52 53]
[ 54 55 56 57 58 59]
[ 60 61 62 63 64 65]
[ 66 67 68 69 70 71]]
[[ 72 73 74 75 76 77]
[ 78 79 80 81 82 83]
[ 84 85 86 87 88 89]
[ 90 91 92 93 94 95]
[ 96 97 98 99 100 101]
[102 103 104 105 106 107]]
[[108 109 110 111 112 113]
[114 115 116 117 118 119]
[120 121 122 123 124 125]
[126 127 128 129 130 131]
[132 133 134 135 136 137]
[138 139 140 141 142 143]]
[[144 145 146 147 148 149]
[150 151 152 153 154 155]
[156 157 158 159 160 161]
[162 163 164 165 166 167]
[168 169 170 171 172 173]
[174 175 176 177 178 179]]
[[180 181 182 183 184 185]
[186 187 188 189 190 191]
[192 193 194 195 196 197]
[198 199 200 201 202 203]
[204 205 206 207 208 209]
[210 211 212 213 214 215]]]
让我们使用非均匀窗口和相等步幅提取所有面片:
y = im2col(x, [1, 3, 2], strides = [1, 3, 2])
print(y.T) # transposed for ease of visualization
[[ 0 1 6 7 12 13]
[ 2 3 8 9 14 15]
[ 4 5 10 11 16 17]
[ 18 19 24 25 30 31]
[ 20 21 26 27 32 33]
[ 22 23 28 29 34 35]
[ 36 37 42 43 48 49]
[ 38 39 44 45 50 51]
[ 40 41 46 47 52 53]
[ 54 55 60 61 66 67]
[ 56 57 62 63 68 69]
[ 58 59 64 65 70 71]
[ 72 73 78 79 84 85]
[ 74 75 80 81 86 87]
[ 76 77 82 83 88 89]
[ 90 91 96 97 102 103]
[ 92 93 98 99 104 105]
[ 94 95 100 101 106 107]
[108 109 114 115 120 121]
[110 111 116 117 122 123]
[112 113 118 119 124 125]
[126 127 132 133 138 139]
[128 129 134 135 140 141]
[130 131 136 137 142 143]
[144 145 150 151 156 157]
[146 147 152 153 158 159]
[148 149 154 155 160 161]
[162 163 168 169 174 175]
[164 165 170 171 176 177]
[166 167 172 173 178 179]
[180 181 186 187 192 193]
[182 183 188 189 194 195]
[184 185 190 191 196 197]
[198 199 204 205 210 211]
[200 201 206 207 212 213]
[202 203 208 209 214 215]]
让我们将其转换回(下采样)图像:
如您所见,最终输出确实是我们期望的下采样图像(您可以通过逐个值轻松检查)。我选择的维度和步幅纯粹是说明性的。没有理由说窗口大小必须与步幅相同,或者不能超过3维
应用程序
如果你想实际使用它,你所要做的就是截取im2col的输出,然后再将其转换回图像。例如,如果要进行池化,可以在第0个轴上取平均值或最大值。如果你想做卷积运算,你只需要把它乘以平坦的卷积滤波器
在Tensorflow等软件的保护下,可能会有比“im2col”更快的更有效的替代方案。这并不是最有效的实现。当然,您可以通过消除“im2col”中的中间重塑步骤来进一步优化我的代码,但这对我来说不是很明显,所以我就不说了。如果你有更好的解决方案,请告诉我。无论如何,希望这能帮助其他人寻找同样的答案
z = col2im(y, x.shape, [1, 3, 2], strides = [1, 3, 2])
print(z)
[[[ 0 2 4]
[ 18 20 22]]
[[ 36 38 40]
[ 54 56 58]]
[[ 72 74 76]
[ 90 92 94]]
[[108 110 112]
[126 128 130]]
[[144 146 148]
[162 164 166]]
[[180 182 184]
[198 200 202]]]