Exemplo n.º 1
0
    def fit_output_pca(self, raw_images, dim=20):

        if self._X is None:
            send_msg(self._log,
                     "return a empty dict, since the model is not fitted yet")
            return dict()
        # convolution
        I_layer1 = dict()
        I_freq = dict()
        for i, one_image in enumerate(raw_images):
            I_i = conv_layer(one_image, self._filters)
            I_layer1[i] = I_i
            for j, one_I in enumerate(I_i):
                if not j in I_freq:
                    I_freq[j] = []
                I_freq[j].append(one_I.reshape(one_I.size, ))
        send_msg(self._log, "conv stage finished")

        self._pca_freq = dict()
        for i in I_freq:
            I_freq[i] = np.asarray(I_freq[i])
            # de-mean
            I_freq[i] = I_freq[i] - (I_freq[i].mean(axis=1)).reshape(-1, 1)
            pca = PCA(n_components=dim)
            pca.fit(I_freq[i])
            self._pca_freq[i] = pca
Exemplo n.º 2
0
def pipeline(train_imgs,
             train_labels,
             test_imgs,
             test_labels,
             param: namedtuple,
             log=False,
             rgb=False):
    global RANDOM_STATE
    net = PCANet2(l1=param.l1,
                  patch_size1=param.patch_size1,
                  stride1=param.stride1,
                  method1=param.method1,
                  fourier_basis_sel1=param.fourier_basis_sel1,
                  l2=param.l2,
                  patch_size2=param.patch_size2,
                  stride2=param.stride2,
                  method2=param.method2,
                  fourier_basis_sel2=param.fourier_basis_sel2,
                  reduction_method=param.reduction_method,
                  block_size=param.block_size,
                  block_stride=param.block_stride,
                  feature_method=param.feature_method,
                  log=log,
                  rgb=rgb)
    train_feats = net.fit_transform(train_imgs, train_labels)
    test_feats = net.transform(test_imgs)
    train_feats, test_feats = dict_feats_to_np_feats(
        train_feats), dict_feats_to_np_feats(test_feats)

    scaler = StandardScaler(with_std=False)
    zero_mean_train_feats = scaler.fit_transform(train_feats)
    X_train = zero_mean_train_feats
    y_train = train_labels

    zero_mean_test_feats = scaler.fit_transform(test_feats)
    X_test = zero_mean_test_feats
    y_test = test_labels
    # X_train = train_feats
    # y_train = train_labels
    # X_test = test_feats
    # y_test = test_labels

    send_msg(log, "training a {} clf ...".format(param.clf))
    CLF = clf_dict.get(param.clf, LinearSVC)
    clf = CLF(random_state=RANDOM_STATE, max_iter=1000)
    # X_train, X_test = sparse.csr_matrix(X_train), sparse.csr_matrix(X_test)

    send_msg(
        log, "train_feats.shape: {}, test_feats.shape: {}".format(
            X_train.shape, X_test.shape))
    clf.fit(X_train, y_train)
    accuracy = clf.score(X_test, y_test)
    send_msg(log, net)
    send_msg(log, 'Mean Accuracy Score: {}'.format(accuracy))
    return accuracy, net, clf
Exemplo n.º 3
0
    def transform_output_pca(self, raw_images):

        if self._pca_freq is None:
            send_msg(self._log,
                     "return a empty dict, since the model is not fitted yet")
            return dict()
        # convolution
        I_layer1 = dict()
        feats = [-1] * len(raw_images)
        for i, one_image in enumerate(raw_images):
            I_i = conv_layer(one_image, self._filters)
            feats_one_img = []
            for j, one_I in enumerate(I_i):
                reduced_feats = self._pca_freq[j].transform(
                    one_I.reshape(1, -1))
                feats_one_img.extend(reduced_feats)
            feats[i] = np.asarray(feats_one_img).reshape(-1, )
        send_msg(self._log, "conv & output pca stage finished")
        return np.asarray(feats)
Exemplo n.º 4
0
def pipeline(train_imgs,
             train_labels,
             test_imgs,
             test_labels,
             param: namedtuple,
             log=False):
    global RANDOM_STATE
    net = PCANet(l=param.l,
                 num_images=param.num_images,
                 patch_size=param.patch_size,
                 stride=param.stride,
                 block_size=param.block_size,
                 block_stride=param.block_stride,
                 method=param.method,
                 fourier_basis_sel=param.fourier_basis_sel,
                 reduction_method=param.reduction_method,
                 feature_method=param.feature_method,
                 quantization_method=param.quantization_method,
                 wavelet=param.wavelet,
                 wavelet_decomp_level=param.wavelet_decomp_level,
                 log=log)
    train_feats = net.fit_transform(train_imgs, train_labels)
    test_feats = net.transform(test_imgs)
    train_feats, test_feats = dict_feats_to_np_feats(
        train_feats), dict_feats_to_np_feats(test_feats)
    send_msg(
        log, "train_feats.shape: {}, test_feats.shape: {}".format(
            train_feats.shape, test_feats.shape))
    scaler = StandardScaler(with_std=False)
    zero_mean_train_feats = scaler.fit_transform(train_feats)
    X_train = zero_mean_train_feats
    y_train = train_labels
    zero_mean_test_feats = scaler.fit_transform(test_feats)
    X_test = zero_mean_test_feats
    y_test = test_labels
    CLF = clf_dict.get(param.clf, LinearSVC)
    clf = CLF(random_state=RANDOM_STATE, max_iter=2000)
    clf.fit(X_train, y_train)
    accuracy = clf.score(X_test, y_test)
    send_msg(log, net)
    send_msg(log, 'Mean Accuracy Score: {}'.format(accuracy))
    return accuracy, net, clf
Exemplo n.º 5
0
    def transform(self, raw_images) -> np.ndarray:
        send_msg(self._log, "begin transforming")
        if self._X is None:
            send_msg(self._log,
                     "return a empty dict, since the model is not fitted yet")
            return dict()
        send_msg(self._log, "conv stage")
        # convolution
        I_layer1 = []
        kwargs = {}
        kwargs['wavelet'] = self._wavelet
        kwargs['level'] = self._wavelet_decomp_level
        kwargs['patch_size'] = self._patch_size
        for i, one_image in enumerate(raw_images):
            I_i = conv_layer(one_image, self._filters, self._select_coeffs_idx,
                             **kwargs)
            I_layer1.append(I_i)

        send_msg(self._log, "conv stage finished")
        send_msg(self._log,
                 "\tI_layer1.shape: {}".format(np.array(I_layer1).shape))

        send_msg(self._log, "reduction stage")

        # int_img_dict = dict()
        int_img_list = []
        # output layer
        # idx refers to img idx
        for idx in range(len(I_layer1)):
            curr_images = I_layer1[idx]
            integer_image = None
            # quantization method
            if self._quantization_method == 'binarize':
                curr_images = [
                    binarize(one_image) for one_image in curr_images
                ]
            elif self._quantization_method == 'relu':
                curr_images = [relu(one_image) for one_image in curr_images]
            elif self._quantization_method == 'identity':
                pass
            else:
                raise NotImplementedError

            if self._reduction_method == 'concat':  # concat method offer a upper bound
                # int_img_dict[idx] = np.stack(curr_images, 2)
                # int_img_list.append(curr_images)
                int_img_list.append(np.stack(curr_images, 2))

            else:
                # FIXME: for exponent method, reverse's behavior is opposite from others, but resembles original paper

                for j, one_image in enumerate(reversed(curr_images)):
                    # reduction method
                    if integer_image is None:
                        if self._reduction_method == 'exponent':
                            integer_image = one_image * (2**0)
                        elif self._reduction_method == 'add':
                            integer_image = one_image * 1
                        elif self._reduction_method == 'linear_add':
                            integer_image = one_image * 1
                        elif self._reduction_method == 'square_add':
                            integer_image = one_image * (1**2)
                        elif self._reduction_method == 'cube_add':
                            integer_image = one_image * (1**3)
                        else:
                            raise NotImplementedError
                    else:
                        if self._reduction_method == 'exponent':
                            integer_image = integer_image * 2 + one_image
                        elif self._reduction_method == 'add':
                            integer_image = integer_image + one_image
                        elif self._reduction_method == 'linear_add':
                            integer_image = integer_image + one_image * (j + 1)
                        elif self._reduction_method == 'square_add':
                            integer_image = integer_image + np.round(
                                one_image * (j + 1)**2 / 2).astype(int)
                        elif self._reduction_method == 'cube_add':
                            integer_image = integer_image + np.round(
                                one_image * (j + 1)**3 / 3).astype(int)
                        else:
                            raise NotImplementedError

                # int_img_dict[idx] = integer_image
                int_img_list.append(integer_image)
        send_msg(self._log, "reduction stage finished")
        send_msg(
            self._log,
            "\tint_img_list.shape: {}".format(np.array(int_img_list).shape))

        send_msg(self._log, "feature stage")
        # feats = dict()
        # feats = [-1] * len(int_img_list)
        feats = []
        for idx in range(len(int_img_list)):
            # integer_image = int_img_dict[idx]
            integer_image = int_img_list[idx]
            all_vec_bhist = []
            for i in range(0, integer_image.shape[0] - self._block_size[0] + 1,
                           self._block_stride):
                for j in range(
                        0, integer_image.shape[1] - self._block_size[1] + 1,
                        self._block_stride):
                    curr_block = integer_image[i:i + self._block_size[0], j:j + self._block_size[1]]\
                                            .reshape(*self._block_size, -1)

                    # feature method
                    if self._feature_method == 'histogram':
                        counter = Counter(
                            curr_block.reshape((curr_block.size, )))
                        block_hist = dict(counter)
                        # vectorize bhist
                        if self._reduction_method == 'exponent':
                            vec_bhist = np.zeros((1 << self._l, ))
                        elif self._reduction_method == 'add':
                            vec_bhist = np.zeros((self._l + 1, ))
                        elif self._reduction_method == 'linear_add':
                            vec_bhist = np.zeros([
                                round((self._l * (self._l + 1)) / 2) + 1,
                            ])
                        elif self._reduction_method == 'square_add':
                            vec_bhist = np.zeros([
                                round((self._l * (self._l + 1) *
                                       (self._l + 0.5)) / 9) + self._l**2 + 1,
                            ])
                        elif self._reduction_method == 'cube_add':
                            vec_bhist = np.zeros([
                                int((self._l * (self._l + 1)) / 2)**2 + 1,
                            ])

                        for hist_bin, val in block_hist.items():
                            vec_bhist[hist_bin] = val
                        all_vec_bhist.extend(vec_bhist)

                    elif self._feature_method == 'avg_pooling':
                        block_avg = np.mean(curr_block)
                        all_vec_bhist.append(block_avg)
                    elif self._feature_method == 'max_pooling':
                        block_max = np.max(curr_block)
                        all_vec_bhist.append(block_max)
                    elif self._feature_method == 'min_pooling':
                        block_min = np.min(curr_block)
                        all_vec_bhist.append(block_min)
                    elif self._feature_method == 'variance_pooling':
                        block_var = np.var(curr_block)
                        all_vec_bhist.append(block_var)
                    elif self._feature_method == 'max_avg_min_pooling':
                        block_avg = np.mean(curr_block)
                        block_max = np.max(curr_block)
                        block_min = np.min(curr_block)
                        all_vec_bhist.extend([block_avg, block_max, block_min])
                    elif self._feature_method == 'quantile':
                        quantile_list = np.linspace(0, 1, self._l)
                        block_quantile = np.quantile(curr_block,
                                                     quantile_list).tolist()
                        all_vec_bhist.extend(
                            block_quantile +
                            [np.mean(curr_block),
                             np.var(curr_block)])
                    elif self._feature_method == 'naive_quantile':  # min, max, mean, var
                        for dim in range(curr_block.shape[2]):
                            block_2d = curr_block[..., dim]
                            quantile_list = np.linspace(0, 1, 2)
                            block_quantile = np.quantile(
                                block_2d, quantile_list).tolist()
                            all_vec_bhist.extend(
                                block_quantile +
                                [np.mean(block_2d),
                                 np.var(block_2d)])
                    elif self._feature_method == 'exponent_quantile':
                        quantile_list = np.linspace(0, 1, 2**self._l)
                        block_quantile = np.quantile(curr_block,
                                                     quantile_list).tolist()
                        all_vec_bhist.extend(
                            block_quantile +
                            [np.mean(curr_block),
                             np.var(curr_block)])
                    else:
                        raise NotImplementedError
            # feats[idx] = all_vec_bhist
            feats.append(all_vec_bhist)

        return np.array(feats)
Exemplo n.º 6
0
    def fit(self, imgs: (list, np.ndarray), labels: (list, np.ndarray)):
        send_msg(self._log, "begin fitting")
        assert len(imgs) == len(
            labels), "len(imgs) = {} while len(labels) = {}".format(
                len(imgs), len(labels))
        send_msg(self._log, 'processing images...')
        X = process_images(imgs, self._patch_size, self._stride)
        send_msg(self._log, "X.shape: {}".format(X.shape))
        # as matrix transform representation is currently not supported, Wavelets based filter
        # get_w will give the selected indices of selected coefficients instead of convolution filters
        if self._method == 'Wavelet':
            send_msg(self._log, "constructing filters")

            l_a = int(self._wavelet_la * self._l)
            l_b = self._l - l_a
            select_coeffs_idx, _ = get_w(
                X, (l_a, l_b),
                patch_size=self._patch_size,
                method=self._method,
                wavelet=self._wavelet,
                wavelet_decomp_level=self._wavelet_decomp_level,
                labels=labels)
            self._select_coeffs_idx = select_coeffs_idx
        else:
            send_msg(self._log, "constructing filters")

            w_l1 = get_w(X,
                         self._l,
                         patch_size=self._patch_size,
                         method=self._method,
                         fourier_basis_sel=self._fourier_basis_sel,
                         labels=labels)
            # construct stage 1 filters
            self._filters = w_l1
            send_msg(
                self._log,
                '\tfilter.shape: {}'.format(np.array(self._filters).shape))
        self._X = X
Exemplo n.º 7
0
    def transform(self, raw_images) -> (np.ndarray, sparse.csr_matrix):
        send_msg(self._log, "raw_images.shape: {}".format(raw_images.shape))
        send_msg(self._log, "begin transforming")
        if self._filters1 is None or self._filters2 is None:
            send_msg(
                self._log,
                "return a empty feats, since the model is not fitted yet")
            return []
        # convolution, every img corresponds to l1l2 feature maps
        O = []  # N x L1 x L2 x h x w
        send_msg(self._log, "\tconv stage")
        for i, one_image in enumerate(raw_images):  # i corresponds to img idx
            # stage 1 conv
            I_i = conv_layer(
                one_image, self._filters1, complex=self._complex
            )  # L1 x h x w, each img generates L1 stage-1 feature maps
            O_i = []  # L1 x L2 x h x w
            assert len(I_i) == self._l1, len(I_i)
            for l in range(self._l1):
                stage1_feature_map_l = I_i[l]
                O_i_l = conv_layer(
                    stage1_feature_map_l,
                    self._filters2,
                    complex=self._complex
                )  # L2 x h x w, each stage-1 map generates L2 stage-2 feature maps
                O_i.append(O_i_l)
            O.append(O_i)
        O = np.array(O)
        # send_msg(self._log, "\tO.shape: {}".format(np.array(O).shape))

        # # FIXME: test code, pool before redecution
        # O = block_reduce(O, block_size=(1, 1, 1, 2, 2), func=np.max)
        # send_msg(self._log, "\tafter max pooling: O.shape: {}".format(np.array(O).shape))

        send_msg(self._log, "\treduction stage")
        T = []  # N x L1 x h x w
        for i in range(len(raw_images)):
            O_i = O[i]  # L1 x L2 x h x w
            # quantalization phase
            O_i = np.array(O_i)
            O_i = np.where(O_i > 0, np.ones_like(O_i),
                           np.zeros_like(O_i))  # binarize

            # reduction phase
            O_i_0 = O_i[0]  # L2 x h x w
            l2, h, w = O_i_0.shape
            assert l2 == self._l2

            T_i = []  # L1 x h x w
            for l in range(self._l1):
                O_i_l = O_i[l]  # L2 x h x w
                exponent_mat = (2**np.arange(0, self._l2,
                                             1)).reshape([-1, 1,
                                                          1])  # L2 x 1 x 1
                integer_image_l = np.sum(exponent_mat * O_i_l,
                                         axis=0).astype(int)  # h x w
                T_i.append(integer_image_l)
            T.append(T_i)
        T = np.array(T)
        send_msg(self._log,
                 "\tT.shape: {}".format(np.array(T).shape))  # N x L1 x h x w

        send_msg(self._log, "\tfeature stage")

        h, w = T.shape[2:4]
        # FIXME: only for cifar method
        if self._feature_method == 'spp_histogram':
            n_pooled_feature = sum([item**2 for item in self._levels])
            feats = np.zeros(
                [T.shape[0], n_pooled_feature * self._l1 * (2**self._l2)])

            # pre-compute B
            B = int((1 + (h - self._block_size[0]) / self._block_stride) *
                    (1 + (w - self._block_size[1]) / self._block_stride))

            send_msg(self._log,
                     "\tnumber blocks in each feature map: {}".format(B),
                     'warn')

            for i in range(len(raw_images)):
                T_i = T[i]  # L1 x h x w
                T_i_idx = np.zeros_like(T_i, dtype=int)
                hist_i = np.zeros([B * self._l1, (2**self._l2)],
                                  dtype=int)  # B * L1, 2^L2
                final_hist_i = np.zeros(
                    [n_pooled_feature,
                     self._l1 * (2**self._l2)])  # n_pooled, (l1 * 2 ^ l2)
                cnt = 0

                # histogram phase
                block_stage_for_spp(self._l1, self._block_size,
                                    self._block_stride, self._l2, T_i, hist_i,
                                    T_i_idx)
                # print(view_as_blocks(T_i_idx[1], (4, 4)))

                for level in self._levels:  # pyramid levels
                    spatial_bin_size = (int(h // level), int(w // level))
                    for bin_idx1 in range(level):
                        for bin_idx2 in range(level):
                            # corresponding blocks idx of this bin
                            valid_T_i_idx = list(
                                set(T_i_idx[:, bin_idx1 *
                                            spatial_bin_size[1]:(bin_idx1 +
                                                                 1) *
                                            spatial_bin_size[1], bin_idx2 *
                                            spatial_bin_size[0]:(bin_idx2 +
                                                                 1) *
                                            spatial_bin_size[0]].reshape([-1
                                                                          ])))

                            # fetch all local histogram corresponding to this bin

                            valid_hist_i = hist_i[valid_T_i_idx, :].reshape(
                                [-1, self._l1 * 2**self._l2])
                            valid_hist_i = np.amax(valid_hist_i,
                                                   axis=0)  # l1 * 2^l2
                            final_hist_i[cnt] = valid_hist_i
                            cnt += 1
                final_hist_i = final_hist_i.reshape([-1
                                                     ])  # n_pooled * l1 * 2^l2
                # feats[i] = final_hist_i / np.linalg.norm(final_hist_i, ord=2)
                feats[i] = final_hist_i
        else:
            n_img, _, h, w, *_ = T.shape
            B = int((1 + (h - self._block_size[0]) / self._block_stride) *
                    (1 + (w - self._block_size[1]) / self._block_stride))
            send_msg(self._log,
                     "\tnumber blocks in each feature map: {}".format(B),
                     'warn')

            feats = np.empty([n_img, B * self._l1 * 2**self._l2
                              ])  # n, (B * L1 * 2^L2)
            for i in range(len(raw_images)):
                T_i = T[i]  # L1 x h x w
                # histogram phase
                hist_i = np.zeros([B * self._l1 * 2**self._l2],
                                  dtype=int)  # 2^L2 x L1 x B
                # hist_i = np.zeros([2 ** self._l2 * self._l1 * B], dtype=int)
                if self._feature_method == 'histogram':
                    block_stage(self._l1, self._block_size, self._block_stride,
                                self._l2, T_i, hist_i)
                else:  # pool_histogram (stage-2 pool)
                    pooled_T_i = np.zeros([self._l1, h // 2, w // 2],
                                          dtype=int)
                    pool_stage(self._l1, T_i, pooled_T_i)
                    block_stage(self._l1, self._block_size, self._block_stride,
                                self._l2, pooled_T_i, hist_i)

                feats[i] = hist_i
        send_msg(self._log, "done")

        return np.array(feats)  # N x 2^L2 x L1 x B
Exemplo n.º 8
0
    def fit(self, imgs: (list, np.ndarray), labels: (list, np.ndarray)):
        assert len(imgs) == len(
            labels), "len(imgs) = {} while len(labels) = {}".format(
                len(imgs), len(labels))
        send_msg(self._log, "begin fitting")
        '''
        stage 1
        '''
        send_msg(self._log, '\tstage-1')
        send_msg(self._log, '\tprocessing images...')

        X = process_images(imgs, self._patch_size1, self._stride1)  # 提取X

        send_msg(self._log, "\tX.shape: {}".format(X.shape))
        # construct stage 1 filters
        send_msg(self._log, "\tconstructing filters 1")

        w_l1 = get_w(X,
                     self._l1,
                     patch_size=self._patch_size1,
                     method=self._method1,
                     fourier_basis_sel=self._fourier_basis_sel1,
                     labels=labels,
                     rgb=self._rgb)
        del X
        self._filters1 = w_l1
        send_msg(self._log,
                 '\tfilter1.shape: {}'.format(np.array(self._filters1).shape))
        '''
        stage 2
        '''
        send_msg(self._log, '\tstage-2')
        send_msg(self._log, "\tconstruct conved images...")
        conved_images = []
        for img in imgs:
            conved_img = conv_layer(
                img,  # no need to pad by hand, scipy.ndimage.convolve do pad for us
                self._filters1,
                complex=self._complex)  # a list, len=len(filters)
            conved_images.extend(conved_img)
        send_msg(
            self._log,
            "\tlength of conved images: {}, each element's shape: {}".format(
                len(conved_images), conved_images[0].shape))

        # another pca stage
        send_msg(self._log, '\tprocessing images...')
        Y = process_images(conved_images,
                           patch_size=self._patch_size2,
                           stride=self._stride2)
        send_msg(self._log, "\tY.shape: {}".format(Y.shape))
        send_msg(self._log, "\tconstructing filters 2")
        # construct stage 2 filters
        w_l2 = get_w(Y,
                     self._l2,
                     patch_size=self._patch_size2,
                     method=self._method2,
                     fourier_basis_sel=self._fourier_basis_sel2,
                     labels=labels)
        del imgs
        del conved_images
        del Y
        self._filters2 = w_l2
        send_msg(self._log,
                 '\tfilter2.shape: {}'.format(np.array(self._filters2).shape))
        send_msg(self._log, "done")
        gc.collect()