Uber Ludwig Applications

Road

Believe it or not, but a lack of coding skills is one of the most common self-excuses for not starting to work on data science and machine learning. This is why in the last few months and years a lot of companies created and open-sourced libraries and tools that allow no-coders to create their own machine learning projects.

These tools include Microsoft Azure ML Studio, Weka, Uber’s Ludwig and many others.

This article is a follow-up on my post “Introduction to Uber’s Ludwig”, where I explained what Uber’s Ludwig is and what it can be used for. In this article, I will try to explain how to use Uber’s Ludwig for different data including tabular data, image data, and text data.

The main focus of the article will be to help you get a good understanding of how to approach different problems so that after this article you will be able to solve your problems using Uber’s Ludwig.

Recap

Uber’s Ludwig is a toolbox build on top of Tensorflow that allows users to create and train models without needing to write any code.

Uber’s Ludwig was built with 5 core principles in mind:

  • No coding required: no coding skills are required to train a model and use it for obtaining predictions.
  • Generality: a new data type-based approach to deep learning model design that makes the tool usable across many different use cases.
  • Flexibility: experienced users have extensive control over model building and training, while newcomers will find it easy to use.
  • Extensibility: easy to add new model architecture and new feature data types.
  • Understandability: standard visualizations to understand the performance of models and compare their predictions.

To use Ludwig for solving a problem we need to create a YAML file containing the input and output features as well as some general training configurations.

input_features:
  ...
  
output_features:
  ...
  
training:
  ...

The configuration file only needs to include the input and output features but can be extended to contain complex configurations like the architecture of the model used.

How to best work with Uber’s Ludwig

To get the most out of Ludwig, like for all tools, you have to think about your data in a certain way. In the case of Ludwig, it is important that you are sure what input and output data you have because the type of input and output data will heavily affect the content of your configuration yaml file.

Tabular Data

Tabular data is data that comes in the form of a table like in an Excel sheet or a SQL database. This kind of data includes a combination of numerical and categorical features.

To work with tabular data inside Ludwig we need to go through each column and specify if it is a numerical, categorical or binary column.

Binary Classification on the Heart Diseases Data-set

As an example of a tabular data-set, I chose the heart disease data-set because it contains a mixture of categorical and numerical features and it isn’t too hard to solve.

Heart Disease data-set

Figure 2: Heart Disease Data-set

To get started we create a file called model_definition.yaml . In it, we will define our input and output features.

input_features:
  ...
output_features:
  ...

For the heart disease data-set, we want to predict if a patient has or doesn’t have a heart disease which is indicated by the target column. This column will be our output column. All other columns will be used for input. Therefore we will look at every single one and determine if it is a numerical or categorical feature.

input_features:
  -
    name: age
    type: numerical
  -
    name: sex
    type: category
  -
    name: cp
    type: category
  -
    name: trestbps
    type: category
  -
    name: chol
    type: numerical
  -
    name: fbs
    type: category
  -
    name: thalach
    type: numerical
  -
    name: exang
    type: category
  -
    name: oldpeak
    type: category
  -
    name: slope
    type: category
  -
    name: ca
    type: category
  -
    name: thal
    type: category

output_features:
  -
    name: target
    type: binary

For some features like the gender and age column, the data type is apparent but for other columns, it is important to take a closer look at how many unique values they contain.

There are multiple options to get the unique value of a column including filtering the data with Excel or using pandas unique method.

Unique values of the age column

Figure 3: Unique values of the age column

Image Data

Computer Vision is one of the most researched topics in machine learning and therefore it is pretty easy to get state of the art results without knowing the inner workings of the algorithms driving these results.

Uber’s Ludwig is very flexible when it comes to working with image data. That means that you can get a model to work by simply specifying an input column of type image but you can also highly customize the architecture of the model by specifying additional attributes like the conv_layers attribute.

Image Classification on the Malaria Cell Image Data-set

The Malaria Cell data-set contains images that either contain or don’t contain malaria-affected cells.

Cell Image

Figure 4: Cell Image (Link)

To get started with this data-set we need to create a csv file containing the image path and their corresponding labels.

import os
import pandas as pd
import argparse
 
 
def folder_structure_to_csv(path: str, save_path: str):
    paths = []
    labels = []
    for folder in os.listdir(path):
        for image in os.listdir(path+'/'+folder):
            paths.append(folder+'/'+image)
            labels.append(folder)
    df = pd.DataFrame({'image_name': paths,'label': labels})
    df.to_csv(save_path, index=None)
 
 
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Create CSV from folder structure of a data-set')
    parser.add_argument('-p', '--path', type=str, required=True, help='Path to the data-set directory')
    parser.add_argument('-s', '--save_path', type=str, required=True, help='Path where the csv will be saved')
    args = parser.parse_args()
    folder_structure_to_csv(args.path, args.save_path)

For the input feature, we need to specify the image_name column which contains the paths to the images. As a type, we need to specify image and for the encoder, we will use a stacked_cnn.

input_features:
    -
        name: image_name
        type: image
        encoder: stacked_cnn
        resize_method: crop_or_pad
        width: 128
        height: 128

output_features:
    -
        name: label
        type: category

training:
    batch_size: 8

This can be easily customized to a specific use case using the conv_layers and fc_layers arguments for the input features. As well as specifying general parameters for training.

input_features:
    -
        name: image_path
        type: image
        encoder: stacked_cnn
        resize_method: crop_or_pad
        width: 128
        height: 128
        conv_layers:
            -
                num_filters: 32
                filter_size: 3
                pool_size: 2
                pool_stride: 2
                dropout: true
            -
                num_filters: 32
                filter_size: 3
                pool_size: 2
                pool_stride: 2
            -
                num_filters: 64
                filter_size: 3
                pool_size: 2
                pool_stride: 2
                dropout: true
        fc_layers:
            -
                fc_size: 256
                dropout: true
            -
                fc_size: 128
                dropout: true

output_features:
    -
        name: label
        type: category

training:
    dropout_rate: 0.3
    batch_size: 4

Multi-class Image Classification on the Amazon Satellite Data-set

For some problems like the “Planet: Understanding the Amazon from Space” competition we don’t want to only predict the most likely label. Rather the competition requires us to create a model that outputs all the classes contained in an image.

Amazon Data-set examples

Figure 5: Amazon Data-set examples

When using libraries like Tensorflow, PyTorch or Keras this can be achieved by changing the activation function of the last layer to Sigmoid and using a threshold to determine when a class is present in the image.

Uber Ludwig makes this even easier by introducing the set type.

input_features:
  -
    name: image_name
    type: image
    encoder: stacked_cnn
    in_memory: False

output_features:
  -
    name: tags
    type: set

training:
    batch_size: 4

Working with text data

Working with text data can be hard. Especially if you don’t have any experience doing so.

This is because when working with text data you can’t just pass the text to the model and magically expect to get out the result. Rather you need to use one of many encoding techniques to transform the text into numbers and pass them into the model.

Uber Ludwig makes the process of working with text data incredible straight forward by allowing you to work with text data by only specifying the type text and some kind of encoder.

input_features:
    -
        name: text
        type: text
        level: word
        encoder: parallel_cnn

output_features:
    -
        name: class
        type: category

The configuration above will automatically transform each word to a unique index before passing the data to the model.

Text Translation on the French-English Bilingual Pairs Data-set

Text translation is the process of translating text from one language into another. This can be straight forward for a human who is fluent in both of the used languages but can be really hard for a machine. This is because for translating the model must have a good understanding of both languages.

In most libraries it is hard to create a text translation system because the output doesn’t have a fixed size but when working with Uber’s Ludwig we don’t need to worry about this because it does all of this in the background.

input_features:
  -
    name: english
    type: text
    level: word
    encoder: rnn
    cell_type: lstm
    reduce_output: null
    preprocessing:
      word_format: english_tokenize

output_features:
  -
    name: french
    type: text
    level: word
    decoder: generator
    cell_type: lstm
    attention: bahdanau
    loss:
      type: sampled_softmax_cross_entropy
    preprocessing:
      word_format: space

training:
  batch_size: 32

Here instead of having a category as our output, we have text. To get the text out of our network we are using a generator with a cell type of lstm and bahdanau attention.

Summary

Uber’s Ludwig is one of the best none-coding deep learning toolkits available. It offers users the ability to train complex models with only a few lines of configurations.

In this article, we explored how to best use Uber’s Ludwig with different types of data.

That’s all from this article. If you have any questions or just want to chat with me feel free to leave a comment below or contact me on social media. If you want to get continuous updates about my blog make sure to follow me on Medium and join my newsletter.