Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Image Dataloader for PASCAL VOC and CIFAR 10 dataset. #13

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
16d7fe1
Add basic definition of models, Needs to be trained and tested
kartikdutt18 May 20, 2020
2c6ca76
Complete labels portion of dataloader
kartikdutt18 May 29, 2020
a17d96a
Style Fix
kartikdutt18 May 29, 2020
e47707e
Add basic definition of augmentation class
kartikdutt18 May 30, 2020
96a894f
Load images according to annotation in column format, Reduce complexi…
kartikdutt18 May 31, 2020
a34d08d
Augmentation work
kartikdutt18 May 31, 2020
6a43f9d
Augmentation work
kartikdutt18 May 31, 2020
193e243
Complete LoadObjectDetection Function
kartikdutt18 Jun 1, 2020
3739acb
Add tests for augmentation
kartikdutt18 Jun 1, 2020
a24514b
Add tests for dataloader
kartikdutt18 Jun 1, 2020
3668335
Upload dataset temp
kartikdutt18 Jun 2, 2020
c5828c6
Resolve merge conflicts
kartikdutt18 Jun 2, 2020
64c950b
Resolve merge conflicts
kartikdutt18 Jun 2, 2020
a6d061a
Resolve merge conflicts
kartikdutt18 Jun 2, 2020
f45cec0
Style fixes
kartikdutt18 Jun 3, 2020
c6a6819
Set up constructor
kartikdutt18 Jun 3, 2020
b782bb9
Complete Dataloader, write function definition for image dataloader
kartikdutt18 Jun 3, 2020
044ffea
Build Fixed, Style Fixed
kartikdutt18 Jun 3, 2020
553273d
style fixed
kartikdutt18 Jun 3, 2020
baae4e6
Fix linux and Windows build by ignoring invalid files like .DS_Store
kartikdutt18 Jun 3, 2020
c5302b9
Add image dataloader, needs clean up
kartikdutt18 Jun 3, 2020
c914e12
Style fixes
kartikdutt18 Jun 3, 2020
fef6b19
Check for file type
kartikdutt18 Jun 4, 2020
90c9039
Check for correct extention and filetype
kartikdutt18 Jun 4, 2020
17da476
Style Fixed
kartikdutt18 Jun 4, 2020
7579ba2
Build Fixed, Nice way to avoid hidden files
kartikdutt18 Jun 4, 2020
3b7bcfa
Style Fixed
kartikdutt18 Jun 4, 2020
adade09
Clean Up
kartikdutt18 Jun 5, 2020
6e230b8
Why is config there even though I did a rebase
kartikdutt18 Jun 5, 2020
1a82151
Add data split (internal), need implementation only for field type
kartikdutt18 Jun 5, 2020
0023b4a
Style Fixed
kartikdutt18 Jun 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ci/macos-steps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ steps:

# Configure CMake Args for models.
- script: |
mkdir data && mkdir build && cd build && cmake $(CMakeArgs-models) ..
mkdir build && cd build && cmake $(CMakeArgs-models) ..
displayName: 'CMake for models'

# Build mlpack
Expand Down
1 change: 0 additions & 1 deletion .ci/windows-steps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ steps:

- powershell: |
mkdir build
mkdir data
cp $(Agent.ToolsDirectory)\boost_libs\*.* build\
cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\*.* build\
cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.* build\
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ xcode*
.DS_Store
.idea
cmake-build-*
data/*
*.csv
*.tar
*.zip
*.tar.gz
*.xml
*.jpeg
*.jpg
*.png
*.txt
.travis/configs.hpp
Testing/*
25 changes: 25 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
sudo: required
dist: xenial
language: cpp

before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq --no-install-recommends cmake binutils-dev libopenblas-dev liblapack-dev build-essential libboost-all-dev
- curl -O http://masterblaster.mlpack.org:5005/armadillo-8.400.0.tar.gz -o armadillo-8.400.0.tar.gz && tar xvzf armadillo-8.400.0.tar.gz && cd armadillo-8.400.0
- cmake . && make && sudo make install
- cd $TRAVIS_BUILD_DIR && git clone https://github.com/mlpack/mlpack.git --depth 1
- cd mlpack && mkdir mlpack_build && cd mlpack_build && cmake -DUSE_OPENMP=OFF -DBUILD_CLI_EXECUTABLES=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_TESTS=OFF .. && make -j2 && sudo make install

install:
- cd $TRAVIS_BUILD_DIR && mkdir build && cd build && cmake -DUSE_OPENMP=OFF ..
script:
- make -j2

notifications:
email:
- [email protected]
irc:
channels:
- "chat.freenode.net#mlpack"
on_success: change
on_failure: always
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ find_package(Boost 1.49
COMPONENTS
filesystem
system
regex
program_options
serialization
unit_test_framework
Expand Down
19 changes: 19 additions & 0 deletions augmentation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(augmentation)

option(DEBUG "DEBUG" OFF)

set(DIR_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../")

set(SOURCES
augmentation.hpp
)

foreach(file ${SOURCES})
set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
endforeach()

# Append sources (with directory name) to list of all models sources (used at
# the parent scope).
set(DIRS ${DIRS} ${DIR_SRCS} PARENT_SCOPE)
172 changes: 172 additions & 0 deletions augmentation/augmentation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/**
* @file augmentation.hpp
* @author Kartik Dutt
*
* Definition of Augmentation class for augmenting data.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/

#include <mlpack/methods/ann/layer/bilinear_interpolation.hpp>
#include <boost/regex.hpp>

#ifndef MODELS_AUGMENTATION_HPP
#define MODELS_AUGMENTATION_HPP

/**
* Augmentation class used to perform augmentations / transform the data.
* For the list of supported augmentation, take a look at our wiki page.
*
* @code
* Augmentation<> augmentation({"horizontal-flip", "resize = (224, 224)"}, 0.2);
* augmentation.Transform(dataloader.TrainFeatures);
* @endcode
*
* @tparam DatasetType Datatype on which augmentation will be done.
*/
template<typename DatasetType = arma::mat>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the class template parameter isn't needed, if we add a template for the method.

Copy link
Member Author

@kartikdutt18 kartikdutt18 Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, I was doing that earlier but it gave me a strange error with the map here,

std::unordered_map<std::string, void(*)(DatasetType&,
       size_t, size_t, size_t, std::string&)> augmentationMap;

So I decided to add a template for the class rather than the method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But looks like the container is used in a single method, so I could be instantiated locally as well? I think removing the class template would make it easier for a user to use the augmentation feature.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think removing the class template would make it easier for a user to use the augmentation feature.

Agreed, @kartikdutt18 can you try do that in #18?

Copy link
Member Author

@kartikdutt18 kartikdutt18 Jun 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, makes sense. Will make the change in #18. Thanks.

class Augmentation
{
public:
//! Create the augmentation class object.
Augmentation();

/**
* Constructor for augmentation class.
*
* @param augmentations List of strings containing one of the supported
* augmentations.
* @param augmentationProbability Probability of applying augmentation on
* the dataset.
* NOTE : This doesn't apply to augmentations
* such as resize.
*/
Augmentation(const std::vector<std::string>& augmentations,
const double augmentationProbability);

/**
* Applies augmentation to the passed dataset.
*
* @param dataset Dataset on which augmentation will be applied.
* @param datapointWidth Width of a single data point i.e.
* Since each column represents a seperate data
* point.
* @param datapointHeight Height of a single data point.
* @param datapointDepth Depth of a single data point. For 2-dimensional
* data point, set it to 1. Defaults to 1.
*/
void Transform(DatasetType& dataset,
const size_t datapointWidth,
const size_t datapointHeight,
const size_t datapointDepth = 1);

/**
* Applies resize transform to the entire dataset.
*
* @param dataset Dataset on which augmentation will be applied.
* @param datapointWidth Width of a single data point i.e.
* Since each column represents a seperate data
* point.
* @param datapointHeight Height of a single data point.
* @param datapointDepth Depth of a single data point. For 2-dimensional
* data point, set it to 1. Defaults to 1.
* @param augmentation String containing the transform.
*/
void ResizeTransform(DatasetType& dataset,
const size_t datapointWidth,
const size_t datapointHeight,
const size_t datapointDepth,
const std::string& augmentation);

private:
/**
* Initializes augmentation map for the class.
*/
void InitializeAugmentationMap();

/**
* Function to determine if augmentation has Resize function.
* @param augmentation Optional argument to check if a string has
* resize substring.
*/
bool HasResizeParam(const std::string& augmentation = "")
{
if (augmentation.length())
return augmentation.find("resize") != std::string::npos;


// Search in augmentation vector.
return augmentations.size() <= 0 ? false :
augmentations[0].find("resize") != std::string::npos;
}

/**
* Sets size of output width and output height of the new data.
*
* @param outWidth Output width of resized data point.
* @param outHeight Output height of resized data point.
* @param augmentation String from which output width and height
* are extracted.
*/
void GetResizeParam(size_t& outWidth,
size_t& outHeight,
const std::string& augmentation)
{
if (!HasResizeParam())
return;


outWidth = 0;
outHeight = 0;

// Use regex to find one / two numbers. If only one provided
// set output width equal to output height.
boost::regex regex{"[0-9]+"};

// Create an iterator to find matches.
boost::sregex_token_iterator matches(augmentation.begin(),
augmentation.end(), regex, 0), end;

size_t matchesCount = std::distance(matches, end);

if (matchesCount == 0)
{
mlpack::Log::Fatal << "Invalid size / shape in " <<
augmentation << std::endl;
}

if (matchesCount == 1)
{
outWidth = std::stoi(*matches);
outHeight = outWidth;
}
else
{
outWidth = std::stoi(*matches);
matches++;
outHeight = std::stoi(*matches);
}
}

//! Locally held augmentations / transforms that need to be applied.
std::vector<std::string> augmentations;

//! Locally held value of augmentation probability.
double augmentationProbability;

//! Locally help map for mapping functions and strings.
std::unordered_map<std::string, void(*)(DatasetType&,
size_t, size_t, size_t, std::string&)> augmentationMap;

// The dataloader class should have access to internal functions of
// the dataloader.
template<typename DatasetX, typename DatasetY, class ScalerType>
friend class DataLoader;
};

#include "augmentation_impl.hpp" // Include implementation.

#endif
104 changes: 104 additions & 0 deletions augmentation/augmentation_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* @file augmentation_impl.hpp
* @author Kartik Dutt
*
* Implementation of Augmentation class for augmenting data.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/

// Incase it has not been included already.
#include "augmentation.hpp"

#ifndef MODELS_AUGMENTATION_IMPL_HPP
#define MODELS_AUGMENTATION_IMPL_HPP

template<typename DatasetType>
Augmentation<DatasetType>::Augmentation() :
augmentations(std::vector<std::string>()),
augmentationProbability(0.2)
{
// Nothing to do here.
}

template<typename DatasetType>
Augmentation<DatasetType>::Augmentation(
const std::vector<std::string>& augmentations,
const double augmentationProbability) :
augmentations(augmentations),
augmentationProbability(augmentationProbability)
{
// Sort the vector to place resize parameter to the front of the string.
// This prevents constant lookups for resize.
sort(this->augmentations.begin(), this->augmentations.end(), [](
std::string& str1, std::string& str2)
{
return str1.find("resize") != std::string::npos;
});

// Fill augmentation map with supported augmentations other than resize.
InitializeAugmentationMap();
}

template<typename DatasetType>
void Augmentation<DatasetType>::Transform(DatasetType& dataset,
const size_t datapointWidth,
const size_t datapointHeight,
const size_t datapointDepth)
{
size_t i = 0;
if (this->HasResizeParam())
{
this->ResizeTransform(dataset, datapointWidth, datapointHeight,
datapointDepth, augmentations[0]);
i++;
}

for (; i < augmentations.size(); i++)
{
if (augmentationMap.count(augmentations[i]))
{
augmentationMap[augmentations[i]](dataset, datapointWidth,
datapointHeight, datapointDepth, augmentations[i]);
}
}
}

template<typename DatasetType>
void Augmentation<DatasetType>::ResizeTransform(
DatasetType& dataset,
const size_t datapointWidth,
const size_t datapointHeight,
const size_t datapointDepth,
const std::string& augmentation)
{
if (!this->HasResizeParam(augmentation))
return;

size_t outputWidth = 0, outputHeight = 0;

// Get output width and output height.
GetResizeParam(outputWidth, outputHeight, augmentation);

// We will use mlpack's bilinear interpolation layer to
// resize the input.
mlpack::ann::BilinearInterpolation<DatasetType, DatasetType> resizeLayer(
datapointWidth, datapointHeight, outputWidth, outputHeight,
datapointDepth);

// Not sure how to avoid a copy here.
DatasetType output;
resizeLayer.Forward(dataset, output);
dataset = std::move(output);
}

template<typename DatasetType>
void Augmentation<DatasetType>::InitializeAugmentationMap()
{
// Fill the map here.
}

#endif
Binary file added data/PASCAL-VOC-Test.tar.gz
Binary file not shown.
Binary file added data/cifar-test.tar.gz
Binary file not shown.
Loading