def lcn_2d(im, sigmas=[1.591, 1.591]): """ Apply local contrast normalization to a square image. Uses a scheme described in Pinto et al (2008) Based on matlab code by Koray Kavukcuoglu http://cs.nyu.edu/~koray/publis/code/randomc101.tar.gz data is 2-d sigmas is a 2-d vector of standard devs (to define local smoothing kernel) Example ======= im_p = lcn_2d(im,[1.591, 1.591]) """ # assert(issubclass(im.dtype.type, np.floating)) im = np.cast[np.float](im) # 1. subtract the mean and divide by std dev mn = np.mean(im) sd = np.std(im, ddof=1) im -= mn im /= sd # # 2. compute local mean and std # kerstring = '''0.0001 0.0005 0.0012 0.0022 0.0027 0.0022 0.0012 0.0005 0.0001 # 0.0005 0.0018 0.0049 0.0088 0.0107 0.0088 0.0049 0.0018 0.0005 # 0.0012 0.0049 0.0131 0.0236 0.0288 0.0236 0.0131 0.0049 0.0012 # 0.0022 0.0088 0.0236 0.0427 0.0520 0.0427 0.0236 0.0088 0.0022 # 0.0027 0.0107 0.0288 0.0520 0.0634 0.0520 0.0288 0.0107 0.0027 # 0.0022 0.0088 0.0236 0.0427 0.0520 0.0427 0.0236 0.0088 0.0022 # 0.0012 0.0049 0.0131 0.0236 0.0288 0.0236 0.0131 0.0049 0.0012 # 0.0005 0.0018 0.0049 0.0088 0.0107 0.0088 0.0049 0.0018 0.0005 # 0.0001 0.0005 0.0012 0.0022 0.0027 0.0022 0.0012 0.0005 0.0001''' # ker = [] # for l in kerstring.split('\n'): # ker.append(np.fromstring(l, dtype=np.float, sep=' ')) # ker = np.asarray(ker) # lmn = scipy.signal.correlate2d(im, ker, mode='same', boundary='symm') # lmnsq = scipy.signal.correlate2d(im ** 2, ker, mode='same', boundary='symm') lmn = gaussian_filter(im, sigmas, mode='reflect') lmnsq = gaussian_filter(im**2, sigmas, mode='reflect') lvar = lmnsq - lmn**2 # lvar = np.where( lvar < 0, lvar, 0) np.clip(lvar, 0, np.inf, lvar) # items < 0 set to 0 lstd = np.sqrt(lvar) np.clip(lstd, 1, np.inf, lstd) im -= lmn im /= lstd return im
def LCNinput(data, kernel_shape): X = T.ftensor4() filter_shape = (1, 1, kernel_shape, kernel_shape) filters = sharedX(gaussian_filter(kernel_shape).reshape(filter_shape)) convout = conv2d(X, filters=filters, border_mode='full') # For each pixel, remove mean of 9x9 neighborhood mid = int(np.floor(kernel_shape/ 2.)) centered_X = X - convout[:,:,mid:-mid,mid:-mid] # Scale down norm of 9x9 patch if norm is bigger than 1 sum_sqr_XX = conv2d(T.sqr(X), filters=filters, border_mode='full') denom = T.sqrt(sum_sqr_XX[:,:,mid:-mid,mid:-mid]) per_img_mean = denom.mean(axis = [2,3]) divisor = T.largest(per_img_mean.dimshuffle(0,1, 'x', 'x'), denom) new_X = centered_X / T.maximum(1., divisor) # new_X = new_X[:,:,mid:-mid, mid:-mid] f = theano.function([X], new_X) return f(data)
def LCN(data, kernel_shape): # X = T.ftensor4() filter_shape = (1, 1, kernel_shape, kernel_shape) filters = sharedX(gaussian_filter(kernel_shape).reshape(filter_shape)) convout = conv2d(data, filters=filters, border_mode='full') # For each pixel, remove mean of 9x9 neighborhood mid = int(np.floor(kernel_shape/ 2.)) centered_X = data - convout[:,:,mid:-mid,mid:-mid] # Scale down norm of 9x9 patch if norm is bigger than 1 sum_sqr_XX = conv2d(T.sqr(data), filters=filters, border_mode='full') denom = T.sqrt(sum_sqr_XX[:,:,mid:-mid,mid:-mid]) per_img_mean = denom.mean(axis = [2,3]) divisor = T.largest(per_img_mean.dimshuffle(0, 1, 'x', 'x'), denom) new_X = centered_X / T.maximum(1., divisor) # new_X = new_X[:,:,mid:-mid, mid:-mid] new_X = T.extra_ops.squeeze(new_X) # remove broadcastable dimension new_X = new_X[:, 0, :, :] # TODO: check whether this forced squeeze is good return new_X
def lcn_3d_input(data, kernel_shape, n_maps): """ :param data: [examples, depth, filters, height, width] :param kernel_shape: int :param n_maps: int :return: new_x: [examples, depth, filters, height, width] """ # create symbolic variable for the input data ftensor5 = T.TensorType('float32', [False] * 5) x = ftensor5() # # determine the number of maps # n_maps = data.shape[2] # create 3d filter that spans across all channels / feature maps # todo: kernel is not really in 3d; need 3d implementation instead of 2d repeated across third dimension # todo: alternative is to keep 2d kernel and extend short range given data size in z-plane; change first kernel_sh. filter_shape = (1, kernel_shape[0], n_maps, kernel_shape[1], kernel_shape[2]) filters = np.resize(gaussian_filter(kernel_shape[1]), filter_shape) filters = filters / np.sum(filters) filters = sharedX(filters) # convolve filter with input signal convolution_out = conv3d( signals=x, filters=filters, signals_shape=data.shape, filters_shape=filter_shape, border_mode='valid' ) # for each pixel, remove mean of 9x9 neighborhood mid_0 = int(np.floor(kernel_shape[0] / 2.)) mid_1 = int(np.floor(kernel_shape[1] / 2.)) mid_2 = int(np.floor(kernel_shape[2] / 2.)) mean = T.tile(convolution_out, (1, 1, n_maps, 1, 1)) padded_mean = T.zeros_like(x) padded_mean = T.set_subtensor(padded_mean[:, mid_0:-mid_0, :, mid_1:-mid_1, mid_2:-mid_2], mean) centered_data = data - padded_mean # scale down norm of 9x9 patch if norm is bigger than 1 sum_sqr_xx = conv3d(signals=T.sqr(data), filters=filters) denominator = T.tile(T.sqrt(sum_sqr_xx), (1, 1, n_maps, 1, 1)) padded_denominator = T.ones_like(x) padded_denominator = T.set_subtensor( padded_denominator[:, mid_0:-mid_0, :, mid_1:-mid_1, mid_2:-mid_2], denominator ) per_img_mean = padded_denominator.mean(axis=[1, 2, 3, 4]) divisor = T.largest( per_img_mean.dimshuffle(0, 'x', 'x', 'x', 'x'), padded_denominator ) new_x = centered_data / T.maximum(1., divisor) # compile theano function f = theano.function([x], new_x) return f(data)
def gen_fcn(batch_size, img_shape, kernel_size, data_type='float32', threshold=1e-4): ''' generate theano function for doing lecun lcn of a given setting modified from lecun_lcn in pylearn2.datasets.preprocessing currently data_type can only be float32 if not, will report error saying input and kernel should be the same type and kernel type is float32 ''' X = tensor.matrix(dtype=data_type) X = X.reshape((batch_size, img_shape[0], img_shape[1], 1)) filter_shape = (1, 1, kernel_size, kernel_size) filters = sharedX(gaussian_filter(kernel_size).reshape(filter_shape)) input_space = Conv2DSpace(shape=img_shape, num_channels=1) transformer = Conv2D(filters=filters, batch_size=batch_size, input_space=input_space, border_mode='full') convout = transformer.lmul(X) # For each pixel, remove mean of 9x9 neighborhood mid = int(np.floor(kernel_size / 2.)) centered_X = X - convout[:, mid:-mid, mid:-mid, :] # Scale down norm of 9x9 patch if norm is bigger than 1 transformer = Conv2D(filters=filters, batch_size=batch_size, input_space=input_space, border_mode='full') sum_sqr_XX = transformer.lmul(X**2) denom = tensor.sqrt(sum_sqr_XX[:, mid:-mid, mid:-mid, :]) per_img_mean = denom.mean(axis=[1, 2]) divisor = tensor.largest(per_img_mean.dimshuffle(0, 'x', 'x', 1), denom) divisor = tensor.maximum(divisor, threshold) new_X = centered_X / divisor new_X = tensor.flatten(new_X, outdim=3) f = function([X], new_X) return f
def lcn_lacombe(data, kernel_shape, n_maps): # create basic filter that spans all feature maps filter_shape = (1, n_maps, kernel_shape, kernel_shape) filters = np.resize(gaussian_filter(kernel_shape), filter_shape) filters = filters / np.sum( filters ) # todo: don't scale as this makes input much smaller than weights filters = sharedX(filters) # for feature_map in xrange(data.shape[0]): # # temp[1, feature_map, :, :] = filters # # temp = temp / ml.repmat(np.sum(temp), (1, data.shape[0], kernel_shape, kernel_shape)) # filters = sharedX(temp) # data = [examples, maps, length, width]; filters = [1, maps, kernel_shape, kernel_shape] # output = [examples, 1, length - (kernel_shape - 1), width - (kernel_shape - 1)] convout = conv2d(data, filters=filters, border_mode='full') # convout = np.reshape(convout, (convout.shape[0], data.shape[1], convout.shape[2], convout.shape[3])) # For each pixel, remove mean of 9x9 neighborhood mid = int(np.floor(kernel_shape / 2.)) convout = convout[:, :, mid:-mid, mid:-mid] centered_X = data - T.tile(convout, (1, n_maps, 1, 1)) # Scale down norm of 9x9 patch if norm is bigger than 1 sum_sqr_XX = conv2d(T.sqr(data), filters=filters, border_mode='full') denom = T.sqrt(sum_sqr_XX[:, :, mid:-mid, mid:-mid]) per_img_mean = denom.mean(axis=[1, 2, 3]) divisor = T.largest(per_img_mean.dimshuffle(0, 'x', 'x', 'x'), T.tile(denom, (1, n_maps, 1, 1))) new_X = centered_X / T.maximum(1., divisor) # new_X = new_X[:, :, mid:-mid, mid:-mid] # maybe safer to return valid area return new_X
def lcn_lacombe(data, kernel_shape, n_maps): # create basic filter that spans all feature maps filter_shape = (1, n_maps, kernel_shape, kernel_shape) filters = np.resize(gaussian_filter(kernel_shape), filter_shape) filters = filters / np.sum(filters) # todo: don't scale as this makes input much smaller than weights filters = sharedX(filters) # for feature_map in xrange(data.shape[0]): # # temp[1, feature_map, :, :] = filters # # temp = temp / ml.repmat(np.sum(temp), (1, data.shape[0], kernel_shape, kernel_shape)) # filters = sharedX(temp) # data = [examples, maps, length, width]; filters = [1, maps, kernel_shape, kernel_shape] # output = [examples, 1, length - (kernel_shape - 1), width - (kernel_shape - 1)] convout = conv2d(data, filters=filters, border_mode='full') # convout = np.reshape(convout, (convout.shape[0], data.shape[1], convout.shape[2], convout.shape[3])) # For each pixel, remove mean of 9x9 neighborhood mid = int(np.floor(kernel_shape / 2.)) convout = convout[:, :, mid:-mid, mid:-mid] centered_X = data - T.tile(convout, (1, n_maps, 1, 1)) # Scale down norm of 9x9 patch if norm is bigger than 1 sum_sqr_XX = conv2d(T.sqr(data), filters=filters, border_mode='full') denom = T.sqrt(sum_sqr_XX[:, :, mid:-mid, mid:-mid]) per_img_mean = denom.mean(axis=[1, 2, 3]) divisor = T.largest(per_img_mean.dimshuffle(0, 'x', 'x', 'x'), T.tile(denom, (1, n_maps, 1, 1))) new_X = centered_X / T.maximum(1., divisor) # new_X = new_X[:, :, mid:-mid, mid:-mid] # maybe safer to return valid area return new_X
" image files, but contains " + str(len(paths))) kernel_shape = 7 from theano import tensor as T from pylearn2.utils import sharedX from pylearn2.datasets.preprocessing import gaussian_filter from theano.tensor.nnet import conv2d X = T.TensorType(dtype='float32', broadcastable=(True, False, False, True))() from theano import config if config.compute_test_value == 'raise': X.tag.test_value = np.zeros((1, 32, 32, 1), dtype=X.dtype) orig_X = X filter_shape = (1, 1, kernel_shape, kernel_shape) filters = sharedX(gaussian_filter(kernel_shape).reshape(filter_shape)) X = X.dimshuffle(0, 3, 1, 2) convout = conv2d(X, filters=filters, border_mode='full') # For each pixel, remove mean of 9x9 neighborhood mid = int(np.floor(kernel_shape / 2.)) centered_X = X - convout[:, :, mid:-mid, mid:-mid] # Scale down norm of 9x9 patch if norm is bigger than 1 sum_sqr_XX = conv2d(T.sqr(X), filters=filters, border_mode='full') denom = T.sqrt(sum_sqr_XX[:, :, mid:-mid, mid:-mid]) per_img_mean = denom.mean(axis=[2, 3]) divisor = T.largest(per_img_mean.dimshuffle(0, 1, 'x', 'x'), denom)