def connect(self, prev_layer: Layer): if prev_layer is not None: self.input_shape = prev_layer.output_shape else: assert self.input_shape is not None assert cp.prod(self.input_shape[1:]) == cp.prod(self.output_shape[1:]), "can not change the element's number" Layer.connect(self, prev_layer)
def __call__(self, layer: Layer)-> Layer: if layer is not None: self.input_shape = layer.output_shape else: assert self.input_shape is not None assert cp.prod(self.input_shape[1:]) == cp.prod(self.output_shape[1:]),"can not change the element's number" super(Reshape, self).__call__(layer) return self
def decompose_size(self, size): size = cp.array(size) if size.ndim == 2: fan_in, fan_out = size elif size.ndim == 4 or size.ndim == 5: respective_field_size = cp.prod(size[2:]) fan_in = size[1] * respective_field_size fan_out = size[0] * respective_field_size else: fan_in = fan_out = int(cp.sqrt(cp.prod(size))) return fan_in, fan_out
def wiener(im, mysize=None, noise=None): """ Perform a Wiener filter on an N-dimensional array. Apply a Wiener filter to the N-dimensional array `im`. Parameters ---------- im : ndarray An N-dimensional array. mysize : int or array_like, optional A scalar or an N-length list giving the size of the Wiener filter window in each dimension. Elements of mysize should be odd. If mysize is a scalar, then this scalar is used as the size in each dimension. noise : float, optional The noise-power to use. If None, then noise is estimated as the average of the local variance of the input. Returns ------- out : ndarray Wiener filtered result with the same shape as `im`. """ im = asarray(im) if mysize is None: mysize = [3] * im.ndim mysize = np.asarray(mysize) if mysize.shape == (): mysize = cp.repeat(mysize.item(), im.ndim) mysize = np.asarray(mysize) # Estimate the local mean lMean = correlate(im, ones(mysize), "same") / prod(mysize, axis=0) # Estimate the local variance lVar = ( correlate(im ** 2, ones(mysize), "same") / prod(mysize, axis=0) - lMean ** 2 ) # Estimate the noise power if needed. if noise is None: noise = mean(ravel(lVar), axis=0) res = im - lMean res *= 1 - noise / lVar res += lMean out = where(lVar < noise, lMean, res) return out
def downsample_gpu(image, size_out): """ Use Fourier methods to change the sample interval and/or aspect ratio of any dimensions of the input image. Uses CuPy. """ x = cp.fft.fftshift(cp.fft.fft2(image)) # crop x: nx, ny = x.shape nsx = int(cp.floor(nx/2) - cp.floor(size_out[1]/2)) nsy = int(cp.floor(ny/2) - cp.floor(size_out[0]/2)) fx = x[nsx : nsx + size_out[1], nsy : nsy + size_out[0]] output = cp.fft.ifft2(cp.fft.ifftshift(fx)) * (cp.prod(cp.array(size_out)) / cp.prod(cp.array(image.shape))) return cp.asnumpy(output.real)
def normal_density_cupy(x, mean, stddev, from_axis=None, eps=1e-8, gpu=0): import cupy as cp with cp.cuda.Device(gpu): variance = cp.maximum(stddev ** 2, eps) stddev = cp.maximum(stddev, eps) density = cp.exp(-cp.square(x - mean) / (2 * variance)) / (stddev * math.sqrt(2 * math.pi)) if (from_axis is not None) and (from_axis >= 0): shape = tuple(density.shape[:from_axis]) + (cp.prod(density.shape[from_axis:]),) density = cp.reshape(density, shape) density = cp.prod(density, axis=from_axis) return density
def __init__(self, name, observables, binning=None, interpolation=None, value=None): self.systematics = [ syst for dim_systs in zip(observables.scales, observables.shifts, observables.resolutions) for syst in dim_systs ] # Should be linked to something that loads MC when called (DataLoader) self.mc_param = observables.analysis.add_parameter(name + '_mc', fixed=False) self.cur_mc = None self.interpolation = interpolation self.binning = binning self.bin_edges = binning_to_edges(binning, lows=observables.lows, highs=observables.highs) self.indexes = [np.arange(len(edges)) for edges in self.bin_edges] self.a_kj, self.b_kj = edges_to_points(self.bin_edges) self.bin_centers = [(edges[:-1] + edges[1:]) / 2 for edges in self.bin_edges] self.bin_vol = cp.prod(self.b_kj - self.a_kj, axis=1) super().__init__(name, observables, [self.mc_param] + self.systematics, value=value)
def integrate_mc_gpu(func, limits, num): xs = sample_from(limits, num, cp.random.uniform) ys = func(xs) integral = cp.prod(cp.array([i[1] - i[0] for i in limits])) * cp.sum(ys) / num return integral
def prob(self, sample, **kwargs): if _GPU_ENABLED: prob = cp.prod( cp.asarray([self[key].prob(sample[key]) for key in sample]), **kwargs) return prob else: return super(PriorDict, self).prob(sample, **kwargs)
def __call__(self, layers): super(Flatten, self).__call__(layers) flatten_shape = cp.prod(cp.array(self.input_shape[self.out_dim - 1:])).tolist() flatten_shape = self.input_shape[:self.out_dim - 1] + (flatten_shape, ) self.output_shape = flatten_shape return self
def connect(self, prev_layer): assert len(prev_layer.output_shape) >= 3 flatten_shape = cp.prod( cp.array(prev_layer.output_shape[self.out_dim - 1:])).tolist() flatten_shape = prev_layer.output_shape[:self.out_dim - 1] + (flatten_shape, ) self.output_shape = flatten_shape Layer.connect(self, prev_layer)
def _get_region(im_height, im_width, center_x, center_y, sigma, bbox): radius = math.sqrt(np.prod(np.array(bbox[2:])) / np.pi) * sigma # top-left corner x0 = int(max(0, center_x - radius + 0.5)) y0 = int(max(0, center_y - radius + 0.5)) # bottom-right corner x1 = int(min(im_width - 1, center_x + radius + 0.5)) + 1 y1 = int(min(im_height - 1, center_y + radius + 0.5)) + 1 return y0, y1, x0, x1
def __call__(self, size): size = cp.array(size) flat_shape = (size[0].tolist(), cp.prod(size[1:]).tolist()) a = Normal(1.)(flat_shape) u, _, v = cp.linalg.svd(a, full_matrices=False) q = u if u.shape == flat_shape else v q = q.reshape(size.tolist()) q = self.gain * q return q
def repeat_to_match_shape(g, shape, dtype, axis, keepdims): """Returns the array g repeated along axis to fit vector space vs. Also returns the number of repetitions of the array.""" if shape == (): return g, 1 axis = list(axis) if isinstance(axis, tuple) else axis new_shape = ocp.array(shape) new_shape[axis] = 1 new_shape = tuple([int(i) for i in new_shape]) num_reps = ocp.prod(ocp.array(shape)[axis]) return acp.reshape(g, new_shape) + ocp.zeros(shape, dtype=dtype), num_reps
def _kdpdf0(x_j, t_ij, h_j, w_i): ''' x_j is the j-dimensional point to evaluate the PDF at t_ij are the i events in the PDF at j-dimensional points h_j are the bandwidths for all PDF events in dimension j ''' w = cp.sum(w_i) h_j_prod = cp.prod(KernelDensityPDF._inv_sqrt_2pi / h_j) res = h_j_prod * cp.sum( w_i * cp.exp(-0.5 * cp.sum(cp.square( (x_j - t_ij) / h_j), axis=1))) / w return res if np == cp else res.get()
def __init__(self,name,pdf,binning): from .signal import BinnedPDF super().__init__(name,[pdf]) self.pdf = pdf if isinstance(pdf,BinnedPDF) and pdf.binning == binning: self.binned_correctly = True else: self.binned_correctly = False self.bin_edges = binning_to_edges(binning) self.a_kj, self.b_kj = edges_to_points(self.bin_edges) self.bin_vol = cp.ascontiguousarray(cp.prod(self.b_kj-self.a_kj,axis=1)) self.last_systs = None self.bin_ints = None
def calc_loss(self, y_hat, y_true): to_sum_shape = cp.asarray(y_hat.shape[:-1]) avg = cp.prod(to_sum_shape) loss = 0 if y_hat.ndim == 2: for m in range(y_hat.shape[0]): loss -= cp.log(y_hat[m, y_true[m]]) elif y_hat.ndim == 3: for m in range(y_hat.shape[0]): for n in range(y_hat.shape[1]): loss -= cp.log(y_hat[m, n, y_true[m, n]]) loss /= avg return loss
def _kdpdf1(x_j, t_ij, h_ij, w_i): ''' Evaluate a the normalized PDF at a single point using generic NumPy/CuPy code instead of a dedicated CUDA kernel. x_j is the j-dimensional point to evaluate the PDF at t_ij are the i events in the PDF at j-dimensional points h_ij are the bandwidths of each PDF event i in dimension j w_i are the weights of each PDF event ''' res = cp.sum( w_i * cp.prod(KernelDensityPDF._inv_sqrt_2pi / h_ij, axis=1) * cp.exp(-0.5 * cp.sum(cp.square((x_j - t_ij) / h_ij), axis=1))) return res if np == cp else res.get()
def normal_log_density_cupy(x, mean, stddev, from_axis=None, eps=1e-8, gpu=0): import cupy as cp with cp.cuda.Device(gpu): variance = cp.maximum(stddev ** 2, eps) log_stddev = cp.log(cp.maximum(stddev, eps)) log_density = -0.5 * (math.log(2 * math.pi) + 2 * log_stddev + ((x - mean)**2 / variance)) if (from_axis is not None) and (from_axis >= 0): shape = tuple(log_density.shape[:from_axis]) + (cp.prod(log_density.shape[from_axis:]),) log_density = cp.reshape(log_density, shape) log_density = cp.sum(log_density, axis=from_axis) return log_density
def prod(tensor, axis=None, dtype=None, out=None, keepdims=False): """Returns the product of an array along a given axis. Args: tensor (ndarray): Array to take the maximum. axis (int): Along which axis to take the maximum. The flattened array is used by default. Defaults to None. dtype: Data type specifier. out (ndarray): Output array. Default to None. keepdims (bool): If ``True``, the axis is kept as an axis of size one. Default to False. Returns: ndarray: The maximum of ``tensor``, along the axis if specified. """ return cp.prod(tensor, axis=axis, out=out, keepdims=keepdims, dtype=dtype)
def add_water(self, atom_histograms_gpu): vacs = cp.prod(cp.where(atom_histograms_gpu == 0, True, False), axis=0) # average number of water molecules in a voxel vox_wat_num = water_num_dens * self.d1 * self.d2 * self.dz box = (self.n_slice, self.n1, self.n2) oxygens = cp.where(vacs, cp.random.poisson(vox_wat_num, box), 0).astype(cp.int) hydrogens = cp.where(vacs, cp.random.poisson(vox_wat_num * 2, box), 0).astype(cp.int) unique_elements_list = list(self.unique_elements) for z, hist in [(1, hydrogens), (8, oxygens)]: idx = unique_elements_list.index(z) atom_histograms_gpu[idx] += hist return atom_histograms_gpu
def _int_kdpdf1(a_j, b_j, t_ij, h_ij, w_i, get=True): ''' Integrates the PDF evaluated by _kdpdf1 and _kdpdf1_multi. a_j and b_j are the j-dimensional points represneting the lower and upper bounds of integration t_ij are the i events in the PDF at j-dimensional points h_ij are the bandwidths of each PDF event i in dimension j w_i are the weights of each PDF event ''' w = cp.sum(w_i) n = t_ij.shape[0] d = t_ij.shape[1] res = cp.sum(w_i * cp.prod(erf( (b_j - t_ij) / h_ij / KernelDensityPDF._sqrt2) - erf( (a_j - t_ij) / h_ij / KernelDensityPDF._sqrt2), axis=1)) / w / (2**d) return res.get() if get else res
def wiener(im, mysize=None, noise=None): """ Perform a Wiener filter on an N-dimensional array. Apply a Wiener filter to the N-dimensional array `im`. Parameters ---------- im : ndarray An N-dimensional array. mysize : int or array_like, optional A scalar or an N-length list giving the size of the Wiener filter window in each dimension. Elements of mysize should be odd. If mysize is a scalar, then this scalar is used as the size in each dimension. noise : float, optional The noise-power to use. If None, then noise is estimated as the average of the local variance of the input. Returns ------- out : ndarray Wiener filtered result with the same shape as `im`. """ im = cp.asarray(im) if mysize is None: mysize = [3] * im.ndim mysize = np.asarray(mysize) if mysize.shape == (): mysize = cp.repeat(mysize.item(), im.ndim) mysize = np.asarray(mysize) lprod = cp.prod(mysize, axis=0) lMean = correlate(im, cp.ones(mysize), "same") lVar = correlate(im**2, cp.ones(mysize), "same") lMean, lVar = _wiener_prep_kernel(lMean, lVar, lprod) # Estimate the noise power if needed. if noise is None: noise = cp.mean(cp.ravel(lVar), axis=0) return _wiener_post_kernel(im, lMean, lVar, noise)
def _adapt_bandwidth(self, w_i=None): ''' Calculates and returns bandwidths for all pdf events. ''' n = self.t_ij.shape[0] d = len(self.observables.dimensions) sigma = cp.prod(self.sigma_j)**(1 / d) estimates = self._estimate_pdf_multi(self.t_ij, w_i=w_i, get=False) h_i = (4/(d+2))**(1/(d+4)) \ * n**(-1/(d+4)) \ / sigma \ / estimates**(1/d) h_ij = cp.outer(h_i, self.rho * self.sigma_j) if cp.any(cp.isnan(h_ij)): print('d:', d, 'n:', n, 'sigma:', sigma) print('sigma_j:', self.sigma_j) print('small_estimates', estimates[estimates < 1e-8]) raise Exception('NaN bandwidths in ' + self.name) cp.cuda.Stream.null.synchronize() return cp.ascontiguousarray(h_ij)
def _arg_min_or_max(self, axis, out, op, compare): if out is not None: raise ValueError("Sparse matrices do not support " "an 'out' parameter.") sputils.validateaxis(axis) if axis is None: if 0 in self.shape: raise ValueError("Can't apply the operation to " "an empty matrix.") if self.nnz == 0: return 0 else: zero = self.dtype.type(0) mat = self.tocoo() mat.sum_duplicates() am = op(mat.data) m = mat.data[am] if compare(m, zero): return mat.row[am] * mat.shape[1] + mat.col[am] else: size = cupy.prod(mat.shape) if size == mat.nnz: return am else: ind = mat.row * mat.shape[1] + mat.col zero_ind = _find_missing_index(ind, size) if m == zero: return min(zero_ind, am) else: return zero_ind if axis < 0: axis += 2 return self._arg_min_or_max_axis(axis, op)
def __init__(self, name, signals, observables, binning=21, nan_behavior='unlikely'): self.nan_behavior = nan_behavior self.bin_edges = binning_to_edges(binning, lows=observables.lows, highs=observables.highs) self.a_kj, self.b_kj = edges_to_points(self.bin_edges) self.bin_vol = cp.ascontiguousarray( cp.prod(self.b_kj - self.a_kj, axis=1)) self.signals = signals self.observables = observables n_evs = [s.nev_param for s in signals] binned_signals = [ PDFBinner(s.name + '_binner', s, binning=binning) for s in signals ] super().__init__(name, n_evs + binned_signals + [observables]) self.last_x_kj = None
def backward(self, y_hat, y_true): # to_sum_shape = cp.asarray(y_hat.shape[:-1]) # avg = cp.prod(to_sum_shape) # idx = [] # for s in to_sum_shape: # idx.append(cp.arange(s).tolist()) # idx.append(y_true.flatten().tolist()) # # y_hat[idx]-=1 # return y_hat/avg to_sum_shape = cp.asarray(y_hat.shape[:-1]) avg = cp.prod(to_sum_shape) output = y_hat if y_hat.ndim == 2: for m in range(y_hat.shape[0]): output[m, y_true[m]] -= 1 elif y_hat.ndim == 3: for m in range(y_hat.shape[0]): for n in range(y_hat.shape[1]): output[m, n, y_true[m, n]] -= 1 output /= avg return output
def backward(self): grads=self.grads gamma,beta=self.variables outputs=cp.zeros_like(grads) for k in range(grads.shape[self.axis]): xmu,sqrtvar,normalzied_x=self.cache[k] if beta.require_grads: beta.grads[k]+=cp.sum(grads[:,k]) if gamma.require_grads: gamma.grads[k]+=cp.sum(grads[:,k]*normalzied_x) dnormalized_x=grads[:,k]*gamma.output_tensor[k] # equals to var^-3/2,where sqrtvar=var^1/2 dvar=cp.sum(cp.power(-1./sqrtvar,3)*xmu*dnormalized_x*0.5) dmean=cp.sum(-dnormalized_x/sqrtvar)-dvar*2*cp.mean(xmu) m=cp.prod(cp.asarray(xmu.shape)).tolist() outputs[:,k]=dnormalized_x/sqrtvar+dvar*2*xmu/m+dmean/m for layer in self.inbound_layers: if layer.require_grads: layer.grads+=outputs else: layer.grads=grads
def ts_product(x, window): if window > len(x): return cp.full(len(x), cp.nan) # # 增加对溢出的处理 # max_element = cp.max(cp.abs(x)) # if max_element**window == cp.inf: # return cp.nan # 对于有空值的地方,开方再取幂 # exp_nan_inf = window / ts_count_not_nan_inf(x, window) # 空值,填充为1 x = cp.where(cp.isinf(x), cp.nan, x) pre_fix = cp.full(window - 1, cp.nan) x_rolling_array = cp_rolling_window(x, window) result = cp.prod(x_rolling_array, axis=1) # 指数放缩, 有一个奇怪的现象就是1^nan = 1 # result = cp.sign(result) * (cp.abs(result)**exp_nan_inf) # 当window内均为nan时,处理为nan # result[cp.isnan(exp_nan_inf)] = cp.nan return cp.concatenate((pre_fix, result))
def __init__(self, name, observables, reflect_axes=None, value=None, bootstrap_binning=None, rho=1.0): self.rho = rho self.bootstrap_binning = bootstrap_binning if bootstrap_binning is not None: self.bin_edges = binning_to_edges(bootstrap_binning, lows=observables.lows, highs=observables.highs) self.indexes = [np.arange(len(edges)) for edges in self.bin_edges] self.a_kj, self.b_kj = edges_to_points(self.bin_edges) self.bin_centers = [(edges[:-1] + edges[1:]) / 2 for edges in self.bin_edges] self.bin_vol = cp.ascontiguousarray( cp.prod(self.b_kj - self.a_kj, axis=1)) self.reflect_axes = reflect_axes if reflect_axes is not None else [ False for _ in range(len(observables.dimensions)) ] self.a = cp.asarray([l for l in observables.lows]) self.b = cp.asarray([h for h in observables.highs]) self.systematics = [ syst for dim_systs in zip(observables.scales, observables.shifts, observables.resolutions) for syst in dim_systs ] # Should be linked to something that loads MC when called (DataLoader) self.mc_param = observables.analysis.add_parameter(name + '_mc', fixed=False) self.cur_mc = None super().__init__(name, observables, [self.mc_param] + self.systematics, value=value)