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)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-7ae41bfa1f8b> in <module>()
----> 1 output_volume_size(x.shape, f, p, s)

NameError: name 'x' is not defined

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]:
(2.0, 2.0)

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]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2])

In [8]:
ko = np.tile(np.repeat(s*np.arange(output_width, dtype=np.int32), f*f*c), output_width)
ko


Out[8]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2])

In [9]:
i, k


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-9-ee3e62a9a9a1> in <module>()
----> 1 i, k

NameError: name 'i' is not defined

In [10]:
j = np.tile(np.repeat(np.arange(c, dtype=np.int32), f*f), output_height*c)
j


Out[10]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
       1, 1, 1])

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)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-11-14b287a0668f> in <module>()
      2 k = np.tile(np.tile(np.tile(np.arange(f, dtype=np.int32), f), output_height*output_width), c)
      3 
----> 4 x_toy_padded[:, j, i + io, k + ko].reshape(2, output_height*output_width, -1)

NameError: name 'x_toy_padded' is not defined

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


C:\Anaconda3\lib\site-packages\ipykernel\__main__.py:27: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
Out[15]:
(1, 9, 27)

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]:
array([[[2, 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]]])

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]:
array([[[[5, 6, 4, 2, 2],
         [5, 6, 5, 2, 2],
         [5, 4, 6, 0, 0],
         [1, 0, 1, 1, 0],
         [1, 2, 0, 1, 1]],

        [[5, 4, 6, 2, 2],
         [5, 5, 5, 2, 2],
         [4, 5, 5, 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]]]])

In [18]:
xt2 = np.array([
        [
            [1, 2, 3],
            [4, 5, 6]
        ],
        [
            [7, 8, 9],
            [10, 11, 12]
        ]
    ])

In [20]:
xt2.shape


Out[20]:
(2, 2, 3)

In [22]:
xt2.reshape(1, 4, -1).reshape(2, 2, 3)


Out[22]:
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])