-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Numpy convolutional #2
Comments
I came up with a solution correlateimport numpy as np
from numpy.fft import fft2, ifft2
def _correlate2D(array, kernel):
a = array
f = kernel
s = f.shape + tuple(np.subtract(a.shape, f.shape) + 1)
strd = np.lib.stride_tricks.as_strided
subM = strd(a, shape=s, strides=a.strides * 2)
return np.einsum("ij,ijkl->kl", f, subM) convolvedef _convolve2D(array, kernel):
a = array
f = np.flip(kernel)
s = f.shape + tuple(np.subtract(a.shape, f.shape) + 1)
strd = np.lib.stride_tricks.as_strided
subM = strd(a, shape=s, strides=a.strides * 2)
return np.einsum("ij,ijkl->kl", f, subM) active usedef correlate2d(array: np.array, kernel: np.array, mode="full"):
modes = ["full", "valid"]
keyFlag = mode in modes
if not keyFlag:
raise KeyError("mode is either full or valid!.\n other than that can't do.")
if mode == "valid":
return _correlate2D(array, kernel)
return _correlate2D(np.pad(array, 1), kernel)
def convolve2d(array: np.array, kernel: np.array, mode="full"):
modes = ["full", "valid"]
keyFlag = mode in modes
if not keyFlag:
raise KeyError("mode is either full or valid!.\n other than that can't do.")
if mode == "valid":
return _convolve2D(array, kernel)
return _convolve2D(np.pad(array, 1), kernel) then it can be used like this:class Convolutional(Layer):
def __init__(self, input_shape, kernel_size, depth):
input_depth, input_height, input_width = input_shape
self.depth = depth
self.input_shape = input_shape
self.input_depth = input_depth
self.output_shape = (depth, input_height - kernel_size + 1, input_width - kernel_size + 1)
self.kernels_shape = (depth, input_depth, kernel_size, kernel_size)
self.kernels = np.random.randn(*self.kernels_shape)
self.biases = np.random.randn(*self.output_shape)
def forward(self, input):
self.input = input
self.output = np.copy(self.biases)
for i in range(self.depth):
for j in range(self.input_depth):
self.output[i] += correlate2d(self.input[j], self.kernels[i, j], "valid")
return self.output
def backward(self, output_gradient, learning_rate):
kernels_gradient = np.zeros(self.kernels_shape)
input_gradient = np.zeros(self.input_shape)
for i in range(self.depth):
for j in range(self.input_depth):
kernels_gradient[i, j] = correlate2d(self.input[j], output_gradient[i], "valid")
input_gradient[j] += convolve2d(output_gradient[i], self.kernels[i, j], "full")
self.kernels -= learning_rate * kernels_gradient
self.biases -= learning_rate * output_gradient
return input_gradient I'm not sure if it really works well |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
First I have to say thanks for your tutorials on neural networks, now I understand the topic better
But there was a thing that I couldn't let pass through
In the conv layer you used a functionality from scipy, But scipy doesn't work in my device for some reasons
And I need a way to implement these functions using numpy, but I don't understand the math behind that
Nor do I find some mathematical formula that tells me how to 2d convolve or correlate and I can't come up with working solution
that's why I'm here I need a way to implement conv layer in numpy only
The text was updated successfully, but these errors were encountered: