I have an image tensor of size [1,3,224,224]. I want to apply the delta algorithm onto it (a type of parsing as such in NLP). I have referred to the paper to replicate the algorithm (Section5) - https://arxiv.org/abs/2204.03479
The code I have used so far is as follows, but it uses too many iterations.
img=torch.squeeze(img)
i=0
j=1
d=torch.zeros(img.shape)
for i in range(img.shape[0]):
d[i,0,:]=img[i,0,:]
for j in range(img.shape[1]-1):
d[i,j,:]=img[i,j,:]-img[i,j-1,:]
for k in range(img.shape[2]-1):
if (torch.abs(d[i,j,k])<torch.tensor(0.05)).any():
d[i,j,k]=torch.tensor(0)
img[i,j-1,:]=img[i,j-2,:]
k=k+1
img[i,j-1,:]=img[i,j,:]
j=j+1
i=i+1
This snippet reverts back the delta matrix onto my image reference matrix.
j=1
for j in range(img.shape[1]-1):
img[:,j,:]=img[:,j-1,:]+d[:,j,:]
j=j+1
I want to vectorize the code as much as possible however, could use some pointers on how to proceed.
inputs=input.cuda()
i=0
j=1
delta_inputs = torch.zeros(inputs.shape).cuda()
d = torch.zeros(inputs.shape[0],inputs.shape[1],inputs.shape[2]).cuda()
merge = torch.zeros(inputs.shape[0],inputs.shape[1],inputs.shape[2]).cuda()
for i in range(inputs.shape[2]):
if(i == 0):
d = inputs[:,:,i,:]
else:
d = inputs[:,:,i,:] - inputs[:,:,i-1,:]
merge = d.abs()
merge = torch.gt(merge, 0)
d = d*merge.int()
merge = d.bool()
merge = merge.int()
inputs[:,:,i,:] = inputs[:,:,i,:]*merge + inputs[:,:,i-1,:]*(torch.ones(inputs.shape[0],inputs.shape[1],inputs.shape[2]).cuda()-merge)
delta_inputs[:,:,i,:] = d[:,:,:]
output = torch.zeros(delta_inputs.shape).cuda()
for i in range(inputs.shape[2]):
if(i == 0):
output[:,:,i,:] = delta_inputs[:,:,i,:]
else:
output[:,:,i,:] = output[:,:,i-1,:] + delta_inputs[:,:,i,:]
input=output.cuda()
Related
# indices to calculate pair-wise products (H, V, D1, D2)
shifts = [[0,1], [1,0], [1,1], [-1,1]]
# calculate pairwise components in each orientation
for itr_shift in range(1, len(shifts) + 1):
OrigArr = structdis
reqshift = shifts[itr_shift-1] # shifting index
for i in range(structdis.shape[0]):
for j in range(structdis.shape[1]):
if(i + reqshift[0] >= 0 and i + reqshift[0] < structdis.shape[0] \
and j + reqshift[1] >= 0 and j + reqshift[1] < structdis.shape[1]):
ShiftArr[i, j] = OrigArr[i + reqshift[0], j + reqshift[1]]
else:
ShiftArr[i, j] = 0
If I try to run the code, I get the following error:
NameError: Name 'ShiftArr' is not defined
How can I solve this error?
By the looks of things you have not defined ShiftArr before you have used it. This is what the error is saying.
It looks like you first use ShiftArr in your nested loop, but nowhere before have you said something like ShiftArr = ...
If you add ShiftArr = [] before your first for loop, this should solve your issue I think. It's a little difficult to understand what you're trying to do as your variable names aren't super informative - this might help you when drying to fix errors in your code.
So I have a problem that might be super duper simple.
I have these numpy ndarrays that I allocated and want to assign values to them via indices returned as lists. It might be easier if I showed you some example code. The questionable code I have is at the bottom, and in my testing (before actually taking this to scale) I keep getting syntax errors :'(
EDIT: edited to make it easier to troubleshoot and put some example code at the bottoms
import numpy as np
def do_stuff(index, mask):
# this is where the calculations are made
magic = sum(mask)
return index, magic
def foo(full_index, comparison_dims, *xargs):
# I have this function executed in Parallel since I'm using a machine with 36 nodes per core, and can access upto 16 cores for each script #blessed
# figure out how many dimensions there are, and how big they are
parent_dims = []
parent_diffs = []
for j in xargs:
parent_dims += [len(j)]
parent_diffs += [j[1] - j[0]] # this is used to find a mask
index = [] # this is where the individual dimension indices will be stored
dim_n = 0
# loop through the dimensions
while dim_n < len(parent_dims):
dim_index = full_index % parent_dims[dim_n]
index += [dim_index]
if dim_n == 0:
mask = (comparison_dims[dim_n] > xargs[dim_n][dim_index] - parent_diffs[dim_n]/2) * \
(comparison_dims[dim_n] <= xargs[dim_n][dim_index] +parent_diffs[dim_n] / 2)
else:
mask *= (comparison_dims[dim_n] > xargs[dim_n][dim_index] - parent_diffs[dim_n]/2) * \
(comparison_dims[dim_n] <=xargs[dim_n][dim_index] + parent_diffs[dim_n] / 2)
full_index //= parent_dims[dim_n]
dim_n += 1
return do_stuff(index, mask)
def bar(comparison_dims, *xargs):
if len(xargs) == comparison_dims.shape[0]:
pass
elif len(comparison_dims.shape) == 2:
pass
else:
raise ValueError("silly person, you failed")
from joblib import Parallel, delayed
dims = []
for j in xargs:
dims += [len(j)]
myArray = np.empty(tuple(dims))
results = Parallel(n_jobs=1)(
delayed(foo)(
index, comparison_dims, *xargs)
for index in range(np.prod(dims))
)
# LOOK HERE, HELP HERE!
for index_list, result in results:
# I thought this would work, but oh golly was I was wrong, index_list here is a list of ints, and result is a value
# for example index, result = [0,3,7], 45.4
# so in execution, that would yield: myArray[0,3,7] = 45.4
# instead it yields SyntaxError because I don't know what I'm doing XD
myArray[*index_list] = result
return myArray
Any ideas how I can make that work. What do I need to do?
I'm not the sharpest tool in the shed, but I think with your help we might be able to figure this out!
A quick example to troubleshoot this problem would be:
compareDims = np.array([np.random.rand(1000), np.random.rand(1000)])
dim0 = np.arange(0,1,1./20)
dim1 = np.arange(0,1,1./30)
myArray = bar(compareDims, dim0, dim1)
To index a numpy array with an arbitrary list of multidimensional indices. you actually need to use a tuple:
for index_list, result in results:
myArray[tuple(index_list)] = result
This portion I was able to vectorize and get rid of a nested loop.
def EMalgofast(obsdata, beta, pjt):
n = np.shape(obsdata)[0]
g = np.shape(pjt)[0]
zijtpo = np.zeros(shape=(n,g))
for j in range(g):
zijtpo[:,j] = pjt[j]*stats.expon.pdf(obsdata,scale=beta[j])
zijdenom = np.sum(zijtpo, axis=1)
zijtpo = zijtpo/np.reshape(zijdenom, (n,1))
pjtpo = np.mean(zijtpo, axis=0)
I wasn't able to vectorize the portion below. I need to figure that out
betajtpo_1 = []
for j in range(g):
num = 0
denom = 0
for i in range(n):
num = num + zijtpo[i][j]*obsdata[i]
denom = denom + zijtpo[i][j]
betajtpo_1.append(num/denom)
betajtpo = np.asarray(betajtpo_1)
return(pjtpo,betajtpo)
I'm guessing Python is not your first programming language based on what I see. The reason I'm saying this is that in python, normally we don't have to deal with manipulating indexes. You act directly on the value or the key returned. Make sure not to take this as an offense, I do the same coming from C++ myself. It's a hard to remove habits ;).
If you're interested in performance, there is a good presentation by Raymond Hettinger on what to do in Python to be optimised and beautiful :
https://www.youtube.com/watch?v=OSGv2VnC0go
As for the code you need help with, is this helping for you? It's unfortunatly untested as I need to leave...
ref:
Iterating over a numpy array
http://docs.scipy.org/doc/numpy/reference/generated/numpy.true_divide.html
def EMalgofast(obsdata, beta, pjt):
n = np.shape(obsdata)[0]
g = np.shape(pjt)[0]
zijtpo = np.zeros(shape=(n,g))
for j in range(g):
zijtpo[:,j] = pjt[j]*stats.expon.pdf(obsdata,scale=beta[j])
zijdenom = np.sum(zijtpo, axis=1)
zijtpo = zijtpo/np.reshape(zijdenom, (n,1))
pjtpo = np.mean(zijtpo, axis=0)
betajtpo_1 = []
#manipulating an array of numerator and denominator instead of creating objects each iteration
num=np.zeros(shape=(g,1))
denom=np.zeros(shape=(g,1))
#generating the num and denom real value for the end result
for (x,y), value in numpy.ndenumerate(zijtpo):
num[x],denom[x] = num[x] + value *obsdata[y],denom[x] + value
#dividing all at once after instead of inside the loop
betajtpo_1= np.true_divide(num/denom)
betajtpo = np.asarray(betajtpo_1)
return(pjtpo,betajtpo)
Please leave me some feedback !
Regards,
Eric Lafontaine
First time publishing in here, here it goes:
I have two sets of data(v and t), each one has 46 values. The data is imported with "pandas" module and coverted to a numpy array in order to do the calculation.
I need to set ml_min1[45], ml_min2[45], and so on to the value "0". The problem is that each time I ran the script, the values corresponding to the position 45 of ml_min1 and ml_min2 are different. This is the piece of code that I have:
t1 = fil_copy.t1.as_matrix()
t2 = fil_copy.t2.as_matrix()
v1 = fil_copy.v1.as_matrix()
v2 = fil_copy.v2.as_matrix()
ml_min1 = np.empty(len(t1))
l_h1 = np.empty(len(t1))
ml_min2 = np.empty(len(t2))
l_h2 = np.empty(len(t2))
for i in range(0, (len(v1) - 1)):
if (i != (len(v1) - 1)) and (v1[i+1] > v1[i]):
ml_min1[i] = v1[i+1] - v1[i]
l_h1[i] = ml_min1[i] * (60/1000)
elif i == (len(v1)-1):
ml_min1[i] = 0
l_h1[i] = 0
print(i, ml_min1[i])
else:
ml_min1[i] = 0
l_h1[i] = 0
print(i, ml_min1[i])
for i in range(0, (len(v2) - 1)):
if (i != (len(v2) - 1)) and (v2[i+1] > v2[i]):
ml_min2[i] = v2[i+1] - v2[i]
l_h2[i] = ml_min2[i] * (60/1000)
elif i == (len(v2)-1):
ml_min2[i] = 0
l_h2[i] = 0
print(i, ml_min2[i])
else:
ml_min2[i] = 0
l_h2[i] = 0
print(i, ml_min2[i])
Your code as it is currently written doesn't work because the elif blocks are never hit, since range(0, x) does not include x (it stops just before getting there). The easiest way to solve this is probably just to initialize your output arrays with numpy.zeros rather than numpy.empty, since then you don't need to do anything in the elif and else blocks (you can just delete them).
That said, it's generally a design error to use loops like yours in numpy code. Instead, you should use numpy's broadcasting features to perform your mathematical operations to a whole array (or a slice of one) at once.
If I understand correctly, the following should be equivalent to what you wanted your code to do (just for one of the arrays, the other should work the same):
ml_min1 = np.zeros(len(t1)) # use zeros rather than empty, so we don't need to assign any 0s
diff = v1[1:] - v1[:-1] # find the differences between all adjacent values (using slices)
mask = diff > 0 # check which ones are positive (creates a Boolean array)
ml_min1[:-1][mask] = diff[mask] # assign with mask to a slice of the ml_min1 array
l_h1 = ml_min1 * (60/1000) # create l_h1 array with a broadcast scalar multiplication
My first attempt to accomplish this resulted in:
def rand_Random(self):
randomRangeI = range(self.gridWidth)
shuffle(randomRangeI)
randomRangeJ = range(self.gridHeight)
shuffle(randomRangeJ)
for i in randomRangeI:
for j in randomRangeJ:
if self.grid[i][j] != 'b':
print i, j
self.grid[i][j].colour = self.rand_Land_Picker()
Which has the issue of going through one inner list at a time:
[1][1..X]
[2][1..X]
What I'd like to be able to do is iterate through the 2d array entirely at random (with no repeats).
Anyone have any solutions to this problem?
Edit: Thanks for the replies, it appears the way I view 2d arrays in my mind is different to most!
Create an array with all possible pairs of coordinates, shuffle this and iterate through as normal.
import random
coords = [(x,y) for x in range(self.gridWidth) for y in range(self.gridHeight)
random.shuffle(coords)
for i,j in coords:
if self.grid[i][j] != 'b':
print i, j
self.grid[i][j].colour = self.rand_Land_Picker()
You can consider 2D array as 1D array and randomly iterate through it.
def rand_Random(self):
randomRange = range(self.gridWidth*self.gridHeight)
shuffle(randomRange)
for index in randomRange:
i = index / self.gridWidth
j = index % self.gridWidth
if self.grid[i][j] != 'b':
print i, j
self.grid[i][j].colour = self.rand_Land_Picker()
You can do something like:
randomRange = range(w*h)
shuffle(randomRange)
for n in randomRange:
i = n/w
j = n%w
Here randomRange basically enumerates all the coordinates from 0 to w*h-1.
Even prettier, i and j, can be found in one statement:
i,j = divmod(n, w)