In [6]:
import sklearn.datasets
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
%matplotlib inline
In [1]:
def output_volume_size(input_shape, f, p, s):
return ((input_shape[0]-f+2*p)/s+1, (input_shape[1]-f+2*p)/s+1)
In [2]:
output_volume_size(x.shape, f, p, s)
In [ ]:
np.tile(np.pad(np.array([[1, 2], [3, 4]]), ((p, p)), mode='constant'), (2, 2))
In [ ]:
def get_im2col_indices(x_shape, field_height, field_width, padding=1, stride=1):
# First figure out what the size of the output should be
N, C, H, W = x_shape
assert (H + 2 * padding - field_height) % stride == 0
assert (W + 2 * padding - field_height) % stride == 0
out_height = (H + 2 * padding - field_height) / stride + 1
out_width = (W + 2 * padding - field_width) / stride + 1
i0 = np.repeat(np.arange(field_height), field_width)
i0 = np.tile(i0, C)
i1 = stride * np.repeat(np.arange(out_height), out_width)
j0 = np.tile(np.arange(field_width), field_height * C)
j1 = stride * np.tile(np.arange(out_width), out_height)
i = i0.reshape(-1, 1) + i1.reshape(1, -1)
j = j0.reshape(-1, 1) + j1.reshape(1, -1)
k = np.repeat(np.arange(C), field_height * field_width).reshape(-1, 1)
return (k, i, j)
def im2col_indices(x, field_height, field_width, padding=1, stride=1):
""" An implementation of im2col based on some fancy indexing """
# Zero-pad the input
p = padding
x_padded = np.pad(x, ((0, 0), (0, 0), (p, p), (p, p)), mode='constant')
k, i, j = get_im2col_indices(x.shape, field_height, field_width, padding,
stride)
cols = x_padded[:, k, i, j]
C = x.shape[1]
cols = cols.transpose(1, 2, 0).reshape(field_height * field_width * C, -1)
return cols
In [ ]:
p = 1
x_toy = np.array(
[
[
[
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
],
[
[-1, -3, -4],
[-3, -2, -7],
[-6, -7, -1]
]
],
[
[
[10, 10, 20],
[30, 40, 50],
[60, 70, 80]
],
[
[-10, -30, -40],
[-30, -20, -70],
[-60, -70, -10]
]
]
])
In [ ]:
x_toy_padded = np.pad(x_toy, ((0, 0), (0, 0), (p, p), (p, p)), mode='constant')
In [3]:
f = 3
w = 3
h = 3
p = 1
s = 2
c = 2
output_width = (w - f + 2*p)/s + 1
output_height = (h - f + 2*p)/s + 1
output_width, output_height
Out[3]:
In [4]:
def im2col(x, receptive_field_size, stride=1, padding=1):
# input width
w = x.shape[2]
# input height
h = x.shape[3]
# number of samples
n = x.shape[0]
# depth
c = x.shape[1]
f = receptive_field_size
p = padding
s = stride
output_width = (w - f + 2*p)/s + 1
output_height = (h - f + 2*p)/s + 1
x_padded = np.pad(x, ((0, 0), (0, 0), (p, p), (p, p)), mode='constant')
io = np.repeat(s*np.arange(output_height, dtype=np.int32), output_height*f*f*c)
ko = np.tile(np.repeat(s*np.arange(output_width, dtype=np.int32), f*f*c), output_width)
i = np.tile(np.tile(np.repeat(np.arange(f, dtype=np.int32), f), c), output_height*output_width)
k = np.tile(np.tile(np.tile(np.arange(f, dtype=np.int32), f), output_height*output_width), c)
j = np.tile(np.repeat(np.arange(c, dtype=np.int32), f*f), output_height*c)
x_col = x_padded[:, j, i + io, k + ko].reshape(n, output_height*output_width, -1)
return x_col
In [7]:
io = np.repeat(s*np.arange(output_height, dtype=np.int32), output_height*f*f*c)
io
Out[7]:
In [8]:
ko = np.tile(np.repeat(s*np.arange(output_width, dtype=np.int32), f*f*c), output_width)
ko
Out[8]:
In [9]:
i, k
In [10]:
j = np.tile(np.repeat(np.arange(c, dtype=np.int32), f*f), output_height*c)
j
Out[10]:
In [11]:
i = np.tile(np.tile(np.repeat(np.arange(f, dtype=np.int32), f), c), output_height*output_width)
k = np.tile(np.tile(np.tile(np.arange(f, dtype=np.int32), f), output_height*output_width), c)
x_toy_padded[:, j, i + io, k + ko].reshape(2, output_height*output_width, -1)
In [ ]:
x_toy_padded[:, :, [0, 0, 1, 1], [0, 0, 3, 3]]
In [ ]:
x_toy_padded
In [ ]:
w0 = np.array([
[-1, 0, 1, 2, 5, 8, 0, 1, 0, -1, 0, 1, 2, 5, 8, 0, 1, 0],
[0, -1, 0, -1, -1, 1, 1, 0, -1, 0, 1, 2, 5, 8, 0, 1, 0, 2],
[2, 3, 4, 3, 4, 2, 1, 0, -1, 0, 1, 2, 5, 8, 0, 1, 0, -1]
])
In [ ]:
x_col = im2col(x_toy, receptive_field_size=3, stride=2, padding=1)
In [ ]:
x_col.transpose(2, 1, 0).shape
In [ ]:
x_col = im2col(x_toy, receptive_field_size=3, stride=2, padding=1)
np.dot(w0, x_col.transpose(2, 1, 0).reshape(x_col.shape[2], -1)).reshape(x_col.shape[0], 3, 2, 2)
In [ ]:
np.dot(w0, x_col.transpose(0, 2, 1))
In [ ]:
from scipy.signal import convolve2d, convolve
In [ ]:
convolve(x_toy, w0, mode='full')
In [ ]:
w0.ravel()
In [ ]:
w0.reshape(2, 9)
In [ ]:
x_toy_padded[:, :, [0, 0, 0, 1, 1, 1, 2, 2, 2], [0, 1, 2, 0, 1, 2, 0, 1, 2]].transpose(1, 2, 0).shape
In [ ]:
f = 3
p = 1
s = 1
np.sum(np.dot(w0.reshape(2, 9), x_toy_padded[:, :, [0, 0, 0, 1, 1, 1, 2, 2, 2], [0, 1, 2, 0, 1, 2, 0, 1, 2]].transpose(1, 2, 0)), axis=0)
In [13]:
x_test = x_test[np.newaxis, :, :, :]
In [14]:
w_test = np.array([
[1, -1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, -1, 0, 0, 0, -1, 1, 1, -1, 1, 0, 0, 0],
[1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 0, -1, -1, 0, 0, 1, 1, 0, 1, -1, -1, 0]
])
In [15]:
x_col = im2col(x_test, receptive_field_size=3, stride=2, padding=1)
x_col.shape
Out[15]:
In [ ]:
product = np.dot(w_test, x_col.transpose(2, 1, 0).reshape(x_col.shape[2], -1)) + np.array([1, 0])[:, np.newaxis]
product = product.reshape(x_col.shape[0], 2, 3, 3)
product[0, 0, :, :]
In [ ]:
x2 = np.array([[1, 2], [3, 4]])
#np.add.at(x2, ([0, 0, 1, 1], [0, 1, 0, 1]), 1)
x2[[0, 0, 1, 1], :]
In [29]:
x_test
Out[29]:
In [57]:
x_test = np.array([
[
[1, 2, 0, 2, 2],
[1, 2, 1, 2, 2],
[1, 0, 2, 0, 0],
[1, 0, 1, 1, 0],
[1, 2, 0, 1, 1]
],
[
[1, 0, 2, 2, 2],
[1, 1, 1, 2, 2],
[0, 1, 1, 2, 2],
[2, 0, 0, 0, 2],
[0, 2, 0, 2, 0]
],
[
[2, 0, 2, 1, 1],
[0, 1, 0, 2, 0],
[0, 0, 0, 2, 1],
[2, 0, 1, 1, 1],
[0, 1, 0, 0, 1]
]
])
x_test_tmp = x_test[np.newaxis, :, :, :]
np.add.at(x_test_tmp, (slice(None), j, i, k), 1)
x_test_tmp
#x_test_tmp[(slice(None), j, i, k)]
Out[57]:
In [18]:
xt2 = np.array([
[
[1, 2, 3],
[4, 5, 6]
],
[
[7, 8, 9],
[10, 11, 12]
]
])
In [20]:
xt2.shape
Out[20]:
In [22]:
xt2.reshape(1, 4, -1).reshape(2, 2, 3)
Out[22]: