def rw(X,w,step=1): """Make sliding-window view of vector array X. Input array X has to be C_CONTIGUOUS otherwise a copy is made. C-contiguous arrays do do not require any additional memory or time for array copy. Example: >> X = arange(10) >> rw(X,4,1) array([[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9]]) >> rw(X,3,3) array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) """ from numpy.lib.stride_tricks import as_strided as ast if not X.flags['C_CONTIGUOUS']: X = X.copy() if hasattr(X,'mask'): return ma.array(ast(X.data,((X.shape[0]-w)//step+1,w),((step*X.dtype.itemsize),X.dtype.itemsize)), mask = ast(X.mask,((X.shape[0]-w)//step+1,w), ((step*X.mask.dtype.itemsize),X.mask.dtype.itemsize))) else: return ast(X, ((X.shape[0]-w)//step+1,w), ((step*X.dtype.itemsize),X.dtype.itemsize))
def patchify(A, step=(1,1), block= (8, 8)): """Make a Ndata by (flattened) patch, 2D array""" shape = ((A.shape[0] - block[0])/step[0] + 1, (A.shape[1] - block[1])/step[1] + 1) + block strides = (A.strides[0]*step[0],A.strides[1]*step[1]) + A.strides blocks = ast(A, shape= shape, strides= strides) blocks = blocks.flatten() shape = (shape[0]*shape[1],block[0]*block[1]) strides = (blocks.itemsize*block[0]*block[1],blocks.itemsize) return ast(blocks, shape= shape, strides= strides)
def rw(x, w, step=1): from numpy.lib.stride_tricks import as_strided as ast if not x.flags["C_CONTIGUOUS"]: x = x.copy() if hasattr(x, "mask"): return ma.array( ast(x.data, ((x.shape[0] - w) // step + 1, w), ((step * x.dtype.itemsize), x.dtype.itemsize)), mask=ast( x.mask, ((x.shape[0] - w) // step + 1, w), ((step * x.mask.dtype.itemsize), x.mask.dtype.itemsize) ), ) else: return ast(x, ((x.shape[0] - w) // step + 1, w), ((step * x.dtype.itemsize), x.dtype.itemsize))
def grid_view(self, inds): """ inds is list, the indices of the grid desired e.g. if inds == [i,j,k] it gets the ith block down, the jth block right, the kth block deep note: len(inds) == len(self.arr.shape) (blocks are 0-indexed) corrects the indices accessing self.arr where they would access outside the dims and returns the grid accessed using those indices """ if len(inds) != len(self.dims): error( "Grid", "Invalid inds sized " + str(len(inds)) + " should be length " + str(len(self.dims))) if not all([a < b for a, b in zip(inds, self.dims)]): error("Grid", "Invalid grid inds: " + str(inds)) block = self.adjust_grid_inds((self.dims[0], self.dims[1]), (inds[0], inds[1])) shape = (self.arr.shape[0] / block[0], self.arr.shape[1] / block[1]) + block strides = (block[0] * self.arr.strides[0], block[1] * self.arr.strides[1]) + self.arr.strides error("Grid", "need to use inds[2:] to access currect slice of self.arr") cur_arr = self.arr # FIXME return ast(cur_arr, shape=shape, strides=strides)
def sliding_window(a,ws,ss = None,flatten = True): ''' Return a sliding window over a in any number of dimensions Parameters: a - an n-dimensional numpy array ws - an int (a is 1D) or tuple (a is 2D or greater) representing the size of each dimension of the window ss - an int (a is 1D) or tuple (a is 2D or greater) representing the amount to slide the window in each dimension. If not specified, it defaults to ws. flatten - if True, all slices are flattened, otherwise, there is an extra dimension for each dimension of the input. Returns an array containing each n-dimensional window from a ''' if None is ss: # ss was not provided. the windows will not overlap in any direction. ss = ws ws = norm_shape(ws) ss = norm_shape(ss) # convert ws, ss, and a.shape to numpy arrays so that we can do math in every # dimension at once. ws = np.array(ws) ss = np.array(ss) shape = np.array(a.shape) # ensure that ws, ss, and a.shape all have the same number of dimensions ls = [len(shape),len(ws),len(ss)] if 1 != len(set(ls)): raise ValueError('a.shape, ws and ss must all have the same length. They were %s' % str(ls)) # ensure that ws is smaller than a in every dimension if np.any(ws > shape): raise ValueError('ws cannot be larger than a in any dimension.a.shape was %s and ws was %s' % (str(a.shape),str(ws))) # how many slices will there be in each dimension? newshape = norm_shape(((shape - ws) // ss) + 1) # the shape of the strided array will be the number of slices in each dimension # plus the shape of the window (tuple addition) newshape += norm_shape(ws) # the strides tuple will be the array's strides multiplied by step size, plus # the array's strides (tuple addition) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides strided = ast(a,shape = newshape,strides = newstrides) if not flatten: return strided # Collapse strided so that it has one more dimension than the window. I.e., # the new array is a flat list of slices. meat = len(ws) if ws.shape else 0 firstdim = (np.product(newshape[:-meat]),) if ws.shape else () dim = firstdim + (newshape[-meat:]) # remove any dimensions with size 1 dim = filter(lambda i : i != 1,dim) return strided.reshape(dim)
def sliding_window(a, ws, ss=None, flatten=True): ''' Return a sliding window over a in any number of dimensions Parameters: a - an n-dimensional numpy array ws - an int (a is 1D) or tuple (a is 2D or greater) representing the size of each dimension of the window ss - an int (a is 1D) or tuple (a is 2D or greater) representing the amount to slide the window in each dimension. If not specified, it defaults to ws. flatten - if True, all slices are flattened, otherwise, there is an extra dimension for each dimension of the input. Returns an array containing each n-dimensional window from a ''' if None is ss: # ss was not provided. the windows will not overlap in any direction. ss = ws ws = norm_shape(ws) ss = norm_shape(ss) # convert ws, ss, and a.shape to numpy arrays so that we can do math in every # dimension at once. ws = np.array(ws) ss = np.array(ss) shape = np.array(a.shape) # ensure that ws, ss, and a.shape all have the same number of dimensions ls = [len(shape), len(ws), len(ss)] if 1 != len(set(ls)): raise ValueError( \ 'a.shape, ws and ss must all have the same length. They were %s' % str(ls)) # ensure that ws is smaller than a in every dimension if np.any(ws > shape): raise ValueError( \ 'ws cannot be larger than a in any dimension.\ a.shape was %s and ws was %s' % (str(a.shape), str(ws))) # how many slices will there be in each dimension? newshape = norm_shape(((shape - ws) // ss) + 1) # the shape of the strided array will be the number of slices in each dimension # plus the shape of the window (tuple addition) newshape += norm_shape(ws) # the strides tuple will be the array's strides multiplied by step size, plus # the array's strides (tuple addition) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides strided = ast(a, shape=newshape, strides=newstrides) if not flatten: return strided # Collapse strided so that it has one more dimension than the window. I.e., # the new array is a flat list of slices. meat = len(ws) if ws.shape else 0 firstdim = (np.product(newshape[:-meat]),) if ws.shape else () dim = firstdim + (newshape[-meat:]) # remove any dimensions with size 1 #dim = filter(lambda i: i != 1, dim) return strided.reshape(dim)
def patchify(self, D): """ Make a Ndata by (flattened) pshape, 2D array """ step = self.step pshape = self.pshape shape = ((D.shape[0] - pshape[0])/step[0] + 1, (D.shape[1] - pshape[1])/step[1] + 1) + pshape strides = (D.strides[0]*step[0],D.strides[1]*step[1]) + D.strides blocks = ast(D, shape= shape, strides= strides) blocks = blocks.ravel() shape = (shape[0]*shape[1],pshape[0]*pshape[1]) strides = (blocks.itemsize*pshape[0]*pshape[1],blocks.itemsize) return ast(blocks, shape= shape, strides= strides)
def chunk_data(data, window_size, overlap_size=0, flatten_inside_window=True): assert data.ndim == 1 or data.ndim == 2 if data.ndim == 1: data = data.reshape((-1, 1)) # get the number of overlapping windows that fit into the data num_windows = (data.shape[0] - window_size) // (window_size - overlap_size) + 1 overhang = data.shape[0] - (num_windows * window_size - (num_windows - 1) * overlap_size) # if there's overhang, need an extra window and a zero pad on the data # (numpy 1.7 has a nice pad function I'm not using here) if overhang != 0: num_windows += 1 newdata = np.zeros( (num_windows * window_size - (num_windows - 1) * overlap_size, data.shape[1])) newdata[:data.shape[0]] = data data = newdata sz = data.dtype.itemsize ret = ast(data, shape=(num_windows, window_size * data.shape[1]), strides=((window_size - overlap_size) * data.shape[1] * sz, sz)) if flatten_inside_window: return ret else: return ret.reshape((num_windows, -1, data.shape[1]))
def block_view(A, block= (3, 3)): """Provide a 2D block view to 2D array. No error checking made. Therefore meaningful (as implemented) only for blocks strictly compatible with the shape of A.""" shape= (A.shape[0]/ block[0], A.shape[1]/ block[1])+ block strides= (block[0]* A.strides[0], block[1]* A.strides[1])+ A.strides return ast(A, shape= shape, strides= strides)
def overlap_data_stream(data, chunk=256, overlap_percentage=.75): chunk_count = len(data)/chunk overlap_samples = int(chunk*overlap_percentage)+1 extended_length = (chunk_count+1)*(chunk-overlap_samples) data = np.hstack((np.asarray(data),np.asarray([0]*(extended_length-len(data))))) shape = (len(data)/(chunk-overlap_samples),chunk) strides = (data.itemsize*(chunk-overlap_samples), data.itemsize) return ast(data, shape=shape, strides=strides)
def AR_striding(data, nlags): data = np.asarray(data) if not data.flags.c_contiguous: data = data.copy(order="C") if data.ndim == 1: data = np.reshape(data, (-1, 1)) sz = data.dtype.itemsize return ast(data, shape=(data.shape[0] - nlags, data.shape[1] * (nlags + 1)), strides=(data.shape[1] * sz, sz))
def block_view(A, block=(3, 3)): """Provide a 2D block view to 2D array. No error checking made. Therefore meaningful (as implemented) only for blocks strictly compatible with the shape of A.""" # simple shape and strides computations may seem at first strange # unless one is able to recognize the 'tuple additions' involved ;-) shape = (A.shape[0] // block[0], A.shape[1] // block[1]) + block strides = (block[0] * A.strides[0], block[1] * A.strides[1]) + A.strides return ast(A, shape=shape, strides=strides)
def _ensure_ndim(X, T, ndim): from numpy.lib.stride_tricks import as_strided as ast X = np.require(X, dtype=np.float64, requirements='C') assert ndim-1 <= X.ndim <= ndim if X.ndim == ndim: assert X.shape[0] == T return X else: return ast(X, shape=(T,) + X.shape, strides=(0,) + X.strides)
def block_view(A, block= (3, 3)): """Provide a 2D block view to 2D array. No error checking made. Therefore meaningful (as implemented) only for blocks strictly compatible with the shape of A.""" # simple shape and strides computations may seem at first strange # unless one is able to recognize the 'tuple additions' involved ;-) shape= (A.shape[0]/ block[0], A.shape[1]/ block[1])+ block strides= (block[0]* A.strides[0], block[1]* A.strides[1])+ A.strides return ast(A, shape= shape, strides= strides)
def sliding_window_sliced(a,density, ws,ss = None,flatten = True): ''' Return a sliding window over a in any number of dimensions ''' if None is ss: # ss was not provided. the windows will not overlap in any direction. ss = ws ws = norm_shape(ws) ss = norm_shape(ss) # convert ws, ss, and a.shape to numpy arrays ws = np.array(ws) ss = np.array(ss) r = np.arange(1,ws[0]-1,density, dtype=np.int) shap = np.array(a.shape) # ensure that ws, ss, and a.shape all have the same number of dimensions ls = [len(shap),len(ws),len(ss)] if 1 != len(set(ls)): raise ValueError(\ 'a.shape, ws and ss must all have the same length. They were %s' % str(ls)) # ensure that ws is smaller than a in every dimension if np.any(ws > shap): raise ValueError(\ 'ws cannot be larger than a in any dimension.\ a.shape was %s and ws was %s' % (str(a.shape),str(ws))) # how many slices will there be in each dimension? newshape = norm_shape(((shap - ws) // ss) + 1) # the shape of the strided array will be the number of slices in each dimension # plus the shape of the window (tuple addition) newshape += norm_shape(ws) # the strides tuple will be the array's strides multiplied by step size, plus # the array's strides (tuple addition) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides a = ast(a,shape = newshape,strides = newstrides)[:,:,:,r] if not flatten: return a # Collapse strided so that it has one more dimension than the window. I.e., # the new array is a flat list of slices. meat = len(ws) if ws.shape else 0 firstdim = (int(np.product(newshape[:-meat])),) if ws.shape else () dim = firstdim + (newshape[-meat:]) dim = list(dim) dim[-1] = len(r) ## remove any dimensions with size 1 dim = filter(lambda i : i != 1,dim) dim = tuple(dim) newshape = np.shape(a) return a.reshape(dim), newshape
def striding(data, lens, stride): from numpy.lib.stride_tricks import as_strided as ast itemsize = data.itemsize t, chan = data.shape n = np.floor((t-lens)/stride) + 1 if data.flags.c_contiguous: strides = tuple(itemsize*i for i in (chan*stride, 1, chan)) else: strides = tuple(itemsize*i for i in (stride, t, 1)) return ast(data, shape=(n, chan, lens), strides=strides)
def block_view(arr, block_shape): assert arr.ndim == len(block_shape), \ "ndim mismatch; arr.ndim(=%s) and len(block_shape(=%s) should be equal" % (arr.ndim, len(block_shape)) assert all([i % j == 0 for i, j in zip(arr.shape, block_shape)]), \ "block_view requires arr.shape[i] to be a multiple of block_shape[i]" shape= tuple(i // j for i, j in zip(arr.shape, block_shape)) + block_shape strides = tuple(i * j for i, j in zip(arr.strides, block_shape)) + arr.strides return ast(arr, shape=shape, strides=strides)
def AR_striding(data, nlags): data = np.asarray(data) if not data.flags.c_contiguous: data = data.copy(order='C') if data.ndim == 1: data = np.reshape(data, (-1, 1)) sz = data.dtype.itemsize return ast(data, shape=(data.shape[0] - nlags, data.shape[1] * (nlags + 1)), strides=(data.shape[1] * sz, sz))
def rw(X, w, step=1): """Make sliding-window view of vector array X. Input array X has to be C_CONTIGUOUS otherwise a copy is made. C-contiguous arrays do not require any additional memory or time for array copy. Parameters ---------- X: array w: window size (in number of elements) step: ofset in elements between the first element two windows Example ------- %>>> X = arange(10) %>>> rw(X,4,1) array([[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9]]) %>>> rw(X,3,3) array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) """ if not X.flags['C_CONTIGUOUS']: X = X.copy() if hasattr(X, 'mask'): return np.ma.array( ast(X.data, ((X.shape[0] - w) // step + 1, w), ((step * X.dtype.itemsize), X.dtype.itemsize)), mask=ast(X.mask, ((X.shape[0] - w) // step + 1, w), ((step * X.mask.dtype.itemsize), X.mask.dtype.itemsize))) else: return ast(X, ((X.shape[0] - w) // step + 1, w), ((step * X.dtype.itemsize), X.dtype.itemsize))
def AR_striding(data, nlags): # I had some trouble with views and as_strided, so copy if not contiguous data = np.asarray(data) if not data.flags.c_contiguous: data = data.copy(order='C') if data.ndim == 1: data = np.reshape(data, (-1, 1)) sz = data.dtype.itemsize return ast(data, shape=(data.shape[0] - nlags, data.shape[1] * (nlags + 1)), strides=(data.shape[1] * sz, sz))
def sliding_window(self, xr): """ :type xr: numpy.ndarray :rtype: numpy.ndarray """ from numpy.lib.stride_tricks import as_strided as ast x = numpy.concatenate([self.zpad, xr, self.zpad]) return ast(x, shape=(x.shape[0] - self.window + 1, 1, self.window, self.num_inputs), strides=(x.strides[0], x.strides[1] * self.num_inputs) + x.strides ).reshape((xr.shape[0], self.num_inputs * self.window))
def AR_striding(data,nlags): # I had some trouble with views and as_strided, so copy if not contiguous data = np.asarray(data) if not data.flags.c_contiguous: data = data.copy(order='C') if data.ndim == 1: data = np.reshape(data,(-1,1)) sz = data.dtype.itemsize return ast( data, shape=(data.shape[0]-nlags,data.shape[1]*(nlags+1)), strides=(data.shape[1]*sz,sz))
def sliding_window(self, xr): """ :type xr: numpy.ndarray :rtype: numpy.ndarray """ from numpy.lib.stride_tricks import as_strided as ast x = numpy.concatenate([self.zpad, xr, self.zpad]) return ast(x, shape=(x.shape[0] - self.window + 1, 1, self.window, self.num_inputs), strides=(x.strides[0], x.strides[1] * self.num_inputs) + x.strides).reshape( (xr.shape[0], self.num_inputs * self.window))
def aggregate(A, blocksize): if A.ndim != 2: raise NotImplementedError('only 2D arrays supported') shape_in = A.shape shape_out = [item // blocksize for item in shape_in] block_shape = shape_out + [blocksize] * A.ndim itemstrides = (shape_in[1] * blocksize, blocksize, shape_in[1], 1) bytestrides = np.array(itemstrides) * A.itemsize return ast(A, shape=block_shape, strides=bytestrides).reshape(shape_out + [-1])
def sliding_window(a, ws, ss=None): ''' Return a sliding window over a in any number of dimensions Parameters: a - an n-dimensional numpy array ws - an int (a is 1D) or tuple (a is 2D or greater) representing the size of each dimension of the window ss - an int (a is 1D) or tuple (a is 2D or greater) representing the amount to slide the window in each dimension. If not specified, it defaults to ws. Returns an array containing each n-dimensional window from a ''' if None is ss: # ss was not provided. the windows will not overlap in any direction. ss = ws ws = norm_shape(ws) ss = norm_shape(ss) # convert ws, ss, and a.shape to numpy arrays so that we can do math in every # dimension at once. ws = np.array(ws) ss = np.array(ss) shape = np.array(a.shape) # ensure that ws, ss, and a.shape all have the same number of dimensions ls = [len(shape),len(ws),len(ss)] if 1 != len(set(ls)): raise ValueError(\ 'a.shape, ws and ss must all have the same length. They were %s' % str(ls)) # ensure that ws is smaller than a in every dimension if np.any(ws > shape): raise ValueError(\ 'ws cannot be larger than a in any dimension.\ a.shape was %s and ws was %s' % (str(a.shape),str(ws))) # how many slices will there be in each dimension? newshape = norm_shape(((shape - ws) // ss) + 1) # the shape of the strided array will be the number of slices in each dimension # plus the shape of the window (tuple addition) newshape += norm_shape(ws) # the strides tuple will be the array's strides multiplied by step size, plus # the array's strides (tuple addition) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides strided = ast(a,shape = newshape, strides = newstrides) return strided
def sliding_window(a, ws, ss=None, flatten=True): ''' Return a sliding window over a in any number of dimensions Parameters: a - an n-dimensional numpy array ws - an int (a is 1D) or tuple (a is 2D or greater) representing the size of each dimension of the window ss - an int (a is 1D) or tuple (a is 2D or greater) representing the amount to slide the window in each dimension. If not specified, it defaults to ws. flatten - if True, all slices are flattened, otherwise, there is an extra dimension for each dimension of the input. Returns an array containing each n-dimensional window from a ''' if None is ss: ss = ws ws = norm_shape(ws) ss = norm_shape(ss) ws = np.array(ws) ss = np.array(ss) shape = np.array(a.shape) ls = [len(shape), len(ws), len(ss)] if 1 != len(set(ls)): raise ValueError( \ 'a.shape, ws and ss must all have the same length. They were %s' % str(ls)) if np.any(ws > shape): raise ValueError( \ 'ws cannot be larger than a in any dimension.\ a.shape was %s and ws was %s' % (str(a.shape), str(ws))) newshape = norm_shape(((shape - ws) // ss) + 1) newshape += norm_shape(ws) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides strided = ast(a, shape=newshape, strides=newstrides) if not flatten: return strided meat = len(ws) if ws.shape else 0 firstdim = (np.product(newshape[:-meat]), ) if ws.shape else () dim = firstdim + (newshape[-meat:]) dim = filter(lambda i: i != 1, dim) dim = list(dim) return np.reshape(strided, dim)
def binning(arr, br, bc): """Return a binned view if 'arr'""" nr, nc = arr.shape if nr % br != 0 or nc % bc != 0: raise ValueError("'bin' must be an integer multiple of size") bnr = nr // br bnc = nc // bc m = arr.dtype.itemsize newshape = bnr, bnc, br, bc newstrides = nc*br*m, bc*m, nc*m, m binned = ast(arr, shape=newshape, strides=newstrides) return binned
def non_overlapping_patch_view(data, patchSize): if isinstance(patchSize, int): patchSize = (patchSize, ) * 3 elif len(patchSize) == 1: patchSize = (patchSize[0], ) * 3 shape = tuple( numpy.int( numpy.asarray(data.shape) / numpy.asarray(patchSize))) + patchSize strides = tuple( numpy.asarray(data.strides) * numpy.asarray(patchSize)) + data.strides patchMatrix = ast(data, shape=shape, strides=strides) return patchMatrix
def block_view(orig, block): """Provide a 2D block view to 2D array. No error checking made. Therefore meaningful (as implemented) only for blocks strictly compatible with the shape of A. Note the tuple addition happening! """ if orig.shape[1] == block[1]: shape = (orig.shape[0] / block[0],) + block strides = (block[0] * orig.strides[0],) + orig.strides else: shape = (orig.shape[0] / block[0], orig.shape[1] / block[1]) + block strides = (block[0] * orig.strides[0], block[1] * orig.strides[1]) + orig.strides return ast(orig, shape=shape, strides=strides)
def patch_view(data, patchSize=(3, 3, 3)): """Returns a view of overlapping patches from the data""" if isinstance(patchSize, int): patchSize = (patchSize, ) * 3 elif len(patchSize) == 1: patchSize = (patchSize[0], ) * 3 else: patchSize = tuple(patchSize) shape = tuple(numpy.asarray(data.shape) - numpy.asarray(patchSize) + 1) + patchSize strides = data.strides + data.strides patchMatrix = ast(data, shape=shape, strides=strides) return patchMatrix
def my1_conv2d(image, kernels, strides=(1, 1)): ''' Implements a 2d valid convolution of kernels with the image Note: filter means the same as kernel and convolution (correlation) of those with the input space produces feature maps (sometimes refereed to also as receptive fields). Also note, that feature maps are synonyms here to channels, and as such num_inp_channels == num_inp_feat_maps :param image: 4D tensor of sizes (batch_size, num_input_channels, img_shape_x, img_shape_y) :param filters: 4D tensor of filters of size (num_inp_feat_maps, num_out_feat_maps, kernel_shape_x, kernel_shape_y) :param strides: a tuple (stride_x, stride_y), specifying the shift of the kernels in x and y dimensions :return: 4D tensor of size (batch_size, num_out_feature_maps, feature_map_shape_x, feature_map_shape_y) ''' # http://cs231n.github.io/convolutional-networks/ batch_size, num_input_channels, img_shape_x, img_shape_y = image.shape num_inp_feat_maps, num_out_feat_maps, kernel_shape_x, kernel_shape_y = kernels.shape stride_x, stride_y = strides feature_map_shape_x = (img_shape_x-kernel_shape_x)/stride_x+1 feature_map_shape_y = (img_shape_y-kernel_shape_y)/stride_y+1 convolution = numpy.zeros((batch_size, num_out_feat_maps, feature_map_shape_x, feature_map_shape_y)) newshape = (batch_size, num_inp_feat_maps, feature_map_shape_x, feature_map_shape_y, kernel_shape_x, kernel_shape_y) newstrides = image.itemsize*numpy.array([num_inp_feat_maps*img_shape_x*img_shape_y,img_shape_x*img_shape_y,img_shape_y,1,img_shape_y,1]) strided = ast(image,shape = newshape,strides = newstrides) convolution = numpy.tensordot(strided, kernels, axes=[[1, 4, 5], [0, 2, 3]]) convolution = numpy.transpose(convolution, (0,3,1,2)) ''' for mx in xrange(0, feature_map_shape_x): # the slice on the x dimension batch_slice = image[:,:,mx:mx+kernel_shape_x,:] for my in xrange(0, feature_map_shape_y): # calculates the result of convolution using the einstein summation # which using the tensor it calculates the element wise multiplication # between the batch slice of the image and the kernels and # then it calculates the sum of the elements of the previous multiplication mult_sum = numpy.einsum('lkni,kjni->lj', batch_slice[:,:,:,my:my+kernel_shape_y], kernels) # stores the result of the convolution convolution[:,:,mx,my] = mult_sum ''' return convolution
def sliding_window(arr, win, sl=None, flatten=True): ''' Return a sliding window over a in any number of dimensions Parameters: arr - n-D numpy array win - an int (if arr is 1D) or tuple (if arr is 2D or more) which represents the size of each dimension of the window sl - an int (if arr is 1D) or tuple (if arr is 2D or more) represents the sliding length (in each dimension). flatten - if True, all slices are flattened, otherwise, there is extra dimension for each dimension of the input. ''' if None is sl: # sl not provided. the windows not overlap in any direction. sl = win win = normalize_shape(win) sl = normalize_shape(sl) # convert win, sl, and arr.shape to numpy arrays win = np.array(win) sl = np.array(sl) shape = np.array(arr.shape) # ensure that win, sl, and arr.shape all have the same number of dimensions ls = [len(shape), len(win), len(sl)] if 1 != len(set(ls)): raise ValueError(\ 'arr.shape, win and sl all must have the same length. They were %s' % str(ls)) if np.any(win > shape): raise ValueError(\ 'win should not be larger than arr in any dimension.\ arr.shape was %s and win was %s' % (str(arr.shape),str(win))) n_shape = normalize_shape(((shape - win) // sl) + 1) # the shape of the strided array will be the number of slices in each dimension # plus the shape of the window (tuple addition) n_shape += normalize_shape(win) newstr = normalize_shape(np.array(arr.strides) * sl) + arr.strides strided = ast(arr, shape=n_shape, strides=newstr) if not flatten: return strided m = len(win) if win.shape else 0 fdim = (np.product(n_shape[:-m]), ) if win.shape else () dim = fdim + (n_shape[-m:]) return strided.reshape(dim)
def gather(a, window=(2, 2)): A = np.arange(torch.numel(a)).reshape(a.size()) batch = A.shape[0] channels = A.shape[1] block = (batch, channels, window[0], window[1]) shape = (1, 1, A.shape[2] // block[2], A.shape[3] // block[3]) + block strides = (block[0] * A.strides[0], block[1] * A.strides[1], block[2] * A.strides[2], block[3] * A.strides[3]) + A.strides indices = ast(A, shape=shape, strides=strides).T.reshape(batch, channels * block[2] * block[3], A.shape[2] // block[2], A.shape[3] // block[3]) ind_variable = Variable(torch.from_numpy(indices)).long() if torch.cuda.is_available(): ind_variable = ind_variable.cuda() a_gathered = torch.take(a, ind_variable) return a_gathered
def sliding_window(a, ws, ss=None, flatten=True): if None is ss: # ss is not provided, the windows will not overlap ss = ws ws = norm_shape(ws) ss = norm_shape(ss) ws = np.array(ws) ss = np.array(ss) shape = np.array(a.shape) newshape = norm_shape(((shape - ws) // ss) + 1) newshape += norm_shape(ws) newstrides = norm_shape(np.array(a.strides * ss) + a.strides) strided = ast(a, shape=newshape, strides=newstrides) if not flatten: return strided meat = len(ws) if ws.shape else 0 firstdim = (np.product(newshape[:, -meat]), ) if ws.shape else () dim = firstdim + (newshape[-meat:]) dim = filter(lambda i: i != 1, dim) return strided.reshape(dim)
def _row_block_view(rx, x_shape, block, block_shape, func=lambda x:x): ''' 2D case single row block view, return the row form of it and with func apply to each block _block_shape_.shape must have a strictly matching with _rx_.shape that means, each dimension of _rx_ could be divisible by corresponding dim of _block_shape_ ''' x = rx.reshape(x_shape) shape = (x.shape[0]/block_shape[0], x.shape[1]/block_shape[1]) + block_shape strides= (block_shape[0]*x.strides[0], block_shape[1]*x.strides[1]) + x.strides block_x = ast(x, shape=shape, strides=strides) l = [] for i in xrange(block[0]): for j in xrange(block[1]): l.append(func(block_x[i][j]).ravel()) # block_rx = np.concatenate((block_rx, func(block_x[i][j]).ravel()), axis=1) return np.concatenate(l, axis=1).reshape(1, -1)
def slide_tensor4_2(tensor4, window_shape, strides): t4 = tensor4 #convert to array for easy algebraic manipulations wd = np.array(window_shape) ss = np.array(strides) img_shp = np.array(t4.shape[2:4]) dim_check = ((img_shp - wd) % ss) if dim_check[0] != 0 or dim_check[1] != 0: raise ValueError("impossible to tile with given strides {0}, window shape {1}, tensor4 shape {2}"\ .format(strides, window_shape, tensor4.shape)) slide_shp = ((img_shp - wd) / ss) + 1 #using tuple addition (1, 2) + (3, 4) = (1, 2, 3, 4) new_shp = t4.shape[0:2] + tuple(slide_shp) + tuple(wd) new_str = t4.strides[0:2] + tuple( np.array(t4.strides[2:4]) * ss) + t4.strides[2:4] #change internal memory numpy array t4 representation #more here: http://www.johnvinyard.com/blog/?p=268 return ast(t4, shape=new_shp, strides=new_str)
def tile_bias(output_shape, bias): """ :output_shape: shape of (batch_size, num_out_feature_maps, feature_map_shape_x, feature_map_shape_y) :bias: tensor1D of shape (num_out_feature_maps) :return: bias of shape (batch_size, num_out_feature_maps, feature_map_shape_x, feature_map_shape_y) Usage/Doctest: >>> b = np.array([1, 3]) >>> output_shape = (1, 2, 3, 3) >>> rslt = tile_bias(output_shape, b) >>> rslt[:, 0, :, :] array([[[1, 1, 1], [1, 1, 1], [1, 1, 1]]]) >>> rslt[:, 1, :, :] array([[[3, 3, 3], [3, 3, 3], [3, 3, 3]]]) """ return ast(bias, shape=output_shape, strides=(0, bias.strides[0], 0, 0))
def fprop(self, inputs): batch_size, num_input_feat_maps, input_shape_x, input_shape_y = inputs.shape pool_shape_x, pool_shape_y = self.pool_shape stride_x, stride_y = self.pool_stride # I calculated the shape of the pool using this web site # http://cs231n.github.io/convolutional-networks/ output_shape_x = (input_shape_x - pool_shape_x) / stride_x + 1 output_shape_y = (input_shape_y - pool_shape_y) / stride_y + 1 # initialize the pseudo-weight tensor # (batch_size, number of input feature maps, pool's x dimension, pool's y dimension) Gvalue = numpy.zeros((batch_size, num_input_feat_maps, output_shape_x, output_shape_y)) # initialize a tensor similar to the weight matrix but we stores the index # from where we take the max value # (batch_size, number of input feature maps, pool's x dimension, pool's y dimension) self.Gindex = numpy.zeros(Gvalue.shape, dtype=int) newshape = (batch_size, num_input_feat_maps, output_shape_x, output_shape_y, pool_shape_x, pool_shape_y) newstrides = inputs.itemsize*numpy.array([num_input_feat_maps*input_shape_x*input_shape_y,input_shape_x*input_shape_y,input_shape_x*stride_x,stride_x,input_shape_y,1]) strided = ast(inputs,shape = newshape,strides = newstrides) Gvalue, self.Gindex = max_and_argmax(strided, axes=(4, 5)) ''' for mx in xrange(0, output_shape_x): # the slice on the x dimension slice_x = slice(mx*stride_x, mx*stride_x + pool_shape_x) for my in xrange(0, output_shape_y): # the slice on the y dimension slice_y = slice(my*stride_y, my*stride_y + pool_shape_y) # stores the max value and the index of the max value Gvalue[:,:,mx,my], self.Gindex[:,:,mx,my] = max_and_argmax(inputs[:, :, slice_x, slice_y], axes=(2, 3)) ''' return Gvalue
def sliding_window(a,ws,ss=1): """Generate sliding window version of an array Parameters ---------- a (np.ndarray): input array ws (int): window size ss (int): step size Returns ------- Array in which iteration along the 0th dimension provides requested data windows """ # sliding window along 0'th axis of a, using stride tricks # ws: window size # ss: step size l = a.shape[0] n_slices = ((l - ws) // ss) + 1 newshape = (n_slices,ws) + a.shape[1:] newstrides = (a.strides[0]*ss,) + a.strides strided = ast(a,shape = newshape,strides = newstrides) return strided
def sliding_window(a, ws, ss=1): """Generate sliding window version of an array Parameters ---------- a (np.ndarray): input array ws (int): window size ss (int): step size Returns ------- Array in which iteration along the 0th dimension provides requested data windows """ # sliding window along 0'th axis of a, using stride tricks # ws: window size # ss: step size l = a.shape[0] n_slices = ((l - ws) // ss) + 1 newshape = (n_slices, ws) + a.shape[1:] newstrides = (a.strides[0] * ss, ) + a.strides strided = ast(a, shape=newshape, strides=newstrides) return strided
def undo_AR_striding(strided_data,nlags): sz = strided_data.dtype.itemsize return ast( strided_data, shape=(strided_data.shape[0]+nlags,strided_data.shape[1]//(nlags+1)), strides=(strided_data.shape[1]//(nlags+1)*sz,sz))
def sliding_window(a, ws, ss=None, flatten=True): """ Return a sliding window over a in any number of dimensions :param a: (np.array) an n-dimensional numpy array :param ws: (int or tuple of ints) int or tuple of ints representing the size of each dimension of the window. :param ss: (int or tuple of ints) int or tuple of ints representing the amount to slide the window in each dimension. If not specified, it defaults to ws. :param flatten: (bool) If True, all slices are flattened. Otherwise, there is an extra dimension for each dimension of the input. :return: (np.array) an array containing each n-dimensional window from a. """ if ss is None: ss = ws ws = norm_shape(ws) ss = norm_shape(ss) # convert ws, ss, and a.shape to numpy arrays so that we can do math in # every dimension at once. ws = np.array(ws) ss = np.array(ss) shape = np.array(a.shape) # ensure that ws, ss, and a.shape all have the same number of dimensions ls = [len(shape), len(ws), len(ss)] if len(set(ls)) != 1: raise ValueError( 'a.shape, ws and ss must all have the same length.' 'They were %s' % str(ls) ) # ensure that ws is smaller than a in every dimension if np.any(ws > shape): raise ValueError( 'ws cannot be larger than a in any dimension. ' 'a.shape was %s and ws was %s' % (str(a.shape), str(ws)) ) # how many slices will there be in each dimension? newshape = norm_shape(((shape - ws) // ss) + 1) print 'newshape', newshape # the shape of the strided array will be the number of slices in each # dimension plus the shape of the window (tuple addition) newshape += norm_shape(ws) # the strides tuple will be the array's strides multiplied by step size, # plus the array's strides (tuple addition) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides strided = ast(a, shape=newshape, strides=newstrides) if not flatten: return strided else: # Collapse strided so that it has one more dimension than the window. # i.e. the new array is a flat list of slices. meat = len(ws) if ws.shape else 0 firstdim = (np.product(newshape[:-meat]),) if ws.shape else () dim = firstdim + (newshape[-meat:]) # remove any dimensions with size 1 dim = filter(lambda i: i != 1, dim) return strided.reshape(dim)
def AR_striding(data,nlags): if data.ndim == 1: data = np.reshape(data,(-1,1)) sz = data.dtype.itemsize return ast(data,shape=(data.shape[0]-nlags,data.shape[1]*(nlags+1)),strides=(data.shape[1]*sz,sz))
def overlap(d): return ast(d, shape=(vec_len/increment,block), strides=(increment*spacing, spacing))
def sliding_window(a,ws,ss = None,flatten = True): ''' Return a sliding window over a in any number of dimensions ''' if None is ss: # ss was not provided. the windows will not overlap in any direction. ss = ws ws = norm_shape(ws) ss = norm_shape(ss) # convert ws, ss, and a.shape to numpy arrays ws = np.array(ws) ss = np.array(ss) #import PyHum.io as io shape_tmp = io.set_mmap_data('', '', 'tmp.dat', 'float32', a) del a a = io.get_mmap_data('', '', 'tmp.dat', 'float32', shape_tmp) shap = np.array(a.shape) try: os.remove('tmp.dat') except: pass # ensure that ws, ss, and a.shape all have the same number of dimensions ls = [len(shap),len(ws),len(ss)] if 1 != len(set(ls)): raise ValueError(\ 'a.shape, ws and ss must all have the same length. They were %s' % str(ls)) # ensure that ws is smaller than a in every dimension if np.any(ws > shap): raise ValueError(\ 'ws cannot be larger than a in any dimension.\ a.shape was %s and ws was %s' % (str(a.shape),str(ws))) # how many slices will there be in each dimension? newshape = norm_shape(((shap - ws) // ss) + 1) # the shape of the strided array will be the number of slices in each dimension # plus the shape of the window (tuple addition) newshape += norm_shape(ws) # the strides tuple will be the array's strides multiplied by step size, plus try: # the array's strides (tuple addition) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides a = ast(a,shape = newshape,strides = newstrides) if not flatten: return a # Collapse strided so that it has one more dimension than the window. I.e., # the new array is a flat list of slices. meat = len(ws) if ws.shape else 0 firstdim = (int(np.product(newshape[:-meat])),) if ws.shape else () dim = firstdim + (newshape[-meat:]) # remove any dimensions with size 1 dim = filter(lambda i : i != 1,dim) return a.reshape(dim), newshape except: from itertools import product print "memory error, windowing using slower method" # For each dimension, create a list of all valid slices slices = [[] for i in range(len(ws))] for i in xrange(len(ws)): nslices = ((shap[i] - ws[i]) // ss[i]) + 1 for j in xrange(0,nslices): start = j * ss[i] stop = start + ws[i] slices[i].append(slice(start,stop)) # Get an iterator over all valid n-dimensional slices of the input allslices = product(*slices) # Allocate memory to hold all valid n-dimensional slices nslices = np.product([len(s) for s in slices]) #out = np.ndarray((nslices,) + tuple(ws),dtype = a.dtype) out=[] for i,s in enumerate(allslices): #out[i] = a[s] out.append(a[s]) del a import dask.bag as db tmp = db.from_sequence(out, npartitions=1000) del out return tmp.compute(), newshape
def block_view(A, block= (32, 32)): # simple shape and strides computations may seem at first strange # unless one is able to recognize the 'tuple additions' involved ;-) shape= (A.shape[0]/ block[0], A.shape[1]/ block[1])+ block strides= (block[0]* A.strides[0], block[1]* A.strides[1])+ A.strides return ast(A, shape= shape, strides= strides)
def sliding_window(a,ws,ss = None,flatten = True): ''' Return a sliding window over a in any number of dimensions ''' if None is ss: # ss was not provided. the windows will not overlap in any direction. ss = ws ws = norm_shape(ws) ss = norm_shape(ss) # convert ws, ss, and a.shape to numpy arrays ws = np.array(ws) ss = np.array(ss) import PyHum.io as io shape_tmp = io.set_mmap_data('', '', 'tmp.dat', 'float32', a) del a a = io.get_mmap_data('', '', 'tmp.dat', 'float32', shape_tmp) shap = np.array(a.shape) try: os.remove('tmp.dat') except: pass # ensure that ws, ss, and a.shape all have the same number of dimensions ls = [len(shap),len(ws),len(ss)] if 1 != len(set(ls)): raise ValueError(\ 'a.shape, ws and ss must all have the same length. They were %s' % str(ls)) # ensure that ws is smaller than a in every dimension if np.any(ws > shap): raise ValueError(\ 'ws cannot be larger than a in any dimension.\ a.shape was %s and ws was %s' % (str(a.shape),str(ws))) # how many slices will there be in each dimension? newshape = norm_shape(((shap - ws) // ss) + 1) # the shape of the strided array will be the number of slices in each dimension # plus the shape of the window (tuple addition) newshape += norm_shape(ws) # the strides tuple will be the array's strides multiplied by step size, plus try: # the array's strides (tuple addition) newstrides = norm_shape(np.array(a.strides) * ss) + a.strides a = ast(a,shape = newshape,strides = newstrides) if not flatten: return a # Collapse strided so that it has one more dimension than the window. I.e., # the new array is a flat list of slices. meat = len(ws) if ws.shape else 0 firstdim = (int(np.product(newshape[:-meat])),) if ws.shape else () dim = firstdim + (newshape[-meat:]) # remove any dimensions with size 1 dim = filter(lambda i : i != 1,dim) return a.reshape(dim), newshape except: from itertools import product print("memory error, windowing using slower method") # For each dimension, create a list of all valid slices slices = [[] for i in range(len(ws))] for i in range(len(ws)): nslices = ((shap[i] - ws[i]) // ss[i]) + 1 for j in range(0,nslices): start = j * ss[i] stop = start + ws[i] slices[i].append(slice(start,stop)) # Get an iterator over all valid n-dimensional slices of the input allslices = product(*slices) # Allocate memory to hold all valid n-dimensional slices nslices = np.product([len(s) for s in slices]) #out = np.ndarray((nslices,) + tuple(ws),dtype = a.dtype) out=[] for i,s in enumerate(allslices): #out[i] = a[s] out.append(a[s]) del a import dask.bag as db tmp = db.from_sequence(out, npartitions=1000) del out return tmp.compute(), newshape
def block_view(self, A, block=(32, 32)): shape = (A.shape[0] // block[0], A.shape[1] // block[1]) + block strides = (block[0] * A.strides[0], block[1] * A.strides[1]) + A.strides return ast(A, shape=shape, strides=strides)
def slide_tensor4(tensor4, window_shape, strides): """ :param tensor4: minibatch size x number of channels x image height x image width :param window_shape: (window_height, window_width) :param strides: (height_step, width_step) :return: tensor4 -> minibatch size x number of channels x number of windows in image x window_width * window_height Description: Slide tensor4 by window with strides step. For that it just changes tensor4 internal numpy stride representation so it must be very fast. Between window and image shape the following must be true: ((img_shp - window_shape) / strides) + 1 == integer Otherwise it is impossible to tile images equally. Usage/Doctests: Simple example 2x2 window with step 1 along each dimension. In 3x3 image 4 windows in total >>> tensor4 = np.arange(9).reshape(1, 1, 3, 3) >>> tensor4 array([[[[0, 1, 2], [3, 4, 5], [6, 7, 8]]]]) >>> slide_tensor4(tensor4, (2,2), (1,1)) array([[[[0, 1, 3, 4], [1, 2, 4, 5], [3, 4, 6, 7], [4, 5, 7, 8]]]]) >>> tensor4 = np.arange(9).reshape(1, 1, 3, 3) >>> tensor4 array([[[[0, 1, 2], [3, 4, 5], [6, 7, 8]]]]) >>> slide_tensor4(tensor4, (2,3), (1,1)) array([[[[0, 1, 2, 3, 4, 5], [3, 4, 5, 6, 7, 8]]]]) >>> tensor4 = np.arange(12).reshape(1, 1, 4, 3) >>> tensor4 array([[[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]]]]) >>> slide_tensor4(tensor4, (2,2), (2,1)) array([[[[ 0, 1, 3, 4], [ 1, 2, 4, 5], [ 6, 7, 9, 10], [ 7, 8, 10, 11]]]]) Example with windows without overlapping. 4 windows in total >>> tensor4 = np.arange(36).reshape(1, 1, 6, 6) >>> tensor4 array([[[[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35]]]]) >>> slide_tensor4(tensor4, (3,3), (3,3)) array([[[[ 0, 1, 2, 6, 7, 8, 12, 13, 14], [ 3, 4, 5, 9, 10, 11, 15, 16, 17], [18, 19, 20, 24, 25, 26, 30, 31, 32], [21, 22, 23, 27, 28, 29, 33, 34, 35]]]]) #Example with 2 images in minibatch and 2 channels >>> tensor4 = np.arange(36).reshape(2, 2, 3, 3) >>> tensor4 array([[[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]], <BLANKLINE> [[ 9, 10, 11], [12, 13, 14], [15, 16, 17]]], <BLANKLINE> <BLANKLINE> [[[18, 19, 20], [21, 22, 23], [24, 25, 26]], <BLANKLINE> [[27, 28, 29], [30, 31, 32], [33, 34, 35]]]]) >>> slide_tensor4(tensor4, (2,2), (1,1)) array([[[[ 0, 1, 3, 4], [ 1, 2, 4, 5], [ 3, 4, 6, 7], [ 4, 5, 7, 8]], <BLANKLINE> [[ 9, 10, 12, 13], [10, 11, 13, 14], [12, 13, 15, 16], [13, 14, 16, 17]]], <BLANKLINE> <BLANKLINE> [[[18, 19, 21, 22], [19, 20, 22, 23], [21, 22, 24, 25], [22, 23, 25, 26]], <BLANKLINE> [[27, 28, 30, 31], [28, 29, 31, 32], [30, 31, 33, 34], [31, 32, 34, 35]]]]) """ t4 = tensor4 #convert to array for easy algebraic manipulations wd = np.array(window_shape) ss = np.array(strides) img_shp = np.array(t4.shape[2:4]) dim_check = ((img_shp - wd) % ss) if dim_check[0] != 0 or dim_check[1] != 0: raise ValueError("impossible to tile with given strides {0}, window shape {1}, tensor4 shape {2}"\ .format(strides, window_shape, tensor4.shape)) slide_shp = ((img_shp - wd) / ss) + 1 #using tuple addition (1, 2) + (3, 4) = (1, 2, 3, 4) new_shp = t4.shape[0:2] + tuple(slide_shp) + tuple(wd) new_str = t4.strides[0:2] + tuple( np.array(t4.strides[2:4]) * ss) + t4.strides[2:4] #change internal memory numpy array t4 representation #more here: http://www.johnvinyard.com/blog/?p=268 strided = ast(t4, shape=new_shp, strides=new_str) final_shape = t4.shape[0:2] + (slide_shp.prod(), ) + (wd.prod(), ) return strided.reshape(final_shape)
def undo_AR_striding(strided_data,nlags): sz = strided_data.dtype.itemsize return ast( strided_data, shape=(strided_data.shape[0]+nlags,strided_data.shape[1]/(nlags+1)), strides=(strided_data.shape[1]/(nlags+1)*sz,sz))
def block_view(a, block_shape): shape = (a.shape[0] / block_shape[0], a.shape[1] / block_shape[1]) + block_shape strides = (a.strides[0] * block_shape[0], a.strides[1] * block_shape[1]) + a.strides return ast(a, shape=shape, strides=strides)
def block_view(a,block_shape): shape = (a.shape[0]/block_shape[0],a.shape[1]/block_shape[1]) + block_shape strides = (a.strides[0]*block_shape[0],a.strides[1]*block_shape[1]) + a.strides return ast(a,shape=shape,strides=strides)
def block_view(A, block=(32, 32)): # simple shape and strides computations may seem at first strange # unless one is able to recognize the 'tuple additions' involved ;-) shape = (A.shape[0] / block[0], A.shape[1] / block[1]) + block strides = (block[0] * A.strides[0], block[1] * A.strides[1]) + A.strides return ast(A, shape=shape, strides=strides)