Module ktrain.vision

Expand source code
from .models import print_image_classifiers, image_classifier
from .models import print_image_regression_models, image_regression_model
from .data import show_image, show_random_images, preview_data_aug, get_data_aug
from .data import images_from_folder, images_from_csv, images_from_array, images_from_fname, preprocess_csv
from .predictor import ImagePredictor
__all__ = [
           'image_classifier', 'image_regression_model',
           'print_image_classifiers', 'print_image_regression_models',
           'images_from_folder', 'images_from_csv', 'images_from_array', 'images_from_fname',
           'get_data_aug',
           'preprocess_csv',
           'ImagePredictor',
           'show_image',
           'show_random_images',
           'preview_data_aug'
           ]

Sub-modules

ktrain.vision.caption
ktrain.vision.data
ktrain.vision.learner
ktrain.vision.models
ktrain.vision.object_detection
ktrain.vision.predictor
ktrain.vision.preprocessor
ktrain.vision.wrn

Functions

def get_data_aug(rotation_range=40, zoom_range=0.2, width_shift_range=0.2, height_shift_range=0.2, horizontal_flip=False, vertical_flip=False, featurewise_center=True, featurewise_std_normalization=True, samplewise_center=False, samplewise_std_normalization=False, rescale=None, **kwargs)
This function is simply a wrapper around ImageDataGenerator
with some reasonable defaults for data augmentation.
Returns the default image_data_generator to support
data augmentation and data normalization.
Parameters can be adjusted by caller.
Note that the ktrain.vision.model.image_classifier
function may adjust these as needed.
Expand source code
def get_data_aug(
                 rotation_range=40,
                 zoom_range=0.2,
                 width_shift_range=0.2,
                 height_shift_range=0.2,
                 horizontal_flip=False,
                 vertical_flip=False,
                 featurewise_center=True,
                 featurewise_std_normalization=True,
                 samplewise_center=False,
                 samplewise_std_normalization=False,
                 rescale=None,
                 **kwargs):
    """
    ```
    This function is simply a wrapper around ImageDataGenerator
    with some reasonable defaults for data augmentation.
    Returns the default image_data_generator to support
    data augmentation and data normalization.
    Parameters can be adjusted by caller.
    Note that the ktrain.vision.model.image_classifier
    function may adjust these as needed.
    ```
    """

    data_aug = keras.preprocessing.image.ImageDataGenerator(
                                rotation_range=rotation_range,
                                zoom_range=zoom_range,
                                width_shift_range=width_shift_range,
                                height_shift_range=height_shift_range,
                                horizontal_flip=horizontal_flip,
                                vertical_flip=vertical_flip,
                                featurewise_center=featurewise_center,
                                featurewise_std_normalization=featurewise_std_normalization,
                                samplewise_center=samplewise_center,
                                samplewise_std_normalization=samplewise_std_normalization,
                                rescale=rescale,
                                **kwargs)
    return data_aug
def image_classifier(name, train_data, val_data=None, freeze_layers=None, metrics=['accuracy'], optimizer_name='adam', multilabel=None, pt_fc=[], pt_ps=[], verbose=1)
Returns a pre-defined/pre-trained model ready to be trained/fine-tuned
for multi-class classification. By default, all layers are
trainable/unfrozen.


Args:
    name (string): one of model shown on ktrain.vision.print_image_classifiers
    train_data (image.Iterator): train data. Note: Will be manipulated here!
    val_data (image.Iterator): validation data.  Note: Will be manipulated here!
    freeze_layers (int):  number of beginning layers to make untrainable
                        If None, then all layers except new Dense layers
                        will be frozen/untrainable.
    metrics (list):  metrics to use
    optimizer_name(str): name of Keras optimizer (e.g., 'adam', 'sgd')
    multilabel(bool):  If True, model will be build to support
                       multilabel classificaiton (labels are not mutually exclusive).
                       If False, binary/multiclassification model will be returned.
                       If None, multilabel status will be inferred from data.
    pt_fc (list of ints): number of hidden units in extra Dense layers
                            before final Dense layer of pretrained model.
                            Only takes effect if name in PRETRAINED_MODELS
    pt_ps (list of floats): dropout probabilities to use before
                            each extra Dense layer in pretrained model.
                            Only takes effect if name in PRETRAINED_MODELS
    verbose (int):         verbosity
Return:
    model(Model):  the compiled model ready to be fine-tuned/trained

Expand source code
def image_classifier(name,
                     train_data,
                     val_data=None,
                     freeze_layers=None, 
                     metrics=['accuracy'],
                     optimizer_name = U.DEFAULT_OPT,
                     multilabel=None,
                     pt_fc = [],
                     pt_ps = [],
                     verbose=1):

    """
    ```
    Returns a pre-defined/pre-trained model ready to be trained/fine-tuned
    for multi-class classification. By default, all layers are
    trainable/unfrozen.


    Args:
        name (string): one of model shown on ktrain.vision.print_image_classifiers
        train_data (image.Iterator): train data. Note: Will be manipulated here!
        val_data (image.Iterator): validation data.  Note: Will be manipulated here!
        freeze_layers (int):  number of beginning layers to make untrainable
                            If None, then all layers except new Dense layers
                            will be frozen/untrainable.
        metrics (list):  metrics to use
        optimizer_name(str): name of Keras optimizer (e.g., 'adam', 'sgd')
        multilabel(bool):  If True, model will be build to support
                           multilabel classificaiton (labels are not mutually exclusive).
                           If False, binary/multiclassification model will be returned.
                           If None, multilabel status will be inferred from data.
        pt_fc (list of ints): number of hidden units in extra Dense layers
                                before final Dense layer of pretrained model.
                                Only takes effect if name in PRETRAINED_MODELS
        pt_ps (list of floats): dropout probabilities to use before
                                each extra Dense layer in pretrained model.
                                Only takes effect if name in PRETRAINED_MODELS
        verbose (int):         verbosity
    Return:
        model(Model):  the compiled model ready to be fine-tuned/trained

    ```
    """
    return image_model(name, train_data, val_data=val_data, freeze_layers=freeze_layers,
                       metrics=metrics, optimizer_name=optimizer_name, multilabel=multilabel,
                       pt_fc=pt_fc, pt_ps=pt_ps, verbose=verbose)
def image_regression_model(name, train_data, val_data=None, freeze_layers=None, metrics=['mae'], optimizer_name='adam', pt_fc=[], pt_ps=[], verbose=1)
Returns a pre-defined/pre-trained model ready to be trained/fine-tuned
for multi-class classification. By default, all layers are
trainable/unfrozen.


Args:
    name (string): one of model shown on ktrain.vision.print_image_regression_models
    train_data (image.Iterator): train data. Note: Will be manipulated here!
    val_data (image.Iterator): validation data.  Note: Will be manipulated here!
    freeze_layers (int):  number of beginning layers to make untrainable
                        If None, then all layers except new Dense layers
                        will be frozen/untrainable.
    metrics (list):  metrics to use
    optimizer_name(str): name of Keras optimizer (e.g., 'adam', 'sgd')
    multilabel(bool):  If True, model will be build to support
                       multilabel classificaiton (labels are not mutually exclusive).
                       If False, binary/multiclassification model will be returned.
                       If None, multilabel status will be inferred from data.
    pt_fc (list of ints): number of hidden units in extra Dense layers
                            before final Dense layer of pretrained model.
                            Only takes effect if name in PRETRAINED_MODELS
    pt_ps (list of floats): dropout probabilities to use before
                            each extra Dense layer in pretrained model.
                            Only takes effect if name in PRETRAINED_MODELS
    verbose (int):         verbosity
Return:
    model(Model):  the compiled model ready to be fine-tuned/trained

Expand source code
def image_regression_model(name,
                          train_data,
                          val_data=None,
                          freeze_layers=None, 
                          metrics=['mae'],
                          optimizer_name = U.DEFAULT_OPT,
                          pt_fc = [],
                          pt_ps = [],
                          verbose=1):

    """
    ```
    Returns a pre-defined/pre-trained model ready to be trained/fine-tuned
    for multi-class classification. By default, all layers are
    trainable/unfrozen.


    Args:
        name (string): one of model shown on ktrain.vision.print_image_regression_models
        train_data (image.Iterator): train data. Note: Will be manipulated here!
        val_data (image.Iterator): validation data.  Note: Will be manipulated here!
        freeze_layers (int):  number of beginning layers to make untrainable
                            If None, then all layers except new Dense layers
                            will be frozen/untrainable.
        metrics (list):  metrics to use
        optimizer_name(str): name of Keras optimizer (e.g., 'adam', 'sgd')
        multilabel(bool):  If True, model will be build to support
                           multilabel classificaiton (labels are not mutually exclusive).
                           If False, binary/multiclassification model will be returned.
                           If None, multilabel status will be inferred from data.
        pt_fc (list of ints): number of hidden units in extra Dense layers
                                before final Dense layer of pretrained model.
                                Only takes effect if name in PRETRAINED_MODELS
        pt_ps (list of floats): dropout probabilities to use before
                                each extra Dense layer in pretrained model.
                                Only takes effect if name in PRETRAINED_MODELS
        verbose (int):         verbosity
    Return:
        model(Model):  the compiled model ready to be fine-tuned/trained

    ```   
    """


    return image_model(name, train_data, val_data=val_data, freeze_layers=freeze_layers,
                       metrics=metrics, optimizer_name=optimizer_name, multilabel=False,
                       pt_fc=pt_fc, pt_ps=pt_ps, verbose=verbose)
def images_from_array(x_train, y_train, validation_data=None, val_pct=0.1, random_state=None, data_aug=None, classes=None, class_names=None, is_regression=False)
Returns image generator (Iterator instance) from training
and validation data in the form of NumPy arrays.
This function only supports image classification.
For image regression, please use images_from_df.

Args:
  x_train(numpy.ndarray):  training gdata
  y_train(numpy.ndarray):  labels must either be:
                           1. one-hot (or multi-hot) encoded arrays
                           2. integer values representing the label
  validation_data (tuple): tuple of numpy.ndarrays for validation data.
                           labels should be in one of the formats listed above.
  val_pct(float): percentage of training data to use for validaton if validation_data is None
  random_state(int): random state to use for splitting data
  data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
  classes(str): old name for class_names - should no longer be used
  class_names(str): list of strings to use as class names
  is_regression(bool): If True, task is treated as regression. 
                       Used when there is single column of numeric values and
                       numeric values should be treated as numeric targets as opposed to class labels
Returns:
  batches: a tuple of two image.Iterator - one for train and one for test and ImagePreprocessor instance
Expand source code
def images_from_array(x_train, y_train,
                      validation_data=None,
                      val_pct=0.1,
                      random_state=None,
                      data_aug=None,
                      classes=None,
                      class_names=None,
                      is_regression=False):

    """
    ```
    Returns image generator (Iterator instance) from training
    and validation data in the form of NumPy arrays.
    This function only supports image classification.
    For image regression, please use images_from_df.

    Args:
      x_train(numpy.ndarray):  training gdata
      y_train(numpy.ndarray):  labels must either be:
                               1. one-hot (or multi-hot) encoded arrays
                               2. integer values representing the label
      validation_data (tuple): tuple of numpy.ndarrays for validation data.
                               labels should be in one of the formats listed above.
      val_pct(float): percentage of training data to use for validaton if validation_data is None
      random_state(int): random state to use for splitting data
      data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
      classes(str): old name for class_names - should no longer be used
      class_names(str): list of strings to use as class names
      is_regression(bool): If True, task is treated as regression. 
                           Used when there is single column of numeric values and
                           numeric values should be treated as numeric targets as opposed to class labels
    Returns:
      batches: a tuple of two image.Iterator - one for train and one for test and ImagePreprocessor instance
    ```
    """
    if classes is not None: raise ValueError('Please use class_names argument instead of "classes".')
    if class_names and is_regression:
        warnings.warn('is_regression=True, but class_names is not empty.  Task being treated as regression.')


    # split out validation set if necessary
    if validation_data:
        x_test = validation_data[0]
        y_test = validation_data[1]
    elif val_pct is not None and val_pct >0:
        x_train, x_test, y_train, y_test = train_test_split(x_train, y_train,
                                                            test_size=val_pct,
                                                            random_state=random_state)
    else:
        x_test = None
        y_test = None

    # transform labels
    ytrans = U.YTransform(class_names=class_names if not is_regression else [])
    y_train = ytrans.apply_train(y_train)
    y_test = ytrans.apply_test(y_test)
    class_names = ytrans.get_classes()

    # train and test data generators
    (train_datagen, test_datagen) = process_datagen(data_aug, train_array=x_train)

    # Image preprocessor
    preproc = ImagePreprocessor(test_datagen, class_names, target_size=None, color_mode=None)

    # training data
    batches_tr = train_datagen.flow(x_train, y_train, shuffle=True)

    # validation data
    batches_te = None
    if x_test is not None and y_test is not None:
        batches_te = test_datagen.flow(x_test, y_test,
                                       shuffle=False)
    return (batches_tr, batches_te, preproc)
def images_from_csv(train_filepath, image_column, label_columns=[], directory=None, suffix='', val_filepath=None, is_regression=False, target_size=(224, 224), color_mode='rgb', data_aug=None, val_pct=0.1, random_state=None)
Returns image generator (Iterator instance).
Assumes output will be 2D one-hot-encoded labels for categorization.
Note: This function preprocesses the input in preparation
      for a ResNet50 model.

Args:
train_filepath (string): path to training dataset in CSV format with header row
image_column (string): name of column containing the filenames of images
                       If values in image_column do not have a file extension,
                       the extension should be supplied with suffix argument.
                       If values in image_column are not full file paths,
                       then the path to directory containing images should be supplied
                       as directory argument.

label_columns(list or str): list or str representing the columns that store labels
                            Labels can be in any one of the following formats:
                            1. a single column string string (or integer) labels

                               image_fname,label
                               -----------------
                               image01,cat
                               image02,dog

                            2. multiple columns for one-hot-encoded labels
                               image_fname,cat,dog
                               image01,1,0
                               image02,0,1

                            3. a single column of numeric values for image regression
                               image_fname,age
                               -----------------
                               image01,68
                               image02,18

directory (string): path to directory containing images
                    not required if image_column contains full filepaths
suffix(str): will be appended to each entry in image_column
             Used when the filenames in image_column do not contain file extensions.
             The extension in suffx should include ".".
val_filepath (string): path to validation dataset in CSV format
suffix(string): suffix to add to file names in image_column
is_regression(bool): If True, task is treated as regression. 
                     Used when there is single column of numeric values and
                     numeric values should be treated as numeric targets as opposed to class labels
target_size (tuple):  image dimensions
color_mode (string):  color mode
data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
                              for data augmentation
val_pct(float):  proportion of training data to be used for validation
                 only used if val_filepath is None
random_state(int): random seed for train/test split

Returns:
batches: a tuple of two Iterators - one for train and one for test
Expand source code
def images_from_csv(train_filepath,
                   image_column,
                   label_columns=[],
                   directory=None,
                   suffix='',
                   val_filepath=None,
                   is_regression=False,
                   target_size=(224,224),
                    color_mode='rgb',
                    data_aug=None,
                    val_pct=0.1, random_state=None):

    """
    ```
    Returns image generator (Iterator instance).
    Assumes output will be 2D one-hot-encoded labels for categorization.
    Note: This function preprocesses the input in preparation
          for a ResNet50 model.

    Args:
    train_filepath (string): path to training dataset in CSV format with header row
    image_column (string): name of column containing the filenames of images
                           If values in image_column do not have a file extension,
                           the extension should be supplied with suffix argument.
                           If values in image_column are not full file paths,
                           then the path to directory containing images should be supplied
                           as directory argument.

    label_columns(list or str): list or str representing the columns that store labels
                                Labels can be in any one of the following formats:
                                1. a single column string string (or integer) labels

                                   image_fname,label
                                   -----------------
                                   image01,cat
                                   image02,dog

                                2. multiple columns for one-hot-encoded labels
                                   image_fname,cat,dog
                                   image01,1,0
                                   image02,0,1

                                3. a single column of numeric values for image regression
                                   image_fname,age
                                   -----------------
                                   image01,68
                                   image02,18

    directory (string): path to directory containing images
                        not required if image_column contains full filepaths
    suffix(str): will be appended to each entry in image_column
                 Used when the filenames in image_column do not contain file extensions.
                 The extension in suffx should include ".".
    val_filepath (string): path to validation dataset in CSV format
    suffix(string): suffix to add to file names in image_column
    is_regression(bool): If True, task is treated as regression. 
                         Used when there is single column of numeric values and
                         numeric values should be treated as numeric targets as opposed to class labels
    target_size (tuple):  image dimensions
    color_mode (string):  color mode
    data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
                                  for data augmentation
    val_pct(float):  proportion of training data to be used for validation
                     only used if val_filepath is None
    random_state(int): random seed for train/test split

    Returns:
    batches: a tuple of two Iterators - one for train and one for test
    ```
    """

    # convert to dataframes
    train_df = pd.read_csv(train_filepath)
    val_df = None
    if val_filepath is not None:
        val_df = pd.read_csv(val_filepath)


    return images_from_df(train_df,
                          image_column,
                          label_columns=label_columns,
                          directory=directory,
                          suffix=suffix,
                          val_df=val_df,
                          is_regression=is_regression,
                          target_size=target_size,
                          color_mode=color_mode,
                          data_aug=data_aug,
                          val_pct=val_pct, random_state=random_state)
def images_from_fname(train_folder, pattern='([^/]+)_\\d+.jpg$', val_folder=None, is_regression=False, target_size=(224, 224), color_mode='rgb', data_aug=None, val_pct=0.1, random_state=None, verbose=1)
Returns image generator (Iterator instance).

Args:
train_folder (str): directory containing images
pat (str):  regular expression to extract class from file name of each image
            Example: r'([^/]+)_\d+.jpg$' to match 'english_setter' in 'english_setter_140.jpg'
            By default, it will extract classes from file names of the form:
               <class_name>_<numbers>.jpg
val_folder (str): directory containing validation images. default:None
is_regression(bool): If True, task is treated as regression. 
                     Used when there is single column of numeric values and
                     numeric values should be treated as numeric targets as opposed to class labels
target_size (tuple):  image dimensions
color_mode (string):  color mode
data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
                              for data augmentation
val_pct(float):  proportion of training data to be used for validation
                 only used if val_folder is None
random_state(int): random seed for train/test split
verbose(bool):   verbosity

Returns:
batches: a tuple of two Iterators - one for train and one for test
Expand source code
def images_from_fname( train_folder,
                      pattern=r'([^/]+)_\d+.jpg$',
                      val_folder=None,
                      is_regression=False,
                     target_size=(224,224),
                     color_mode='rgb',
                     data_aug=None,
                     val_pct=0.1, random_state=None,
                     verbose=1):

    """
    ```
    Returns image generator (Iterator instance).

    Args:
    train_folder (str): directory containing images
    pat (str):  regular expression to extract class from file name of each image
                Example: r'([^/]+)_\d+.jpg$' to match 'english_setter' in 'english_setter_140.jpg'
                By default, it will extract classes from file names of the form:
                   <class_name>_<numbers>.jpg
    val_folder (str): directory containing validation images. default:None
    is_regression(bool): If True, task is treated as regression. 
                         Used when there is single column of numeric values and
                         numeric values should be treated as numeric targets as opposed to class labels
    target_size (tuple):  image dimensions
    color_mode (string):  color mode
    data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
                                  for data augmentation
    val_pct(float):  proportion of training data to be used for validation
                     only used if val_folder is None
    random_state(int): random seed for train/test split
    verbose(bool):   verbosity

    Returns:
    batches: a tuple of two Iterators - one for train and one for test
    ```
    """

    image_column = 'image_name'
    label_column = 'label'
    train_df = _img_fnames_to_df(train_folder, pattern, 
                                 image_column=image_column, label_column=label_column, verbose=verbose)
    val_df = None
    if val_folder is not None:
        val_df = _img_fnames_to_df(val_folder, pattern, 
                                   image_column=image_column, label_column=label_column, verbose=verbose)
    return images_from_df(train_df,
                          image_column,
                          label_columns=label_column,
                          directory=train_folder,
                          val_directory=val_folder,
                          val_df=val_df,
                          is_regression=is_regression,
                          target_size=target_size,
                          color_mode=color_mode,
                          data_aug=data_aug,
                          val_pct=val_pct, random_state=random_state)
def images_from_folder(datadir, target_size=(224, 224), classes=None, color_mode='rgb', train_test_names=['train', 'test'], data_aug=None, verbose=1)
Returns image generator (Iterator instance).
Assumes output will be 2D one-hot-encoded labels for categorization.
Note: This function preprocesses the input in preparation
      for a ResNet50 model.

Args:
datadir (string): path to training (or validation/test) dataset
    Assumes folder follows this structure:
    ├── datadir
    │   ├── train
    │   │   ├── class0       # folder containing documents of class 0
    │   │   ├── class1       # folder containing documents of class 1
    │   │   ├── class2       # folder containing documents of class 2
    │   │   └── classN       # folder containing documents of class N
    │   └── test
    │       ├── class0       # folder containing documents of class 0
    │       ├── class1       # folder containing documents of class 1
    │       ├── class2       # folder containing documents of class 2
    │       └── classN       # folder containing documents of class N

target_size (tuple):  image dimensions
classes (list):  optional list of class subdirectories (e.g., ['cats','dogs'])
color_mode (string):  color mode
train_test_names(list): names for train and test subfolders
data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
                              for data augmentation
verbose (bool):               verbosity

Returns:
batches: a tuple of two Iterators - one for train and one for test
Expand source code
def images_from_folder(datadir, target_size=(224,224),
                       classes=None,
                       color_mode='rgb',
                       train_test_names=['train', 'test'],
                       data_aug=None, verbose=1):

    """
    ```
    Returns image generator (Iterator instance).
    Assumes output will be 2D one-hot-encoded labels for categorization.
    Note: This function preprocesses the input in preparation
          for a ResNet50 model.

    Args:
    datadir (string): path to training (or validation/test) dataset
        Assumes folder follows this structure:
        ├── datadir
        │   ├── train
        │   │   ├── class0       # folder containing documents of class 0
        │   │   ├── class1       # folder containing documents of class 1
        │   │   ├── class2       # folder containing documents of class 2
        │   │   └── classN       # folder containing documents of class N
        │   └── test
        │       ├── class0       # folder containing documents of class 0
        │       ├── class1       # folder containing documents of class 1
        │       ├── class2       # folder containing documents of class 2
        │       └── classN       # folder containing documents of class N

    target_size (tuple):  image dimensions
    classes (list):  optional list of class subdirectories (e.g., ['cats','dogs'])
    color_mode (string):  color mode
    train_test_names(list): names for train and test subfolders
    data_aug(ImageDataGenerator):  a keras.preprocessing.image.ImageDataGenerator
                                  for data augmentation
    verbose (bool):               verbosity

    Returns:
    batches: a tuple of two Iterators - one for train and one for test
    ```
    """

    # train/test names
    train_str = train_test_names[0]
    test_str = train_test_names[1]
    train_dir = os.path.join(datadir, train_str)
    test_dir = os.path.join(datadir, test_str)

    # color mode warning
    if PIL_INSTALLED:
        inferred_color_mode = detect_color_mode(train_dir)
        if inferred_color_mode is not None and (inferred_color_mode != color_mode):
            U.vprint('color_mode detected (%s) different than color_mode selected (%s)' % (inferred_color_mode, color_mode),
                     verbose=verbose)

    # get train and test data generators
    (train_datagen, test_datagen) = process_datagen(data_aug,
                                        train_directory=train_dir,
                                        target_size=target_size,
                                        color_mode=color_mode)
    batches_tr = train_datagen.flow_from_directory(train_dir,
                                         target_size=target_size,
                                         classes=classes,
                                         class_mode='categorical',
                                         shuffle=True,
                                         interpolation='bicubic',
                                         color_mode = color_mode)

    batches_te = test_datagen.flow_from_directory(test_dir,
                                              target_size=target_size,
                                              classes=classes,
                                              class_mode='categorical',
                                              shuffle=False,
                                              interpolation='bicubic',
                                              color_mode = color_mode)

    # setup preprocessor
    class_tup = sorted(batches_tr.class_indices.items(), key=operator.itemgetter(1))
    preproc = ImagePreprocessor(test_datagen,
                                [x[0] for x in class_tup],
                                target_size=target_size,
                                color_mode=color_mode)
    return (batches_tr, batches_te, preproc)
def preprocess_csv(csv_in, csv_out, x_col='filename', y_col=None, sep=',', label_sep=' ', suffix='', split_by=None)
Takes a CSV where the one column contains a file name and a column
containing a string representations of the class(es) like here:
image_name,tags
01, sunny|hot
02, cloudy|cold
03, cloudy|hot

.... and one-hot encodes the classes to produce a CSV as follows:
image_name, cloudy, cold, hot, sunny
01.jpg,0,0,1,1
02.jpg,1,1,0,0
03.jpg,1,0,1,0
Args:
    csv_in (str):  filepath to input CSV file
    csv_out (str): filepath to output CSV file
    x_col (str):  name of column containing file names
    y_col (str): name of column containing the classes
    sep (str): field delimiter of entire file (e.g., comma fore CSV)
    label_sep (str): delimiter for column containing classes
    suffix (str): adds suffix to x_col values
    split_by(str): name of column. A separate CSV will be
                   created for each value in column. Useful
                   for splitting a CSV based on whether a column
                   contains 'train' or 'valid'.
Return:
    list :  the list of clases (and csv_out will be new CSV file)
Expand source code
def preprocess_csv(csv_in, csv_out, x_col='filename', y_col=None,
                   sep=',', label_sep=' ', suffix='', split_by=None):
    """
    ```
    Takes a CSV where the one column contains a file name and a column
    containing a string representations of the class(es) like here:
    image_name,tags
    01, sunny|hot
    02, cloudy|cold
    03, cloudy|hot

    .... and one-hot encodes the classes to produce a CSV as follows:
    image_name, cloudy, cold, hot, sunny
    01.jpg,0,0,1,1
    02.jpg,1,1,0,0
    03.jpg,1,0,1,0
    Args:
        csv_in (str):  filepath to input CSV file
        csv_out (str): filepath to output CSV file
        x_col (str):  name of column containing file names
        y_col (str): name of column containing the classes
        sep (str): field delimiter of entire file (e.g., comma fore CSV)
        label_sep (str): delimiter for column containing classes
        suffix (str): adds suffix to x_col values
        split_by(str): name of column. A separate CSV will be
                       created for each value in column. Useful
                       for splitting a CSV based on whether a column
                       contains 'train' or 'valid'.
    Return:
        list :  the list of clases (and csv_out will be new CSV file)
    ```
    """
    if not y_col and not suffix:
        raise ValueError('one or both of y_col and suffix should be supplied')
    df = pd.read_csv(csv_in, sep=sep)
    f_csv_out = open(csv_out, 'w')
    writer = csv.writer(f_csv_out, delimiter=sep)
    if y_col: df[y_col] = df[y_col].apply(str)

    # write header
    if y_col:
        classes = set()
        for row in df.iterrows():
            data = row[1]
            tags = data[y_col].split(label_sep)
            classes.update(tags)
        classes = list(classes)
        classes.sort()
        writer.writerow([x_col] + classes)
    else:
        classes = df.columns[:-1]
        write.writerow(df.columns)

    # write rows
    for row in df.iterrows():
        data = row[1]
        data[x_col] = data[x_col] + suffix
        if y_col:
            out = list(data[[x_col]].values)
            tags = set(data[y_col].strip().split(label_sep))
            for c in classes:
                if c in tags: out.append(1)
                else: out.append(0)
        else:
            out = data
        writer.writerow(out)
    f_csv_out.close()
    return classes
def preview_data_aug(img_path, data_aug, rows=1, n=4)
Preview data augmentation (ImageDatagenerator)
on a supplied image.
Expand source code
def preview_data_aug(img_path, data_aug, rows=1, n=4):
    """
    ```
    Preview data augmentation (ImageDatagenerator)
    on a supplied image.
    ```
    """
    if type(img_path) != type('') or not os.path.isfile(img_path):
        raise ValueError('img_path must be valid file path to image')
    idg = copy.copy(data_aug)
    idg.featurewise_center = False
    idg.featurewise_std_normalization = False
    idg.samplewise_center = False
    idg.samplewise_std_normalization = False
    idg.rescale = None
    idg.zca_whitening = False
    idg.preprocessing_function = None

    img = keras.preprocessing.image.load_img(img_path)
    x = keras.preprocessing.image.img_to_array(img)
    x = x/255.
    x = x.reshape((1,) + x.shape)
    i = 0
    ims = []
    for batch in idg.flow(x, batch_size=1):
        ims.append(np.squeeze(batch))
        i += 1
        if i >= n: break
    U.plots(ims, rows=rows)
    return
def print_image_classifiers()
Expand source code
def print_image_classifiers():
    for k,v in IMAGE_CLASSIFIERS.items():
        print("%s: %s" % (k,v))
def print_image_regression_models()
Expand source code
def print_image_regression_models():
    for k,v in IMAGE_CLASSIFIERS.items():
        print("%s: %s" % (k,v))
def show_image(img_path)
Given file path to image, show it in Jupyter notebook
Expand source code
def show_image(img_path):
    """
    ```
    Given file path to image, show it in Jupyter notebook
    ```
    """
    if not os.path.isfile(img_path):
        raise ValueError('%s is not valid file' % (img_path))
    img = plt.imread(img_path)
    out = plt.imshow(img)
    return out
def show_random_images(img_folder, n=4, rows=1)
display random images from a img_folder
Expand source code
def show_random_images(img_folder, n=4, rows=1):
    """
    ```
    display random images from a img_folder
    ```
    """
    fnames = []
    for ext in ('*.gif', '*.png', '*.jpg'):
        fnames.extend(glob.glob(os.path.join(img_folder, ext)))
    ims = []
    for i in range(n):
        img_path = random.choice(fnames)
        img = keras.preprocessing.image.load_img(img_path)
        x = keras.preprocessing.image.img_to_array(img)
        x = x/255.
        ims.append(x)
    U.plots(ims, rows=rows)
    return

Classes

class ImagePredictor (model, preproc, batch_size=32)
predicts image classes
Expand source code
class ImagePredictor(Predictor):
    """
    ```
    predicts image classes
    ```
    """

    def __init__(self, model, preproc, batch_size=U.DEFAULT_BS):

        if not isinstance(model, keras.Model):
            raise ValueError('model must be of instance keras.Model')
        if not isinstance(preproc, ImagePreprocessor):
            raise ValueError('preproc must be instance of ImagePreprocessor')
        self.model = model
        self.preproc = preproc
        self.datagen = self.preproc.get_preprocessor()
        self.c = self.preproc.get_classes()
        self.batch_size = batch_size


    def get_classes(self):
        return self.c


    def explain(self, img_fpath):
        """
        ```
        Highlights image to explain prediction
        ```
        """
        #if U.is_tf_keras():
            #warnings.warn("currently_unsupported: explain() method is not available because tf.keras is "+\
                          #"not yet adequately supported by the eli5 library. You can switch to " +\
                          #"stand-alone Keras by setting os.environ['TF_KERAS']='0'" )
            #return

        try:
            import eli5
        except:
            msg = 'ktrain requires a forked version of eli5 to support tf.keras. '+\
                  'Install with: pip install https://github.com/amaiya/eli5/archive/refs/heads/tfkeras_0_10_1.zip'
            warnings.warn(msg)
            return

        #if not hasattr(eli5, 'KTRAIN'):
        if not hasattr(eli5, 'KTRAIN_ELI5_TAG') or eli5.KTRAIN_ELI5_TAG != KTRAIN_ELI5_TAG:
            warnings.warn("Since eli5 does not yet support tf.keras, ktrain uses a forked version of eli5.  " +\
                           "We do not detect this forked version (or it is out-of-date), so predictor.explain may not work.  " +\
                           "It will work if you uninstall the current version of eli5 and install "+\
                           "the forked version:  " +\
                           "pip install https://github.com/amaiya/eli5/archive/refs/heads/tfkeras_0_10_1.zip")
            return

        if not DISABLE_V2_BEHAVIOR:
            warnings.warn("Please add os.environ['DISABLE_V2_BEHAVIOR'] = '1' at top of your script or notebook.")
            msg = "\nFor image classification, the explain method currently requires disabling V2 behavior in TensorFlow 2.\n" +\
                    "Please add the following to the top of your script or notebook BEFORE you import ktrain and restart Colab runtime or Jupyter kernel:\n\n" +\
                  "import os\n" +\
                  "os.environ['DISABLE_V2_BEHAVIOR'] = '1'\n"
            print(msg)
            return


        img = keras.preprocessing.image.load_img(img_fpath,
                             target_size=self.preproc.target_size,
                             color_mode=self.preproc.color_mode)
        x = keras.preprocessing.image.img_to_array(img)
        x = np.expand_dims(x, axis=0)
        return eli5.show_prediction(self.model, x)




    def predict(self, data, return_proba=False):
        """
        ```
        Predicts class from image in array format.
        If return_proba is True, returns probabilities of each class.
        ```
        """
        if not isinstance(data, np.ndarray):
            raise ValueError('data must be numpy.ndarray')
        (generator, steps) = self.preproc.preprocess(data, batch_size=self.batch_size)
        return self.predict_generator(generator, steps=steps, return_proba=return_proba)


    def predict_filename(self, img_path, return_proba=False):
        """
        ```
        Predicts class from filepath to single image file.
        If return_proba is True, returns probabilities of each class.
        ```
        """
        if not os.path.isfile(img_path): raise ValueError('img_path must be valid file')
        (generator, steps) = self.preproc.preprocess(img_path, batch_size=self.batch_size)
        return self.predict_generator(generator, steps=steps, return_proba=return_proba)


    def predict_folder(self, folder, return_proba=False):
        """
        ```
        Predicts the classes of all images in a folder.
        If return_proba is True, returns probabilities of each class.
        ```

        """
        if not os.path.isdir(folder): raise ValueError('folder must be valid directory')
        (generator, steps) = self.preproc.preprocess(folder, batch_size=self.batch_size)
        result = self.predict_generator(generator, steps=steps, return_proba=return_proba)
        if len(result) != len(generator.filenames):
            raise Exception('number of results does not equal number of filenames')
        return list(zip(generator.filenames, result))


    def predict_generator(self, generator, steps=None, return_proba=False):
        #loss = self.model.loss
        #if callable(loss): loss = loss.__name__
        #treat_multilabel = False
        #if loss != 'categorical_crossentropy' and not return_proba:
        #    return_proba=True
        #    treat_multilabel = True
        classification, multilabel = U.is_classifier(self.model)
        if not classification: return_proba=True
        # *_generator methods are deprecated from TF 2.1.0
        #preds =  self.model.predict_generator(generator, steps=steps)
        preds =  self.model.predict(generator, steps=steps)
        result =  preds if return_proba or multilabel else [self.c[np.argmax(pred)] for pred in preds]
        if multilabel and not return_proba:
            return [list(zip(self.c, r)) for r in result]
        if not classification:
            return np.squeeze(result, axis=1)
        else:
            return result


    def predict_proba(self, data):
        return self.predict(data, return_proba=True)


    def predict_proba_folder(self, folder):
        return self.predict_folder(folder, return_proba=True)


    def predict_proba_filename(self, img_path):
        return self.predict_filename(img_path, return_proba=True)


    def predict_proba_generator(self, generator, steps=None):
        return self.predict_proba_generator(generator, steps=steps, return_proba=True)



    def analyze_valid(self, generator, print_report=True, multilabel=None):
        """
        ```
        Makes predictions on validation set and returns the confusion matrix.
        Accepts as input a genrator (e.g., DirectoryIterator, DataframeIterator)
        representing the validation set.


        Optionally prints a classification report.
        Currently, this method is only supported for binary and multiclass
        problems, not multilabel classification problems.
        ```
        """
        if multilabel is None:
            multilabel = U.is_multilabel(generator)
        if multilabel:
            warnings.warn('multilabel_confusion_matrix not yet supported - skipping')
            return

        y_true = generator.classes
        # *_generator methods are deprecated from TF 2.1.0
        #y_pred = self.model.predict_generator(generator)
        y_pred = self.model.predict(generator)
        y_pred = np.argmax(y_pred, axis=1)
        if print_report:
            print(classification_report(y_true, y_pred, target_names=self.c))
        if not multilabel:
            cm_func = confusion_matrix
            cm =  cm_func(y_true,  y_pred)
        else:
            cm = None
        return cm


    def _save_preproc(self, fpath):
        preproc_name = 'tf_model.preproc'
        with open(os.path.join(fpath, preproc_name), 'wb') as f:
            datagen = self.preproc.get_preprocessor()
            pfunc = datagen.preprocessing_function
            datagen.preprocessing_function = None
            pickle.dump(self.preproc, f)
            datagen.preprocessing_function = pfunc
        return

Ancestors

Methods

def analyze_valid(self, generator, print_report=True, multilabel=None)
Makes predictions on validation set and returns the confusion matrix.
Accepts as input a genrator (e.g., DirectoryIterator, DataframeIterator)
representing the validation set.


Optionally prints a classification report.
Currently, this method is only supported for binary and multiclass
problems, not multilabel classification problems.
Expand source code
def analyze_valid(self, generator, print_report=True, multilabel=None):
    """
    ```
    Makes predictions on validation set and returns the confusion matrix.
    Accepts as input a genrator (e.g., DirectoryIterator, DataframeIterator)
    representing the validation set.


    Optionally prints a classification report.
    Currently, this method is only supported for binary and multiclass
    problems, not multilabel classification problems.
    ```
    """
    if multilabel is None:
        multilabel = U.is_multilabel(generator)
    if multilabel:
        warnings.warn('multilabel_confusion_matrix not yet supported - skipping')
        return

    y_true = generator.classes
    # *_generator methods are deprecated from TF 2.1.0
    #y_pred = self.model.predict_generator(generator)
    y_pred = self.model.predict(generator)
    y_pred = np.argmax(y_pred, axis=1)
    if print_report:
        print(classification_report(y_true, y_pred, target_names=self.c))
    if not multilabel:
        cm_func = confusion_matrix
        cm =  cm_func(y_true,  y_pred)
    else:
        cm = None
    return cm
def explain(self, img_fpath)
Highlights image to explain prediction
Expand source code
def explain(self, img_fpath):
    """
    ```
    Highlights image to explain prediction
    ```
    """
    #if U.is_tf_keras():
        #warnings.warn("currently_unsupported: explain() method is not available because tf.keras is "+\
                      #"not yet adequately supported by the eli5 library. You can switch to " +\
                      #"stand-alone Keras by setting os.environ['TF_KERAS']='0'" )
        #return

    try:
        import eli5
    except:
        msg = 'ktrain requires a forked version of eli5 to support tf.keras. '+\
              'Install with: pip install https://github.com/amaiya/eli5/archive/refs/heads/tfkeras_0_10_1.zip'
        warnings.warn(msg)
        return

    #if not hasattr(eli5, 'KTRAIN'):
    if not hasattr(eli5, 'KTRAIN_ELI5_TAG') or eli5.KTRAIN_ELI5_TAG != KTRAIN_ELI5_TAG:
        warnings.warn("Since eli5 does not yet support tf.keras, ktrain uses a forked version of eli5.  " +\
                       "We do not detect this forked version (or it is out-of-date), so predictor.explain may not work.  " +\
                       "It will work if you uninstall the current version of eli5 and install "+\
                       "the forked version:  " +\
                       "pip install https://github.com/amaiya/eli5/archive/refs/heads/tfkeras_0_10_1.zip")
        return

    if not DISABLE_V2_BEHAVIOR:
        warnings.warn("Please add os.environ['DISABLE_V2_BEHAVIOR'] = '1' at top of your script or notebook.")
        msg = "\nFor image classification, the explain method currently requires disabling V2 behavior in TensorFlow 2.\n" +\
                "Please add the following to the top of your script or notebook BEFORE you import ktrain and restart Colab runtime or Jupyter kernel:\n\n" +\
              "import os\n" +\
              "os.environ['DISABLE_V2_BEHAVIOR'] = '1'\n"
        print(msg)
        return


    img = keras.preprocessing.image.load_img(img_fpath,
                         target_size=self.preproc.target_size,
                         color_mode=self.preproc.color_mode)
    x = keras.preprocessing.image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    return eli5.show_prediction(self.model, x)
def get_classes(self)
Expand source code
def get_classes(self):
    return self.c
def predict(self, data, return_proba=False)
Predicts class from image in array format.
If return_proba is True, returns probabilities of each class.
Expand source code
def predict(self, data, return_proba=False):
    """
    ```
    Predicts class from image in array format.
    If return_proba is True, returns probabilities of each class.
    ```
    """
    if not isinstance(data, np.ndarray):
        raise ValueError('data must be numpy.ndarray')
    (generator, steps) = self.preproc.preprocess(data, batch_size=self.batch_size)
    return self.predict_generator(generator, steps=steps, return_proba=return_proba)
def predict_filename(self, img_path, return_proba=False)
Predicts class from filepath to single image file.
If return_proba is True, returns probabilities of each class.
Expand source code
def predict_filename(self, img_path, return_proba=False):
    """
    ```
    Predicts class from filepath to single image file.
    If return_proba is True, returns probabilities of each class.
    ```
    """
    if not os.path.isfile(img_path): raise ValueError('img_path must be valid file')
    (generator, steps) = self.preproc.preprocess(img_path, batch_size=self.batch_size)
    return self.predict_generator(generator, steps=steps, return_proba=return_proba)
def predict_folder(self, folder, return_proba=False)
Predicts the classes of all images in a folder.
If return_proba is True, returns probabilities of each class.
Expand source code
def predict_folder(self, folder, return_proba=False):
    """
    ```
    Predicts the classes of all images in a folder.
    If return_proba is True, returns probabilities of each class.
    ```

    """
    if not os.path.isdir(folder): raise ValueError('folder must be valid directory')
    (generator, steps) = self.preproc.preprocess(folder, batch_size=self.batch_size)
    result = self.predict_generator(generator, steps=steps, return_proba=return_proba)
    if len(result) != len(generator.filenames):
        raise Exception('number of results does not equal number of filenames')
    return list(zip(generator.filenames, result))
def predict_generator(self, generator, steps=None, return_proba=False)
Expand source code
def predict_generator(self, generator, steps=None, return_proba=False):
    #loss = self.model.loss
    #if callable(loss): loss = loss.__name__
    #treat_multilabel = False
    #if loss != 'categorical_crossentropy' and not return_proba:
    #    return_proba=True
    #    treat_multilabel = True
    classification, multilabel = U.is_classifier(self.model)
    if not classification: return_proba=True
    # *_generator methods are deprecated from TF 2.1.0
    #preds =  self.model.predict_generator(generator, steps=steps)
    preds =  self.model.predict(generator, steps=steps)
    result =  preds if return_proba or multilabel else [self.c[np.argmax(pred)] for pred in preds]
    if multilabel and not return_proba:
        return [list(zip(self.c, r)) for r in result]
    if not classification:
        return np.squeeze(result, axis=1)
    else:
        return result
def predict_proba(self, data)
Expand source code
def predict_proba(self, data):
    return self.predict(data, return_proba=True)
def predict_proba_filename(self, img_path)
Expand source code
def predict_proba_filename(self, img_path):
    return self.predict_filename(img_path, return_proba=True)
def predict_proba_folder(self, folder)
Expand source code
def predict_proba_folder(self, folder):
    return self.predict_folder(folder, return_proba=True)
def predict_proba_generator(self, generator, steps=None)
Expand source code
def predict_proba_generator(self, generator, steps=None):
    return self.predict_proba_generator(generator, steps=steps, return_proba=True)

Inherited members