Multimodal Data Tables: Tabular, Text, and Image

Tip: Prior to reading this tutorial, it is recommended to have a basic understanding of the TabularPredictor API covered in Predicting Columns in a Table - Quick Start.

In this tutorial, we will train a multi-modal ensemble using data that contains image, text, and tabular features.

Note: A GPU is required for this tutorial in order to train the image and text models. Additionally, GPU installations are required for MXNet and Torch with appropriate CUDA versions.

The PetFinder Dataset

We will be using the PetFinder dataset. The PetFinder dataset provides information about shelter animals that appear on their adoption profile with the goal to predict the adoption rate of the animal. The end goal is for rescue shelters to use the predicted adoption rate to identify animals whose profiles could be improved so that they can find a home.

Each animal’s adoption profile contains a variety of information, such as pictures of the animal, a text description of the animal, and various tabular features such as age, breed, name, color, and more.

To get started, we first need to download the dataset. Datasets that contain images require more than a CSV file, so the dataset is packaged in a zip file in S3. We will first download it and unzip the contents:

download_dir = './ag_petfinder_tutorial'
zip_file = 'https://automl-mm-bench.s3.amazonaws.com/petfinder_kaggle.zip'
from autogluon.core.utils.loaders import load_zip
load_zip.unzip(zip_file, unzip_dir=download_dir)
Downloading ./ag_petfinder_tutorial/file.zip from https://automl-mm-bench.s3.amazonaws.com/petfinder_kaggle.zip...
100%|██████████| 2.00G/2.00G [01:26<00:00, 23.1MiB/s]

Now that the data is download and unzipped, lets take a look at the contents:

import os
os.listdir(download_dir)
['petfinder_processed', 'file.zip']

‘file.zip’ is the original zip file we downloaded, and ‘petfinder_processed’ is a directory containing the dataset files.

dataset_path = download_dir + '/petfinder_processed'
os.listdir(dataset_path)
['test.csv', 'dev.csv', 'test_images', 'train_images', 'train.csv']

Here we can see the train, test, and dev CSV files, as well as two directories: ‘test_images’ and ‘train_images’ which contain the image JPG files.

Note: We will be using the dev data as testing data as dev contains the ground truth labels for showing scores via predictor.leaderboard.

Let’s take a peek at the first 10 files inside of the ‘train_images’ directory:

os.listdir(dataset_path + '/train_images')[:10]
['ca587cb42-1.jpg',
 'ae00eded4-4.jpg',
 '6e3457b81-2.jpg',
 'acb248693-1.jpg',
 '0bd867d1b-1.jpg',
 'fa53dd6cd-1.jpg',
 '9726ab93e-1.jpg',
 '39818f12c-2.jpg',
 '90ce48a71-2.jpg',
 '2ece6b26b-1.jpg']

As expected, these are the images we will be training with alongside the other features.

Next, we will load the train and dev CSV files:

import pandas as pd

train_data = pd.read_csv(f'{dataset_path}/train.csv', index_col=0)
test_data = pd.read_csv(f'{dataset_path}/dev.csv', index_col=0)
train_data.head(3)
Type Name Age Breed1 Breed2 Gender Color1 Color2 Color3 MaturitySize ... Quantity Fee State RescuerID VideoAmt Description PetID PhotoAmt AdoptionSpeed Images
10721 1 Elbi 2 307 307 2 5 0 0 3 ... 1 0 41336 e9a86209c54f589ba72c345364cf01aa 0 I'm looking for people to adopt my dog e4b90955c 4.0 4 train_images/e4b90955c-1.jpg;train_images/e4b9...
13114 2 Darling 4 266 0 1 1 0 0 2 ... 1 0 41401 01f954cdf61526daf3fbeb8a074be742 0 Darling was born at the back lane of Jalan Alo... a0c1384d1 5.0 3 train_images/a0c1384d1-1.jpg;train_images/a0c1...
13194 1 Wolf 3 307 0 1 1 2 0 2 ... 1 0 41332 6e19409f2847326ce3b6d0cec7e42f81 0 I found Wolf about a month ago stuck in a drai... cf357f057 7.0 4 train_images/cf357f057-1.jpg;train_images/cf35...

3 rows × 25 columns

Looking at the first 3 examples, we can tell that there is a variety of tabular features, a text description (‘Description’), and an image path (‘Images’).

For the PetFinder dataset, we will try to predict the speed of adoption for the animal (‘AdoptionSpeed’), grouped into 5 categories. This means that we are dealing with a multi-class classification problem.

label = 'AdoptionSpeed'
image_col = 'Images'

Preparing the image column

Let’s take a look at what a value in the image column looks like:

train_data[image_col].iloc[0]
'train_images/e4b90955c-1.jpg;train_images/e4b90955c-2.jpg;train_images/e4b90955c-3.jpg;train_images/e4b90955c-4.jpg'

Currently, AutoGluon only supports one image per row. Since the PetFinder dataset contains one or more images per row, we first need to preprocess the image column to only contain the first image of each row.

train_data[image_col] = train_data[image_col].apply(lambda ele: ele.split(';')[0])
test_data[image_col] = test_data[image_col].apply(lambda ele: ele.split(';')[0])

train_data[image_col].iloc[0]
'train_images/e4b90955c-1.jpg'

AutoGluon loads images based on the file path provided by the image column.

Here we update the path to point to the correct location on disk:

def path_expander(path, base_folder):
    path_l = path.split(';')
    return ';'.join([os.path.abspath(os.path.join(base_folder, path)) for path in path_l])

train_data[image_col] = train_data[image_col].apply(lambda ele: path_expander(ele, base_folder=dataset_path))
test_data[image_col] = test_data[image_col].apply(lambda ele: path_expander(ele, base_folder=dataset_path))

train_data[image_col].iloc[0]
'/var/lib/jenkins/workspace/workspace/autogluon-tutorial-tabular-v3/docs/_build/eval/tutorials/tabular_prediction/ag_petfinder_tutorial/petfinder_processed/train_images/e4b90955c-1.jpg'
train_data.head(3)
Type Name Age Breed1 Breed2 Gender Color1 Color2 Color3 MaturitySize ... Quantity Fee State RescuerID VideoAmt Description PetID PhotoAmt AdoptionSpeed Images
10721 1 Elbi 2 307 307 2 5 0 0 3 ... 1 0 41336 e9a86209c54f589ba72c345364cf01aa 0 I'm looking for people to adopt my dog e4b90955c 4.0 4 /var/lib/jenkins/workspace/workspace/autogluon...
13114 2 Darling 4 266 0 1 1 0 0 2 ... 1 0 41401 01f954cdf61526daf3fbeb8a074be742 0 Darling was born at the back lane of Jalan Alo... a0c1384d1 5.0 3 /var/lib/jenkins/workspace/workspace/autogluon...
13194 1 Wolf 3 307 0 1 1 2 0 2 ... 1 0 41332 6e19409f2847326ce3b6d0cec7e42f81 0 I found Wolf about a month ago stuck in a drai... cf357f057 7.0 4 /var/lib/jenkins/workspace/workspace/autogluon...

3 rows × 25 columns

Analyzing an example row

Now that we have preprocessed the image column, lets take a look at an example row of data and display the text description and the picture.

example_row = train_data.iloc[1]

example_row
Type                                                             2
Name                                                       Darling
Age                                                              4
Breed1                                                         266
Breed2                                                           0
Gender                                                           1
Color1                                                           1
Color2                                                           0
Color3                                                           0
MaturitySize                                                     2
FurLength                                                        1
Vaccinated                                                       2
Dewormed                                                         2
Sterilized                                                       2
Health                                                           1
Quantity                                                         1
Fee                                                              0
State                                                        41401
RescuerID                         01f954cdf61526daf3fbeb8a074be742
VideoAmt                                                         0
Description      Darling was born at the back lane of Jalan Alo...
PetID                                                    a0c1384d1
PhotoAmt                                                       5.0
AdoptionSpeed                                                    3
Images           /var/lib/jenkins/workspace/workspace/autogluon...
Name: 13114, dtype: object
example_row['Description']
'Darling was born at the back lane of Jalan Alor and was foster by a feeder. All his siblings had died of accident. His mother and grandmother had just been spayed. Darling make a great condo/apartment cat. He love to play a lot. He would make a great companion for someone looking for a cat to love.'
example_image = example_row['Images']

from IPython.display import Image, display
pil_img = Image(filename=example_image)
display(pil_img)
../../_images/output_tabular-multimodal_e625cb_24_0.jpg

The PetFinder dataset is fairly large. For the purposes of the tutorial, we will sample 500 rows for training.

Training on large multi-modal datasets can be very computationally intensive, especially if using the best_quality preset in AutoGluon. When prototyping, it is recommended to sample your data to get an idea of which models are worth training, then gradually train with larger amounts of data and longer time limits as you would with any other machine learning algorithm.

train_data = train_data.sample(500, random_state=0)

Constructing the FeatureMetadata

Next, lets see what AutoGluon infers the feature types to be by constructing a FeatureMetadata object from the training data:

from autogluon.tabular import FeatureMetadata
feature_metadata = FeatureMetadata.from_df(train_data)

print(feature_metadata)
('float', [])        :  1 | ['PhotoAmt']
('int', [])          : 19 | ['Type', 'Age', 'Breed1', 'Breed2', 'Gender', ...]
('object', [])       :  4 | ['Name', 'RescuerID', 'PetID', 'Images']
('object', ['text']) :  1 | ['Description']

Notice that FeatureMetadata automatically identified the column ‘Description’ as text, so we don’t need to manually specify that it is text.

In order to leverage images, we need to tell AutoGluon which column contains the image path. We can do this by specifying a FeatureMetadata object and adding the ‘image_path’ special type to the image column. We later pass this custom FeatureMetadata to TabularPredictor.fit.

feature_metadata = feature_metadata.add_special_types({image_col: ['image_path']})

print(feature_metadata)
('float', [])              :  1 | ['PhotoAmt']
('int', [])                : 19 | ['Type', 'Age', 'Breed1', 'Breed2', 'Gender', ...]
('object', [])             :  3 | ['Name', 'RescuerID', 'PetID']
('object', ['image_path']) :  1 | ['Images']
('object', ['text'])       :  1 | ['Description']

Specifying the hyperparameters

Next, we need to specify the models we want to train with. This is done via the hyperparameters argument to TabularPredictor.fit.

AutoGluon has a predefined config that works well for multimodal datasets called ‘multimodal’. We can access it via:

from autogluon.tabular.configs.hyperparameter_configs import get_hyperparameter_config
hyperparameters = get_hyperparameter_config('multimodal')

hyperparameters
{'NN': {},
 'GBM': [{},
  {'extra_trees': True, 'ag_args': {'name_suffix': 'XT'}},
  'GBMLarge'],
 'CAT': {},
 'XGB': {},
 'AG_TEXT_NN': ['medium_quality_faster_train'],
 'AG_IMAGE_NN': {}}

This hyperparameter config will train a variety of Tabular models as well as finetune an Electra BERT text model, and a ResNet image model.

Fitting with TabularPredictor

Now we will train a TabularPredictor on the dataset, using the feature metadata and hyperparameters we defined prior. This TabularPredictor will leverage tabular, text, and image features all at once.

from autogluon.tabular import TabularPredictor
predictor = TabularPredictor(label=label).fit(
    train_data=train_data,
    hyperparameters=hyperparameters,
    feature_metadata=feature_metadata,
    time_limit=900,
)
No path specified. Models will be saved in: "AutogluonModels/ag-20210827_222702/"
Beginning AutoGluon training ... Time limit = 900s
AutoGluon will save models to "AutogluonModels/ag-20210827_222702/"
AutoGluon Version:  0.3.0b20210827
Train Data Rows:    500
Train Data Columns: 24
Preprocessing data ...
AutoGluon infers your prediction problem is: 'multiclass' (because dtype of label-column == int, but few unique label-values observed).
    5 unique label values:  [2, 3, 4, 0, 1]
    If 'multiclass' is not the correct problem_type, please manually specify the problem_type argument in fit() (You may specify problem_type as one of: ['binary', 'multiclass', 'regression'])
Train Data Class Count: 5
Using Feature Generators to preprocess the data ...
Fitting AutoMLPipelineFeatureGenerator...
    Available Memory:                    22132.33 MB
    Train Data (Original)  Memory Usage: 0.51 MB (0.0% of available memory)
    Stage 1 Generators:
            Fitting AsTypeFeatureGenerator...
    Stage 2 Generators:
            Fitting FillNaFeatureGenerator...
    Stage 3 Generators:
            Fitting IdentityFeatureGenerator...
            Fitting IdentityFeatureGenerator...
                    Fitting RenameFeatureGenerator...
            Fitting CategoryFeatureGenerator...
                    Fitting CategoryMemoryMinimizeFeatureGenerator...
            Fitting TextSpecialFeatureGenerator...
                    Fitting BinnedFeatureGenerator...
                    Fitting DropDuplicatesFeatureGenerator...
            Fitting TextNgramFeatureGenerator...
                    Fitting CountVectorizer for text features: ['Description']
                    CountVectorizer fit with vocabulary size = 170
            Fitting IdentityFeatureGenerator...
            Fitting IsNanFeatureGenerator...
    Stage 4 Generators:
            Fitting DropUniqueFeatureGenerator...
    Unused Original Features (Count: 1): ['PetID']
            These features were not used to generate any of the output features. Add a feature generator compatible with these features to utilize them.
            Features can also be unused if they carry very little information, such as being categorical but having almost entirely unique values or being duplicates of other features.
            These features do not need to be present at inference time.
            ('object', []) : 1 | ['PetID']
    Types of features in original data (raw dtype, special dtypes):
            ('float', [])              :  1 | ['PhotoAmt']
            ('int', [])                : 18 | ['Type', 'Age', 'Breed1', 'Breed2', 'Gender', ...]
            ('object', [])             :  2 | ['Name', 'RescuerID']
            ('object', ['image_path']) :  1 | ['Images']
            ('object', ['text'])       :  1 | ['Description']
    Types of features in processed data (raw dtype, special dtypes):
            ('category', [])                    :   2 | ['Name', 'RescuerID']
            ('category', ['text_as_category'])  :   1 | ['Description']
            ('float', [])                       :   1 | ['PhotoAmt']
            ('int', [])                         :  18 | ['Type', 'Age', 'Breed1', 'Breed2', 'Gender', ...]
            ('int', ['binned', 'text_special']) :  24 | ['Description.char_count', 'Description.word_count', 'Description.capital_ratio', 'Description.lower_ratio', 'Description.digit_ratio', ...]
            ('int', ['text_ngram'])             : 171 | ['__nlp__.about', '__nlp__.active', '__nlp__.active and', '__nlp__.adopt', '__nlp__.adopted', ...]
            ('object', ['image_path'])          :   1 | ['Images']
            ('object', ['text'])                :   1 | ['Description_raw_text']
    0.5s = Fit runtime
    23 features in original data used to generate 219 features in processed data.
    Train Data (Processed) Memory Usage: 0.59 MB (0.0% of available memory)
Data preprocessing and feature engineering runtime = 0.58s ...
AutoGluon will gauge predictive performance using evaluation metric: 'accuracy'
    To change this, specify the eval_metric argument of fit()
Automatically generating train/validation split with holdout_frac=0.2, Train Rows: 400, Val Rows: 100
Fitting 8 L1 models ...
Fitting model: LightGBM ... Training model for up to 899.42s of the 898.54s of remaining time.
    0.34     = Validation score   (accuracy)
    0.67s    = Training   runtime
    0.01s    = Validation runtime
Fitting model: LightGBMXT ... Training model for up to 898.74s of the 897.86s of remaining time.
    0.37     = Validation score   (accuracy)
    0.42s    = Training   runtime
    0.01s    = Validation runtime
Fitting model: CatBoost ... Training model for up to 898.31s of the 897.43s of remaining time.
    0.35     = Validation score   (accuracy)
    1.39s    = Training   runtime
    0.01s    = Validation runtime
Fitting model: XGBoost ... Training model for up to 896.89s of the 896.02s of remaining time.
    0.35     = Validation score   (accuracy)
    0.94s    = Training   runtime
    0.01s    = Validation runtime
Fitting model: NeuralNetMXNet ... Training model for up to 895.9s of the 895.02s of remaining time.
    0.33     = Validation score   (accuracy)
    2.61s    = Training   runtime
    0.03s    = Validation runtime
Fitting model: LightGBMLarge ... Training model for up to 893.25s of the 892.37s of remaining time.
    0.37     = Validation score   (accuracy)
    1.75s    = Training   runtime
    0.01s    = Validation runtime
Fitting model: TextPredictor ... Training model for up to 891.49s of the 890.61s of remaining time.
All Logs will be saved to /var/lib/jenkins/workspace/workspace/autogluon-tutorial-tabular-v3/docs/_build/eval/tutorials/tabular_prediction/AutogluonModels/ag-20210827_222702/models/TextPredictor/task0/training.log
[Iter 1/40, Epoch 0] valid accuracy=2.6000e-01, log_loss=1.7115e+00, accuracy=2.6000e-01, time spent=1.089s, total time spent=0.11min. Find new best=True, Find new top-3=True
[Iter 2/40, Epoch 0] valid accuracy=2.5000e-01, log_loss=1.7735e+00, accuracy=2.5000e-01, time spent=1.107s, total time spent=0.21min. Find new best=False, Find new top-3=True
[Iter 3/40, Epoch 0] valid accuracy=2.7000e-01, log_loss=1.6355e+00, accuracy=2.7000e-01, time spent=1.099s, total time spent=0.31min. Find new best=True, Find new top-3=True
[Iter 4/40, Epoch 0] valid accuracy=3.3000e-01, log_loss=1.4861e+00, accuracy=3.3000e-01, time spent=1.104s, total time spent=0.44min. Find new best=True, Find new top-3=True
[Iter 5/40, Epoch 1] valid accuracy=2.7000e-01, log_loss=1.6336e+00, accuracy=2.7000e-01, time spent=1.104s, total time spent=0.54min. Find new best=False, Find new top-3=True
[Iter 6/40, Epoch 1] valid accuracy=2.5000e-01, log_loss=1.4989e+00, accuracy=2.5000e-01, time spent=1.107s, total time spent=0.62min. Find new best=False, Find new top-3=False
[Iter 7/40, Epoch 1] valid accuracy=2.6000e-01, log_loss=1.5441e+00, accuracy=2.6000e-01, time spent=1.113s, total time spent=0.71min. Find new best=False, Find new top-3=False
[Iter 8/40, Epoch 1] valid accuracy=3.0000e-01, log_loss=1.5220e+00, accuracy=3.0000e-01, time spent=1.098s, total time spent=0.80min. Find new best=False, Find new top-3=True
[Iter 9/40, Epoch 2] valid accuracy=2.8000e-01, log_loss=1.5367e+00, accuracy=2.8000e-01, time spent=1.123s, total time spent=0.91min. Find new best=False, Find new top-3=True
[Iter 10/40, Epoch 2] valid accuracy=3.0000e-01, log_loss=1.4981e+00, accuracy=3.0000e-01, time spent=1.112s, total time spent=1.01min. Find new best=False, Find new top-3=True
[Iter 11/40, Epoch 2] valid accuracy=2.4000e-01, log_loss=1.5138e+00, accuracy=2.4000e-01, time spent=1.122s, total time spent=1.09min. Find new best=False, Find new top-3=False
[Iter 12/40, Epoch 2] valid accuracy=2.3000e-01, log_loss=1.5209e+00, accuracy=2.3000e-01, time spent=1.121s, total time spent=1.17min. Find new best=False, Find new top-3=False
[Iter 13/40, Epoch 3] valid accuracy=2.4000e-01, log_loss=1.5624e+00, accuracy=2.4000e-01, time spent=1.131s, total time spent=1.26min. Find new best=False, Find new top-3=False
[Iter 14/40, Epoch 3] valid accuracy=2.4000e-01, log_loss=1.5485e+00, accuracy=2.4000e-01, time spent=1.137s, total time spent=1.36min. Find new best=False, Find new top-3=False
[Iter 15/40, Epoch 3] valid accuracy=2.7000e-01, log_loss=1.5387e+00, accuracy=2.7000e-01, time spent=1.132s, total time spent=1.44min. Find new best=False, Find new top-3=False
[Iter 16/40, Epoch 3] valid accuracy=2.8000e-01, log_loss=1.5500e+00, accuracy=2.8000e-01, time spent=1.142s, total time spent=1.53min. Find new best=False, Find new top-3=False
[Iter 17/40, Epoch 4] valid accuracy=2.5000e-01, log_loss=1.6021e+00, accuracy=2.5000e-01, time spent=1.133s, total time spent=1.62min. Find new best=False, Find new top-3=False
[Iter 18/40, Epoch 4] valid accuracy=2.2000e-01, log_loss=1.6318e+00, accuracy=2.2000e-01, time spent=1.148s, total time spent=1.70min. Find new best=False, Find new top-3=False
[Iter 19/40, Epoch 4] valid accuracy=2.5000e-01, log_loss=1.6321e+00, accuracy=2.5000e-01, time spent=1.154s, total time spent=1.79min. Find new best=False, Find new top-3=False
[Iter 20/40, Epoch 4] valid accuracy=2.6000e-01, log_loss=1.6406e+00, accuracy=2.6000e-01, time spent=1.150s, total time spent=1.88min. Find new best=False, Find new top-3=False
[Iter 21/40, Epoch 5] valid accuracy=2.4000e-01, log_loss=1.6581e+00, accuracy=2.4000e-01, time spent=1.156s, total time spent=1.97min. Find new best=False, Find new top-3=False
[Iter 22/40, Epoch 5] valid accuracy=2.7000e-01, log_loss=1.7323e+00, accuracy=2.7000e-01, time spent=1.167s, total time spent=2.06min. Find new best=False, Find new top-3=False
[Iter 23/40, Epoch 5] valid accuracy=2.5000e-01, log_loss=1.7713e+00, accuracy=2.5000e-01, time spent=1.154s, total time spent=2.15min. Find new best=False, Find new top-3=False
[Iter 24/40, Epoch 5] valid accuracy=2.1000e-01, log_loss=1.8234e+00, accuracy=2.1000e-01, time spent=1.138s, total time spent=2.23min. Find new best=False, Find new top-3=False
    0.26     = Validation score   (accuracy)
    144.15s  = Training   runtime
    1.65s    = Validation runtime
Fitting model: ImagePredictor ... Training model for up to 744.95s of the 744.07s of remaining time.
/var/lib/jenkins/workspace/workspace/autogluon-tutorial-tabular-v3/venv/lib/python3.7/site-packages/gluoncv/__init__.py:40: UserWarning: Both mxnet==1.7.0 and torch==1.7.1+cu101 are installed. You might encounter increased GPU memory footprint if both framework are used at the same time.
  warnings.warn(f'Both mxnet=={mx.__version__} and torch=={torch.__version__} are installed. '
ImagePredictor sets accuracy as default eval_metric for classification problems.
The number of requested GPUs is greater than the number of available GPUs.Reduce the number to 1
modified configs(<old> != <new>): {
root.misc.seed       42 != 601
root.misc.num_workers 4 != 8
root.train.early_stop_baseline 0.0 != -inf
root.train.early_stop_max_value 1.0 != inf
root.train.early_stop_patience -1 != 10
root.train.epochs    200 != 15
root.train.batch_size 32 != 16
root.img_cls.model   resnet101 != resnet50
}
Saved config to /var/lib/jenkins/workspace/workspace/autogluon-tutorial-tabular-v3/docs/_build/eval/tutorials/tabular_prediction/AutogluonModels/ag-20210827_222702/models/ImagePredictor/7297ed5f/.trial_0/config.yaml
Model resnet50 created, param count:                                         23518277
AMP not enabled. Training in float32.
Disable EMA as it is not supported for now.
Start training from [Epoch 0]
[Epoch 0] training: accuracy=0.202500
[Epoch 0] speed: 74 samples/sec     time cost: 5.164430
[Epoch 0] validation: top1=0.250000 top5=1.000000
[Epoch 0] Current best top-1: 0.250000 vs previous -inf, saved to /var/lib/jenkins/workspace/workspace/autogluon-tutorial-tabular-v3/docs/_build/eval/tutorials/tabular_prediction/AutogluonModels/ag-20210827_222702/models/ImagePredictor/7297ed5f/.trial_0/best_checkpoint.pkl
[Epoch 1] training: accuracy=0.287500
[Epoch 1] speed: 89 samples/sec     time cost: 4.297956
[Epoch 1] validation: top1=0.250000 top5=1.000000
[Epoch 2] training: accuracy=0.315000
[Epoch 2] speed: 89 samples/sec     time cost: 4.288746
[Epoch 2] validation: top1=0.210000 top5=1.000000
[Epoch 3] training: accuracy=0.332500
[Epoch 3] speed: 89 samples/sec     time cost: 4.290897
[Epoch 3] validation: top1=0.260000 top5=1.000000
[Epoch 3] Current best top-1: 0.260000 vs previous 0.250000, saved to /var/lib/jenkins/workspace/workspace/autogluon-tutorial-tabular-v3/docs/_build/eval/tutorials/tabular_prediction/AutogluonModels/ag-20210827_222702/models/ImagePredictor/7297ed5f/.trial_0/best_checkpoint.pkl
[Epoch 4] training: accuracy=0.345000
[Epoch 4] speed: 89 samples/sec     time cost: 4.285051
[Epoch 4] validation: top1=0.250000 top5=1.000000
[Epoch 5] training: accuracy=0.450000
[Epoch 5] speed: 89 samples/sec     time cost: 4.282331
[Epoch 5] validation: top1=0.230000 top5=1.000000
[Epoch 6] training: accuracy=0.422500
[Epoch 6] speed: 89 samples/sec     time cost: 4.279387
[Epoch 6] validation: top1=0.240000 top5=1.000000
[Epoch 7] training: accuracy=0.435000
[Epoch 7] speed: 89 samples/sec     time cost: 4.278119
[Epoch 7] validation: top1=0.210000 top5=1.000000
[Epoch 8] training: accuracy=0.430000
[Epoch 8] speed: 89 samples/sec     time cost: 4.268685
[Epoch 8] validation: top1=0.230000 top5=1.000000
[Epoch 9] training: accuracy=0.460000
[Epoch 9] speed: 90 samples/sec     time cost: 4.261562
[Epoch 9] validation: top1=0.240000 top5=1.000000
[Epoch 10] training: accuracy=0.485000
[Epoch 10] speed: 89 samples/sec    time cost: 4.284987
[Epoch 10] validation: top1=0.240000 top5=1.000000
[Epoch 11] training: accuracy=0.482500
[Epoch 11] speed: 89 samples/sec    time cost: 4.274632
[Epoch 11] validation: top1=0.240000 top5=1.000000
[Epoch 12] training: accuracy=0.510000
[Epoch 12] speed: 89 samples/sec    time cost: 4.282893
[Epoch 12] validation: top1=0.230000 top5=1.000000
[Epoch 13] training: accuracy=0.517500
[Epoch 13] speed: 89 samples/sec    time cost: 4.273556
[Epoch 13] validation: top1=0.250000 top5=1.000000
[Epoch 14] EarlyStop after 10 epochs: no better than 0.26
Applying the state from the best checkpoint...
    0.26     = Validation score   (accuracy)
    80.07s   = Training   runtime
    1.35s    = Validation runtime
Fitting model: WeightedEnsemble_L2 ... Training model for up to 360.0s of the 657.38s of remaining time.
    0.37     = Validation score   (accuracy)
    0.17s    = Training   runtime
    0.0s     = Validation runtime
AutoGluon training complete, total runtime = 242.81s ...
TabularPredictor saved. To load, use: predictor = TabularPredictor.load("AutogluonModels/ag-20210827_222702/")

After the predictor is fit, we can take a look at the leaderboard and see the performance of the various models:

leaderboard = predictor.leaderboard(test_data)
                 model  score_test  score_val  pred_time_test  pred_time_val    fit_time  pred_time_test_marginal  pred_time_val_marginal  fit_time_marginal  stack_level  can_infer  fit_order
0           LightGBMXT    0.328776       0.37        0.026961       0.006548    0.421152                 0.026961                0.006548           0.421152            1       True          2
1  WeightedEnsemble_L2    0.328776       0.37        0.044582       0.006927    0.594044                 0.017621                0.000379           0.172893            2       True          9
2        LightGBMLarge    0.323775       0.37        0.018214       0.006538    1.746738                 0.018214                0.006538           1.746738            1       True          6
3        TextPredictor    0.315438       0.26       43.202971       1.653899  144.151662                43.202971                1.653899         144.151662            1       True          7
4       ImagePredictor    0.301767       0.26       11.461797       1.347679   80.068130                11.461797                1.347679          80.068130            1       True          8
5       NeuralNetMXNet    0.297766       0.33        0.151960       0.031508    2.609199                 0.151960                0.031508           2.609199            1       True          5
6              XGBoost    0.292431       0.35        0.121338       0.006172    0.940261                 0.121338                0.006172           0.940261            1       True          4
7             LightGBM    0.289763       0.34        0.021433       0.006537    0.668204                 0.021433                0.006537           0.668204            1       True          1
8             CatBoost    0.269757       0.35        0.020993       0.014226    1.394260                 0.020993                0.014226           1.394260            1       True          3

That’s all it takes to train with image, text, and tabular data (at the same time) using AutoGluon!

For an in-depth tutorial on text + tabular multimodal functionality, refer to Multimodal Data Tables: Combining BERT/Transformers and Classical Tabular Models.

For more tutorials, refer to Predicting Columns in a Table - Quick Start and Predicting Columns in a Table - In Depth.