Ejemplo n.º 1
0
class ImageClassifier(ImageSupervised):
    """ImageClassifier class.

    It is used for image classification. It searches convolutional neural network architectures
    for the best configuration for the image dataset.
    """
    @property
    def loss(self):
        return classification_loss

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes

    @property
    def metric(self):
        return Accuracy
Ejemplo n.º 2
0
class MyData(torch.utils.data.Dataset):
    def __init__(self, csv_file, root, transforms=None, test=False):
        self.test = test
        img_names, self.labels = read_csv_file(csv_file)
        print('root is {}'.format(root))
        self.img_names = []
        for img in img_names:
            img = os.path.join(root, img)
            self.img_names.append(img)

        self.encoder = OneHotEncoder()
        self.encoder.fit(self.labels)
        self.labels = self.encoder.transform(self.labels)
        self.n_classes = self.encoder.n_classes

        if transforms is None:
            normalize = torchvision.transforms.Normalize(
                mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
            if self.test:
                self.transforms = torchvision.transforms.Compose([
                    torchvision.transforms.Resize(256),
                    torchvision.transforms.CenterCrop(224),
                    torchvision.transforms.ToTensor(),
                    normalize,
                ])
            else:
                self.transforms = torchvision.transforms.Compose([
                    torchvision.transforms.Resize(256),
                    torchvision.transforms.RandomResizedCrop(224),
                    torchvision.transforms.RandomHorizontalFlip(),
                    torchvision.transforms.RandomVerticalFlip(),
                    torchvision.transforms.ToTensor(),
                    normalize,
                ])

    def __getitem__(self, index):
        img_path = self.img_names[index]
        label = self.labels[index]
        data = Image.open(img_path)
        data = self.transforms(data)
        return data, label

    def __len__(self):
        return len(self.img_names)
Ejemplo n.º 3
0
class ImageClassifier(ImageSupervised):
    @property
    def loss(self):
        return classification_loss

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes

    @property
    def metric(self):
        return Accuracy
Ejemplo n.º 4
0
class ImageClassifier(ImageSupervised):
    @property
    def loss(self):
        return classification_loss

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes

    @property
    def metric(self):
        return Accuracy
Ejemplo n.º 5
0
class ImageClassifier(ImageSupervised):
    """ImageClassifier class.

    It is used for image classification. It searches convolutional neural network architectures
    for the best configuration for the image dataset.
    """
    @property
    def loss(self):
        return classification_loss

    @property
    def metric(self):
        return Accuracy

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes

    def export_autokeras_model(self, model_file_name):
        """ Creates and Exports the AutoKeras model to the given filename. """
        portable_model = PortableImageClassifier(
            graph=self.cnn.best_model,
            y_encoder=self.y_encoder,
            data_transformer=self.data_transformer,
            resize_params=self.resize_shape,
            path=self.path)
        pickle_to_file(portable_model, model_file_name)
Ejemplo n.º 6
0
class ImageClassifier(ImageSupervised):
    """ImageClassifier class.

    It is used for image classification. It searches convolutional neural network architectures
    for the best configuration for the image dataset.
    """

    @property
    def loss(self):
        return classification_loss

    @property
    def metric(self):
        return Accuracy

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes

    def export_autokeras_model(self, model_file_name):
        """ Creates and Exports the AutoKeras model to the given filename. """
        portable_model = PortableImageClassifier(graph=self.cnn.best_model,
                                                 y_encoder=self.y_encoder,
                                                 data_transformer=self.data_transformer,
                                                 resize_params=self.resize_shape,
                                                 path=self.path)
        pickle_to_file(portable_model, model_file_name)
Ejemplo n.º 7
0

model = Net(50, 100, 10)
n_instance = 100
batch_size = 32

train_x = np.random.random((n_instance, 50))
test_x = np.random.random((n_instance, 50))
train_y = np.random.randint(0, 9, n_instance)
test_y = np.random.randint(0, 9, n_instance)
print(train_x.shape)
print(train_y.shape)

encoder = OneHotEncoder()
encoder.fit(train_y)
train_y = encoder.transform(train_y)
test_y = encoder.transform(test_y)

compose_list = Compose([])
train_data = DataLoader(MultiTransformDataset(torch.Tensor(train_x), torch.Tensor(train_y), compose_list), batch_size=batch_size, shuffle=False)
test_data = DataLoader(MultiTransformDataset(torch.Tensor(test_x), torch.Tensor(test_y), compose_list), batch_size=batch_size, shuffle=False)

model_trainer = ModelTrainer(model,
                             loss_function=classification_loss,
                             metric=Accuracy,
                             train_data=train_data,
                             test_data=test_data,
                             verbose=True)

model_trainer.train_model(2, 1)
model.eval()
Ejemplo n.º 8
0
class ImageClassifier:
    """The image classifier class.

    It is used for image classification. It searches convolutional neural network architectures
    for the best configuration for the dataset.

    Attributes:
        path: A path to the directory to save the classifier.
        y_encoder: An instance of OneHotEncoder for y_train (array of categorical labels).
        verbose: A boolean value indicating the verbosity mode.
        searcher: An instance of BayesianSearcher. It search different
            neural architecture to find the best model.
        searcher_args: A dictionary containing the parameters for the searcher's __init__ function.
    """
    def __init__(self,
                 verbose=False,
                 path=constant.DEFAULT_SAVE_PATH,
                 resume=False,
                 searcher_args=None):
        """Initialize the instance.

        The classifier will be loaded from the files in 'path' if parameter 'resume' is True.
        Otherwise it would create a new one.

        Args:
            verbose: An boolean of whether the search process will be printed to stdout.
            path: A string. The path to a directory, where the intermediate results are saved.
            resume: An boolean. If True, the classifier will continue to previous work saved in path.
                Otherwise, the classifier will start a new search.

        """
        if searcher_args is None:
            searcher_args = {}

        if has_file(os.path.join(path, 'classifier')) and resume:
            classifier = pickle_from_file(os.path.join(path, 'classifier'))
            self.__dict__ = classifier.__dict__
            self.path = path
        else:
            self.y_encoder = None
            self.verbose = verbose
            self.searcher = False
            self.path = path
            self.searcher_args = searcher_args
            ensure_dir(path)

    def fit(self, x_train=None, y_train=None, time_limit=None):
        """Find the best neural architecture and train it.

        Based on the given dataset, the function will find the best neural architecture for it.
        The dataset is in numpy.ndarray format.
        So they training data should be passed through x_train, y_train.

        Args:
            x_train: An numpy.ndarray instance contains the training data.
            y_train: An numpy.ndarray instance contains the label of the training data.
            time_limit: The time limit for the search in seconds.
        """

        if y_train is None:
            y_train = []
        if x_train is None:
            x_train = []

        x_train = np.array(x_train)
        y_train = np.array(y_train).flatten()

        _validate(x_train, y_train)

        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)

        y_train = self.y_encoder.transform(y_train)

        # Create the searcher and save on disk
        if not self.searcher:
            input_shape = x_train.shape[1:]
            n_classes = self.y_encoder.n_classes
            self.searcher_args['n_classes'] = n_classes
            self.searcher_args['input_shape'] = input_shape
            self.searcher_args['path'] = self.path
            self.searcher_args['verbose'] = self.verbose
            searcher = BayesianSearcher(**self.searcher_args)
            self.save_searcher(searcher)
            self.searcher = True

        # Divide training data into training and testing data.
        x_train, x_test, y_train, y_test = train_test_split(x_train,
                                                            y_train,
                                                            test_size=0.25,
                                                            random_state=42)

        pickle.dump(self, open(os.path.join(self.path, 'classifier'), 'wb'))
        pickle_to_file(self, os.path.join(self.path, 'classifier'))

        if time_limit is None:
            time_limit = 24 * 60 * 60

        start_time = time.time()
        while time.time() - start_time <= time_limit:
            run_searcher_once(x_train, y_train, x_test, y_test, self.path)
            if len(self.load_searcher().history) >= constant.MAX_MODEL_NUM:
                break

    def predict(self, x_test):
        """Return predict result for the testing data.

        Args:
            x_test: An instance of numpy.ndarray contains the testing data.

        Returns:
            An numpy.ndarray containing the results.
        """
        if constant.LIMIT_MEMORY:
            config = tf.ConfigProto()
            config.gpu_options.allow_growth = True
            sess = tf.Session(config=config)
            init = tf.global_variables_initializer()
            sess.run(init)
            backend.set_session(sess)
        x_test = x_test.astype('float32') / 255
        model = self.load_searcher().load_best_model().produce_model()
        return self.y_encoder.inverse_transform(model.predict(x_test, ))

    def summary(self):
        """Print the summary of the best model."""
        model = self.load_searcher().load_best_model()
        model.summary()

    def evaluate(self, x_test, y_test):
        """Return the accuracy score between predict value and test_y."""
        y_predict = self.predict(x_test)
        return accuracy_score(y_test, y_predict)

    def save_searcher(self, searcher):
        pickle.dump(searcher, open(os.path.join(self.path, 'searcher'), 'wb'))

    def load_searcher(self):
        return pickle_from_file(os.path.join(self.path, 'searcher'))

    def final_fit(self,
                  x_train,
                  y_train,
                  x_test,
                  y_test,
                  trainer_args=None,
                  retrain=False):
        """Final training after found the best architecture.

        Args:
            x_train: An numpy.ndarray of training data.
            y_train: An numpy.ndarray of training targets.
            x_test: An numpy.ndarray of testing data.
            y_test: An numpy.ndarray of testing targets.
            trainer_args: A dictionary containing the parameters of the ModelTrainer constructure.
            retrain: A boolean of whether reinitialize the weights of the model.
        """
        if trainer_args is None:
            trainer_args = {}
        y_train = self.y_encoder.transform(y_train)
        y_test = self.y_encoder.transform(y_test)
        searcher = self.load_searcher()
        graph = searcher.load_best_model()
        if retrain:
            graph.weighted = False
        _, _1, graph = train(
            (graph, x_train, y_train, x_test, y_test, trainer_args, None))

    def export_keras_model(self, path, model_id=None):
        """Export the searched model as a Keras saved model.

        Args:
            path: A string. The path to the file to save.
            model_id: A integer. If not provided, the function will export the best model.
        """
        if model_id is None:
            model_id = self.get_best_model_id()
        graph = self.load_searcher().load_model_by_id(model_id)
        graph.produce_model().save(path)

    def get_best_model_id(self):
        """
        Returns:
            An integer. The best model id.
        """
        return self.load_searcher().get_best_model_id()
Ejemplo n.º 9
0
class ImageClassifier(ImageSupervised):
    @property
    def loss(self):
        return classification_loss

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes

    @property
    def metric(self):
        return Accuracy

    def fit_dataset(self,
                    train_root,
                    train_csv_file,
                    test_root,
                    test_csv_file,
                    time_limit=None):
        """

        :param train_data_root:
        :param test_data_root:
        :param time_limit:
        :return:
        """
        # loading data
        train_dataset = MyData(csv_file=train_csv_file,
                               root=train_root,
                               test=False)
        train_data = torch.utils.data.DataLoader(
            train_dataset,
            # TODO
            batch_size=8,
            shuffle=True,
            pin_memory=True)
        test_dataset = MyData(csv_file=test_csv_file,
                              root=test_root,
                              test=True)
        test_data = torch.utils.data.DataLoader(
            test_dataset,
            # TODO
            batch_size=8,
            shuffle=False,
            pin_memory=True)

        # Create the searcher and save on disk
        if not self.searcher:
            input_shape = (224, 224, 3)
            self.searcher_args['n_output_node'] = 4
            self.searcher_args['input_shape'] = input_shape
            self.searcher_args['path'] = self.path
            self.searcher_args['metric'] = self.metric
            self.searcher_args['loss'] = self.loss
            self.searcher_args['verbose'] = self.verbose
            searcher = Searcher(**self.searcher_args)
            self.save_searcher(searcher)
            self.searcher = True

        # Save the classifier
        pickle.dump(self, open(os.path.join(self.path, 'classifier'), 'wb'))
        pickle_to_file(self, os.path.join(self.path, 'classifier'))

        if time_limit is None:
            time_limit = 24 * 60 * 60

        start_time = time.time()
        time_remain = time_limit
        try:
            while time_remain > 0:
                run_searcher_once(train_data, test_data, self.path,
                                  int(time_remain))
                if len(self.load_searcher().history) >= Constant.MAX_MODEL_NUM:
                    break
                time_elapsed = time.time() - start_time
                time_remain = time_limit - time_elapsed
            # if no search executed during the time_limit, then raise an error
            if time_remain <= 0:
                raise TimeoutError
        except TimeoutError:
            if len(self.load_searcher().history) == 0:
                raise TimeoutError(
                    "Search Time too short. No model was found during the search time."
                )
            elif self.verbose:
                print('Time is out.')

    def final_fit_dataset(self,
                          train_root,
                          train_csv_file,
                          test_root,
                          test_csv_file,
                          trainer_args=None,
                          retrain=False):
        # loading data
        train_dataset = MyData(csv_file=train_csv_file,
                               root=train_root,
                               test=False)
        train_data = torch.utils.data.DataLoader(
            train_dataset,
            # TODO
            batch_size=8,
            shuffle=True,
            pin_memory=True)
        test_dataset = MyData(csv_file=test_csv_file,
                              root=test_root,
                              test=True)
        test_data = torch.utils.data.DataLoader(
            test_dataset,
            # TODO
            batch_size=8,
            shuffle=False,
            pin_memory=True)

        if trainer_args is None:
            trainer_args = {'max_no_improvement_num': 3}

        searcher = self.load_searcher()
        graph = searcher.load_best_model()

        if retrain:
            graph.weighted = False

        model = graph.produce_model()
        loss, metric_value = ModelTrainer(
            model=model,
            train_data=train_data,
            test_data=test_data,
            metric=self.metric,
            loss_function=self.loss,
            verbose=self.verbose).train_model(**trainer_args)
        print('*********************')
        print('metric_value = {}'.format(metric_value))
        acc = self.evaluate_dataset(test_root=test_root,
                                    test_csv_file=test_csv_file,
                                    model=model)
        print('0000000000000000000')
        print('acc = {}'.format(acc))
        torch.save(model, 'final_' + str(acc) + '.pth.tar')

    def evaluate_dataset(self, test_root, test_csv_file, model=None):
        test_dataset = MyData(csv_file=test_csv_file,
                              root=test_root,
                              test=True)
        test_data = torch.utils.data.DataLoader(
            test_dataset,
            # TODO
            batch_size=8,
            shuffle=False,
            pin_memory=True)

        if model is None:
            model = self.load_searcher().load_best_model().produce_model()
        device = get_device()
        model.to(device)
        model.eval()

        all_targets = []
        all_predicted = []
        with torch.no_grad():
            for batch_idx, (inputs, targets) in enumerate(test_data):
                inputs, targets = inputs.to(device), targets.to(device)
                outputs = model(inputs)
                all_predicted.append(outputs.cpu().numpy())
                all_targets.append(targets.cpu().numpy())
        all_predicted = reduce(lambda x, y: np.concatenate((x, y)),
                               all_predicted)
        all_targets = reduce(lambda x, y: np.concatenate((x, y)), all_targets)
        return self.metric.compute(all_predicted, all_targets)
Ejemplo n.º 10
0
class ImageClassifier(Classifier):
    """The image classifier class.

    It is used for image classification. It searches convolutional neural network architectures
    for the best configuration for the dataset.

    Attributes:
        path: A path to the directory to save the classifier.
        y_encoder: An instance of OneHotEncoder for `y_train` (array of categorical labels).
        verbose: A boolean value indicating the verbosity mode.
        searcher: An instance of BayesianSearcher. It searches different
            neural architecture to find the best model.
        searcher_args: A dictionary containing the parameters for the searcher's __init__ function.
        augment: A boolean value indicating whether the data needs augmentation.
    """
    def __init__(self,
                 verbose=False,
                 path=Constant.DEFAULT_SAVE_PATH,
                 resume=False,
                 searcher_args=None,
                 augment=None):
        """Initialize the instance.

        The classifier will be loaded from the files in 'path' if parameter 'resume' is True.
        Otherwise it would create a new one.

        Args:
            verbose: A boolean of whether the search process will be printed to stdout.
            path: A string. The path to a directory, where the intermediate results are saved.
            resume: A boolean. If True, the classifier will continue to previous work saved in path.
                Otherwise, the classifier will start a new search.
            augment: A boolean value indicating whether the data needs augmentation.

        """
        super().__init__(verbose)
        if searcher_args is None:
            searcher_args = {}

        if augment is None:
            augment = Constant.DATA_AUGMENTATION

        if has_file(os.path.join(path, 'classifier')) and resume:
            classifier = pickle_from_file(os.path.join(path, 'classifier'))
            self.__dict__ = classifier.__dict__
            self.path = path
        else:
            self.y_encoder = None
            self.data_transformer = None
            self.verbose = verbose
            self.searcher = False
            self.path = path
            self.searcher_args = searcher_args
            self.augment = augment
            self.metric = Accuracy
            ensure_dir(path)

    def fit(self, x_train=None, y_train=None, time_limit=None):
        """Find the best neural architecture and train it.

        Based on the given dataset, the function will find the best neural architecture for it.
        The dataset is in numpy.ndarray format.
        So they training data should be passed through `x_train`, `y_train`.

        Args:
            x_train: A numpy.ndarray instance containing the training data.
            y_train: A numpy.ndarray instance containing the label of the training data.
            time_limit: The time limit for the search in seconds.
        """

        if y_train is None:
            y_train = []
        if x_train is None:
            x_train = []

        x_train = np.array(x_train)
        y_train = np.array(y_train).flatten()

        _validate(x_train, y_train)

        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)

        y_train = self.y_encoder.transform(y_train)

        # Transform x_train
        if self.data_transformer is None:
            self.data_transformer = DataTransformer(x_train,
                                                    augment=self.augment)

        # Create the searcher and save on disk
        if not self.searcher:
            input_shape = x_train.shape[1:]
            n_classes = self.y_encoder.n_classes
            self.searcher_args['n_classes'] = n_classes
            self.searcher_args['input_shape'] = input_shape
            self.searcher_args['path'] = self.path
            self.searcher_args['metric'] = self.metric
            self.searcher_args['verbose'] = self.verbose
            searcher = BayesianSearcher(**self.searcher_args)
            self.save_searcher(searcher)
            self.searcher = True

        # Divide training data into training and testing data.
        x_train, x_test, y_train, y_test = train_test_split(
            x_train,
            y_train,
            test_size=min(Constant.VALIDATION_SET_SIZE,
                          int(len(y_train) * 0.2)),
            random_state=42)

        train_data = self.data_transformer.transform_train(x_train, y_train)
        test_data = self.data_transformer.transform_test(x_test, y_test)
        pickle.dump(self, open(os.path.join(self.path, 'classifier'), 'wb'))
        pickle_to_file(self, os.path.join(self.path, 'classifier'))

        if time_limit is None:
            time_limit = 24 * 60 * 60

        start_time = time.time()
        while time.time() - start_time <= time_limit:
            run_searcher_once(train_data, test_data, self.path)
            if len(self.load_searcher().history) >= Constant.MAX_MODEL_NUM:
                break

    def predict(self, x_test):
        """Return predict results for the testing data.

        Args:
            x_test: An instance of numpy.ndarray containing the testing data.

        Returns:
            A numpy.ndarray containing the results.
        """
        if Constant.LIMIT_MEMORY:
            pass
        test_data = self.data_transformer.transform_test(x_test)
        test_loader = DataLoader(test_data,
                                 batch_size=Constant.MAX_BATCH_SIZE,
                                 shuffle=False)
        model = self.load_searcher().load_best_model().produce_model()
        model.eval()

        outputs = []
        with torch.no_grad():
            for index, inputs in enumerate(test_loader):
                outputs.append(model(inputs).numpy())
        output = reduce(lambda x, y: np.concatenate((x, y)), outputs)
        return self.y_encoder.inverse_transform(output)

    def evaluate(self, x_test, y_test):
        """Return the accuracy score between predict value and `y_test`."""
        y_predict = self.predict(x_test)
        return accuracy_score(y_test, y_predict)

    def save_searcher(self, searcher):
        pickle.dump(searcher, open(os.path.join(self.path, 'searcher'), 'wb'))

    def load_searcher(self):
        return pickle_from_file(os.path.join(self.path, 'searcher'))

    def final_fit(self,
                  x_train,
                  y_train,
                  x_test,
                  y_test,
                  trainer_args=None,
                  retrain=False):
        """Final training after found the best architecture.

        Args:
            x_train: A numpy.ndarray of training data.
            y_train: A numpy.ndarray of training targets.
            x_test: A numpy.ndarray of testing data.
            y_test: A numpy.ndarray of testing targets.
            trainer_args: A dictionary containing the parameters of the ModelTrainer constructure.
            retrain: A boolean of whether reinitialize the weights of the model.
        """
        if trainer_args is None:
            trainer_args = {'max_no_improvement_num': 30}

        y_train = self.y_encoder.transform(y_train)
        y_test = self.y_encoder.transform(y_test)

        train_data = self.data_transformer.transform_train(x_train, y_train)
        test_data = self.data_transformer.transform_test(x_test, y_test)

        searcher = self.load_searcher()
        graph = searcher.load_best_model()

        if retrain:
            graph.weighted = False
        _, _1, graph = train((graph, train_data, test_data, trainer_args, None,
                              self.metric, self.verbose))

    def get_best_model_id(self):
        """ Return an integer indicating the id of the best model."""
        return self.load_searcher().get_best_model_id()
Ejemplo n.º 11
0
class TextClassifier(ImageSupervised):
    @property
    def loss(self):
        return classification_loss

    def fit(self,
            x_train=None,
            y_train=None,
            batch_size=None,
            time_limit=None):
        """Find the best neural architecture and train it.

        Based on the given dataset, the function will find the best neural architecture for it.
        The dataset is in numpy.ndarray format.
        So they training data should be passed through `x_train`, `y_train`.

        Args:
            x_train: A numpy.ndarray instance containing the training data.
            y_train: A numpy.ndarray instance containing the label of the training data.
            time_limit: The time limit for the search in seconds.
        """
        if y_train is None:
            y_train = []
        if x_train is None:
            x_train = []
        if self.augment:
            x_train = text_preprocess(x_train, path=self.path)

        x_train = np.array(x_train)
        y_train = np.array(y_train)
        _validate(x_train, y_train)
        y_train = self.transform_y(y_train)

        if batch_size is None:
            batch_size = Constant.MAX_BATCH_SIZE
        # Create the searcher and save on disk
        if not self.searcher:
            input_shape = x_train.shape[1:]
            self.searcher_args['n_output_node'] = self.get_n_output_node()
            self.searcher_args['input_shape'] = input_shape
            self.searcher_args['path'] = self.path
            self.searcher_args['metric'] = self.metric
            self.searcher_args['loss'] = self.loss
            self.searcher_args['verbose'] = self.verbose
            searcher = Searcher(**self.searcher_args)
            self.save_searcher(searcher)
            self.searcher = True

        # Divide training data into training and testing data.
        x_train, x_test, y_train, y_test = train_test_split(
            x_train,
            y_train,
            test_size=min(Constant.VALIDATION_SET_SIZE,
                          int(len(y_train) * 0.2)),
            random_state=42)

        # Wrap the data into DataLoaders
        train_data = text_dataloader(x_train,
                                     y_train,
                                     batch_size=batch_size,
                                     shuffle=True)
        test_data = text_dataloader(x_test, y_test, shuffle=True)

        # Save the classifier
        pickle.dump(self, open(os.path.join(self.path, 'classifier'), 'wb'))
        pickle_to_file(self, os.path.join(self.path, 'classifier'))

        if time_limit is None:
            time_limit = 24 * 60 * 60

        self.cnn.fit(self.get_n_output_node(), x_train.shape, train_data,
                     test_data, time_limit)

    def final_fit(self,
                  x_train=None,
                  y_train=None,
                  x_test=None,
                  y_test=None,
                  trainer_args=None,
                  retrain=False):
        """Final training after found the best architecture.

        Args:
            x_train: A numpy.ndarray of training data.
            y_train: A numpy.ndarray of training targets.
            x_test: A numpy.ndarray of testing data.
            y_test: A numpy.ndarray of testing targets.
            trainer_args: A dictionary containing the parameters of the ModelTrainer constructor.
            retrain: A boolean of whether reinitialize the weights of the model.
        """
        if trainer_args is None:
            trainer_args = {'max_no_improvement_num': 30}

        if x_test is None:
            x_train, x_test, y_train, y_test = train_test_split(
                x_train,
                y_train,
                test_size=min(Constant.VALIDATION_SET_SIZE,
                              int(len(y_train) * 0.2)),
                random_state=42)
        if self.augment:
            x_train = text_preprocess(x_train, path=self.path)
            x_test = text_preprocess(x_test, path=self.path)

        y_train = self.transform_y(y_train)
        y_test = self.transform_y(y_test)

        train_data = text_dataloader(x_train,
                                     y_train,
                                     batch_size=Constant.MAX_BATCH_SIZE)
        test_data = text_dataloader(x_test,
                                    y_test,
                                    batch_size=Constant.MAX_BATCH_SIZE)

        self.cnn.final_fit(train_data, test_data, trainer_args, retrain)

    @property
    def metric(self):
        return Accuracy

    def predict(self, x_test):
        """Return predict results for the testing data.

        Args:
            x_test: An instance of numpy.ndarray containing the testing data.

        Returns:
            A numpy.ndarray containing the results.
        """
        if Constant.LIMIT_MEMORY:
            pass
        test_loader = text_dataloader(x_test)
        model = self.cnn.best_model
        model.eval()

        outputs = []
        with torch.no_grad():
            for index, inputs in enumerate(test_loader):
                outputs.append(model(inputs).numpy())
        output = reduce(lambda x, y: np.concatenate((x, y)), outputs)
        return self.inverse_transform_y(output)

    def evaluate(self, x_test, y_test):
        if self.augment:
            x_test = text_preprocess(x_test, path=self.path)
        """Return the accuracy score between predict value and `y_test`."""
        y_predict = self.predict(x_test)
        return self.metric().evaluate(y_test, y_predict)

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes
Ejemplo n.º 12
0
class VideoClassifier(Supervised):
    def __init__(self):
        super().__init__(verbose=False)
        self.labels = None
        self.net = None
        self.augment = None
        self.Length = 3
        self.Width = 4
        self.Epochs = 10
        self.encoder = OneHotEncoder()
        self.path = '../temp'
        self.capacity = 50

    def evaluate(self, x_test, y_test):
        y_predict = self.predict(x_test)
        return self.metric().evaluate(y_test, y_predict)

    def predict(self, x_test):
        classifier = pickle_from_file(os.path.join(self.path, 'classifier'))
        self.__dict__ = classifier.__dict__
        self.net.eval()
        test_data = self.preprocess(x_test)
        test_data = self.data_transformer.transform_test(test_data)
        outputs = []
        with torch.no_grad():
            for index, inputs in enumerate(test_data):
                outputs.append(self.net(inputs).numpy())
        output = reduce(lambda x, y: np.concatenate((x, y)), outputs)
        predicted = self.encoder.inverse_transform(output)
        return predicted

    def fit(self, x_train=None, y_train=None, time_limit=60 * 60 * 6):
        end_time = time.time() + time_limit

        x_train = self.preprocess(x_train)
        x_train, x_valid, y_train, y_valid = train_test_split(x_train,
                                                              y_train,
                                                              test_size=0.25,
                                                              shuffle=True)
        x_train, y_train = np.array(x_train), np.array(y_train)
        x_valid, y_valid = np.array(x_valid), np.array(y_valid)

        self.encoder.fit(y_train)
        y_train = self.encoder.transform(y_train)
        y_valid = self.encoder.transform(y_valid)

        self.data_transformer = ImageDataTransformer(x_train,
                                                     augment=self.augment)
        train_data = self.data_transformer.transform_train(x_train,
                                                           y_train,
                                                           batch_size=1)
        test_data = self.data_transformer.transform_test(x_valid,
                                                         y_valid,
                                                         batch_size=1)

        y_valid = self.encoder.inverse_transform(y_valid)

        visited = set()
        pq = []
        trainingQ = [(self.Length, self.Width, self.Epochs)]
        accuracy = 0.0

        while trainingQ:
            for len, width, epoch in trainingQ:
                if time.time() < end_time and (len, width,
                                               epoch) not in visited:
                    visited.add((len, width, epoch))
                    try:
                        net = CnnGenerator(self.encoder.n_classes, x_train.shape[1:])\
                            .generate(model_len=len, model_width=width).produce_model()

                        model_trainer = ModelTrainer(
                            net,
                            path=self.path,
                            loss_function=classification_loss,
                            metric=Accuracy,
                            train_data=train_data,
                            test_data=test_data,
                            verbose=True)
                        model_trainer.train_model(epoch, 3)

                        outputs = []
                        with torch.no_grad():
                            for index, (inputs, _) in enumerate(test_data):
                                outputs.append(net(inputs).numpy())
                        output = reduce(lambda x, y: np.concatenate((x, y)),
                                        outputs)
                        pred_valid = self.encoder.inverse_transform(output)
                        accu = self.metric().evaluate(y_valid, pred_valid)
                        print("Accuracy: ", accu, " Parameters: ", len, width,
                              epoch)

                        pq.append((-accu, (len, width, epoch)))
                        if pq.__len__() > self.capacity:
                            heapq.heapify(pq)
                            pq.remove(heapq.nlargest(1, pq)[0])
                        if accu > accuracy:
                            self.Epochs = epoch
                            self.Length = len
                            self.Width = width
                            accuracy = accu
                    except Exception as e:
                        print(e)

            if not pq:
                break
            heapq.heapify(pq)
            _, (nexlen, nexwidth, nexepoch) = heapq.heappop(pq)

            # Create children
            trainingQ = []
            trainingQ.append((nexlen + 1, nexwidth, nexepoch))
            trainingQ.append((nexlen, nexwidth * 2, nexepoch))
            trainingQ.append((nexlen, nexwidth, nexepoch + 5))
            trainingQ.append((nexlen + 2, nexwidth, nexepoch + 3))
            trainingQ.append((nexlen, nexwidth * 2, nexepoch + 2))
            trainingQ.append((nexlen + 1, nexwidth, nexepoch + 3))

        print('Finished Fit')
        print("Optimal Conv3D Network Parameters:")
        print("Number of Layers (Length):", self.Length)
        print("Number of Filters (Width):", self.Width)
        print("Number of Epochs", self.Epochs)
        print()

    def final_fit(self,
                  x_train,
                  y_train,
                  x_test,
                  y_test,
                  trainer_args=None,
                  retrain=True):
        x_train = self.preprocess(x_train)
        x_test = self.preprocess(x_test)

        self.encoder.fit(y_train)
        y_train = self.encoder.transform(y_train)
        y_test = self.encoder.transform(y_test)

        self.data_transformer = ImageDataTransformer(x_train,
                                                     augment=self.augment)
        train_data = self.data_transformer.transform_train(x_train,
                                                           y_train,
                                                           batch_size=1)
        test_data = self.data_transformer.transform_test(x_test,
                                                         y_test,
                                                         batch_size=1)

        self.net = CnnGenerator(self.encoder.n_classes, x_train.shape[1:]) \
            .generate(model_len=self.Length, model_width=self.Width).produce_model()

        pickle_to_file(self, os.path.join(self.path, 'classifier'))

        self.model_trainer = ModelTrainer(self.net,
                                          path=self.path,
                                          loss_function=classification_loss,
                                          metric=Accuracy,
                                          train_data=train_data,
                                          test_data=test_data,
                                          verbose=True)

        self.model_trainer.train_model(self.Epochs, 3)
        print('Finished Final Fit')

    def preprocess(self, data):
        result = []
        for video in data:
            clip = np.array([
                resize(frame, output_shape=(112, 200), preserve_range=True)
                for frame in video
            ])
            clip = clip[:, :, 44:44 + 112, :]  # crop centrally
            result.append(clip)
        result = np.array(result)
        return result

    @property
    def metric(self):
        return Accuracy
Ejemplo n.º 13
0
def transform_y(y_train):
    # Transform y_train.
    y_encoder = OneHotEncoder()
    y_encoder.fit(y_train)
    y_train = y_encoder.transform(y_train)
    return y_train, y_encoder
Ejemplo n.º 14
0
class ClassifierBase:
    """Base class of Classifier.

    ClassifierBase is the base class of all classifier classes, classifier is used
    to train and predict data.

    Attributes:
        y_encoder: An instance of OneHotEncoder for y_train (array of categorical labels).
        verbose: A boolean value indicating the verbosity mode.
        searcher: An instance of one of the subclasses of Searcher. It search different
            neural architecture to find the best model.
        searcher_type: The type of searcher to use. It must be 'climb' or 'random'.
        path: A path to the directory to save the classifier.
        model_id: Identifier for the best model.
    """
    def __init__(self,
                 verbose=False,
                 searcher_type=None,
                 path=constant.DEFAULT_SAVE_PATH):
        """Initialize the instance.

        The classifier will be loaded from file if the directory in 'path' has a saved classifier.
        Otherwise it would create a new one.
        """
        if has_file(os.path.join(path, 'classifier')):
            classifier = pickle.load(
                open(os.path.join(path, 'classifier'), 'rb'))
            classifier.searcher = pickle.load(
                open(os.path.join(path, 'searcher'), 'rb'))
            self.__dict__ = classifier.__dict__
        else:
            self.y_encoder = None
            self.verbose = verbose
            self.searcher = None
            self.searcher_type = searcher_type
            self.path = path
            self.model_id = None
            ensure_dir(path)

    def _validate(self, x_train, y_train):
        """Check x_train's type and the shape of x_train, y_train."""
        try:
            x_train = x_train.astype('float64')
        except ValueError:
            raise ValueError('x_train should only contain numerical data.')

        if len(x_train.shape) < 2:
            raise ValueError('x_train should at least has 2 dimensions.')

        if x_train.shape[0] != y_train.shape[0]:
            raise ValueError(
                'x_train and y_train should have the same number of instances.'
            )

    def fit(self, x_train, y_train):
        """Find the best model.

        Format the input, and split the dataset into training and testing set,
        save the classifier and find the best model.

        Args:
            x_train: An numpy.ndarray instance contains the training data.
            y_train: An numpy.ndarray instance contains the label of the training data.
        """
        x_train = np.array(x_train)
        y_train = np.array(y_train).flatten()

        self._validate(x_train, y_train)

        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)

        y_train = self.y_encoder.transform(y_train)

        if self.searcher is None:
            input_shape = x_train.shape[1:]
            n_classes = self.y_encoder.n_classes
            self.searcher = self._get_searcher_class()(n_classes, input_shape,
                                                       self.path, self.verbose)

        # Divide training data into training and testing data.
        x_train, x_test, y_train, y_test = train_test_split(x_train,
                                                            y_train,
                                                            test_size=0.25,
                                                            random_state=42)

        pickle.dump(self, open(os.path.join(self.path, 'classifier'), 'wb'))
        self.model_id = self.searcher.search(x_train, y_train, x_test, y_test)

    def predict(self, x_test):
        """Return predict result for the testing data.

        Args:
            x_test: An instance of numpy.ndarray contains the testing data.
        """
        model = self.searcher.load_best_model()
        return self.y_encoder.inverse_transform(
            model.predict(x_test, verbose=self.verbose))

    def summary(self):
        """Print the summary of the best model."""
        model = self.searcher.load_best_model()
        model.summary()

    def _get_searcher_class(self):
        """Return searcher class based on the 'searcher_type'."""
        if self.searcher_type == 'climb':
            return HillClimbingSearcher
        elif self.searcher_type == 'random':
            return RandomSearcher
        return None

    def evaluate(self, x_test, y_test):
        """Return the accuracy score between predict value and test_y."""
        y_predict = self.predict(x_test)
        return accuracy_score(y_test, y_predict)

    def cross_validate(self, x_all, y_all, n_splits):
        """Do the n_splits cross-validation for the input."""
        k_fold = StratifiedKFold(n_splits=n_splits,
                                 shuffle=False,
                                 random_state=7)
        scores = []
        y_raw_all = y_all
        y_all = self.y_encoder.transform(y_all)
        for train, test in k_fold.split(x_all, y_raw_all):
            model = self.searcher.load_best_model()
            reset_weights(model)
            ModelTrainer(model, x_all[train], y_all[train], x_all[test],
                         y_all[test], self.verbose).train_model()
            scores = model.evaluate(x_all[test],
                                    y_all[test],
                                    verbose=self.verbose)
            scores.append(scores[1] * 100)
        return np.array(scores)
Ejemplo n.º 15
0
from keras.datasets import cifar10

from autokeras.generator import DefaultClassifierGenerator
from autokeras.net_transformer import default_transform
from autokeras.preprocessor import OneHotEncoder
from autokeras.utils import ModelTrainer

if __name__ == '__main__':
    (x_train, y_train), (x_test, y_test) = cifar10.load_data()

    print('Start Encoding')
    encoder = OneHotEncoder()
    encoder.fit(y_train)

    y_train = encoder.transform(y_train)
    y_test = encoder.transform(y_test)

    print('Start Generating')
    graphs = default_transform(
        DefaultClassifierGenerator(10, x_train.shape[1:]).generate())
    keras_model = graphs[0].produce_model()

    print('Start Training')
    ModelTrainer(keras_model, x_train, y_train, x_test, y_test,
                 True).train_model(max_no_improvement_num=100, batch_size=128)
    print(keras_model.evaluate(x_test, y_test, True))
Ejemplo n.º 16
0
class ClassifierBase:
    """Base class of Classifier.

    ClassifierBase is the base class of all classifier classes, classifier is used
    to train and predict data.

    Attributes:
        y_encoder: An instance of OneHotEncoder for y_train (array of categorical labels).
        verbose: A boolean value indicating the verbosity mode.
        searcher: An instance of one of the subclasses of Searcher. It search different
            neural architecture to find the best model.
        searcher_type: The type of searcher to use. It must be 'climb' or 'random'.
        path: A path to the directory to save the classifier.
    """
    def __init__(self,
                 verbose=False,
                 searcher_type=None,
                 path=constant.DEFAULT_SAVE_PATH,
                 resume=False):
        """Initialize the instance.

        The classifier will be loaded from file if the directory in 'path' has a saved classifier.
        Otherwise it would create a new one.
        """
        if has_file(os.path.join(path, 'classifier')) and resume:
            classifier = pickle.load(
                open(os.path.join(path, 'classifier'), 'rb'))
            self.__dict__ = classifier.__dict__
        else:
            self.y_encoder = None
            self.verbose = verbose
            self.searcher = False
            self.searcher_type = searcher_type
            self.path = path
            ensure_dir(path)

    def fit(self,
            x_train=None,
            y_train=None,
            csv_file_path=None,
            images_path=None):
        """Find the best model.

        Format the input, and split the dataset into training and testing set,
        save the classifier and find the best model.

        Args:
            x_train: An numpy.ndarray instance contains the training data.
            y_train: An numpy.ndarray instance contains the label of the training data.
            csv_file_path: CVS file path
            images_path: Path where images exist
        """

        if y_train is None:
            y_train = []
        if x_train is None:
            x_train = []
        if csv_file_path is not None:
            img_file_name, y_train = read_csv_file(csv_file_path)
            if images_path is not None:
                x_train = read_images(img_file_name, images_path)
            else:
                raise ValueError('Directory containing images is not provided')

        x_train = np.array(x_train)
        y_train = np.array(y_train).flatten()

        _validate(x_train, y_train)

        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)

        y_train = self.y_encoder.transform(y_train)

        # Create the searcher and save on disk
        if not self.searcher:
            input_shape = x_train.shape[1:]
            n_classes = self.y_encoder.n_classes
            searcher = self._get_searcher_class()(n_classes, input_shape,
                                                  self.path, self.verbose)
            self.save_searcher(searcher)
            self.searcher = True

        # Divide training data into training and testing data.
        x_train, x_test, y_train, y_test = train_test_split(x_train,
                                                            y_train,
                                                            test_size=0.25,
                                                            random_state=42)

        pickle.dump(self, open(os.path.join(self.path, 'classifier'), 'wb'))

        while True:
            searcher = self.load_searcher()
            if searcher.model_count >= constant.MAX_MODEL_NUM:
                break
            p = multiprocessing.Process(target=run_searcher_once,
                                        args=(x_train, y_train, x_test, y_test,
                                              self.path))
            p.start()
            p.join()

    def predict(self, x_test):
        """Return predict result for the testing data.

        Args:
            x_test: An instance of numpy.ndarray contains the testing data.
        """
        model = self.load_searcher().load_best_model()
        return self.y_encoder.inverse_transform(model.predict(x_test, ))

    def summary(self):
        """Print the summary of the best model."""
        model = self.load_searcher().load_best_model()
        model.summary()

    def _get_searcher_class(self):
        """Return searcher class based on the 'searcher_type'."""
        if self.searcher_type == 'climb':
            return HillClimbingSearcher
        elif self.searcher_type == 'random':
            return RandomSearcher
        elif self.searcher_type == 'bayesian':
            return BayesianSearcher
        return None

    def evaluate(self, x_test, y_test):
        """Return the accuracy score between predict value and test_y."""
        y_predict = self.predict(x_test)
        return accuracy_score(y_test, y_predict)

    def cross_validate(self, x_all, y_all, n_splits):
        """Do the n_splits cross-validation for the input."""
        k_fold = StratifiedKFold(n_splits=n_splits,
                                 shuffle=False,
                                 random_state=7)
        scores = []
        y_raw_all = y_all
        y_all = self.y_encoder.transform(y_all)
        for train, test in k_fold.split(x_all, y_raw_all):
            model = self.load_searcher().load_best_model()
            reset_weights(model)
            ModelTrainer(model, x_all[train], y_all[train], x_all[test],
                         y_all[test], self.verbose).train_model()
            scores = model.evaluate(x_all[test],
                                    y_all[test],
                                    verbose=self.verbose)
            scores.append(scores[1] * 100)
        return np.array(scores)

    def save_searcher(self, searcher):
        pickle.dump(searcher, open(os.path.join(self.path, 'searcher'), 'wb'))

    def load_searcher(self):
        return pickle.load(open(os.path.join(self.path, 'searcher'), 'rb'))
Ejemplo n.º 17
0
class ClassifierBase:
    """Base class of Classifier.

    ClassifierBase is the base class of all classifier classes, classifier is used
    to train and predict data.

    Attributes:
        y_encoder: An instance of OneHotEncoder for y_train (array of categorical labels).
        verbose: A boolean value indicating the verbosity mode.
        searcher: An instance of one of the subclasses of Searcher. It search different
            neural architecture to find the best model.
        searcher_type: The type of searcher to use. It must be 'climb' or 'random'.
        path: A path to the directory to save the classifier.
    """

    def __init__(self, verbose=False, searcher_type=None, path=constant.DEFAULT_SAVE_PATH, resume=False,
                 searcher_args=None):
        """Initialize the instance.

        The classifier will be loaded from file if the directory in 'path' has a saved classifier.
        Otherwise it would create a new one.
        """
        if searcher_args is None:
            searcher_args = {}

        if has_file(os.path.join(path, 'classifier')) and resume:
            classifier = pickle_from_file(os.path.join(path, 'classifier'))
            self.__dict__ = classifier.__dict__
            self.path = path
        else:
            self.y_encoder = None
            self.verbose = verbose
            self.searcher = False
            self.searcher_type = searcher_type
            self.path = path
            self.searcher_args = searcher_args
            ensure_dir(path)

    def fit(self, x_train=None, y_train=None, csv_file_path=None, images_path=None, time_limit=None):
        """Find the best model.

        Format the input, and split the dataset into training and testing set,
        save the classifier and find the best model.

        Args:
            time_limit:
            x_train: An numpy.ndarray instance contains the training data.
            y_train: An numpy.ndarray instance contains the label of the training data.
            csv_file_path: CVS file path
            images_path: Path where images exist
        """

        if y_train is None:
            y_train = []
        if x_train is None:
            x_train = []
        if csv_file_path is not None:
            img_file_name, y_train = read_csv_file(csv_file_path)
            if images_path is not None:
                x_train = read_images(img_file_name, images_path)
            else:
                raise ValueError('Directory containing images is not provided')

        x_train = np.array(x_train)
        y_train = np.array(y_train).flatten()

        _validate(x_train, y_train)

        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)

        y_train = self.y_encoder.transform(y_train)

        # Create the searcher and save on disk
        if not self.searcher:
            input_shape = x_train.shape[1:]
            n_classes = self.y_encoder.n_classes
            self.searcher_args['n_classes'] = n_classes
            self.searcher_args['input_shape'] = input_shape
            self.searcher_args['path'] = self.path
            self.searcher_args['verbose'] = self.verbose
            searcher = self._get_searcher_class()(**self.searcher_args)
            self.save_searcher(searcher)
            self.searcher = True

        # Divide training data into training and testing data.
        x_train, x_test, y_train, y_test = train_test_split(x_train, y_train, test_size=0.25, random_state=42)

        pickle.dump(self, open(os.path.join(self.path, 'classifier'), 'wb'))
        pickle_to_file(self, os.path.join(self.path, 'classifier'))

        if time_limit is None:
            while True:
                searcher = self.load_searcher()
                if searcher.model_count >= constant.MAX_MODEL_NUM:
                    return
                p = multiprocessing.Process(target=run_searcher_once, args=(x_train, y_train, x_test, y_test, self.path))
                p.start()
                p.join()

        start_time = time.time()
        while time.time() - start_time <= time_limit:
            p = multiprocessing.Process(target=run_searcher_once, args=(x_train, y_train, x_test, y_test, self.path))
            p.start()
            # Kill the process if necessary.
            while time.time() - start_time <= time_limit:
                if p.is_alive():
                    time.sleep(1)
                else:
                    break
            else:
                # If break above the code in this else won't run
                p.terminate()
                p.join()

    def predict(self, x_test):
        """Return predict result for the testing data.

        Args:
            x_test: An instance of numpy.ndarray contains the testing data.
        """
        if constant.LIMIT_MEMORY:
            config = tf.ConfigProto()
            config.gpu_options.allow_growth = True
            sess = tf.Session(config=config)
            init = tf.global_variables_initializer()
            sess.run(init)
            backend.set_session(sess)
        model = self.load_searcher().load_best_model()
        return self.y_encoder.inverse_transform(model.predict(x_test, ))

    def summary(self):
        """Print the summary of the best model."""
        model = self.load_searcher().load_best_model()
        model.summary()

    def _get_searcher_class(self):
        """Return searcher class based on the 'searcher_type'."""
        if self.searcher_type == 'climb':
            return HillClimbingSearcher
        elif self.searcher_type == 'random':
            return RandomSearcher
        elif self.searcher_type == 'bayesian':
            return BayesianSearcher
        return None

    def evaluate(self, x_test, y_test):
        """Return the accuracy score between predict value and test_y."""
        y_predict = self.predict(x_test)
        return accuracy_score(y_test, y_predict)

    def cross_validate(self, x_all, y_all, n_splits, trainer_args=None):
        """Do the n_splits cross-validation for the input."""
        if trainer_args is None:
            trainer_args = {}

        if constant.LIMIT_MEMORY:
            config = tf.ConfigProto()
            config.gpu_options.allow_growth = True
            sess = tf.Session(config=config)
            init = tf.global_variables_initializer()
            sess.run(init)
            backend.set_session(sess)

        k_fold = StratifiedKFold(n_splits=n_splits, shuffle=False, random_state=7)
        ret = []
        y_raw_all = y_all
        y_all = self.y_encoder.transform(y_all)
        model = self.load_searcher().load_best_model()
        for train, test in k_fold.split(x_all, y_raw_all):
            graph = Graph(model, False)
            backend.clear_session()
            model = graph.produce_model()
            ModelTrainer(model,
                         x_all[train],
                         y_all[train],
                         x_all[test],
                         y_all[test], False).train_model(**trainer_args)
            scores = model.evaluate(x_all[test], y_all[test], verbose=self.verbose)
            if self.verbose:
                print('Score:', scores[1])
            ret.append(scores[1] * 100)
        return np.array(ret)

    def save_searcher(self, searcher):
        pickle.dump(searcher, open(os.path.join(self.path, 'searcher'), 'wb'))

    def load_searcher(self):
        return pickle_from_file(os.path.join(self.path, 'searcher'))

    def final_fit(self, x_train, y_train, x_test, y_test, trainer_args=None, retrain=False):
        if trainer_args is None:
            trainer_args = {}
        y_train = self.y_encoder.transform(y_train)
        y_test = self.y_encoder.transform(y_test)
        searcher = self.load_searcher()
        model = searcher.load_best_model()
        if retrain:
            model = Graph(model, False).produce_model()
        ModelTrainer(model, x_train, y_train, x_test, y_test, True).train_model(**trainer_args)
        searcher.replace_model(model, searcher.get_best_model_id())
Ejemplo n.º 18
0
class TextClassifier(Supervised):
    """TextClassifier class.

    Attributes:
        cnn: CNN module from net_module.py.
        path: A path to the directory to save the classifier as well as intermediate results.
        y_encoder: Label encoder, used in transform_y or inverse_transform_y for encode the label. For example,
                    if one hot encoder needed, y_encoder can be OneHotEncoder.
        data_transformer: A transformer class to process the data. See example as ImageDataTransformer.
        verbose: A boolean value indicating the verbosity mode which determines whether the search process
                will be printed to stdout.
    """
    def __init__(self,
                 verbose=False,
                 path=None,
                 resume=False,
                 searcher_args=None):
        """Initialize the instance.

        The classifier will be loaded from the files in 'path' if parameter 'resume' is True.
        Otherwise it would create a new one.
        Args:
            verbose: A boolean of whether the search process will be printed to stdout.
            path: A string. The path to a directory, where the intermediate results are saved.
            resume: A boolean. If True, the classifier will continue to previous work saved in path.
                Otherwise, the classifier will start a new search.
            searcher_args: A dictionary containing the parameters for the searcher's __init__ function.
        """
        super().__init__(verbose)

        if searcher_args is None:
            searcher_args = {}

        if path is None:
            path = temp_folder_generator()

        self.cnn = CnnModule(self.loss, self.metric, searcher_args, path,
                             verbose)

        self.path = path
        if has_file(os.path.join(self.path, 'text_classifier')) and resume:
            classifier = pickle_from_file(
                os.path.join(self.path, 'text_classifier'))
            self.__dict__ = classifier.__dict__
        else:
            self.y_encoder = None
            self.data_transformer = None
            self.verbose = verbose

    def fit(self,
            x,
            y,
            x_test=None,
            y_test=None,
            batch_size=None,
            time_limit=None):
        """Find the best neural architecture and train it.

        Based on the given dataset, the function will find the best neural architecture for it.
        The dataset is in numpy.ndarray format.
        So they training data should be passed through `x_train`, `y_train`.

        Args:
            x: A numpy.ndarray instance containing the training data.
            y: A numpy.ndarray instance containing the label of the training data.
            y_test: A numpy.ndarray instance containing the testing data.
            x_test: A numpy.ndarray instance containing the label of the testing data.
            batch_size: int, define the batch size.
            time_limit: The time limit for the search in seconds.
        """
        x = text_preprocess(x, path=self.path)

        x = np.array(x)
        y = np.array(y)
        validate_xy(x, y)
        y = self.transform_y(y)

        if batch_size is None:
            batch_size = Constant.MAX_BATCH_SIZE
        # Divide training data into training and testing data.
        if x_test is None or y_test is None:
            x_train, x_test, y_train, y_test = train_test_split(
                x,
                y,
                test_size=min(Constant.VALIDATION_SET_SIZE, int(len(y) * 0.2)),
                random_state=42)
        else:
            x_train = x
            y_train = y

        # Wrap the data into DataLoaders
        if self.data_transformer is None:
            self.data_transformer = TextDataTransformer()

        train_data = self.data_transformer.transform_train(
            x_train, y_train, batch_size=batch_size)
        test_data = self.data_transformer.transform_test(x_test, y_test)

        # Save the classifier
        pickle.dump(self, open(os.path.join(self.path, 'text_classifier'),
                               'wb'))
        pickle_to_file(self, os.path.join(self.path, 'text_classifier'))

        if time_limit is None:
            time_limit = 24 * 60 * 60

        self.cnn.fit(self.get_n_output_node(), x_train.shape, train_data,
                     test_data, time_limit)

    def final_fit(self,
                  x_train=None,
                  y_train=None,
                  x_test=None,
                  y_test=None,
                  trainer_args=None,
                  retrain=False):
        """Final training after found the best architecture.

        Args:
            x_train: A numpy.ndarray of training data.
            y_train: A numpy.ndarray of training targets.
            x_test: A numpy.ndarray of testing data.
            y_test: A numpy.ndarray of testing targets.
            trainer_args: A dictionary containing the parameters of the ModelTrainer constructor.
            retrain: A boolean of whether reinitialize the weights of the model.
        """
        if trainer_args is None:
            trainer_args = {'max_no_improvement_num': 30}

        if x_test is None:
            x_train, x_test, y_train, y_test = train_test_split(
                x_train,
                y_train,
                test_size=min(Constant.VALIDATION_SET_SIZE,
                              int(len(y_train) * 0.2)),
                random_state=42)

        x_train = text_preprocess(x_train, path=self.path)
        x_test = text_preprocess(x_test, path=self.path)

        y_train = self.transform_y(y_train)
        y_test = self.transform_y(y_test)

        train_data = self.data_transformer.transform_train(
            x_train, y_train, batch_size=Constant.MAX_BATCH_SIZE)
        test_data = self.data_transformer.transform_test(
            x_test, y_test, batch_size=Constant.MAX_BATCH_SIZE)

        self.cnn.final_fit(train_data, test_data, trainer_args, retrain)

    def predict(self, x_test):
        """Return predict results for the testing data.

        Args:
            x_test: An instance of numpy.ndarray containing the testing data.

        Returns:
            A numpy.ndarray containing the results.
        """
        if Constant.LIMIT_MEMORY:
            pass
        test_loader = self.data_transformer.transform_test(x_test)
        model = self.cnn.best_model.produce_model()
        model.eval()

        outputs = []
        with torch.no_grad():
            for index, inputs in enumerate(test_loader):
                outputs.append(model(inputs).numpy())
        output = reduce(lambda x, y: np.concatenate((x, y)), outputs)
        return self.inverse_transform_y(output)

    def evaluate(self, x_test, y_test):
        x_test = text_preprocess(x_test, path=self.path)
        """Return the accuracy score between predict value and `y_test`."""
        y_predict = self.predict(x_test)
        return self.metric().evaluate(y_test, y_predict)

    @property
    def metric(self):
        return Accuracy

    @property
    def loss(self):
        return classification_loss

    def transform_y(self, y_train):
        # Transform y_train.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y_train)
        y_train = self.y_encoder.transform(y_train)
        return y_train

    def inverse_transform_y(self, output):
        return self.y_encoder.inverse_transform(output)

    def load_searcher(self):
        return pickle_from_file(os.path.join(self.path, 'searcher'))

    def get_n_output_node(self):
        return self.y_encoder.n_classes
Ejemplo n.º 19
0

model = Net(50, 100, 10)
n_instance = 100
batch_size = 32

train_x = np.random.random((n_instance, 50))
test_x = np.random.random((n_instance, 50))
train_y = np.random.randint(0, 9, n_instance)
test_y = np.random.randint(0, 9, n_instance)
print(train_x.shape)
print(train_y.shape)

encoder = OneHotEncoder()
encoder.fit(train_y)
train_y = encoder.transform(train_y)
test_y = encoder.transform(test_y)

compose_list = Compose([])
train_data = DataLoader(MultiTransformDataset(torch.Tensor(train_x),
                                              torch.Tensor(train_y),
                                              compose_list),
                        batch_size=batch_size,
                        shuffle=False)
test_data = DataLoader(MultiTransformDataset(torch.Tensor(test_x),
                                             torch.Tensor(test_y),
                                             compose_list),
                       batch_size=batch_size,
                       shuffle=False)

model_trainer = ModelTrainer(model,
Ejemplo n.º 20
0
class ImageClassifier(ImageSupervised):
    """ImageClassifier class.
    
    Inherits from ImageSupervised

    It is used for image classification. It searches convolutional neural network architectures
    for the best configuration for the image dataset.
    
    Attributes:
        path: A string of the path to the directory to save the classifier as well as intermediate results.
        cnn: CNN module from net_module.py.
        y_encoder: Label encoder, used in transform_y or inverse_transform_y for encode the label. For example,
                    if one hot encoder needed, y_encoder can be OneHotEncoder.
        data_transformer: A transformer class to process the data. See example as ImageDataTransformer.
        verbose: A boolean value indicating the verbosity mode which determines whether the search process
                will be printed to stdout.
        augment: A boolean value indicating whether the data needs augmentation.  If not define, then it
                will use the value of Constant.DATA_AUGMENTATION which is True by default.
        searcher_args: A dictionary containing the parameters for the searcher's __init__ function.
        resize_shape: resize image height and width
    """
    @property
    def loss(self):
        return Backend.classification_loss

    @property
    def metric(self):
        return Accuracy

    def transform_y(self, y):
        """Transform the parameter y_train using the variable self.y_encoder
        
        Args:
            y: list of labels to convert
        """
        # Transform y.
        if self.y_encoder is None:
            self.y_encoder = OneHotEncoder()
            self.y_encoder.fit(y)
        y = self.y_encoder.transform(y)
        return y

    def inverse_transform_y(self, output):
        """Convert the encoded labels back to the original label space.
        
        Args:
            output: list of labels to decode
        """
        return self.y_encoder.inverse_transform(output)

    def get_n_output_node(self):
        return self.y_encoder.n_classes

    def export_autokeras_model(self, model_file_name):
        """ Creates and Exports the AutoKeras model to the given filename.
        
        Args:
            model_file_name: A string containing the name of the file to which the model should be saved
        
        Effects:
            Saves the AutoKeras model to a file.
        """
        portable_model = PortableImageClassifier(graph=self.cnn.best_model,
                                                 y_encoder=self.y_encoder,
                                                 data_transformer=self.data_transformer,
                                                 resize_params=self.resize_shape,
                                                 path=self.path)
        pickle_to_file(portable_model, model_file_name)
Ejemplo n.º 21
0
def transform_y(y_train):
	y_encoder = OneHotEncoder()
	y_encoder.fit(y_train)
	y_train = y_encoder.transform(y_train)
	return y_train