def unfold_tensor(self, X): r = self.n_components if not self.learn_joint_dict: X_unfold = tl_unfold(X, mode=self.mode) # d, n = X_unfold.shape else: X_unfold = tl_unfold(X, mode=self.mode).T # d, n = X_unfold.shape return X_unfold
def image_to_patches(self, path, patch_size=7, iterations=500, batch_size=20, color=False, downscale_factor=2, is_matrix=False, is_recons=False): ''' #***** args: path (string): Path and filename of input image patch_size (int): Pixel dimension of square patches taken of image color (boolean): Specifies conversion of image to RGB (True) or grayscale (False). Default value = false. When color = True, images in gray colorspace will still appear gray, but will thereafter be represented in RGB colorspace using three channels. downscale_factor: Specifies the extent to which the image will be downscaled. Greater values will result in more downscaling but faster speed. For no downscaling, use downscale_factor=1. returns: #*** ''' #open image and convert it to either RGB (three channel) or grayscale (one channel) if is_matrix: img = np.load(path) data = (img + 1) / 2 # it was +-1 matrix; now it is 0-1 matrix else: img = Image.open(path) if color: img = img.convert('RGB') img = tl_unfold(img, mode=2).T print('img.shape_color_after_unfolding', img.shape) else: img = img.convert('L') # normalize pixel values (range 0-1) data = np.asarray(img) / 255 ''' img = np.load(path) data = (img + 1) / 2 # it was +-1 matrix; now it is 0-1 matrix ''' if DEBUG: print(np.asarray(img)) # downscale image for speed if downscale_factor > 1: data = downscale_local_mean(data, (downscale_factor, downscale_factor)) # show_array(data) if not is_recons: patches = extract_patches_2d(data, (patch_size, patch_size), max_patches=iterations * batch_size) else: # for reconstruction we need to use all patches not to mess up with the ordering patches = extract_patches_2d(data, (patch_size, patch_size)) # we do not need more than iterations*batch_size patches for training dictionaries # convert 7x7 squares to 1d (49,) vectors patches_flat = patches.reshape(len(patches), -1).T # (Num patches)*(7*7) array # .reshape(len(patches),-1) makes it two dimensional -- (Num patches)*(whatever that's correct) # take transpose to make it 49 * (Num patches) print(patches_flat.shape) return patches_flat
def train_dict_single(self): ''' Given data tensor X and mode=i, learn dictionary matrix W and the complementary joint sparse code H. Reduce to matrix factorization by unfolding X along mode i ---------------if 'learn_joint_dict' = False: args: X (numpy array): data tensor with dimensions = (d) x (n) x (m) W (numpy array): dictionary matrix with dimensions = features (d) x topics (r) if mode=0 = features (n) x topics (r) if mode=1 = features (m) x topics (r) if mode=2 method: X(i) = mode-i (Katri-Rao) unfolding of tensor X with dimensions = (d) x (n m) if mode = 0 = (n) x (d m) if mode = 1 = (m) x (d n) if mode = 2 find sparse code H such that X(i) \approx W @ H using online matrix factorization returns: H (numpy array): code matrix with dimensions = (r) x (n m) if mode = 0 = (r) x (d m) if mode = 1 = (r) x (d n) if mode = 2 if 'learn_joint_dict = False': ---------------if 'learn_joint_dict' = True: args: X (numpy array): data tensor with dimensions = (d) x (n) x (m) W (numpy array): dictionary matrix with dimensions = features (n m) x topics (r) if mode=0 = features (d m) x topics (r) if mode=1 = features (d n) x topics (r) if mode=2 method: X(i) = mode-i (Katri-Rao) unfolding of tensor X with dimensions = (n m) x (d) if mode = 0 = (d m) x (n) if mode = 1 = (d n) x (m) if mode = 2 find sparse code H such that X(i) \approx W @ H using online matrix factorization returns: H (numpy array): code matrix with dimensions = (r) x (d) if mode = 0 = (r) x (n) if mode = 1 = (r) x (m) if mode = 2 ''' r = self.n_components ### matricize the tensor input if not self.learn_joint_dict: X_unfold = tl_unfold(self.X, mode=self.mode) d, n = X_unfold.shape else: X_unfold = tl_unfold(self.X, mode=self.mode).T d, n = X_unfold.shape if self.initial_dict is None: # initialize dictionary matrix W with random values # and initialize aggregate matrices A, B with zeros W = np.random.rand(d, r) # print('W.shape', W.shape) A = np.zeros(shape=(r, r)) B = np.zeros(shape=(r, d)) t0 = self.history else: W = self.initial_dict A = self.initial_A B = self.initial_B t0 = self.history if self.initial_A is None: A = np.zeros(shape=(r, r)) if self.initial_B is None: B = np.zeros(shape=(r, d)) code = np.zeros(shape=(r, n)) for i in np.arange(1, self.iterations): # randomly choose batch_size number of columns to sample # initializing the "batch" of X, which are the subset # of columns from X_unfold that were randomly chosen above if self.subsample: idx = np.random.randint(n, size=self.batch_size) X_batch = X_unfold[:, idx] H, A, B, W = self.step(X_batch, A, B, W, t0 + i) code[:, idx] += H.T else: X_batch = X_unfold H, A, B, W = self.step(X_batch, A, B, W, t0 + i) code += H.T # iteratively update W using batches of X, along with # iteratively updated values of A and B # print('X.shape before training step', self.X.shape) # print('dictionary=', W) # print('code=', H) # plt.matshow(H) # progress status # print('Current iteration %i out of %i' % (i, self.iterations)) return W, A, B, code