Python simple Convolution in numpy - python

I have written this simple convolution function in numpy. But the final array values are all still zero.
Please help me correct this function.
def convolve(a_prev, w, b):
pad = 0
stride = 1
s1 = a_prev.shape
s2 = w.shape
f = s2[1]
m = s1[0]
n_c = s2[0]
n_h = int((s1[1] - f + 2 * pad) / stride) + 1
n_w = int((s1[2] - f + 2 * pad) / stride) + 1
a = np.zeros((m,n_h,n_w,n_c), dtype=np.float32)
for n in range(m):
for z in range(n_c):
y = 0
x = 0
while ((y+f) <= n_h):
# Edit: forget to inialize the x = 0
while ((x+f) <= n_w):
#a[n,y,x,z] = np.sum(a_prev[n,y:y+f,x:x+f]*w[z]) + b[z,0]
a[n,y,x,z] = np.sum(np.multiply(a_prev[n,y:y+f,x:x+f],w[z])) + b[z,0]
x += stride
y += stride
print(a[0,85,:,3])
return a
shape of a_prev is [num_exmamples,height, width, 3] and w is [num_filters,3,3,3]
I found the reason, why it was not working, i make a programming error and forget to initialize the x = 0 before while loop.
Its working fine now.
Below is the correct function.
def convolve(a_prev, kernel, b, pad = 0, stride = 1):
m = a_prev.shape[0]
prev_h = a_prev.shape[1]
prev_w = a_prev.shape[2]
f = kernel.shape[1]
n_c = kernel.shape[0]
new_h = int((prev_h - f + 2 * pad) / stride) + 1
new_w = int((prev_w - f + 2 * pad) / stride) + 1
az = np.zeros((m,new_h,new_w,n_c), dtype=np.float32)
for n in range(m):
for z in range(n_c):
y = 0
while (y+f) <= prev_h:
x = 0
while (x+f) <= prev_w:
az[n,y,x,z] = np.sum(a_prev[n,y:y+f,x:x+f]*kernel[z]) + b[z,0]
x += stride
y += stride
return az

There is an easier way to do convolution without using the previous input as a function input.
import numpy as np
def convolution(x, h):
# x and h are numpy arrays
M, N = np.size(x), np.size(h)
y = np.zeros(M+N-1)
# Initialise y with the length of the output signal
for m in np.arange(M):
for n in np.arange(N):
y[m+n] += x[m]*h[n]
return y
This function uses the basic definition of convolution for discrete signals

Related

Setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (6000,)

I'm trying to give fch1 to pywt.cwt for creating coefficients but when I give that this comes with a value error as a question
samplingFreq = 100
dataPeriod = 60 # sec
numSamples = samplingFreq * dataPeriod * 3
print(numSamples)
readDataFromFile = open('input.ecg', 'rb')
datatype = np.dtype('B')
filedata = np.fromfile(readDataFromFile, datatype)
# print(filedata)
p = list(filedata)
ecgarr = np.array(p)
totSamples = len(ecgarr)
numRows = int(totSamples / numSamples)
curateData = [[0] * numSamples for i in range(numRows)]
totEntries = int(numSamples / 3)
fch1 = [[0] * 1 for i in range(totEntries)]
# Divide the total samples in sets of 'numSamples'
xcntr = 0
for x in range(0, totSamples, numSamples):
ycntr = 0
for y in range(x, (x + numSamples), 1):
curateData[xcntr][ycntr] = ecgarr[y]
ycntr = ycntr + 1
xcntr = xcntr + 1
## Convert curateData into a channels
cntr = 0
for x in range(0, numRows, 1):
cntr = 0
for y in range(1, int(numSamples / 3), 1):
#print(y)
fch1[cntr] = curateData[x][3 * (y - 1)]
# Do CWT
coef, freq = pywt.cwt(fch1, np.arange(1, 129), 'morl')
print(coef)
I'm not able to find out why I'm getting the error.
coef, freq = pywt.cwt(fch1, np.arange(1, 129), 'morl')
On the above line of code, I'm getting error.
Any Help would be so appreciable.
Thank you

How can I reshape two different shapes to be able to compute them?

I am trying to get this code to work but I keep getting value errors for shapes. when I tried np.reshape(w,(103,126)) I got another error saying the size was 103 and could not reshape. Any help would be greatly appreciated.
def run_epoch(X,Y,w,b):
print("w",w.shape)
for i in range(len(X)):
print(len(X))
print("X[i] shape",X[i].shape)
print("X[i] shape",X[102].shape)
a = np.sum(np.reshape(w,(126,103)) * X[i]) + b
#a = np.sum(w * X[i]) + b
if(Y[i]*a <= 0):
w = w + Y[i] * X[i]
b = b + Y[i]
#print("a,w,b: ",a, w, b)
return w,b
def perceptron_train(X,Y):
w = np.zeros(X.shape[0])
b = 0.0
temp_w, temp_b = run_epoch(X,Y,w,b)
n_epoch = 1
while( n_epoch <= 50 ):
#print("Epoch: ", n_epoch)
w,b = run_epoch(X,Y,w,b)
n_epoch += 1
return w,b
def perceptron_test(X_test, Y_test, w, b):
a = np.sum(X_test * w, axis = 1) + b
y = np.where(a>0, 1,-1)
acc = (y == Y_test).sum()/len(Y_test)
return acc
I get the first error when I try to reshape
and the second says it can't broadcast.

I keep getting the error "index 2 is out of bounds for axis 0 with size 2" in my loop

I'm basically trying to sum a gradient here, see the screenshots I have attached for a better idea. Rho is an nx1 input vector, the screenshot I have attached shows the idea for a 3x1 rho vector but it really has an undefined length.
enter image description here
enter image description here
# JACOBIAN
def derivative(rho, a, A, tilde_k, x, y, vecinc, chi):
n = rho.shape[0]
result1 = np.array([n,1],complex)
result2 = np.array([n,1],complex)
result = np.array([n,1],complex)
u = np.zeros((n, 3))
W_tilde = np.array([3,3],complex)
loop1 = 0
loop2 = 0
for i in range(n):
for j in range(n):
u[i] = x[i] - y[j] # n x 3
W_tilde = A_matrix * chi.imag * A_matrix * G(u[i],k) * A_matrix # 3 x 3
ei_block = np.exp(1j * np.vdot(x[i], tilde_k)) * vecinc # 3 x 1
ej_block = np.exp(1j * np.vdot(x[j], tilde_k)) * vecinc # 3 x 1
eiT_block = np.matrix.getH(ei_block) # 1 x 3
mm = np.matmul(W_tilde, ej_block) # (3 x 3)(3 x 1) = 3 x 1
alpha_tilde = np.dot(eiT_block, mm) # (1 x 3)(3 x 1) = 1 x 1 = scalar
loop1 = loop1 + (2 * rho[i] * alpha_tilde * rho[j]) # scalar
if (i != j):
loop2 = loop2 + ((rho[j]**2) * alpha_tilde) # scalar
result1[i] = loop1
result2[i] = loop2
result = result1 + result2 # (n x 1) + (n x 1) = n x 1 vector
return result
I am getting "IndexError: index 2 is out of bounds for axis 0 with size 2" for the line, result1[i] = loop1. Pls help :(
That error means that you are attempting to access the third element (index 2) of an array with only two elements (size 2).
It looks like you're defining your arrays in a funny way; np.array([n,1],complex) creates an array of length 2, not n. What you want is probably np.zeros(n,complex), which will create an n-length array filled with 0s.

How to generate a multidimensional cube in Python

This program creates a cube of size Gridsize**3 with user choice of starting point and space between point (even if they are not function parameters there isn't difficult to implement).
import numpy as np
def CreateMap(Gridsize):
X = Y = Z = Gridsize
M = np.zeros(shape=(X*Y*Z, 3))
d_x = 5 / Gridsize # increment of the cube x dimension
d_y = 5 / Gridsize
d_z = 5 / Gridsize
x0 = -1.0
y0 = 1.0
z0 = 0
x = np.arange(x0, X * d_x, d_x, dtype=float)
y = np.arange(y0, Y * d_y, d_y, dtype=float)
z = np.arange(z0, Z * d_z, d_z, dtype=float)
g = 0
for i in range(X):
for j in range(Y):
for k in range(Z):
M[g, 0] = x[i]
M[g, 1] = y[j]
M[g, 2] = z[k]
g = g + 1
print(M)
return 0
I was wondering what was the best method to create an hyper cube of size Gridsize**n were n will also be user defined?
Check out np.meshgrid. Instead of your for loops, you can just do
M = np.stack(np.meshgrid(x, y, z))
If you guys have optimization advice...
import numpy as np
def CreateMap(Gridsize, x0, xf):
k = np.shape(x0)[0]
M = np.zeros(shape=(Gridsize**k, k))
d_x = np.zeros(k)
for i in range(k):
d = 0
j = 0
d_x[i] = (xf[i] - x0[i]) / (Gridsize - 1) # increment of the cube x dimension
x = np.arange(x0[i], xf[i]+d_x[i], d_x[i], dtype=float)
for v in range(Gridsize ** (k - i - 1)):
for j in range(Gridsize):
temp = x[j]
for z in range(Gridsize ** i):
M[d, i] = temp
d = d + 1
print(M)
return 0
x0 = np.array([-1, 0, 1])
xf = np.array([10, 2, 5])
CreateMap(4, x0, xf)

Generalized Distance Transform in Python

I'm currently trying to implement the GDT described by Felzenszwalb and Huttenlocher (http://www.cs.cornell.edu/~dph/papers/dt.pdf) inside of Python for an image processing algorithm. However I used the algorithm described in the paper they published a few years back but got faulty results. I found a C# implementation here: https://dsp.stackexchange.com/questions/227/fastest-available-algorithm-for-distance-transform/29727?noredirect=1#comment55866_29727
And converted it to Python (which is pretty much the same I had before).
This is my code:
def of_column(dataInput):
output = zeros(dataInput.shape)
n = len(dataInput)
k = 0
v = zeros((n,))
z = zeros((n + 1,))
v[0] = 0
z[0] = -inf
z[1] = +inf
s = 0
for q in range(1, n):
while True:
s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]))
if s <= z[k]:
k -= 1
else:
break
k += 1
v[k] = q
z[k] = s
z[k + 1] = +inf
k = 0
for q in range(n):
while z[k + 1] < q:
k += 1
output[q] = ((q - v[k]) * (q - v[k]) + dataInput[v[k]])
return output
I still can't find my error. When giving the algorithm a binary (boolean) numpy array it just returns the array itself not the Distance Transform. Why is this not working in Python?
I got it working after hours and hours. The answer given in the link above implementing the code in C# suggests putting up the "white" areas to a very large number. My dataInput array was a boolean array (0, 1). I replaced all 1s with 2^32 and it works just fine. The higher the number the more blurry it gets. The lower the more similar to the source it gets.
I would like to add the function for 2D that works with the 1D function described previously:
###############################################################################
# distance transform of 1d function using squared distance
###############################################################################
def dt_1d(dataInput, n):
output = np.zeros(dataInput.shape)
k = 0
v = np.zeros((n,))
z = np.zeros((n + 1,))
v[0] = 0
z[0] = -np.inf
z[1] = +np.inf
for q in range(1, n):
s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]))
while s <= z[k]:
k -= 1
s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]))
k += 1
v[k] = q
z[k] = s
z[k + 1] = +np.inf
k = 0
for q in range(n):
while z[k + 1] < q:
k += 1
value = ((q - v[k]) * (q - v[k]) + dataInput[v[k]])
if value > 255: value = 255
if value < 0: value = 0
output[q] = value
print output
return output
###############################################################################
# distance transform of 2d function using squared distance
###############################################################################
def dt_2d(dataInput):
height, width = dataInput.shape
f = np.zeros(max(height, width))
# transform along columns
for x in range(width):
f = dataInput[:,x]
dataInput[:,x] = dt_1d(f, height)
# transform along rows
for y in range(height):
f = dataInput[y,:]
dataInput[y,:] = dt_1d(f, width)
return dataInput
I hope it helps.

Categories

Resources