Skip to content

Instantly share code, notes, and snippets.

@aiwithshekhar
Created March 6, 2020 19:36
Show Gist options
  • Save aiwithshekhar/dbae0dd5f7988c0b337b608544f53252 to your computer and use it in GitHub Desktop.
Save aiwithshekhar/dbae0dd5f7988c0b337b608544f53252 to your computer and use it in GitHub Desktop.
class Convolution(Conv_Module):
def forward(self, img, ker):
self.out_h= int((self.img_h-self.ker_h)+(2*self.pad)/self.stride) +1 #output height with same padding(10).
self.out_w= int((self.img_w-self.ker_w)+(2*self.pad)/self.stride) +1 #output width with same padding(10).
pad_img=np.pad(img, ((0,0),(0,0),(1,1),(1,1)),mode='constant') #pad the input images with zeros around
i0=np.repeat(np.arange(self.ker_h), self.ker_h)
i1=np.repeat(np.arange(self.img_h), self.img_h)
j0=np.tile(np.arange(self.ker_w), self.ker_h)
j1=np.tile(np.arange(self.img_h), self.img_w)
self.i=i0.reshape(-1,1)+i1.reshape(1,-1)
self.j=j0.reshape(-1,1)+j1.reshape(1,-1)
self.k=np.repeat(np.arange(self.img_d), self.ker_h*self.ker_w).reshape(-1,1)
self.select_img=pad_img[:,:,self.i,self.j].squeeze() #receptive feild pixels are selected based on the index***[1,9,100] reshaped to [9,100]
weights=ker.reshape(self.ker_h*self.ker_w, -1) # weights reshaped to [9,1]
convolve=weights.transpose()@self.select_img # convolution operation [1,9]*[9,100] ----> [1,100]
convolve=convolve.reshape(1,1,10,10) # reshaped in image dimension [1,1,10,10]
return convolve
def bwd(self, out):
out_h= self.img_h + 2 * self.pad #output height with padding(12)
out_w= self.img_w + 2 * self.pad #output width with padding(12)
db=np.sum(out, axis=(0,2,3)) #bias gradient calculation
db=db.reshape(self.ker_b, -1)
out_reshape=out.squeeze().reshape(self.ker_b, -1) #[1,100]
dw=out_reshape @ self.select_img.T #[1,100] * [100,9]---->[1,9]
dw=dw.reshape(ker.shape) #weight gradient caculation
ker_reshape=self.ker.reshape(self.ker_b, -1)
X= ker_reshape.T @ out_reshape # gradient calculation w.r.t input image
#[9,1]*[1,100]----->[9,100]
padded=np.zeros((self.img_b, self.img_d, out_h, out_w), dtype=X.dtype) #empty padded array
X_reshaped=X.reshape(self.ker_h*self.ker_w, -1, self.ker_b) #[9,100,1]
X_reshaped=X_reshaped.transpose(2,0,1) #reshapin [1,9,100]
np.add.at(padded, (slice(None), self.k, self.i, self.j), X_reshaped) #gradient are stored in the corresponding locations
dX=padded[:,:,self.pad:-self.pad, self.pad:-self.pad] #input image gradient
return dX, dw, db
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment