Merge branch 'master' into patch-2
This commit is contained in:
-17
@@ -57,23 +57,6 @@ jobs:
|
||||
steps:
|
||||
- template: macos-steps.yaml
|
||||
|
||||
- job: WindowsVS14
|
||||
timeoutInMinutes: 360
|
||||
displayName: Windows VS14
|
||||
pool:
|
||||
vmImage: vs2015-win2012r2
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF'
|
||||
CMakeGenerator: '-G "Visual Studio 14 2015 Win64"'
|
||||
MSBuildVersion: '14.0'
|
||||
ArchiveNoLibs: 'mlpack-windows-vs14-no-libs.zip'
|
||||
ArchiveLibs: 'mlpack-windows-vs14.zip'
|
||||
ArchiveTests: 'mlpack_test-vs14.xml'
|
||||
steps:
|
||||
- template: windows-steps.yaml
|
||||
|
||||
- job: WindowsVS15
|
||||
timeoutInMinutes: 360
|
||||
displayName: Windows VS15
|
||||
|
||||
@@ -328,6 +328,7 @@ if (NOT STB_IMAGE_FOUND)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image_write.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
add_definitions(-DHAS_STB)
|
||||
set(STB_AVAILABLE "1")
|
||||
else ()
|
||||
message(WARNING
|
||||
"stb/stb_image.h is not installed. Image utilities will not be available!")
|
||||
@@ -348,6 +349,7 @@ else ()
|
||||
# Already has STB installed.
|
||||
add_definitions(-DHAS_STB)
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${STB_IMAGE_INCLUDE_DIR})
|
||||
set(STB_AVAILABLE "1")
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
+15
-3
@@ -2,8 +2,10 @@
|
||||
###### ????-??-??
|
||||
* Updated terminal state for Pendulum environment (#2354).
|
||||
|
||||
### mlpack 3.3.0
|
||||
###### 2020-04-07
|
||||
* Templated return type of `Forward function` of loss functions (#2339).
|
||||
|
||||
|
||||
* Added `R2 Score` regression metric (#2323).
|
||||
|
||||
* Added `mean squared logarithmic error` loss function for neural networks
|
||||
@@ -40,6 +42,9 @@
|
||||
|
||||
* CMake fix for finding STB include directory (#2145).
|
||||
|
||||
* Add bindings for loading and saving images (#2019); `mlpack_image_converter`
|
||||
from the command-line, `mlpack.image_converter()` from Python.
|
||||
|
||||
* Add normalization support for CF binding (#2136).
|
||||
|
||||
* Add Mish activation function (#2158).
|
||||
@@ -55,7 +60,7 @@
|
||||
* Add LiSHT activation function (#2182).
|
||||
|
||||
* Add Valid and Same Padding for Transposed Convolution layer (#2163).
|
||||
|
||||
|
||||
* Add CELU activation function (#2191)
|
||||
|
||||
* Add Log-Hyperbolic-Cosine Loss function (#2207)
|
||||
@@ -65,7 +70,7 @@
|
||||
|
||||
* Bump minimum Boost version to 1.58 (#2305).
|
||||
|
||||
* Refactor STB support so HAS_STB macro is not needed when compiling against
|
||||
* Refactor STB support so `HAS_STB` macro is not needed when compiling against
|
||||
mlpack (#2312).
|
||||
|
||||
* Add Hard Shrink Activation Function (#2186).
|
||||
@@ -74,6 +79,13 @@
|
||||
|
||||
* Add Hinge Embedding Loss Function (#2229).
|
||||
|
||||
* Add Cosine Embedding Loss Function (#2209).
|
||||
|
||||
* Add Margin Ranking Loss Function (#2264).
|
||||
|
||||
* Bugfix for incorrect parameter vector sizes in logistic regression and
|
||||
softmax regression (#2359).
|
||||
|
||||
### mlpack 3.2.2
|
||||
###### 2019-11-26
|
||||
* Add `valid` and `same` padding option in `Convolution` and `Atrous
|
||||
|
||||
@@ -23,7 +23,7 @@ src="https://cdn.rawgit.com/mlpack/mlpack.org/e7d36ed8/mlpack-black.svg" style="
|
||||
<p align="center">
|
||||
<em>
|
||||
Download:
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.2.2.tar.gz">current stable version (3.2.2)</a>
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.3.0.tar.gz">current stable version (3.3.0)</a>
|
||||
</em>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -104,16 +104,16 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.2.1\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.3.0\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>C:\mlpack\mlpack-3.2.1\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_program_options-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>C:\mlpack\mlpack-3.3.0\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_program_options-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y "C:\mlpack\mlpack-3.2.1\build\Debug\mlpack.dll" $(OutDir)
|
||||
xcopy /y "C:\mlpack\mlpack-3.2.1\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
<Command>xcopy /y "C:\mlpack\mlpack-3.3.0\build\Debug\mlpack.dll" $(OutDir)
|
||||
xcopy /y "C:\mlpack\mlpack-3.3.0\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
xcopy /y "$(ProjectDir)..\..\..\..\src\mlpack\tests\data\german.csv" "$(ProjectDir)data\german.csv*"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
+6
-6
@@ -30,7 +30,7 @@ to build mlpack on Windows, see \ref build_windows (alternatively, you can read
|
||||
is based on older versions).
|
||||
|
||||
You can download the latest mlpack release from here:
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.2.2.tar.gz">mlpack-3.2.2</a>
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.3.0.tar.gz">mlpack-3.3.0</a>
|
||||
|
||||
@section build_simple Simple Linux build instructions
|
||||
|
||||
@@ -38,9 +38,9 @@ Assuming all dependencies are installed in the system, you can run the commands
|
||||
below directly to build and install mlpack.
|
||||
|
||||
@code
|
||||
$ wget https://www.mlpack.org/files/mlpack-3.2.2.tar.gz
|
||||
$ tar -xvzpf mlpack-3.2.2.tar.gz
|
||||
$ mkdir mlpack-3.2.2/build && cd mlpack-3.2.2/build
|
||||
$ wget https://www.mlpack.org/files/mlpack-3.3.0.tar.gz
|
||||
$ tar -xvzpf mlpack-3.3.0.tar.gz
|
||||
$ mkdir mlpack-3.3.0/build && cd mlpack-3.3.0/build
|
||||
$ cmake ../
|
||||
$ make -j4 # The -j is the number of cores you want to use for a build.
|
||||
$ sudo make install
|
||||
@@ -65,8 +65,8 @@ configure mlpack.
|
||||
First we should unpack the mlpack source and create a build directory.
|
||||
|
||||
@code
|
||||
$ tar -xvzpf mlpack-3.2.2.tar.gz
|
||||
$ cd mlpack-3.2.2
|
||||
$ tar -xvzpf mlpack-3.3.0.tar.gz
|
||||
$ cd mlpack-3.3.0
|
||||
$ mkdir build
|
||||
@endcode
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ build and install mlpack. You can copy-paste the commands into your shell.
|
||||
@code{.sh}
|
||||
sudo apt-get install libboost-all-dev g++ cmake libarmadillo-dev python-pip wget
|
||||
sudo pip install cython setuptools distutils numpy pandas
|
||||
wget https://www.mlpack.org/files/mlpack-3.2.1.tar.gz
|
||||
tar -xvzpf mlpack-3.2.1.tar.gz
|
||||
mkdir -p mlpack-3.2.1/build/ && cd mlpack-3.2.1/build/
|
||||
wget https://www.mlpack.org/files/mlpack-3.3.0.tar.gz
|
||||
tar -xvzpf mlpack-3.3.0.tar.gz
|
||||
mkdir -p mlpack-3.3.0/build/ && cd mlpack-3.3.0/build/
|
||||
cmake ../ && make -j4 && sudo make install
|
||||
@endcode
|
||||
|
||||
|
||||
@@ -29,18 +29,18 @@ mlpack and dependencies in Release Mode).
|
||||
@code
|
||||
- C:\boost\boost_1_71_0\lib\native\include
|
||||
- C:\mlpack\armadillo-9.800.3\include
|
||||
- C:\mlpack\mlpack-3.2.2\build\include
|
||||
- C:\mlpack\mlpack-3.3.0\build\include
|
||||
@endcode
|
||||
- Under Linker > Input > Additional Dependencies add:
|
||||
@code
|
||||
- C:\mlpack\mlpack-3.2.2\build\Debug\mlpack.lib
|
||||
- C:\mlpack\mlpack-3.3.0\build\Debug\mlpack.lib
|
||||
- C:\boost\boost_1_71_0\lib64-msvc-14.2\libboost_serialization-vc142-mt-gd-x64-1_71.lib
|
||||
- C:\boost\boost_1_71_0\lib64-msvc-14.2\libboost_program_options-vc142-mt-gd-x64-1_71.lib
|
||||
@endcode
|
||||
- Under Build Events > Post-Build Event > Command Line add:
|
||||
@code
|
||||
- xcopy /y "C:\mlpack\mlpack-3.2.2\build\Debug\mlpack.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.2.2\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.3.0\build\Debug\mlpack.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.3.0\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
@endcode
|
||||
|
||||
@note Recent versions of Visual Studio set "Conformance Mode" enabled by default. This causes some issues with
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*!
|
||||
@file image.txt
|
||||
@author Mehul Kumar Nirala
|
||||
@brief Tutorial for how to load and save images in mlpack.
|
||||
|
||||
@page imagetutorial Image Utilities tutorial
|
||||
|
||||
@section intro_imagetut Introduction
|
||||
|
||||
Image datasets are becoming increasingly popular in deep learning.
|
||||
|
||||
mlpack's image saving/loading functionality is based on [stb/](https://github.com/nothings/stb).
|
||||
|
||||
@section toc_imagetut Table of Contents
|
||||
|
||||
This tutorial is split into the following sections:
|
||||
|
||||
- \ref intro_imagetut
|
||||
- \ref toc_imagetut
|
||||
- \ref model_api_imagetut
|
||||
- \ref imageinfo_api_imagetut
|
||||
- \ref load_api_imagetut
|
||||
- \ref save_api_imagetut
|
||||
|
||||
@section model_api_imagetut Model API
|
||||
|
||||
Image utilities supports loading and saving of images.
|
||||
|
||||
It supports filetypes "jpg", "png", "tga","bmp", "psd", "gif", "hdr", "pic", "pnm" for loading and "jpg", "png", "tga", "bmp", "hdr" for saving.
|
||||
|
||||
The datatype associated is unsigned char to support RGB values in the range 1-255. To feed data into the network typecast of `arma::Mat` may be required. Images are stored in matrix as (width * height * channels, NumberOfImages). Therefore imageMatrix.col(0) would be the first image if images are loaded in imageMatrix.
|
||||
|
||||
@section imageinfo_api_imagetut ImageInfo
|
||||
|
||||
ImageInfo class contains the metadata of the images.
|
||||
@code
|
||||
/**
|
||||
* Instantiate the ImageInfo object with the image width, height, channels.
|
||||
*
|
||||
* @param width Image width.
|
||||
* @param height Image height.
|
||||
* @param channels number of channels in the image.
|
||||
*/
|
||||
ImageInfo(const size_t width,
|
||||
const size_t height,
|
||||
const size_t channels);
|
||||
@endcode
|
||||
Other public memebers include:
|
||||
- quality Compression of the image if saved as jpg (0-100).
|
||||
|
||||
@section load_api_imagetut Load
|
||||
|
||||
|
||||
Standalone loading of images.
|
||||
@code
|
||||
/**
|
||||
* Load the image file into the given matrix.
|
||||
*
|
||||
* @param filename Name of the image file.
|
||||
* @param matrix Matrix to load the image into.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, flips the image, same as transposing the
|
||||
* matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Load(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
Loading a test image. It also fills up the ImageInfo class object.
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
data::Load("test_image.png", matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
ImageInfo requires height, width, number of channels of the image.
|
||||
|
||||
@code
|
||||
size_t height = 64, width = 64, channels = 1;
|
||||
data::ImageInfo info(width, height, channels);
|
||||
@endcode
|
||||
|
||||
More than one image can be loaded into the same matrix.
|
||||
|
||||
Loading multiple images:
|
||||
|
||||
@code
|
||||
/**
|
||||
* Load the image file into the given matrix.
|
||||
*
|
||||
* @param files A vector consisting of filenames.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, flips the image, same as transposing the
|
||||
* matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Load(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
std::vector<std::string>> files{"test_image1.bmp","test_image2.bmp"};
|
||||
data::load(files, matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
@section save_api_imagetut Save
|
||||
|
||||
Save images expects a matrix of type unsigned char in the form (width * height * channels, NumberOfImages).
|
||||
Just like load it can be used to save one image or multiple images. Besides image data it also expects the shape of the image as input (width, height, channels).
|
||||
|
||||
Saving one image:
|
||||
|
||||
@code
|
||||
/**
|
||||
* Save the image file from the given matrix.
|
||||
*
|
||||
* @param filename Name of the image file.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, flips the image, same as transposing the
|
||||
* matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
info.width = info.height = 25;
|
||||
info.channels = 3;
|
||||
info.quality = 90;
|
||||
data::Save("test_image.bmp", matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
If the matrix contains more than one image, only the first one is saved.
|
||||
|
||||
Saving multiple images:
|
||||
|
||||
@code
|
||||
/**
|
||||
* Save the image file from the given matrix.
|
||||
*
|
||||
* @param files A vector consisting of filenames.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, Flips the image, same as transposing the
|
||||
* matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
info.width = info.height = 25;
|
||||
info.channels = 3;
|
||||
info.quality = 90;
|
||||
std::vector<std::string>> files{"test_image1.bmp", "test_image2.bmp"};
|
||||
data::Save(files, matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
Multiple images are saved according to the vector of filenames specified.
|
||||
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ target_link_libraries(mlpack ${MLPACK_LIBRARIES})
|
||||
|
||||
set_target_properties(mlpack
|
||||
PROPERTIES
|
||||
VERSION 3.2
|
||||
VERSION 3.3
|
||||
SOVERSION 3
|
||||
)
|
||||
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Get the Julia-named type of an mlpack C++ type.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_GET_JULIA_TYPE_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_GET_JULIA_TYPE_HPP
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
*
|
||||
* Get the printable type of a parameter. This type is not the C++ type but
|
||||
* instead the Julia type that a user would use.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_GET_PRINTABLE_TYPE_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_GET_PRINTABLE_TYPE_HPP
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
*
|
||||
* Get the printable type of a parameter. This type is not the C++ type but
|
||||
* instead the Julia type that a user would use.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_GET_PRINTABLE_TYPE_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_GET_PRINTABLE_TYPE_IMPL_HPP
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementations of Julia binding functionality.
|
||||
*
|
||||
* 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/bindings/julia/julia_util.h>
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Print inline documentation for a single option.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_DOC_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_DOC_HPP
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
*
|
||||
* Print the declaration of an input parameter as part of a line in a Julia
|
||||
* function definition.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_INPUT_PARAM_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_INPUT_PARAM_HPP
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Print Julia code to handle input arguments.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_INPUT_PROCESSING_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_INPUT_PROCESSING_HPP
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Print Julia code to handle input arguments.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_INPUT_PROCESSING_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_INPUT_PROCESSING_IMPL_HPP
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of utility PrintJL() function.
|
||||
*
|
||||
* 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 "print_jl.hpp"
|
||||
#include <mlpack/core/util/hyphenate_string.hpp>
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Definition of utility PrintJL() function.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_JL_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_JL_HPP
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Print Julia code to handle output arguments.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_OUTPUT_PROCESSING_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_OUTPUT_PROCESSING_HPP
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Print Julia code to handle output arguments.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_OUTPUT_PROCESSING_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_OUTPUT_PROCESSING_IMPL_HPP
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
*
|
||||
* If the type is serializable, we need to define a special utility function to
|
||||
* set a CLI parameter of that type.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_PRINT_PARAM_DEFN_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_PRINT_PARAM_DEFN_HPP
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
*
|
||||
* Given a C++ type name, turn it into something that has no special characters
|
||||
* that can simply be printed.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_BINDINGS_JULIA_STRIP_TYPE_HPP
|
||||
#define MLPACK_BINDINGS_JULIA_STRIP_TYPE_HPP
|
||||
|
||||
@@ -69,6 +69,15 @@ class ImageInfo
|
||||
//! Modify the image quality.
|
||||
size_t& Quality() { return quality; }
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(width);
|
||||
ar & BOOST_SERIALIZATION_NVP(channels);
|
||||
ar & BOOST_SERIALIZATION_NVP(height);
|
||||
ar & BOOST_SERIALIZATION_NVP(quality);
|
||||
}
|
||||
|
||||
private:
|
||||
// To store the image width.
|
||||
size_t width;
|
||||
|
||||
@@ -3,19 +3,23 @@
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* Implementation of image loading functionality via STB.
|
||||
*
|
||||
* 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 "load.hpp"
|
||||
#include "image_info.hpp"
|
||||
|
||||
#ifdef HAS_STB
|
||||
|
||||
// The definition of STB_IMAGE_IMPLEMENTATION means that the implementation will
|
||||
// be included here directly.
|
||||
#define STB_IMAGE_STATIC
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
#define STB_IMAGE_WRITE_STATIC
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <stb_image_write.h>
|
||||
#include <stb_image.h>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
@@ -3,18 +3,29 @@
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* Implementation of image saving functionality via STB.
|
||||
*
|
||||
* 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 "save.hpp"
|
||||
|
||||
#ifdef HAS_STB
|
||||
|
||||
#define STB_IMAGE_STATIC
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
// The implementation of the functions is included directly, so we need to make
|
||||
// sure it doesn't get included twice. This is to work around a bug in old
|
||||
// versions of STB where not all functions were correctly marked static.
|
||||
#define STB_IMAGE_WRITE_STATIC
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#ifndef STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#else
|
||||
#undef STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#endif
|
||||
#include <stb_image_write.h>
|
||||
#ifndef STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
@@ -54,6 +65,12 @@ bool SaveImage(const std::string& filename,
|
||||
Log::Warn << "Only the first image will be saved!" << std::endl;
|
||||
}
|
||||
|
||||
if (info.Width() * info.Height() * info.Channels() != image.n_elem)
|
||||
{
|
||||
Log::Fatal << "data::Save(): The given image dimensions do not match the "
|
||||
<< "dimensions of the matrix to be saved!" << std::endl;
|
||||
}
|
||||
|
||||
bool status = false;
|
||||
unsigned char* imageMem = image.memptr();
|
||||
|
||||
|
||||
@@ -328,15 +328,11 @@ bool Save(const std::vector<std::string>& files,
|
||||
}
|
||||
|
||||
arma::Mat<unsigned char> img;
|
||||
bool status = Save(files[0], img, info, fatal);
|
||||
bool status = true;
|
||||
|
||||
// Decide matrix dimension using the image height and width.
|
||||
matrix.set_size(info.Width() * info.Height() * info.Channels(), files.size());
|
||||
matrix.col(0) = img;
|
||||
|
||||
for (size_t i = 1; i < files.size() ; i++)
|
||||
for (size_t i = 0; i < files.size() ; i++)
|
||||
{
|
||||
arma::Mat<unsigned char> colImg(matrix.colptr(i), matrix.n_rows, 1,
|
||||
arma::Mat<eT> colImg(matrix.colptr(i), matrix.n_rows, 1,
|
||||
false, true);
|
||||
status &= Save(files[i], colImg, info, fatal);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ namespace data {
|
||||
|
||||
/**
|
||||
* The class translates a set of strings into numbers using various encoding
|
||||
* algorithms.
|
||||
* algorithms. The encoder writes data either in the column-major order or
|
||||
* in the row-major order depending on the output data type.
|
||||
*
|
||||
* @tparam EncodingPolicyType Type of the encoding algorithm itself.
|
||||
* @tparam DictionaryType Type of the dictionary.
|
||||
@@ -90,11 +91,17 @@ class StringEncoding
|
||||
void Clear();
|
||||
|
||||
/**
|
||||
* Encode the given text and write the result to the given output.
|
||||
* Encode the given text and write the result to the given output. The encoder
|
||||
* writes data in the column-major order or in the row-major order depending
|
||||
* on the output data type.
|
||||
*
|
||||
* If the output type is either arma::mat or arma::sp_mat then the function
|
||||
* writes it in the column-major order. If the output type is 2D std::vector
|
||||
* then the function writes it in the row major order.
|
||||
*
|
||||
* @tparam OutputType Type of the output container. The function supports
|
||||
* the following types: arma::mat, arma::sp_mat,
|
||||
* std::vector<std::vector<size_t>>.
|
||||
* std::vector<std::vector<>>.
|
||||
* @tparam TokenizerType Type of the tokenizer.
|
||||
*
|
||||
* @param input Corpus of text to encode.
|
||||
@@ -132,11 +139,16 @@ class StringEncoding
|
||||
private:
|
||||
/**
|
||||
* A helper function to encode the given text and write the result to
|
||||
* the given output.
|
||||
* the given output. The encoder writes data in the column-major order or
|
||||
* in the row-major order depending on the output data type.
|
||||
*
|
||||
* If the output type is either arma::mat or arma::sp_mat then the function
|
||||
* writes it in the column-major order. If the output type is 2D std::vector
|
||||
* then the function writes it in the row major order.
|
||||
*
|
||||
* @tparam OutputType Type of the output container. The function supports
|
||||
* the following types: arma::mat, arma::sp_mat,
|
||||
* std::vector<std::vector<size_t>>.
|
||||
* std::vector<std::vector<>>.
|
||||
* @tparam TokenizerType Type of the tokenizer.
|
||||
* @tparam PolicyType The type of the encoding policy. It has to be
|
||||
* equal to EncodingPolicyType.
|
||||
@@ -153,9 +165,7 @@ class StringEncoding
|
||||
* 2. IsTokenEmpty() that accepts a token and returns true if the given
|
||||
* token is empty.
|
||||
*/
|
||||
template<typename OutputType,
|
||||
typename TokenizerType,
|
||||
typename PolicyType>
|
||||
template<typename OutputType, typename TokenizerType, typename PolicyType>
|
||||
void EncodeHelper(const std::vector<std::string>& input,
|
||||
OutputType& output,
|
||||
const TokenizerType& tokenizer,
|
||||
@@ -164,11 +174,13 @@ class StringEncoding
|
||||
/**
|
||||
* A helper function to encode the given text and write the result to
|
||||
* the given output. This is an optimized overload for policies that support
|
||||
* the one pass encoding algorithm.
|
||||
* the one pass encoding algorithm. The encoder writes data in the row-major
|
||||
* order.
|
||||
*
|
||||
* @tparam TokenizerType Type of the tokenizer.
|
||||
* @tparam PolicyType The type of the encoding policy. It has to be
|
||||
* equal to EncodingPolicyType.
|
||||
* @tparam ElemType Type of the output values.
|
||||
*
|
||||
* @param input Corpus of text to encode.
|
||||
* @param output Output container to store the result.
|
||||
@@ -182,9 +194,9 @@ class StringEncoding
|
||||
* 2. IsTokenEmpty() that accepts a token and returns true if the given
|
||||
* token is empty.
|
||||
*/
|
||||
template<typename TokenizerType, typename PolicyType>
|
||||
template<typename TokenizerType, typename PolicyType, typename ElemType>
|
||||
void EncodeHelper(const std::vector<std::string>& input,
|
||||
std::vector<std::vector<size_t>>& output,
|
||||
std::vector<std::vector<ElemType>>& output,
|
||||
const TokenizerType& tokenizer,
|
||||
PolicyType& policy,
|
||||
typename std::enable_if<StringEncodingPolicyTraits<
|
||||
|
||||
@@ -107,10 +107,12 @@ EncodeHelper(const std::vector<std::string>& input,
|
||||
{
|
||||
size_t numColumns = 0;
|
||||
|
||||
policy.Reset();
|
||||
|
||||
// The first pass adds the extracted tokens to the dictionary.
|
||||
for (const std::string& line : input)
|
||||
for (size_t i = 0; i < input.size(); i++)
|
||||
{
|
||||
boost::string_view strView(line);
|
||||
boost::string_view strView(input[i]);
|
||||
auto token = tokenizer(strView);
|
||||
|
||||
static_assert(
|
||||
@@ -127,9 +129,12 @@ EncodeHelper(const std::vector<std::string>& input,
|
||||
if (!dictionary.HasToken(token))
|
||||
dictionary.AddToken(std::move(token));
|
||||
|
||||
policy.PreprocessToken(i, numTokens, dictionary.Value(token));
|
||||
|
||||
token = tokenizer(strView);
|
||||
numTokens++;
|
||||
}
|
||||
|
||||
numColumns = std::max(numColumns, numTokens);
|
||||
}
|
||||
|
||||
@@ -152,15 +157,17 @@ EncodeHelper(const std::vector<std::string>& input,
|
||||
}
|
||||
|
||||
template<typename EncodingPolicyType, typename DictionaryType>
|
||||
template<typename TokenizerType, typename PolicyType>
|
||||
template<typename TokenizerType, typename PolicyType, typename ElemType>
|
||||
void StringEncoding<EncodingPolicyType, DictionaryType>::
|
||||
EncodeHelper(const std::vector<std::string>& input,
|
||||
std::vector<std::vector<size_t>>& output,
|
||||
std::vector<std::vector<ElemType>>& output,
|
||||
const TokenizerType& tokenizer,
|
||||
PolicyType& policy,
|
||||
typename std::enable_if<StringEncodingPolicyTraits<
|
||||
PolicyType>::onePassEncoding>::type*)
|
||||
{
|
||||
policy.Reset();
|
||||
|
||||
// The loop below extracts the tokens and writes the encoded values
|
||||
// at once.
|
||||
for (size_t i = 0; i < input.size(); i++)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Define the files that we need to compile.
|
||||
# Anything not in this list will not be compiled into mlpack.
|
||||
set(SOURCES
|
||||
bag_of_words_encoding_policy.hpp
|
||||
dictionary_encoding_policy.hpp
|
||||
policy_traits.hpp
|
||||
tf_idf_encoding_policy.hpp
|
||||
)
|
||||
|
||||
# add directory name to sources
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @file bag_of_words_encoding_policy.hpp
|
||||
* @author Jeffin Sam
|
||||
* @author Mikhail Lozhnikov
|
||||
*
|
||||
* Definition of the BagOfWordsEncodingPolicy class.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_DATA_STR_ENCODING_POLICIES_BAG_OF_WORDS_ENCODING_POLICY_HPP
|
||||
#define MLPACK_CORE_DATA_STR_ENCODING_POLICIES_BAG_OF_WORDS_ENCODING_POLICY_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/data/string_encoding_policies/policy_traits.hpp>
|
||||
#include <mlpack/core/data/string_encoding.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* Definition of the BagOfWordsEncodingPolicy class.
|
||||
*
|
||||
* BagOfWords is used as a helper class for StringEncoding. The encoder maps
|
||||
* each dataset item to a vector of size N, where N is equal to the total unique
|
||||
* number of tokens. The i-th coordinate of the output vector is equal to
|
||||
* the number of times when the i-th token occurs in the corresponding dataset
|
||||
* item. The order in which the tokens are labeled is defined by the dictionary
|
||||
* used by the StringEncoding class. The encoder writes data either in the
|
||||
* column-major order or in the row-major order depending on the output data
|
||||
* type.
|
||||
*/
|
||||
class BagOfWordsEncodingPolicy
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Clear the necessary internal variables.
|
||||
*/
|
||||
static void Reset()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* The function initializes the output matrix. The encoder writes data
|
||||
* in the column-major order.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param datasetSize The number of strings in the input dataset.
|
||||
* @param maxNumTokens The maximum number of tokens in the strings of the
|
||||
* input dataset (not used).
|
||||
* @param dictionarySize The size of the dictionary.
|
||||
*/
|
||||
template<typename MatType>
|
||||
static void InitMatrix(MatType& output,
|
||||
const size_t datasetSize,
|
||||
const size_t /* maxNumTokens */,
|
||||
const size_t dictionarySize)
|
||||
{
|
||||
output.zeros(dictionarySize, datasetSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function initializes the output matrix. The encoder writes data
|
||||
* in the row-major order.
|
||||
*
|
||||
* Overloaded function to save the result in vector<vector<ElemType>>.
|
||||
*
|
||||
* @tparam ElemType Type of the output values.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results.
|
||||
* @param datasetSize The number of strings in the input dataset.
|
||||
* @param maxNumTokens The maximum number of tokens in the strings of the
|
||||
* input dataset (not used).
|
||||
* @param dictionarySize The size of the dictionary.
|
||||
*/
|
||||
template<typename ElemType>
|
||||
static void InitMatrix(std::vector<std::vector<ElemType>>& output,
|
||||
const size_t datasetSize,
|
||||
const size_t /* maxNumTokens */,
|
||||
const size_t dictionarySize)
|
||||
{
|
||||
output.resize(datasetSize, std::vector<ElemType>(dictionarySize));
|
||||
}
|
||||
|
||||
/**
|
||||
* The function performs the bag of words encoding algorithm i.e. it writes
|
||||
* the encoded token to the output. The encoder writes data in the
|
||||
* column-major order.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param value The encoded token.
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The token index in the line.
|
||||
*/
|
||||
template<typename MatType>
|
||||
static void Encode(MatType& output,
|
||||
const size_t value,
|
||||
const size_t line,
|
||||
const size_t /* index */)
|
||||
{
|
||||
// The labels are assigned sequentially starting from one.
|
||||
output(value - 1, line) += 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function performs the bag of words encoding algorithm i.e. it writes
|
||||
* the encoded token to the output. The encoder writes data in the
|
||||
* row-major order.
|
||||
*
|
||||
* Overloaded function to accept vector<vector<ElemType>> as the output
|
||||
* type.
|
||||
*
|
||||
* @tparam ElemType Type of the output values.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results.
|
||||
* @param value The encoded token.
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The line token number at which the encoding is performed.
|
||||
*/
|
||||
template<typename ElemType>
|
||||
static void Encode(std::vector<std::vector<ElemType>>& output,
|
||||
const size_t value,
|
||||
const size_t line,
|
||||
const size_t /* index */)
|
||||
{
|
||||
// The labels are assigned sequentially starting from one.
|
||||
output[line][value - 1] += 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function is not used by the bag of words encoding policy.
|
||||
*
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The token sequence number in the line.
|
||||
* @param value The encoded token.
|
||||
*/
|
||||
static void PreprocessToken(size_t /* line */,
|
||||
size_t /* index */,
|
||||
size_t /* value */)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Serialize the class to the given archive.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& /* ar */, const unsigned int /* version */)
|
||||
{
|
||||
// Nothing to serialize.
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A convenient alias for the StringEncoding class with BagOfWordsEncodingPolicy
|
||||
* and the default dictionary for the given token type.
|
||||
*
|
||||
* @tparam TokenType Type of the tokens.
|
||||
*/
|
||||
template<typename TokenType>
|
||||
using BagOfWordsEncoding = StringEncoding<BagOfWordsEncodingPolicy,
|
||||
StringEncodingDictionary<TokenType>>;
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -25,65 +25,92 @@ namespace data {
|
||||
* The encoder assigns a positive integer number to each unique token and treats
|
||||
* the dataset as categorical. The numbers are assigned sequentially starting
|
||||
* from one. The order in which the tokens are labeled is defined by
|
||||
* the dictionary used by the StringEncoding class.
|
||||
* the dictionary used by the StringEncoding class. The encoder writes data
|
||||
* either in the column-major order or in the row-major order depending on
|
||||
* the output data type.
|
||||
*/
|
||||
class DictionaryEncodingPolicy
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* The function initializes the output matrix.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param datasetSize The number of strings in the input dataset.
|
||||
* @param maxNumTokens The maximum number of tokens in the strings of the
|
||||
input dataset.
|
||||
* @param dictionarySize The size of the dictionary (not used).
|
||||
*/
|
||||
* Clear the necessary internal variables.
|
||||
*/
|
||||
static void Reset()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* The function initializes the output matrix. The encoder writes data
|
||||
* in the column-major order.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param datasetSize The number of strings in the input dataset.
|
||||
* @param maxNumTokens The maximum number of tokens in the strings of the
|
||||
* input dataset.
|
||||
* @param dictionarySize The size of the dictionary (not used).
|
||||
*/
|
||||
template<typename MatType>
|
||||
static void InitMatrix(MatType& output,
|
||||
const size_t datasetSize,
|
||||
const size_t maxNumTokens,
|
||||
const size_t /*dictionarySize*/)
|
||||
const size_t /* dictionarySize */)
|
||||
{
|
||||
output.zeros(datasetSize, maxNumTokens);
|
||||
output.zeros(maxNumTokens, datasetSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function performs the dictionary encoding algorithm i.e. it writes
|
||||
* the encoded token to the ouput.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param value The encoded token.
|
||||
* @param row The row number at which the encoding is performed.
|
||||
* @param col The token index in the row.
|
||||
*/
|
||||
/**
|
||||
* The function performs the dictionary encoding algorithm i.e. it writes
|
||||
* the encoded token to the output. The encoder writes data in the
|
||||
* column-major order.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param value The encoded token.
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The token index in the line.
|
||||
*/
|
||||
template<typename MatType>
|
||||
static void Encode(MatType& output,
|
||||
const size_t value,
|
||||
const size_t row,
|
||||
const size_t col)
|
||||
const size_t line,
|
||||
const size_t index)
|
||||
{
|
||||
output(row, col) = value;
|
||||
output(index, line) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* The function performs the dictionary encoding algorithm i.e. it writes
|
||||
* the encoded token to the ouput. This is an overload function which saves
|
||||
* the result into the given vector to avoid padding.
|
||||
* the encoded token to the output. This is an overloaded function which saves
|
||||
* the result into the given vector to avoid padding. The encoder writes data
|
||||
* in the row-major order.
|
||||
*
|
||||
* @param output Output vector to store the encoded results.
|
||||
* @tparam ElemType Type of the output values.
|
||||
*
|
||||
* @param output Output vector to store the encoded line.
|
||||
* @param value The encoded token.
|
||||
*/
|
||||
static void Encode(std::vector<size_t>& output,
|
||||
const size_t value)
|
||||
template<typename ElemType>
|
||||
static void Encode(std::vector<ElemType>& output, size_t value)
|
||||
{
|
||||
output.push_back(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function is not used by the dictionary encoding policy.
|
||||
*
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The token sequence number in the line.
|
||||
* @param value The encoded token.
|
||||
*/
|
||||
static void PreprocessToken(const size_t /* line */,
|
||||
const size_t /* index */,
|
||||
const size_t /* value */)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Serialize the class to the given archive.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* @file tf_idf_encoding_policy.hpp
|
||||
* @author Jeffin Sam
|
||||
* @author Mikhail Lozhnikov
|
||||
*
|
||||
* Definition of the TfIdfEncodingPolicy class.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_DATA_STRING_ENCODING_POLICIES_TF_IDF_ENCODING_POLICY_HPP
|
||||
#define MLPACK_CORE_DATA_STRING_ENCODING_POLICIES_TF_IDF_ENCODING_POLICY_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/data/string_encoding_policies/policy_traits.hpp>
|
||||
#include <mlpack/core/data/string_encoding.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* Definition of the TfIdfEncodingPolicy class. TfIdfEncodingPolicy is used
|
||||
* as a helper class for StringEncoding.
|
||||
*
|
||||
* Tf-idf is a weighting scheme that takes into account the importance of
|
||||
* encoded tokens. The tf-idf statistics is equal to term frequency (tf)
|
||||
* multiplied by inverse document frequency (idf).
|
||||
* The encoder assigns the corresponding tf-idf value to each token. The order
|
||||
* in which the tokens are labeled is defined by the dictionary used by the
|
||||
* StringEncoding class. The encoder writes data either in the column-major
|
||||
* order or in the row-major order depending on the output data type.
|
||||
*/
|
||||
class TfIdfEncodingPolicy
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Enum class used to identify the type of the term frequency statistics.
|
||||
*
|
||||
* The present implementation supports the following types:
|
||||
* BINARY Term frequency equals 1 if the row contains the encoded
|
||||
* token and 0 otherwise.
|
||||
* RAW_COUNT Term frequency equals the number of times when the encoded
|
||||
* token occurs in the row.
|
||||
* TERM_FREQUENCY Term frequency equals the number of times when the encoded
|
||||
* token occurs in the row divided by the total number of
|
||||
* tokens in the row.
|
||||
* SUBLINEAR_TF Term frequency equals \f$ 1 + log(rawCount), \f$ where
|
||||
* rawCount is equal to the number of times when the encoded
|
||||
* token occurs in the row.
|
||||
*/
|
||||
enum class TfTypes
|
||||
{
|
||||
BINARY,
|
||||
RAW_COUNT,
|
||||
TERM_FREQUENCY,
|
||||
SUBLINEAR_TF,
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct this using the term frequency type and the inverse document
|
||||
* frequency type.
|
||||
*
|
||||
* @param tfType Type of the term frequency statistics.
|
||||
* @param smoothIdf Used to indicate whether to use smooth idf or not.
|
||||
* If idf is smooth it's calculated by the following formula:
|
||||
* \f$ idf(T) = \log \frac{1 + N}{1 + df(T)} + 1, \f$ where
|
||||
* \f$ N \f$ is the total number of strings in the document,
|
||||
* \f$ T \f$ is the current encoded token, \f$ df(T) \f$
|
||||
* equals the number of strings which contain the token.
|
||||
* If idf isn't smooth then the following rule applies:
|
||||
* \f$ idf(T) = \log \frac{N}{df(T)} + 1. \f$
|
||||
*/
|
||||
TfIdfEncodingPolicy(const TfTypes tfType = TfTypes::RAW_COUNT,
|
||||
const bool smoothIdf = true) :
|
||||
tfType(tfType),
|
||||
smoothIdf(smoothIdf)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Clear the necessary internal variables.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
tokensFrequences.clear();
|
||||
numContainingStrings.clear();
|
||||
linesSizes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* The function initializes the output matrix. The encoder writes data
|
||||
* in the row-major order.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param datasetSize The number of strings in the input dataset.
|
||||
* @param maxNumTokens The maximum number of tokens in the strings of the
|
||||
* input dataset (not used).
|
||||
* @param dictionarySize The size of the dictionary.
|
||||
*/
|
||||
template<typename MatType>
|
||||
static void InitMatrix(MatType& output,
|
||||
const size_t datasetSize,
|
||||
const size_t /* maxNumTokens */,
|
||||
const size_t dictionarySize)
|
||||
{
|
||||
output.zeros(dictionarySize, datasetSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* The function initializes the output matrix. The encoder writes data
|
||||
* in the row-major order.
|
||||
*
|
||||
* Overloaded function to save the result in vector<vector<ElemType>>.
|
||||
*
|
||||
* @tparam ElemType Type of the output values.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results.
|
||||
* @param datasetSize The number of strings in the input dataset.
|
||||
* @param maxNumTokens The maximum number of tokens in the strings of the
|
||||
* input dataset (not used).
|
||||
* @param dictionarySize The size of the dictionary.
|
||||
*/
|
||||
template<typename ElemType>
|
||||
static void InitMatrix(std::vector<std::vector<ElemType>>& output,
|
||||
const size_t datasetSize,
|
||||
const size_t /* maxNumTokens */,
|
||||
const size_t dictionarySize)
|
||||
{
|
||||
output.resize(datasetSize, std::vector<ElemType>(dictionarySize));
|
||||
}
|
||||
|
||||
/**
|
||||
* The function performs the TfIdf encoding algorithm i.e. it writes
|
||||
* the encoded token to the output. The encoder writes data in the
|
||||
* column-major order.
|
||||
*
|
||||
* @tparam MatType The output matrix type.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results (sp_mat or mat).
|
||||
* @param value The encoded token.
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The token index in the line.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Encode(MatType& output,
|
||||
const size_t value,
|
||||
const size_t line,
|
||||
const size_t /* index */)
|
||||
{
|
||||
const typename MatType::elem_type tf =
|
||||
TermFrequency<typename MatType::elem_type>(
|
||||
tokensFrequences[line][value], linesSizes[line]);
|
||||
|
||||
const typename MatType::elem_type idf =
|
||||
InverseDocumentFrequency<typename MatType::elem_type>(
|
||||
output.n_cols, numContainingStrings[value]);
|
||||
|
||||
output(value - 1, line) = tf * idf;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function performs the TfIdf encoding algorithm i.e. it writes
|
||||
* the encoded token to the output. The encoder writes data in the
|
||||
* row-major order.
|
||||
*
|
||||
* Overloaded function to accept vector<vector<ElemType>> as the output
|
||||
* type.
|
||||
*
|
||||
* @tparam ElemType Type of the output values.
|
||||
*
|
||||
* @param output Output matrix to store the encoded results.
|
||||
* @param value The encoded token.
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The token index in the line.
|
||||
*/
|
||||
template<typename ElemType>
|
||||
void Encode(std::vector<std::vector<ElemType>>& output,
|
||||
const size_t value,
|
||||
const size_t line,
|
||||
const size_t /* index */)
|
||||
{
|
||||
const ElemType tf = TermFrequency<ElemType>(
|
||||
tokensFrequences[line][value], linesSizes[line]);
|
||||
|
||||
const ElemType idf = InverseDocumentFrequency<ElemType>(
|
||||
output.size(), numContainingStrings[value]);
|
||||
|
||||
output[line][value - 1] = tf * idf;
|
||||
}
|
||||
|
||||
/*
|
||||
* The function calculates the necessary statistics for the purpose
|
||||
* of the tf-idf algorithm during the first pass through the dataset.
|
||||
*
|
||||
* @param line The line number at which the encoding is performed.
|
||||
* @param index The token sequence number in the line.
|
||||
* @param value The encoded token.
|
||||
*/
|
||||
void PreprocessToken(const size_t line,
|
||||
const size_t /* index */,
|
||||
const size_t value)
|
||||
{
|
||||
if (line >= tokensFrequences.size())
|
||||
{
|
||||
linesSizes.resize(line + 1);
|
||||
tokensFrequences.resize(line + 1);
|
||||
}
|
||||
|
||||
tokensFrequences[line][value]++;
|
||||
|
||||
if (tokensFrequences[line][value] == 1)
|
||||
numContainingStrings[value]++;
|
||||
|
||||
linesSizes[line]++;
|
||||
}
|
||||
|
||||
//! Return token frequencies.
|
||||
const std::vector<std::unordered_map<size_t, size_t>>&
|
||||
TokensFrequences() const { return tokensFrequences; }
|
||||
//! Modify token frequencies.
|
||||
std::vector<std::unordered_map<size_t, size_t>>& TokensFrequences()
|
||||
{
|
||||
return tokensFrequences;
|
||||
}
|
||||
|
||||
//! Get the number of containing strings depending on the given token.
|
||||
const std::unordered_map<size_t, size_t>& NumContainingStrings() const
|
||||
{
|
||||
return numContainingStrings;
|
||||
}
|
||||
|
||||
//! Modify the number of containing strings depending on the given token.
|
||||
std::unordered_map<size_t, size_t>& NumContainingStrings()
|
||||
{
|
||||
return numContainingStrings;
|
||||
}
|
||||
|
||||
//! Return the lines sizes.
|
||||
const std::vector<size_t>& LinesSizes() const { return linesSizes; }
|
||||
//! Modify the lines sizes.
|
||||
std::vector<size_t>& LinesSizes() { return linesSizes; }
|
||||
|
||||
//! Return the term frequency type.
|
||||
TfTypes TfType() const { return tfType; }
|
||||
//! Modify the term frequency type.
|
||||
TfTypes& TfType() { return tfType; }
|
||||
|
||||
//! Determine the idf algorithm type (whether it's smooth or not).
|
||||
bool SmoothIdf() const { return smoothIdf; }
|
||||
//! Modify the idf algorithm type (whether it's smooth or not).
|
||||
bool& SmoothIdf() { return smoothIdf; }
|
||||
|
||||
/**
|
||||
* Serialize the class to the given archive.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(tfType);
|
||||
ar & BOOST_SERIALIZATION_NVP(smoothIdf);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* The function calculates the term frequency statistics.
|
||||
*
|
||||
* @tparam ValueType Type of the returned value.
|
||||
*
|
||||
* @param numOccurrences The number of the given token occurrences in
|
||||
* the line.
|
||||
* @param numTokens The total number of tokens in the line.
|
||||
*/
|
||||
template<typename ValueType>
|
||||
ValueType TermFrequency(const size_t numOccurrences,
|
||||
const size_t numTokens)
|
||||
{
|
||||
switch (tfType)
|
||||
{
|
||||
case TfTypes::BINARY:
|
||||
return numOccurrences > 0;
|
||||
case TfTypes::RAW_COUNT:
|
||||
return numOccurrences;
|
||||
case TfTypes::TERM_FREQUENCY:
|
||||
return static_cast<ValueType>(numOccurrences) / numTokens;
|
||||
case TfTypes::SUBLINEAR_TF:
|
||||
return std::log(static_cast<ValueType>(numOccurrences)) + 1;
|
||||
default:
|
||||
Log::Fatal << "Incorrect term frequency type!";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function calculates the inverse document frequency statistics.
|
||||
*
|
||||
* @tparam ValueType Type of the returned value.
|
||||
*
|
||||
* @param totalNumLines The total number of strings in the input dataset.
|
||||
* @param numOccurrences The number of strings in the input dataset
|
||||
* which contain the current token.
|
||||
*/
|
||||
template<typename ValueType>
|
||||
ValueType InverseDocumentFrequency(const size_t totalNumLines,
|
||||
const size_t numOccurrences)
|
||||
{
|
||||
if (smoothIdf)
|
||||
{
|
||||
return std::log(static_cast<ValueType>(totalNumLines + 1) /
|
||||
(1 + numOccurrences)) + 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::log(static_cast<ValueType>(totalNumLines) /
|
||||
numOccurrences) + 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//! Used to store the total number of tokens for each line.
|
||||
std::vector<std::unordered_map<size_t, size_t>> tokensFrequences;
|
||||
/**
|
||||
* Used to store the number of strings which contain a token depending
|
||||
* on the given token.
|
||||
*/
|
||||
std::unordered_map<size_t, size_t> numContainingStrings;
|
||||
//! Used to store the number of tokens in each line.
|
||||
std::vector<size_t> linesSizes;
|
||||
//! Type of the term frequency scheme.
|
||||
TfTypes tfType;
|
||||
//! Indicates whether the idf scheme is smooth or not.
|
||||
bool smoothIdf;
|
||||
};
|
||||
|
||||
/**
|
||||
* A convenient alias for the StringEncoding class with TfIdfEncodingPolicy
|
||||
* and the default dictionary for the given token type.
|
||||
*
|
||||
* @tparam TokenType Type of the tokens.
|
||||
*/
|
||||
template<typename TokenType>
|
||||
using TfIdfEncoding = StringEncoding<TfIdfEncodingPolicy,
|
||||
StringEncodingDictionary<TokenType>>;
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -81,14 +81,34 @@ struct IsVector<arma::subview_row<eT> >
|
||||
const static bool value = true;
|
||||
};
|
||||
|
||||
// I'm not so sure about this one. An SpSubview object can be a row or column,
|
||||
// but it can also be a matrix subview.
|
||||
|
||||
// template<>
|
||||
template<typename eT>
|
||||
struct IsVector<arma::SpSubview<eT> >
|
||||
{
|
||||
const static bool value = true;
|
||||
};
|
||||
#if ((ARMA_VERSION_MAJOR >= 10) || \
|
||||
((ARMA_VERSION_MAJOR == 9) && (ARMA_VERSION_MINOR >= 869)))
|
||||
|
||||
// Armadillo 9.869+ has SpSubview_col and SpSubview_row
|
||||
|
||||
template<typename eT>
|
||||
struct IsVector<arma::SpSubview_col<eT> >
|
||||
{
|
||||
const static bool value = true;
|
||||
};
|
||||
|
||||
template<typename eT>
|
||||
struct IsVector<arma::SpSubview_row<eT> >
|
||||
{
|
||||
const static bool value = true;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// fallback for older Armadillo versions
|
||||
|
||||
template<typename eT>
|
||||
struct IsVector<arma::SpSubview<eT> >
|
||||
{
|
||||
const static bool value = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
// The version of mlpack. If this is a git repository, this will be a version
|
||||
// with higher number than the most recent release.
|
||||
#define MLPACK_VERSION_MAJOR 3
|
||||
#define MLPACK_VERSION_MINOR 2
|
||||
#define MLPACK_VERSION_PATCH 3
|
||||
#define MLPACK_VERSION_MINOR 3
|
||||
#define MLPACK_VERSION_PATCH 1
|
||||
|
||||
// The name of the version (for use by --version).
|
||||
namespace mlpack {
|
||||
|
||||
@@ -12,32 +12,57 @@
|
||||
#ifndef MLPACK_METHODS_ANN_LAYER_LAYER_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_LAYER_HPP
|
||||
|
||||
#include "add.hpp"
|
||||
#include "add_merge.hpp"
|
||||
#include "alpha_dropout.hpp"
|
||||
#include "atrous_convolution.hpp"
|
||||
#include "base_layer.hpp"
|
||||
#include "batch_norm.hpp"
|
||||
#include "bilinear_interpolation.hpp"
|
||||
#include "c_relu.hpp"
|
||||
#include "celu.hpp"
|
||||
#include "concat_performance.hpp"
|
||||
#include "concat.hpp"
|
||||
#include "concatenate.hpp"
|
||||
#include "constant.hpp"
|
||||
#include "convolution.hpp"
|
||||
#include "dropconnect.hpp"
|
||||
#include "dropout.hpp"
|
||||
#include "elu.hpp"
|
||||
#include "fast_lstm.hpp"
|
||||
#include "flexible_relu.hpp"
|
||||
#include "glimpse.hpp"
|
||||
#include "gru.hpp"
|
||||
#include "hard_tanh.hpp"
|
||||
#include "hardshrink.hpp"
|
||||
#include "highway.hpp"
|
||||
#include "join.hpp"
|
||||
#include "layer_norm.hpp"
|
||||
#include "layer_types.hpp"
|
||||
#include "leaky_relu.hpp"
|
||||
#include "linear.hpp"
|
||||
#include "linear_no_bias.hpp"
|
||||
#include "log_softmax.hpp"
|
||||
#include "lookup.hpp"
|
||||
#include "lstm.hpp"
|
||||
#include "max_pooling.hpp"
|
||||
#include "mean_pooling.hpp"
|
||||
#include "minibatch_discrimination.hpp"
|
||||
#include "multiply_constant.hpp"
|
||||
#include "multiply_merge.hpp"
|
||||
#include "padding.hpp"
|
||||
#include "gru.hpp"
|
||||
#include "fast_lstm.hpp"
|
||||
#include "recurrent.hpp"
|
||||
#include "parametric_relu.hpp"
|
||||
#include "recurrent_attention.hpp"
|
||||
#include "recurrent.hpp"
|
||||
#include "reinforce_normal.hpp"
|
||||
#include "reparametrization.hpp"
|
||||
#include "select.hpp"
|
||||
#include "sequential.hpp"
|
||||
#include "softshrink.hpp"
|
||||
#include "subview.hpp"
|
||||
#include "concat.hpp"
|
||||
#include "vr_class_reward.hpp"
|
||||
#include "transposed_convolution.hpp"
|
||||
#include "virtual_batch_norm.hpp"
|
||||
#include "vr_class_reward.hpp"
|
||||
#include "weight_norm.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <mlpack/methods/ann/layer/leaky_relu.hpp>
|
||||
#include <mlpack/methods/ann/layer/c_relu.hpp>
|
||||
#include <mlpack/methods/ann/layer/flexible_relu.hpp>
|
||||
#include <mlpack/methods/ann/layer/linear_no_bias.hpp>
|
||||
#include <mlpack/methods/ann/layer/log_softmax.hpp>
|
||||
#include <mlpack/methods/ann/layer/lookup.hpp>
|
||||
#include <mlpack/methods/ann/layer/multiply_constant.hpp>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
set(SOURCES
|
||||
cross_entropy_error.hpp
|
||||
cross_entropy_error_impl.hpp
|
||||
cosine_embedding_loss.hpp
|
||||
cosine_embedding_loss_impl.hpp
|
||||
dice_loss.hpp
|
||||
dice_loss_impl.hpp
|
||||
earth_mover_distance.hpp
|
||||
@@ -11,6 +13,8 @@ set(SOURCES
|
||||
huber_loss_impl.hpp
|
||||
kl_divergence.hpp
|
||||
kl_divergence_impl.hpp
|
||||
margin_ranking_loss.hpp
|
||||
margin_ranking_loss_impl.hpp
|
||||
mean_bias_error.hpp
|
||||
mean_bias_error_impl.hpp
|
||||
mean_squared_error.hpp
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* @file cosine_embedding_loss.hpp
|
||||
* @author Kartik Dutt
|
||||
*
|
||||
* Definition of the Cosine Embedding loss function.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_METHODS_ANN_LOSS_FUNCTION_COSINE_EMBEDDING_HPP
|
||||
#define MLPACK_METHODS_ANN_LOSS_FUNCTION_COSINE_EMBEDDING_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
/**
|
||||
* Cosine Embedding Loss function is used for measuring whether two inputs are
|
||||
* similar or dissimilar, using the cosine distance, and is typically used
|
||||
* for learning nonlinear embeddings or semi-supervised learning.
|
||||
*
|
||||
* @f{eqnarray*}{
|
||||
* f(x) = 1 - cos(x1, x2) , for y = 1
|
||||
* f(x) = max(0, cos(x1, x2) - margin) , for y = -1
|
||||
* @f}
|
||||
*
|
||||
* @tparam InputDataType Type of the input data (arma::colvec, arma::mat,
|
||||
* arma::sp_mat or arma::cube).
|
||||
* @tparam OutputDataType Type of the output data (arma::colvec, arma::mat,
|
||||
* arma::sp_mat or arma::cube).
|
||||
*/
|
||||
template <
|
||||
typename InputDataType = arma::mat,
|
||||
typename OutputDataType = arma::mat
|
||||
>
|
||||
class CosineEmbeddingLoss
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create the CosineEmbeddingLoss object.
|
||||
*
|
||||
* @param margin Increases cosine distance in case of dissimilarity.
|
||||
* Refer definition of cosine-embedding-loss above.
|
||||
* @param similarity Determines whether to use similarity or dissimilarity for
|
||||
* comparision.
|
||||
* @param takeMean Boolean variable to specify whether to take mean or not.
|
||||
* Specifies reduction method i.e. sum or mean corresponding
|
||||
* to 0 and 1 respectively. Default value = 0.
|
||||
*/
|
||||
CosineEmbeddingLoss(const double margin = 0.0,
|
||||
const bool similarity = true,
|
||||
const bool takeMean = false);
|
||||
|
||||
/**
|
||||
* Ordinary feed forward pass of a neural network.
|
||||
*
|
||||
* @param input Input data used for evaluating the specified function.
|
||||
* @param target The target vector.
|
||||
*/
|
||||
template <typename InputType, typename TargetType>
|
||||
typename InputType::elem_type Forward(const InputType& input,
|
||||
const TargetType& target);
|
||||
|
||||
/**
|
||||
* Ordinary feed backward pass of a neural network.
|
||||
*
|
||||
* @param input The propagated input activation.
|
||||
* @param target The target vector.
|
||||
* @param output The calculated error.
|
||||
*/
|
||||
template<typename InputType, typename TargetType, typename OutputType>
|
||||
void Backward(const InputType& input,
|
||||
const TargetType& target,
|
||||
OutputType& output);
|
||||
|
||||
//! Get the input parameter.
|
||||
InputDataType& InputParameter() const { return inputParameter; }
|
||||
//! Modify the input parameter.
|
||||
InputDataType& InputParameter() { return inputParameter; }
|
||||
|
||||
//! Get the output parameter.
|
||||
OutputDataType& OutputParameter() const { return outputParameter; }
|
||||
//! Modify the output parameter.
|
||||
OutputDataType& OutputParameter() { return outputParameter; }
|
||||
|
||||
//! Get the delta.
|
||||
OutputDataType& Delta() const { return delta; }
|
||||
//! Modify the delta.
|
||||
OutputDataType& Delta() { return delta; }
|
||||
|
||||
//! Get the value of takeMean.
|
||||
bool TakeMean() const { return takeMean; }
|
||||
//! Modify the value of takeMean.
|
||||
bool& TakeMean() { return takeMean; }
|
||||
|
||||
//! Get the value of margin.
|
||||
double Margin() const { return margin; }
|
||||
//! Modify the value of takeMean.
|
||||
double& Margin() { return margin; }
|
||||
|
||||
//! Get the value of similarity hyperparameter.
|
||||
bool Similarity() const { return similarity; }
|
||||
//! Modify the value of takeMean.
|
||||
bool& Similarity() { return similarity; }
|
||||
|
||||
/**
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */);
|
||||
|
||||
private:
|
||||
//! Locally-stored delta object.
|
||||
OutputDataType delta;
|
||||
|
||||
//! Locally-stored input parameter object.
|
||||
InputDataType inputParameter;
|
||||
|
||||
//! Locally-stored output parameter object.
|
||||
OutputDataType outputParameter;
|
||||
|
||||
//! Locally-stored value of similarity hyper-parameter.
|
||||
bool similarity;
|
||||
|
||||
//! Locally-stored value of margin hyper-parameter.
|
||||
double margin;
|
||||
|
||||
//! Locally-stored value of takeMean hyper-parameter.
|
||||
bool takeMean;
|
||||
}; // class CosineEmbeddingLoss
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation.
|
||||
#include "cosine_embedding_loss_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @file cosine_embedding_loss_impl.hpp
|
||||
* @author Kartik Dutt
|
||||
*
|
||||
* Implementation of the Cosine Embedding loss function.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_METHODS_ANN_LOSS_FUNCTION_COSINE_EMBEDDING_IMPL_HPP
|
||||
#define MLPACK_METHODS_ANN_LOSS_FUNCTION_COSINE_EMBEDDING_IMPL_HPP
|
||||
|
||||
// In case it hasn't yet been included.
|
||||
#include "cosine_embedding_loss.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
CosineEmbeddingLoss<InputDataType, OutputDataType>::CosineEmbeddingLoss(
|
||||
const double margin, const bool similarity, const bool takeMean):
|
||||
margin(margin), similarity(similarity), takeMean(takeMean)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputType, typename TargetType>
|
||||
typename InputType::elem_type
|
||||
CosineEmbeddingLoss<InputDataType, OutputDataType>::Forward(
|
||||
const InputType& input,
|
||||
const TargetType& target)
|
||||
{
|
||||
typedef typename InputType::elem_type ElemType;
|
||||
|
||||
const size_t cols = input.n_cols;
|
||||
const size_t batchSize = input.n_elem / cols;
|
||||
if (arma::size(input) != arma::size(target))
|
||||
Log::Fatal << "Input Tensors must have same dimensions." << std::endl;
|
||||
|
||||
arma::colvec inputTemp1 = arma::vectorise(input);
|
||||
arma::colvec inputTemp2 = arma::vectorise(target);
|
||||
ElemType loss = 0.0;
|
||||
|
||||
for (size_t i = 0; i < inputTemp1.n_elem; i += cols)
|
||||
{
|
||||
const ElemType cosDist = kernel::CosineDistance::Evaluate(
|
||||
inputTemp1(arma::span(i, i + cols - 1)), inputTemp2(arma::span(i,
|
||||
i + cols - 1)));
|
||||
if (similarity)
|
||||
loss += 1 - cosDist;
|
||||
else
|
||||
{
|
||||
const ElemType currentLoss = cosDist - margin;
|
||||
loss += currentLoss > 0 ? currentLoss : 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (takeMean)
|
||||
loss = (ElemType) loss / batchSize;
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputType, typename TargetType, typename OutputType>
|
||||
void CosineEmbeddingLoss<InputDataType, OutputDataType>::Backward(
|
||||
const InputType& input,
|
||||
const TargetType& target,
|
||||
OutputType& output)
|
||||
{
|
||||
typedef typename InputType::elem_type ElemType;
|
||||
|
||||
const size_t cols = input.n_cols;
|
||||
const size_t batchSize = input.n_elem / cols;
|
||||
if (arma::size(input) != arma::size(target))
|
||||
Log::Fatal << "Input Tensors must have same dimensions." << std::endl;
|
||||
|
||||
arma::colvec inputTemp1 = arma::vectorise(input);
|
||||
arma::colvec inputTemp2 = arma::vectorise(target);
|
||||
output.set_size(arma::size(inputTemp1));
|
||||
|
||||
arma::colvec outputTemp(output.memptr(), inputTemp1.n_elem,
|
||||
false, false);
|
||||
for (size_t i = 0; i < inputTemp1.n_elem; i += cols)
|
||||
{
|
||||
const ElemType cosDist = kernel::CosineDistance::Evaluate(inputTemp1(
|
||||
arma::span(i, i + cols -1)), inputTemp2(arma::span(i, i + cols -1)));
|
||||
|
||||
if (cosDist < margin && !similarity)
|
||||
outputTemp(arma::span(i, i + cols - 1)).zeros();
|
||||
else
|
||||
{
|
||||
const int multiplier = similarity ? 1 : -1;
|
||||
outputTemp(arma::span(i, i + cols -1)) = -1 * multiplier *
|
||||
(arma::normalise(inputTemp2(arma::span(i, i + cols - 1))) -
|
||||
cosDist * arma::normalise(inputTemp1(arma::span(i, i + cols -
|
||||
1)))) / std::sqrt(arma::accu(arma::pow(inputTemp1(arma::span(i, i +
|
||||
cols - 1)), 2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename Archive>
|
||||
void CosineEmbeddingLoss<InputDataType, OutputDataType>::serialize(
|
||||
Archive& ar ,
|
||||
const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(margin);
|
||||
ar & BOOST_SERIALIZATION_NVP(similarity);
|
||||
ar & BOOST_SERIALIZATION_NVP(takeMean);
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file margin_ranking_loss.hpp
|
||||
* @author Andrei Mihalea
|
||||
*
|
||||
* Definition of the Margin Ranking Loss function.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_ANN_LOSS_FUNCTION_MARGIN_RANKING_LOSS_HPP
|
||||
#define MLPACK_ANN_LOSS_FUNCTION_MARGIN_RANKING_LOSS_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
/**
|
||||
* Margin ranking loss measures the loss given inputs and a label vector with
|
||||
* values of 1 or -1. If the label is 1 then the first input should be ranked
|
||||
* higher than the second input at a distance larger than a margin, and vice-
|
||||
* versa if the label is -1.
|
||||
*
|
||||
* @tparam InputDataType Type of the input data (arma::colvec, arma::mat,
|
||||
* arma::sp_mat or arma::cube).
|
||||
* @tparam OutputDataType Type of the output data (arma::colvec, arma::mat,
|
||||
* arma::sp_mat or arma::cube).
|
||||
*/
|
||||
template <
|
||||
typename InputDataType = arma::mat,
|
||||
typename OutputDataType = arma::mat
|
||||
>
|
||||
class MarginRankingLoss
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create the MarginRankingLoss object with Hyperparameter margin.
|
||||
* Hyperparameter margin defines a minimum distance between correctly ranked
|
||||
* samples.
|
||||
*/
|
||||
MarginRankingLoss(const double margin = 1.0);
|
||||
|
||||
/**
|
||||
* Computes the Margin Ranking Loss function.
|
||||
*
|
||||
* @param input Concatenation of the two inputs for evaluating the specified
|
||||
* function.
|
||||
* @param target The label vector which contains values of -1 or 1.
|
||||
*/
|
||||
template<typename InputType, typename TargetType>
|
||||
typename InputType::elem_type Forward(const InputType& input,
|
||||
const TargetType& target);
|
||||
|
||||
/**
|
||||
* Ordinary feed backward pass of a neural network.
|
||||
*
|
||||
* @param input The propagated concatenated input activation.
|
||||
* @param target The label vector which contains -1 or 1 values.
|
||||
* @param output The calculated error.
|
||||
*/
|
||||
template <
|
||||
typename InputType,
|
||||
typename TargetType,
|
||||
typename OutputType
|
||||
>
|
||||
void Backward(const InputType& input,
|
||||
const TargetType& target,
|
||||
OutputType& output);
|
||||
|
||||
//! Get the output parameter.
|
||||
OutputDataType& OutputParameter() const { return outputParameter; }
|
||||
//! Modify the output parameter.
|
||||
OutputDataType& OutputParameter() { return outputParameter; }
|
||||
|
||||
//! Get the margin parameter.
|
||||
double Margin() const { return margin; }
|
||||
//! Modify the margin parameter.
|
||||
double& Margin() { return margin; }
|
||||
|
||||
/**
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */);
|
||||
|
||||
private:
|
||||
//! Locally-stored output parameter object.
|
||||
OutputDataType outputParameter;
|
||||
|
||||
//! The margin value used in calculating Margin Ranking Loss.
|
||||
double margin;
|
||||
}; // class MarginRankingLoss
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
// include implementation.
|
||||
#include "margin_ranking_loss_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @file margin_ranking_loss_impl.hpp
|
||||
* @author Andrei Mihalea
|
||||
*
|
||||
* Implementation of the Margin Ranking Loss function.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_METHODS_ANN_LOSS_FUNCTION_MARGIN_IMPL_LOSS_HPP
|
||||
#define MLPACK_METHODS_ANN_LOSS_FUNCTION_MARGIN_IMPL_LOSS_HPP
|
||||
|
||||
// In case it hasn't been included.
|
||||
#include "margin_ranking_loss.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artifical Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
MarginRankingLoss<InputDataType, OutputDataType>::MarginRankingLoss(
|
||||
const double margin) : margin(margin)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputType, typename TargetType>
|
||||
typename InputType::elem_type
|
||||
MarginRankingLoss<InputDataType, OutputDataType>::Forward(
|
||||
const InputType& input,
|
||||
const TargetType& target)
|
||||
{
|
||||
const int inputRows = input.n_rows;
|
||||
const InputType& input1 = input.rows(0, inputRows / 2 - 1);
|
||||
const InputType& input2 = input.rows(inputRows / 2, inputRows - 1);
|
||||
return arma::accu(arma::max(arma::zeros(size(target)),
|
||||
-target % (input1 - input2) + margin)) / target.n_cols;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template <
|
||||
typename InputType,
|
||||
typename TargetType,
|
||||
typename OutputType
|
||||
>
|
||||
void MarginRankingLoss<InputDataType, OutputDataType>::Backward(
|
||||
const InputType& input,
|
||||
const TargetType& target,
|
||||
OutputType& output)
|
||||
{
|
||||
const int inputRows = input.n_rows;
|
||||
const InputType& input1 = input.rows(0, inputRows / 2 - 1);
|
||||
const InputType& input2 = input.rows(inputRows / 2, inputRows - 1);
|
||||
output = -target % (input1 - input2) + margin;
|
||||
output.elem(arma::find(output >= 0)).ones();
|
||||
output.elem(arma::find(output < 0)).zeros();
|
||||
output = (input2 - input1) % output / target.n_cols;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename Archive>
|
||||
void MarginRankingLoss<InputDataType, OutputDataType>::serialize(
|
||||
Archive& ar,
|
||||
const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(margin);
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -25,7 +25,6 @@ LogisticRegression<MatType>::LogisticRegression(
|
||||
const MatType& predictors,
|
||||
const arma::Row<size_t>& responses,
|
||||
const double lambda) :
|
||||
parameters(arma::rowvec(predictors.n_rows + 1, arma::fill::zeros)),
|
||||
lambda(lambda)
|
||||
{
|
||||
Train(predictors, responses);
|
||||
@@ -60,7 +59,6 @@ LogisticRegression<MatType>::LogisticRegression(
|
||||
const arma::Row<size_t>& responses,
|
||||
OptimizerType& optimizer,
|
||||
const double lambda) :
|
||||
parameters(arma::rowvec(predictors.n_rows + 1, arma::fill::zeros)),
|
||||
lambda(lambda)
|
||||
{
|
||||
Train(predictors, responses, optimizer);
|
||||
@@ -85,9 +83,11 @@ double LogisticRegression<MatType>::Train(
|
||||
OptimizerType& optimizer,
|
||||
CallbackTypes&&... callbacks)
|
||||
{
|
||||
LogisticRegressionFunction<MatType> errorFunction(predictors,
|
||||
responses,
|
||||
lambda);
|
||||
LogisticRegressionFunction<MatType> errorFunction(predictors, responses,
|
||||
lambda);
|
||||
|
||||
// Set size of parameters vector according to the input data received.
|
||||
parameters = arma::rowvec(predictors.n_rows + 1, arma::fill::zeros);
|
||||
errorFunction.InitialPoint() = parameters;
|
||||
|
||||
Timer::Start("logistic_regression_optimization");
|
||||
|
||||
@@ -40,4 +40,12 @@ add_markdown_docs(preprocess_imputer "cli" "preprocessing")
|
||||
|
||||
add_cli_executable(preprocess_scale)
|
||||
add_python_binding(preprocess_scale)
|
||||
add_markdown_docs(preprocess_scale "cli;python" "preprocessing")
|
||||
add_julia_binding(preprocess_scale)
|
||||
add_markdown_docs(preprocess_scale "cli;python;julia" "preprocessing")
|
||||
|
||||
if (STB_AVAILABLE)
|
||||
add_cli_executable(image_converter)
|
||||
add_python_binding(image_converter)
|
||||
add_julia_binding(image_converter)
|
||||
add_markdown_docs(image_converter "cli;python;julia" "preprocessing")
|
||||
endif ()
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @file image_converter_main.cpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* A CLI executable to load and save a image dataset.
|
||||
*
|
||||
* 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/prereqs.hpp>
|
||||
#include <mlpack/core/util/cli.hpp>
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::util;
|
||||
using namespace arma;
|
||||
using namespace std;
|
||||
using namespace mlpack::data;
|
||||
|
||||
PROGRAM_INFO("Image Converter",
|
||||
// Short description.
|
||||
"A utility to load an image or set of images into a single dataset that"
|
||||
" can then be used by other mlpack methods and utilities. This can also"
|
||||
" unpack an image dataset into individual files, for instance after mlpack"
|
||||
" methods have been used.",
|
||||
// Long description.
|
||||
"This utility takes an image or an array of images and loads them to a"
|
||||
" matrix. You can optionally specify the height " +
|
||||
PRINT_PARAM_STRING("height") + " width " + PRINT_PARAM_STRING("width")
|
||||
+ " and channel " + PRINT_PARAM_STRING("channels") + " of the images that"
|
||||
" needs to be loaded; otherwise, these parameters will be automatically"
|
||||
" detected from the image."
|
||||
"\n"
|
||||
"There are other options too, that can be specified such as " +
|
||||
PRINT_PARAM_STRING("quality")
|
||||
+ ".\n\n" +
|
||||
"You can also provide a dataset and save them as images using " +
|
||||
PRINT_PARAM_STRING("dataset") + " and " + PRINT_PARAM_STRING("save") +
|
||||
" as an parameter. An example to load an image : " +
|
||||
"\n\n" +
|
||||
PRINT_CALL("image_converter", "input", "X", "height", 256, "width", 256,
|
||||
"channels", 3, "output", "Y") +
|
||||
"\n\n" +
|
||||
" An example to save an image is :" +
|
||||
"\n\n" +
|
||||
PRINT_CALL("image_converter", "input", "X", "height", 256, "width", 256,
|
||||
"channels", 3, "dataset", "Y", "save", true),
|
||||
SEE_ALSO("@preprocess_binarize", "#preprocess_binarize"),
|
||||
SEE_ALSO("@preprocess_describe", "#preprocess_describe"),
|
||||
SEE_ALSO("@preprocess_imputer", "#preprocess_imputer"));
|
||||
|
||||
// DEFINE PARAM
|
||||
PARAM_VECTOR_IN_REQ(string, "input", "Image filenames which have to "
|
||||
"be loaded/saved.", "i");
|
||||
|
||||
PARAM_INT_IN("width", "Width of the image.", "w", 0);
|
||||
PARAM_INT_IN("channels", "Number of channels in the image.", "c", 0);
|
||||
|
||||
PARAM_MATRIX_OUT("output", "Matrix to save images data to, Only"
|
||||
"needed if you are specifying 'save' option.", "o");
|
||||
|
||||
PARAM_INT_IN("quality", "Compression of the image if saved as jpg (0-100).",
|
||||
"q", 90);
|
||||
|
||||
PARAM_INT_IN("height", "Height of the images.", "H", 0);
|
||||
PARAM_FLAG("save", "Save a dataset as images.", "s");
|
||||
PARAM_MATRIX_IN("dataset", "Input matrix to save as images.", "I");
|
||||
|
||||
static void mlpackMain()
|
||||
{
|
||||
Timer::Start("Loading/Saving Image");
|
||||
// Parse command line options.
|
||||
const vector<string> fileNames = CLI::GetParam<vector<string> >("input");
|
||||
arma::mat out;
|
||||
|
||||
if (!CLI::HasParam("save"))
|
||||
{
|
||||
ReportIgnoredParam("width", "Width of image is determined from file.");
|
||||
ReportIgnoredParam("height", "Height of image is determined from file.");
|
||||
ReportIgnoredParam("channels", "Number of channels determined from file.");
|
||||
data::ImageInfo info;
|
||||
Load(fileNames, out, info, true);
|
||||
if (CLI::HasParam("output"))
|
||||
CLI::GetParam<arma::mat>("output") = std::move(out);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequireNoneOrAllPassed({ "save", "width", "height", "channels", "dataset" }
|
||||
, true, "Image size information is needed when 'save' is specified!");
|
||||
// Positive value for width.
|
||||
RequireParamValue<int>("width", [](int x) { return x >= 0;}, true,
|
||||
"width must be positive");
|
||||
// Positive value for height.
|
||||
RequireParamValue<int>("height", [](int x) { return x >= 0;}, true,
|
||||
"height must be positive");
|
||||
// Positive value for channel.
|
||||
RequireParamValue<int>("channels", [](int x) { return x >= 0;}, true,
|
||||
"channels must be positive");
|
||||
// Positive value for quality.
|
||||
RequireParamValue<int>("quality", [](int x) { return x >= 0;}, true,
|
||||
"quality must be positive");
|
||||
|
||||
const size_t height = CLI::GetParam<int>("height");
|
||||
const size_t width = CLI::GetParam<int>("width");
|
||||
const size_t channels = CLI::GetParam<int>("channels");
|
||||
const size_t quality = CLI::GetParam<int>("quality");
|
||||
data::ImageInfo info(width, height, channels, quality);
|
||||
Save(fileNames, CLI::GetParam<arma::mat>("dataset"), info, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/cli.hpp>
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
#include <mlpack/core/util/cli.hpp>
|
||||
#include <mlpack/core/math/ccov.hpp>
|
||||
#include <mlpack/core/data/scaler_methods/max_abs_scaler.hpp>
|
||||
#include <mlpack/core/data/scaler_methods/mean_normalization.hpp>
|
||||
#include <mlpack/core/data/scaler_methods/min_max_scaler.hpp>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Define the files we need to compile
|
||||
# Anything not in this list will not be compiled into mlpack.
|
||||
set(SOURCES
|
||||
simple_dqn.hpp
|
||||
)
|
||||
|
||||
# Add directory name to sources.
|
||||
set(DIR_SRCS)
|
||||
foreach(file ${SOURCES})
|
||||
set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
|
||||
endforeach()
|
||||
# Append sources (with directory name) to list of all mlpack sources (used at
|
||||
# the parent scope).
|
||||
set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE)
|
||||
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* @file simple_dqn.hpp
|
||||
* @author Nishant Kumar
|
||||
*
|
||||
* This file contains the implementation of the simple deep q network.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MLPACK_METHODS_RL_SIMPLE_DQN_HPP
|
||||
#define MLPACK_METHODS_RL_SIMPLE_DQN_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/methods/ann/ffn.hpp>
|
||||
#include <mlpack/methods/ann/init_rules/gaussian_init.hpp>
|
||||
#include <mlpack/methods/ann/layer/layer.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/mean_squared_error.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace rl {
|
||||
|
||||
using namespace mlpack::ann;
|
||||
|
||||
/**
|
||||
* @tparam NetworkType The type of network used for simple dqn.
|
||||
*/
|
||||
template <typename NetworkType = FFN<MeanSquaredError<>,
|
||||
GaussianInitialization>>
|
||||
class SimpleDQN
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
SimpleDQN() : network()
|
||||
{ /* Nothing to do here. */ }
|
||||
|
||||
/**
|
||||
* Construct an instance of SimpleDQN class.
|
||||
*
|
||||
* @param inputDim Number of inputs.
|
||||
* @param h1 Number of neurons in hiddenlayer-1.
|
||||
* @param h2 Number of neurons in hiddenlayer-2.
|
||||
* @param outputDim Number of neurons in output layer.
|
||||
*/
|
||||
SimpleDQN(const int inputDim,
|
||||
const int h1,
|
||||
const int h2,
|
||||
const int outputDim) : network()
|
||||
{
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(inputDim, h1);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(h1, h2);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(h2, outputDim);
|
||||
network = model;
|
||||
}
|
||||
|
||||
SimpleDQN(NetworkType network) : network(std::move(network))
|
||||
{ /* Nothing to do here. */ }
|
||||
|
||||
/**
|
||||
* Predict the responses to a given set of predictors. The responses will
|
||||
* reflect the output of the given output layer as returned by the
|
||||
* output layer function.
|
||||
*
|
||||
* If you want to pass in a parameter and discard the original parameter
|
||||
* object, be sure to use std::move to avoid unnecessary copy.
|
||||
*
|
||||
* @param state Input state.
|
||||
* @param actionValue Matrix to put output action values of states input.
|
||||
*/
|
||||
void Predict(const arma::mat state, arma::mat& actionValue)
|
||||
{
|
||||
network.Predict(state, actionValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the forward pass of the states in real batch mode.
|
||||
*
|
||||
* @param state The input state.
|
||||
* @param target The predicted target.
|
||||
*/
|
||||
void Forward(const arma::mat state, arma::mat& target)
|
||||
{
|
||||
network.Forward(state, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the parameters of the network.
|
||||
*/
|
||||
void ResetParameters()
|
||||
{
|
||||
network.ResetParameters();
|
||||
}
|
||||
|
||||
//! Return the Parameters.
|
||||
const arma::mat& Parameters() const { return network.Parameters(); }
|
||||
//! Modify the Parameters.
|
||||
arma::mat& Parameters() { return network.Parameters(); }
|
||||
|
||||
/**
|
||||
* Perform the backward pass of the state in real batch mode.
|
||||
*
|
||||
* @param state The input state.
|
||||
* @param target The training target.
|
||||
* @return gradient The gradient.
|
||||
*/
|
||||
void Backward(const arma::mat state, arma::mat& target,
|
||||
arma::mat& gradient)
|
||||
{
|
||||
network.Backward(state, target, gradient);
|
||||
}
|
||||
|
||||
private:
|
||||
//! Locally-stored network.
|
||||
NetworkType network;
|
||||
};
|
||||
|
||||
} // namespace rl
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -65,7 +65,7 @@ double SoftmaxRegression::Train(const arma::mat& data,
|
||||
{
|
||||
SoftmaxRegressionFunction regressor(data, labels, numClasses, lambda,
|
||||
fitIntercept);
|
||||
if (parameters.is_empty())
|
||||
if (parameters.n_elem != regressor.GetInitialPoint().n_elem)
|
||||
parameters = regressor.GetInitialPoint();
|
||||
|
||||
// Train the model.
|
||||
@@ -88,7 +88,7 @@ double SoftmaxRegression::Train(const arma::mat& data,
|
||||
{
|
||||
SoftmaxRegressionFunction regressor(data, labels, numClasses, lambda,
|
||||
fitIntercept);
|
||||
if (parameters.is_empty())
|
||||
if (parameters.n_elem != regressor.GetInitialPoint().n_elem)
|
||||
parameters = regressor.GetInitialPoint();
|
||||
|
||||
// Train the model.
|
||||
|
||||
@@ -137,6 +137,7 @@ add_executable(mlpack_test
|
||||
main_tests/kfn_test.cpp
|
||||
main_tests/knn_test.cpp
|
||||
main_tests/linear_regression_test.cpp
|
||||
main_tests/image_converter_test.cpp
|
||||
main_tests/linear_svm_test.cpp
|
||||
main_tests/logistic_regression_test.cpp
|
||||
main_tests/local_coordinate_coding_test.cpp
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::data;
|
||||
@@ -43,7 +45,11 @@ BOOST_AUTO_TEST_CASE(LoadImageAPITest)
|
||||
arma::Mat<unsigned char> matrix;
|
||||
data::ImageInfo info;
|
||||
BOOST_REQUIRE(data::Load("test_image.png", matrix, info, false) == true);
|
||||
BOOST_REQUIRE_EQUAL(matrix.n_rows, 50 * 50 * 3); // width * height * channels.
|
||||
// width * height * channels.
|
||||
BOOST_REQUIRE_EQUAL(matrix.n_rows, 50 * 50 * 3);
|
||||
BOOST_REQUIRE_EQUAL(info.Height(), 50);
|
||||
BOOST_REQUIRE_EQUAL(info.Width(), 50);
|
||||
BOOST_REQUIRE_EQUAL(info.Channels(), 3);
|
||||
BOOST_REQUIRE_EQUAL(matrix.n_cols, 1);
|
||||
}
|
||||
|
||||
@@ -64,8 +70,91 @@ BOOST_AUTO_TEST_CASE(SaveImageAPITest)
|
||||
|
||||
BOOST_REQUIRE_EQUAL(im1.n_cols, im2.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(im1.n_rows, im2.n_rows);
|
||||
for (size_t i = 10; i < im1.n_elem; ++i)
|
||||
for (size_t i = 0; i < im1.n_elem; ++i)
|
||||
BOOST_REQUIRE_EQUAL(im1[i], im2[i]);
|
||||
remove("APITest.bmp");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if an image with a wrong dimesion throws an expected
|
||||
* exception while saving.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SaveImageWrongInfo)
|
||||
{
|
||||
data::ImageInfo info(5, 5, 3, 90);
|
||||
|
||||
arma::Mat<unsigned char> im1;
|
||||
size_t dimension = info.Width() * info.Height() * info.Channels();
|
||||
im1 = arma::randi<arma::Mat<unsigned char>>(24 * 25 * 7, 1);
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(data::Save("APITest.bmp", im1, info, false),
|
||||
std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the image is loaded correctly into the matrix using the API
|
||||
* for vectors.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(LoadVectorImageAPITest)
|
||||
{
|
||||
arma::Mat<unsigned char> matrix;
|
||||
data::ImageInfo info;
|
||||
std::vector<std::string> files = {"test_image.png", "test_image.png"};
|
||||
BOOST_REQUIRE(data::Load(files, matrix, info, false) == true);
|
||||
// width * height * channels.
|
||||
BOOST_REQUIRE_EQUAL(matrix.n_rows, 50 * 50 * 3);
|
||||
BOOST_REQUIRE_EQUAL(info.Height(), 50);
|
||||
BOOST_REQUIRE_EQUAL(info.Width(), 50);
|
||||
BOOST_REQUIRE_EQUAL(info.Channels(), 3);
|
||||
BOOST_REQUIRE_EQUAL(matrix.n_cols, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the image is saved correctly using API for arma mat.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SaveImageMatAPITest)
|
||||
{
|
||||
data::ImageInfo info(5, 5, 3);
|
||||
|
||||
arma::Mat<unsigned char> im1;
|
||||
size_t dimension = info.Width() * info.Height() * info.Channels();
|
||||
im1 = arma::randi<arma::Mat<unsigned char>>(dimension, 1);
|
||||
arma::mat input = arma::conv_to<arma::mat>::from(im1);
|
||||
BOOST_REQUIRE(Save("APITest.bmp", input, info, false) == true);
|
||||
|
||||
arma::mat output;
|
||||
BOOST_REQUIRE(Load("APITest.bmp", output, info, false) == true);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(input.n_cols, output.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(input.n_rows, output.n_rows);
|
||||
for (size_t i = 0; i < input.n_elem; ++i)
|
||||
BOOST_REQUIRE_CLOSE(input[i], output[i], 1e-5);
|
||||
remove("APITest.bmp");
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization test for the ImageInfo class.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ImageInfoSerialization)
|
||||
{
|
||||
data::ImageInfo info(5, 5, 3, 90);
|
||||
data::ImageInfo xmlInfo, textInfo, binaryInfo;
|
||||
|
||||
SerializeObjectAll(info, xmlInfo, textInfo, binaryInfo);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(info.Width(), xmlInfo.Width());
|
||||
BOOST_REQUIRE_EQUAL(info.Height(), xmlInfo.Height());
|
||||
BOOST_REQUIRE_EQUAL(info.Channels(), xmlInfo.Channels());
|
||||
BOOST_REQUIRE_EQUAL(info.Quality(), xmlInfo.Quality());
|
||||
BOOST_REQUIRE_EQUAL(info.Width(), textInfo.Width());
|
||||
BOOST_REQUIRE_EQUAL(info.Height(), textInfo.Height());
|
||||
BOOST_REQUIRE_EQUAL(info.Channels(), textInfo.Channels());
|
||||
BOOST_REQUIRE_EQUAL(info.Quality(), textInfo.Quality());
|
||||
BOOST_REQUIRE_EQUAL(info.Width(), binaryInfo.Width());
|
||||
BOOST_REQUIRE_EQUAL(info.Height(), binaryInfo.Height());
|
||||
BOOST_REQUIRE_EQUAL(info.Channels(), binaryInfo.Channels());
|
||||
BOOST_REQUIRE_EQUAL(info.Quality(), binaryInfo.Quality());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -1002,4 +1002,25 @@ BOOST_AUTO_TEST_CASE(LogisticRegressionTrainReturnObjective)
|
||||
BOOST_REQUIRE_EQUAL(std::isfinite(objVal), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that construction *then* training works fine. Thanks @Trento89 for the
|
||||
* test case (see #2358).
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(ConstructionThenTraining)
|
||||
{
|
||||
arma::mat myMatrix;
|
||||
|
||||
// Four points, three dimensions.
|
||||
myMatrix << 0.555950 << 0.274690 << 0.540605 << 0.798938 << arma::endr
|
||||
<< 0.948014 << 0.973234 << 0.216504 << 0.883152 << arma::endr
|
||||
<< 0.023787 << 0.675382 << 0.231751 << 0.450332 << arma::endr;
|
||||
|
||||
arma::Row<size_t> myTargets("1 0 1 0");
|
||||
|
||||
regression::LogisticRegression<> lr;
|
||||
|
||||
// Make sure that training doesn't crash with invalid parameter sizes.
|
||||
BOOST_REQUIRE_NO_THROW(lr.Train(myMatrix, myTargets));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -22,11 +22,13 @@
|
||||
#include <mlpack/methods/ann/loss_functions/sigmoid_cross_entropy_error.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/cross_entropy_error.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/reconstruction_loss.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/margin_ranking_loss.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/mean_squared_logarithmic_error.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/mean_bias_error.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/dice_loss.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/log_cosh_loss.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/hinge_embedding_loss.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/cosine_embedding_loss.hpp>
|
||||
#include <mlpack/methods/ann/init_rules/nguyen_widrow_init.hpp>
|
||||
#include <mlpack/methods/ann/ffn.hpp>
|
||||
|
||||
@@ -578,4 +580,135 @@ BOOST_AUTO_TEST_CASE(HingeEmbeddingLossTest)
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, input.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, input.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the Cosine Embedding loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(CosineEmbeddingLossTest)
|
||||
{
|
||||
arma::mat input1, input2, y, output;
|
||||
double loss;
|
||||
CosineEmbeddingLoss<> module;
|
||||
|
||||
// Test the Forward function. Loss should be 0 if input1 = input2 and y = 1.
|
||||
input1 = arma::mat(1, 10);
|
||||
input2 = arma::mat(1, 10);
|
||||
input1.ones();
|
||||
input2.ones();
|
||||
y = arma::mat(1, 1);
|
||||
y.ones();
|
||||
loss = module.Forward(input1, input1);
|
||||
BOOST_REQUIRE_SMALL(loss, 1e-6);
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, input1, output);
|
||||
BOOST_REQUIRE_SMALL(arma::accu(output), 1e-6);
|
||||
|
||||
// Check for dissimilarity.
|
||||
module.Similarity() = false;
|
||||
loss = module.Forward(input1, input1);
|
||||
BOOST_REQUIRE_CLOSE(loss, 1.0, 1e-4);
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, input1, output);
|
||||
BOOST_REQUIRE_SMALL(arma::accu(output), 1e-6);
|
||||
|
||||
input1 = arma::mat(3, 2);
|
||||
input2 = arma::mat(3, 2);
|
||||
input1.fill(1);
|
||||
input1(4) = 2;
|
||||
input2.fill(1);
|
||||
input2(0) = 2;
|
||||
input2(1) = 2;
|
||||
input2(2) = 2;
|
||||
loss = module.Forward(input1, input2);
|
||||
// Calculated using torch.nn.CosineEmbeddingLoss().
|
||||
BOOST_REQUIRE_CLOSE(loss, 2.897367, 1e-3);
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input1, input2, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), 0.06324556, 1e-3);
|
||||
|
||||
// Check for correctness for cube.
|
||||
CosineEmbeddingLoss<> module2(0.5, true);
|
||||
|
||||
arma::cube input3(3, 2, 2);
|
||||
arma::cube input4(3, 2, 2);
|
||||
input3.fill(1);
|
||||
input4.fill(1);
|
||||
input3(0) = 2;
|
||||
input3(1) = 2;
|
||||
input3(4) = 2;
|
||||
input3(6) = 2;
|
||||
input3(8) = 2;
|
||||
input3(10) = 2;
|
||||
input4(2) = 2;
|
||||
input4(9) = 2;
|
||||
input4(11) = 2;
|
||||
loss = module2.Forward(input3, input4);
|
||||
// Calculated using torch.nn.CosineEmbeddingLoss().
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.55395, 1e-3);
|
||||
|
||||
// Test the Backward function.
|
||||
module2.Backward(input3, input4, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), -0.36649111, 1e-3);
|
||||
|
||||
// Check Output for mean type of reduction.
|
||||
CosineEmbeddingLoss<> module3(0.0, true, true);
|
||||
loss = module3.Forward(input3, input4);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.092325, 1e-3);
|
||||
|
||||
// Check correctness for cube.
|
||||
module3.Similarity() = false;
|
||||
loss = module3.Forward(input3, input4);
|
||||
BOOST_REQUIRE_CLOSE(loss, 0.90767498236, 1e-3);
|
||||
|
||||
// Test the Backward function.
|
||||
module3.Backward(input3, input4, output);
|
||||
BOOST_REQUIRE_CLOSE(arma::accu(output), 0.36649111, 1e-4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test for the Margin Ranking Loss function.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(MarginRankingLossTest)
|
||||
{
|
||||
arma::mat input, input1, input2, target, output;
|
||||
MarginRankingLoss<> module;
|
||||
|
||||
// Test the Forward function on a user generator input and compare it against
|
||||
// the manually calculated result.
|
||||
input1 = arma::mat("1 2 5 7 -1 -3");
|
||||
input2 = arma::mat("-1 3 -4 11 3 -3");
|
||||
input = arma::join_cols(input1, input2);
|
||||
target = arma::mat("1 -1 -1 1 -1 1");
|
||||
double error = module.Forward(input, target);
|
||||
// Computed using torch.nn.functional.margin_ranking_loss()
|
||||
BOOST_REQUIRE_CLOSE(error, 2.66667, 1e-3);
|
||||
|
||||
// Test the Backward function.
|
||||
module.Backward(input, target, output);
|
||||
|
||||
CheckMatrices(output, arma::mat("-0.000000 0.166667 -1.500000 0.666667 "
|
||||
"0.000000 -0.000000"), 1e-3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, target.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, target.n_cols);
|
||||
|
||||
// Test the error function on another input.
|
||||
input1 = arma::mat("0.4287 -1.6208 -1.5006 -0.4473 1.5208 -4.5184 9.3574 "
|
||||
"-4.8090 4.3455 5.2070");
|
||||
input2 = arma::mat("-4.5288 -9.2766 -0.5882 -5.6643 -6.0175 8.8506 3.4759 "
|
||||
"-9.4886 2.2755 8.4951");
|
||||
input = arma::join_cols(input1, input2);
|
||||
target = arma::mat("1 1 -1 1 -1 1 1 1 -1 1");
|
||||
error = module.Forward(input, target);
|
||||
BOOST_REQUIRE_CLOSE(error, 3.03530, 1e-3);
|
||||
|
||||
// Test the Backward function on the second input.
|
||||
module.Backward(input, target, output);
|
||||
|
||||
CheckMatrices(output, arma::mat("0.000000 0.000000 0.091240 0.000000 "
|
||||
"-0.753830 1.336900 0.000000 0.000000 -0.207000 0.328810"), 1e-6);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* @file image_converter_test.cpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* Test mlpackMain() of load_save_image_main.cpp.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#define BINDING_TYPE BINDING_TYPE_TEST
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
static const std::string testName = "ImageConverter";
|
||||
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/methods/preprocess/image_converter_main.cpp>
|
||||
|
||||
#include "test_helper.hpp"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "../test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
struct ImageConverterTestFixture
|
||||
{
|
||||
public:
|
||||
ImageConverterTestFixture()
|
||||
{
|
||||
// Cache in the options for this program.
|
||||
CLI::RestoreSettings(testName);
|
||||
}
|
||||
|
||||
~ImageConverterTestFixture()
|
||||
{
|
||||
// Clear the settings.
|
||||
remove("test_image777.png");
|
||||
remove("test_image999.png");
|
||||
bindings::tests::CleanMemory();
|
||||
CLI::ClearSettings();
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(ImageConverterMainTest,
|
||||
ImageConverterTestFixture);
|
||||
|
||||
BOOST_AUTO_TEST_CASE(LoadImageTest)
|
||||
{
|
||||
SetInputParam<vector<string>>("input", {"test_image.png", "test_image.png"});
|
||||
|
||||
mlpackMain();
|
||||
arma::mat output = CLI::GetParam<arma::mat>("output");
|
||||
// width * height * channels.
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, 50 * 50 * 3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SaveImageTest)
|
||||
{
|
||||
arma::mat testimage = arma::conv_to<arma::mat>::from(
|
||||
arma::randi<arma::Mat<unsigned char>>((5 * 5 * 3), 2));
|
||||
SetInputParam<vector<string>>("input", {"test_image777.png",
|
||||
"test_image999.png"});
|
||||
SetInputParam("height", 5);
|
||||
SetInputParam("width", 5);
|
||||
SetInputParam("channels", 3);
|
||||
SetInputParam("save", true);
|
||||
SetInputParam("dataset", testimage);
|
||||
mlpackMain();
|
||||
|
||||
CLI::ClearSettings();
|
||||
CLI::RestoreSettings(testName);
|
||||
|
||||
SetInputParam<vector<string>>("input", {"test_image777.png",
|
||||
"test_image999.png"});
|
||||
SetInputParam("height", 5);
|
||||
SetInputParam("width", 5);
|
||||
SetInputParam("channels", 3);
|
||||
|
||||
mlpackMain();
|
||||
arma::mat output = CLI::GetParam<arma::mat>("output");
|
||||
BOOST_REQUIRE_EQUAL(output.n_rows, 5 * 5 * 3);
|
||||
BOOST_REQUIRE_EQUAL(output.n_cols, 2);
|
||||
for (size_t i = 0; i < output.n_elem; ++i)
|
||||
BOOST_REQUIRE_CLOSE(testimage[i], output[i], 1e-5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether binding throws error if height, width or channel are not
|
||||
* specified.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(IncompleteTest)
|
||||
{
|
||||
arma::mat testimage = arma::conv_to<arma::mat>::from(
|
||||
arma::randi<arma::Mat<unsigned char>>((5 * 5 * 3), 2));
|
||||
SetInputParam<vector<string>>("input", {"test_image777.png",
|
||||
"test_image999.png"});
|
||||
SetInputParam("save", true);
|
||||
SetInputParam("height", 50);
|
||||
SetInputParam("width", 50);
|
||||
SetInputParam("dataset", testimage);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for invalid height values.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(InvalidInputTest)
|
||||
{
|
||||
arma::mat testimage = arma::conv_to<arma::mat>::from(
|
||||
arma::randi<arma::Mat<unsigned char>>((5 * 5 * 3), 2));
|
||||
SetInputParam<vector<string>>("input", {"test_image777.png",
|
||||
"test_image999.png"});
|
||||
SetInputParam("save", true);
|
||||
SetInputParam("dataset", testimage);
|
||||
|
||||
SetInputParam("height", -50);
|
||||
SetInputParam("width", 50);
|
||||
SetInputParam("channels", 3);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for invalid width values.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(InvalidWidthTest)
|
||||
{
|
||||
arma::mat testimage = arma::conv_to<arma::mat>::from(
|
||||
arma::randi<arma::Mat<unsigned char>>((5 * 5 * 3), 2));
|
||||
SetInputParam<vector<string>>("input", {"test_image777.png",
|
||||
"test_image999.png"});
|
||||
SetInputParam("save", true);
|
||||
SetInputParam("dataset", testimage);
|
||||
SetInputParam("height", 50);
|
||||
SetInputParam("width", -50);
|
||||
SetInputParam("channels", 3);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for invalid channel values.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(InvalidChannelTest)
|
||||
{
|
||||
arma::mat testimage = arma::conv_to<arma::mat>::from(
|
||||
arma::randi<arma::Mat<unsigned char>>((5 * 5 * 3), 2));
|
||||
SetInputParam<vector<string>>("input", {"test_image777.png",
|
||||
"test_image999.png"});
|
||||
SetInputParam("save", true);
|
||||
SetInputParam("dataset", testimage);
|
||||
SetInputParam("height", 50);
|
||||
SetInputParam("width", 50);
|
||||
SetInputParam("channels", -1);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for invalid input values.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(EmptyInputTest)
|
||||
{
|
||||
SetInputParam<vector<string>>("input", {});
|
||||
SetInputParam("height", 50);
|
||||
SetInputParam("width", 50);
|
||||
SetInputParam("channels", 50);
|
||||
|
||||
Log::Fatal.ignoreInput = true;
|
||||
BOOST_REQUIRE_THROW(mlpackMain(), std::runtime_error);
|
||||
Log::Fatal.ignoreInput = false;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <mlpack/methods/ann/layer/layer.hpp>
|
||||
#include <mlpack/methods/ann/loss_functions/mean_squared_error.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/q_learning.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/q_networks/simple_dqn.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/environment/mountain_car.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/environment/acrobot.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/environment/cart_pole.hpp>
|
||||
@@ -41,13 +42,7 @@ BOOST_AUTO_TEST_SUITE(QLearningTest);
|
||||
BOOST_AUTO_TEST_CASE(CartPoleWithDQN)
|
||||
{
|
||||
// Set up the network.
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(4, 128);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(128, 128);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(128, 2);
|
||||
SimpleDQN<> model(4, 128, 128, 2);
|
||||
|
||||
// Set up the policy and replay method.
|
||||
GreedyPolicy<CartPole> policy(1.0, 1000, 0.1, 0.99);
|
||||
@@ -107,13 +102,7 @@ BOOST_AUTO_TEST_CASE(CartPoleWithDQN)
|
||||
BOOST_AUTO_TEST_CASE(CartPoleWithDQNPrioritizedReplay)
|
||||
{
|
||||
// Set up the network.
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(4, 128);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(128, 128);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(128, 2);
|
||||
SimpleDQN<> model(4, 128, 128, 2);
|
||||
|
||||
// Set up the policy and replay method.
|
||||
GreedyPolicy<CartPole> policy(1.0, 1000, 0.1);
|
||||
@@ -182,13 +171,7 @@ BOOST_AUTO_TEST_CASE(CartPoleWithDoubleDQN)
|
||||
for (size_t trial = 0; trial < 4; ++trial)
|
||||
{
|
||||
// Set up the network.
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(4, 20);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(20, 20);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(20, 2);
|
||||
SimpleDQN<> model(4, 20, 20, 2);
|
||||
|
||||
// Set up the policy and replay method.
|
||||
GreedyPolicy<CartPole> policy(1.0, 1000, 0.1, 0.99);
|
||||
@@ -251,13 +234,7 @@ BOOST_AUTO_TEST_CASE(AcrobotWithDQN)
|
||||
for (size_t trial = 0; trial < 3; ++trial)
|
||||
{
|
||||
// Set up the network.
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(4, 64);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(64, 32);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(32, 3);
|
||||
SimpleDQN<> model(4, 64, 32, 3);
|
||||
|
||||
// Set up the policy and replay method.
|
||||
GreedyPolicy<Acrobot> policy(1.0, 1000, 0.1, 0.99);
|
||||
@@ -328,13 +305,7 @@ BOOST_AUTO_TEST_CASE(MountainCarWithDQN)
|
||||
for (size_t trial = 0; trial < 3; trial++)
|
||||
{
|
||||
// Set up the network.
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(2, 64);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(64, 32);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(32, 3);
|
||||
SimpleDQN<> model(2, 64, 32, 3);
|
||||
|
||||
// Set up the policy and replay method.
|
||||
GreedyPolicy<MountainCar> policy(1.0, 1000, 0.1, 0.99);
|
||||
@@ -404,7 +375,8 @@ BOOST_AUTO_TEST_CASE(DoublePoleCartWithDQN)
|
||||
bool success = false;
|
||||
for (size_t trial = 0; trial < 4; trial++)
|
||||
{
|
||||
// Set up the network.
|
||||
// Set up the network. Note that we use a custom model here, and
|
||||
// pass it directly into the agent, without using SimpleDQN.
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(6, 256);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <mlpack/methods/reinforcement_learning/environment/mountain_car.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/q_networks/simple_dqn.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/environment/continuous_mountain_car.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/environment/cart_pole.hpp>
|
||||
#include <mlpack/methods/reinforcement_learning/environment/acrobot.hpp>
|
||||
@@ -63,13 +64,7 @@ BOOST_AUTO_TEST_CASE(RewardClippedAcrobotWithDQN)
|
||||
for (size_t trial = 0; trial < 3; ++trial)
|
||||
{
|
||||
// Set up the network.
|
||||
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(),
|
||||
GaussianInitialization(0, 0.001));
|
||||
model.Add<Linear<>>(4, 64);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(64, 32);
|
||||
model.Add<ReLULayer<>>();
|
||||
model.Add<Linear<>>(32, 3);
|
||||
SimpleDQN<> model(4, 64, 32, 3);
|
||||
|
||||
// Set up the policy and replay method.
|
||||
GreedyPolicy<RewardClipping<Acrobot>> policy(1.0, 1000, 0.1, 0.99);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <mlpack/core/data/tokenizers/char_extract.hpp>
|
||||
#include <mlpack/core/data/string_encoding.hpp>
|
||||
#include <mlpack/core/data/string_encoding_policies/dictionary_encoding_policy.hpp>
|
||||
#include <mlpack/core/data/string_encoding_policies/bag_of_words_encoding_policy.hpp>
|
||||
#include <mlpack/core/data/string_encoding_policies/tf_idf_encoding_policy.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <memory>
|
||||
#include "test_tools.hpp"
|
||||
@@ -54,6 +56,25 @@ static vector<string> stringEncodingUtf8Input = {
|
||||
"\xE2\x93\x82\xE2\x93\x81\xE2\x93\x85\xE2\x92\xB6\xE2\x92\xB8\xE2\x93\x80"
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the values of two 2D vectors.
|
||||
*/
|
||||
template<typename ValueType>
|
||||
void CheckVectors(const vector<vector<ValueType>>& a,
|
||||
const vector<vector<ValueType>>& b,
|
||||
const ValueType tolerance = 1e-5)
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(a.size(), b.size());
|
||||
|
||||
for (size_t i = 0; i < a.size(); i++)
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(a[i].size(), b[i].size());
|
||||
|
||||
for (size_t j = 0; j < a[i].size(); j++)
|
||||
BOOST_REQUIRE_CLOSE(a[i][j], b[i][j], tolerance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the dictionary encoding algorithm.
|
||||
*/
|
||||
@@ -88,7 +109,7 @@ BOOST_AUTO_TEST_CASE(DictionaryEncodingTest)
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, expected);
|
||||
CheckMatrices(output, expected.t());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +143,7 @@ BOOST_AUTO_TEST_CASE(UnicodeDictionaryEncodingTest)
|
||||
{ 5, 2, 3, 5, 4 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, expected);
|
||||
CheckMatrices(output, expected.t());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,8 +243,8 @@ BOOST_AUTO_TEST_CASE(SplitByAnyOfTokenizerUnicodeTest)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the CharExtract tokenizer.
|
||||
*/
|
||||
* Test the CharExtract tokenizer.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DictionaryEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
@@ -242,7 +263,7 @@ BOOST_AUTO_TEST_CASE(DictionaryEncodingIndividualCharactersTest)
|
||||
{ 2, 4, 3, 2, 4, 3, 5 },
|
||||
{ 1, 2, 4, 0, 0, 0, 0 }
|
||||
};
|
||||
CheckMatrices(output, target);
|
||||
CheckMatrices(output, target.t());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -520,5 +541,889 @@ BOOST_AUTO_TEST_CASE(CharExtractDictionaryEncodingSerialization)
|
||||
CheckMatrices(output, xmlOutput, textOutput, binaryOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Bag of Words encoding algorithm.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(BagOfWordsEncodingTest)
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
arma::mat output;
|
||||
BagOfWordsEncoding<SplitByAnyOf::TokenType> encoder;
|
||||
SplitByAnyOf tokenizer(" ,.");
|
||||
|
||||
encoder.Encode(stringEncodingInput, output, tokenizer);
|
||||
|
||||
const DictionaryType& dictionary = encoder.Dictionary();
|
||||
|
||||
// Checking that each token has a unique label.
|
||||
std::unordered_map<size_t, size_t> keysCount;
|
||||
|
||||
for (auto& keyValue : dictionary.Mapping())
|
||||
{
|
||||
keysCount[keyValue.second]++;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1);
|
||||
}
|
||||
|
||||
/* The expected values were obtained by the following Python script:
|
||||
|
||||
from sklearn.feature_extraction.text import CountVectorizer
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
|
||||
string_encoding_input = [
|
||||
"mlpack is an intuitive, fast, and flexible C++ machine learning library "
|
||||
"with bindings to other languages. ",
|
||||
"It is meant to be a machine learning analog to LAPACK, and aims to "
|
||||
"implement a wide array of machine learning methods and functions "
|
||||
"as a \"swiss army knife\" for machine learning researchers.",
|
||||
"In addition to its powerful C++ interface, mlpack also provides "
|
||||
"command-line programs and Python bindings."
|
||||
]
|
||||
|
||||
dictionary = OrderedDict()
|
||||
|
||||
count = 0
|
||||
for line in string_encoding_input:
|
||||
for word in re.split(' |,|\.', line):
|
||||
if word and (not (word in dictionary)):
|
||||
dictionary[word] = count
|
||||
count += 1
|
||||
|
||||
def tokenizer(line):
|
||||
return re.split(' |,|\.', line)
|
||||
|
||||
vectorizer = CountVectorizer(strip_accents=False, lowercase=False,
|
||||
preprocessor=None, tokenizer=tokenizer, stop_words=None,
|
||||
vocabulary=dictionary, binary=False)
|
||||
|
||||
X = vectorizer.fit_transform(string_encoding_input)
|
||||
|
||||
for row in X.toarray():
|
||||
print("{ " + ", ".join(map(str, row)) + " },")
|
||||
*/
|
||||
|
||||
arma::mat expected = {
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 1, 0, 0, 0, 2, 0, 0, 3, 3, 0, 0, 0, 3, 0, 0, 1, 1, 1, 3, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, expected.t());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Bag of Words encoding algorithm. The output is saved into a vector.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingTest)
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
vector<vector<size_t>> output;
|
||||
BagOfWordsEncoding<SplitByAnyOf::TokenType> encoder(
|
||||
(BagOfWordsEncodingPolicy()));
|
||||
SplitByAnyOf tokenizer(" ,.");
|
||||
|
||||
encoder.Encode(stringEncodingInput, output, tokenizer);
|
||||
|
||||
const DictionaryType& dictionary = encoder.Dictionary();
|
||||
|
||||
// Checking that each token has a unique label.
|
||||
std::unordered_map<size_t, size_t> keysCount;
|
||||
|
||||
for (auto& keyValue : dictionary.Mapping())
|
||||
{
|
||||
keysCount[keyValue.second]++;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1);
|
||||
}
|
||||
|
||||
/* The expected values were obtained by the same script as in
|
||||
BagOfWordsEncodingTest. */
|
||||
vector<vector<size_t>> expected = {
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 1, 0, 0, 0, 2, 0, 0, 3, 3, 0, 0, 0, 3, 0, 0, 1, 1, 1, 3, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
|
||||
};
|
||||
|
||||
BOOST_REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Bag of Words algorithm for individual characters.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(BagOfWordsEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
BagOfWordsEncoding<CharExtract::TokenType> encoder;
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
arma::mat target = {
|
||||
{ 1, 2, 2, 0, 0 },
|
||||
{ 0, 2, 2, 2, 1 },
|
||||
{ 1, 1, 0, 1, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Bag of Words encoding algorithm in case of individual
|
||||
* characters encoding. The output type is vector<vector<size_t>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorBagOfWordsEncodingIndividualCharactersTest)
|
||||
{
|
||||
std::vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
vector<vector<size_t>> output;
|
||||
BagOfWordsEncoding<CharExtract::TokenType> encoder;
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
vector<vector<size_t>> expected = {
|
||||
{ 1, 2, 2, 0, 0 },
|
||||
{ 0, 2, 2, 2, 1 },
|
||||
{ 1, 1, 0, 1, 0 }
|
||||
};
|
||||
|
||||
BOOST_REQUIRE(output == expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm with the raw count term frequency type
|
||||
* and the smooth inverse document frequency type. These parameters are
|
||||
* the default ones.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingTest)
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<SplitByAnyOf::TokenType> encoder;
|
||||
SplitByAnyOf tokenizer(" ,.");
|
||||
|
||||
encoder.Encode(stringEncodingInput, output, tokenizer);
|
||||
const DictionaryType& dictionary = encoder.Dictionary();
|
||||
|
||||
// Checking that each token has a unique label.
|
||||
std::unordered_map<size_t, size_t> keysCount;
|
||||
|
||||
for (auto& keyValue : dictionary.Mapping())
|
||||
{
|
||||
keysCount[keyValue.second]++;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1);
|
||||
}
|
||||
|
||||
/* The expected values were obtained by the following Python script:
|
||||
|
||||
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
|
||||
string_encoding_input = [
|
||||
"mlpack is an intuitive, fast, and flexible C++ machine learning library "
|
||||
"with bindings to other languages. ",
|
||||
"It is meant to be a machine learning analog to LAPACK, and aims to "
|
||||
"implement a wide array of machine learning methods and functions "
|
||||
"as a \"swiss army knife\" for machine learning researchers.",
|
||||
"In addition to its powerful C++ interface, mlpack also provides "
|
||||
"command-line programs and Python bindings."
|
||||
]
|
||||
|
||||
smooth_idf = True
|
||||
tf_type = 'raw_count'
|
||||
|
||||
dictionary = OrderedDict()
|
||||
|
||||
count = 0
|
||||
for line in string_encoding_input:
|
||||
for word in re.split(' |,|\.', line):
|
||||
if word and (not (word in dictionary)):
|
||||
dictionary[word] = count
|
||||
count += 1
|
||||
|
||||
def tokenizer(line):
|
||||
return re.split(' |,|\.', line)
|
||||
|
||||
if tf_type == 'raw_count':
|
||||
binary = False
|
||||
sublinear_tf = False
|
||||
elif tf_type == 'binary':
|
||||
binary = True
|
||||
sublinear_tf = False
|
||||
elif tf_type == 'sublinear_tf':
|
||||
binary = False
|
||||
sublinear_tf = True
|
||||
|
||||
vectorizer = TfidfVectorizer(strip_accents=False, lowercase=False,
|
||||
preprocessor=None, tokenizer=tokenizer, stop_words=None,
|
||||
vocabulary=dictionary, binary=binary, norm=None, smooth_idf=smooth_idf,
|
||||
sublinear_tf=sublinear_tf)
|
||||
|
||||
X = vectorizer.fit_transform(string_encoding_input)
|
||||
|
||||
def format_result(value):
|
||||
if value == int(value):
|
||||
return str(int(value))
|
||||
else:
|
||||
return "{0:.8f}".format(value)
|
||||
|
||||
for row in X.toarray():
|
||||
print("{ " + ", ".join(map(format_result, row)) + " },")
|
||||
*/
|
||||
arma::mat expected = {
|
||||
{ 1.28768207, 1.28768207, 1.69314718, 1.69314718, 1.69314718, 1, 1.69314718,
|
||||
1.28768207, 1.28768207, 1.28768207, 1.69314718, 1.69314718, 1.28768207, 1,
|
||||
1.69314718, 1.69314718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 1.28768207, 0, 0, 0, 2, 0, 0, 3.86304622, 3.86304622, 0, 0, 0, 3, 0,
|
||||
0, 1.69314718, 1.69314718, 1.69314718, 5.07944154, 1.69314718, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718,
|
||||
1.69314718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 1.28768207, 0, 0, 0, 0, 1, 0, 1.28768207, 0, 0, 0, 0, 1.28768207, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, expected.t(), 1e-6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm with the raw count term frequency type
|
||||
* and the smooth inverse document frequency type. These parameters are
|
||||
* the default ones. The output type is vector<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingTest)
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
vector<vector<double>> output;
|
||||
TfIdfEncoding<SplitByAnyOf::TokenType> encoder(
|
||||
(TfIdfEncodingPolicy()));
|
||||
SplitByAnyOf tokenizer(" ,.");
|
||||
|
||||
encoder.Encode(stringEncodingInput, output, tokenizer);
|
||||
|
||||
const DictionaryType& dictionary = encoder.Dictionary();
|
||||
|
||||
// Checking that each token has a unique label.
|
||||
std::unordered_map<size_t, size_t> keysCount;
|
||||
|
||||
for (auto& keyValue : dictionary.Mapping())
|
||||
{
|
||||
keysCount[keyValue.second]++;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1);
|
||||
}
|
||||
|
||||
/* The expected values were obtained by the same script as in
|
||||
RawCountSmoothIdfEncodingTest. */
|
||||
vector<vector<double>> expected = {
|
||||
{ 1.28768207, 1.28768207, 1.69314718, 1.69314718, 1.69314718, 1, 1.69314718,
|
||||
1.28768207, 1.28768207, 1.28768207, 1.69314718, 1.69314718, 1.28768207, 1,
|
||||
1.69314718, 1.69314718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 1.28768207, 0, 0, 0, 2, 0, 0, 3.86304622, 3.86304622, 0, 0, 0, 3, 0,
|
||||
0, 1.69314718, 1.69314718, 1.69314718, 5.07944154, 1.69314718, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718,
|
||||
1.69314718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 1.28768207, 0, 0, 0, 0, 1, 0, 1.28768207, 0, 0, 0, 0, 1.28768207, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718, 1.69314718,
|
||||
1.69314718, 1.69314718, 1.69314718 }
|
||||
};
|
||||
CheckVectors(output, expected, 1e-6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* raw count term frequency type and the smooth inverse document frequency type.
|
||||
* These parameters are the default ones.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RawCountSmoothIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder;
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by the following Python script:
|
||||
|
||||
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
|
||||
input_string = [
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
]
|
||||
|
||||
smooth_idf = True
|
||||
tf_type = 'raw_count'
|
||||
|
||||
dictionary = OrderedDict()
|
||||
|
||||
count = 0
|
||||
for line in input_string:
|
||||
for word in list(line):
|
||||
if word and (not (word in dictionary)):
|
||||
dictionary[word] = count
|
||||
count += 1
|
||||
|
||||
def tokenizer(line):
|
||||
return list(line)
|
||||
|
||||
if tf_type == 'raw_count':
|
||||
binary = False
|
||||
sublinear_tf = False
|
||||
elif tf_type == 'binary':
|
||||
binary = True
|
||||
sublinear_tf = False
|
||||
elif tf_type == 'sublinear_tf':
|
||||
binary = False
|
||||
sublinear_tf = True
|
||||
|
||||
vectorizer = TfidfVectorizer(strip_accents=False, lowercase=False,
|
||||
preprocessor=None, tokenizer=tokenizer, stop_words=None,
|
||||
vocabulary=dictionary, binary=binary, norm=None, smooth_idf=smooth_idf,
|
||||
sublinear_tf=sublinear_tf)
|
||||
|
||||
X = vectorizer.fit_transform(input_string)
|
||||
|
||||
def format_result(value):
|
||||
if value == int(value):
|
||||
return str(int(value))
|
||||
else:
|
||||
return "{0:.14f}".format(value)
|
||||
|
||||
for row in X.toarray():
|
||||
print("{ " + ", ".join(map(format_result, row)) + " },")
|
||||
*/
|
||||
arma::mat target = {
|
||||
{ 1.28768207245178, 2, 2.57536414490356, 0, 0 },
|
||||
{ 0, 2, 2.57536414490356, 2.57536414490356, 1.69314718055995 },
|
||||
{ 1.28768207245178, 1, 0, 1.28768207245178, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* raw count term frequency type and the smooth inverse document frequency type.
|
||||
* These parameters are the default ones. The output type is
|
||||
* vector<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorRawCountSmoothIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
std::vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
vector<vector<double>> output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder;
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. */
|
||||
vector<vector<double>> expected = {
|
||||
{ 1.28768207245178, 2, 2.57536414490356, 0, 0 },
|
||||
{ 0, 2, 2.57536414490356, 2.57536414490356, 1.69314718055995 },
|
||||
{ 1.28768207245178, 1, 0, 1.28768207245178, 0 }
|
||||
};
|
||||
|
||||
CheckVectors(output, expected, 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm with the raw count term frequency type
|
||||
* and the non-smooth inverse document frequency type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(TfIdfRawCountEncodingTest)
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<SplitByAnyOf::TokenType> encoder(
|
||||
TfIdfEncodingPolicy(TfIdfEncodingPolicy::TfTypes::RAW_COUNT, false));
|
||||
SplitByAnyOf tokenizer(" ,.");
|
||||
|
||||
encoder.Encode(stringEncodingInput, output, tokenizer);
|
||||
|
||||
const DictionaryType& dictionary = encoder.Dictionary();
|
||||
|
||||
// Checking that each token has a unique label.
|
||||
std::unordered_map<size_t, size_t> keysCount;
|
||||
|
||||
for (auto& keyValue : dictionary.Mapping())
|
||||
{
|
||||
keysCount[keyValue.second]++;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1);
|
||||
}
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingTest. The only difference is smooth_idf equals
|
||||
False. */
|
||||
arma::mat expected = {
|
||||
{ 1.40546511, 1.40546511, 2.09861229, 2.09861229, 2.09861229, 1, 2.09861229,
|
||||
1.40546511, 1.40546511, 1.40546511, 2.09861229, 2.09861229, 1.40546511, 1,
|
||||
2.09861229, 2.09861229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 1.40546511, 0, 0, 0, 2, 0, 0, 4.21639532, 4.21639532, 0, 0, 0, 3, 0, 0,
|
||||
2.09861229, 2.09861229, 2.09861229, 6.29583687, 2.09861229, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229,
|
||||
2.09861229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 1.40546511, 0, 0, 0, 0, 1, 0, 1.40546511, 0, 0, 0, 0, 1.40546511, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, expected.t(), 1e-6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm with the raw count term frequency type
|
||||
* and the non-smooth inverse document frequency type. The output type is
|
||||
* vector<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorTfIdfRawCountEncodingTest)
|
||||
{
|
||||
using DictionaryType = StringEncodingDictionary<boost::string_view>;
|
||||
|
||||
vector<vector<double>> output;
|
||||
TfIdfEncoding<SplitByAnyOf::TokenType>
|
||||
encoder(TfIdfEncodingPolicy::TfTypes::RAW_COUNT, false);
|
||||
SplitByAnyOf tokenizer(" ,.");
|
||||
|
||||
encoder.Encode(stringEncodingInput, output, tokenizer);
|
||||
|
||||
const DictionaryType& dictionary = encoder.Dictionary();
|
||||
|
||||
// Checking that each token has a unique label.
|
||||
std::unordered_map<size_t, size_t> keysCount;
|
||||
for (auto& keyValue : dictionary.Mapping())
|
||||
{
|
||||
keysCount[keyValue.second]++;
|
||||
|
||||
BOOST_REQUIRE_EQUAL(keysCount[keyValue.second], 1);
|
||||
}
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingTest. The only difference is smooth_idf equals
|
||||
False. */
|
||||
vector<vector<double>> expected = {
|
||||
{ 1.40546511, 1.40546511, 2.09861229, 2.09861229, 2.09861229, 1, 2.09861229,
|
||||
1.40546511, 1.40546511, 1.40546511, 2.09861229, 2.09861229, 1.40546511, 1,
|
||||
2.09861229, 2.09861229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 1.40546511, 0, 0, 0, 2, 0, 0, 4.21639532, 4.21639532, 0, 0, 0, 3, 0, 0,
|
||||
2.09861229, 2.09861229, 2.09861229, 6.29583687, 2.09861229, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229,
|
||||
2.09861229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 1.40546511, 0, 0, 0, 0, 1, 0, 1.40546511, 0, 0, 0, 0, 1.40546511, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229, 2.09861229,
|
||||
2.09861229, 2.09861229, 2.09861229 }
|
||||
};
|
||||
CheckVectors(output, expected, 1e-6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* raw count term frequency type and the non-smooth inverse document frequency
|
||||
* type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(RawCountTfIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder(
|
||||
TfIdfEncodingPolicy::TfTypes::RAW_COUNT, false);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. The only difference is
|
||||
smooth_idf equals False. */
|
||||
arma::mat target = {
|
||||
{ 1.40546510810816, 2, 2.81093021621633, 0, 0 },
|
||||
{ 0, 2, 2.81093021621633, 2.81093021621633, 2.09861228866811 },
|
||||
{ 1.40546510810816, 1, 0, 1.40546510810816, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* raw count term frequency type and the non-smooth inverse document frequency
|
||||
* type. The output type is vector<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorRawCountTfIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
std::vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
vector<vector<double>> output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder(
|
||||
TfIdfEncodingPolicy::TfTypes::RAW_COUNT, false);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. The only difference is
|
||||
smooth_idf equals False. */
|
||||
vector<vector<double>> expected = {
|
||||
{ 1.40546510810816, 2, 2.81093021621633, 0, 0 },
|
||||
{ 0, 2, 2.81093021621633, 2.81093021621633, 2.09861228866811 },
|
||||
{ 1.40546510810816, 1, 0, 1.40546510810816, 0 }
|
||||
};
|
||||
|
||||
CheckVectors(output, expected, 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* binary term frequency type and the smooth inverse document frequency type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(BinarySmoothIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder(
|
||||
TfIdfEncodingPolicy::TfTypes::BINARY, true);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. The only difference is
|
||||
tf_type equals 'binary'. */
|
||||
arma::mat target = {
|
||||
{ 1.28768207245178, 1, 1.28768207245178, 0, 0 },
|
||||
{ 0, 1, 1.28768207245178, 1.28768207245178, 1.69314718055995 },
|
||||
{ 1.28768207245178, 1, 0, 1.28768207245178, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* binary term frequency type and the smooth inverse document frequency type.
|
||||
* The output type is vector<vector<double>>.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(VectorBinarySmoothIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
std::vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
vector<vector<double>> output;
|
||||
TfIdfEncoding<CharExtract::TokenType>
|
||||
encoder(TfIdfEncodingPolicy::TfTypes::BINARY, true);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. The only difference is
|
||||
tf_type equals 'binary'. */
|
||||
vector<vector<double>> expected = {
|
||||
{ 1.28768207245178, 1, 1.28768207245178, 0, 0 },
|
||||
{ 0, 1, 1.28768207245178, 1.28768207245178, 1.69314718055995 },
|
||||
{ 1.28768207245178, 1, 0, 1.28768207245178, 0 }
|
||||
};
|
||||
|
||||
CheckVectors(output, expected, 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* binary term frequency type and the non-smooth inverse document frequency
|
||||
* type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(BinaryTfIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder(
|
||||
TfIdfEncodingPolicy::TfTypes::BINARY, false);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. The only difference is
|
||||
tf_type equals 'binary' and smooth_idf equals False. */
|
||||
arma::mat target = {
|
||||
{ 1.40546510810816, 1, 1.40546510810816, 0, 0 },
|
||||
{ 0, 1, 1.40546510810816, 1.40546510810816, 2.09861228866811 },
|
||||
{ 1.40546510810816, 1, 0, 1.40546510810816, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* sublinear term frequency type and the smooth inverse document frequency
|
||||
* type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SublinearSmoothIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder(
|
||||
TfIdfEncodingPolicy::TfTypes::SUBLINEAR_TF, true);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. The only difference is
|
||||
tf_type equals 'sublinear_tf'. */
|
||||
arma::mat target = {
|
||||
{ 1.28768207245178, 1.69314718055995, 2.18023527042932, 0, 0 },
|
||||
{ 0, 1.69314718055995, 2.18023527042932, 2.18023527042932,
|
||||
1.69314718055995 },
|
||||
{ 1.28768207245178, 1, 0, 1.28768207245178, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* sublinear term frequency type and the non-smooth inverse document frequency
|
||||
* type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SublinearTfIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType>
|
||||
encoder(TfIdfEncodingPolicy::TfTypes::SUBLINEAR_TF, false);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
RawCountSmoothIdfEncodingIndividualCharactersTest. The only difference is
|
||||
tf_type equals 'sublinear_tf' and smooth_idf equals False. */
|
||||
arma::mat target = {
|
||||
{ 1.40546510810816, 1.69314718055995, 2.37965928516872, 0, 0 },
|
||||
{ 0, 1.69314718055995, 2.37965928516872, 2.37965928516872,
|
||||
2.09861228866811 },
|
||||
{ 1.40546510810816, 1, 0, 1.40546510810816, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* standard term frequency type and the smooth inverse document frequency
|
||||
* type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(TermFrequencySmoothIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder(
|
||||
TfIdfEncodingPolicy::TfTypes::TERM_FREQUENCY, true);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by the following Python script:
|
||||
|
||||
from sklearn.feature_extraction.text import CountVectorizer
|
||||
from sklearn.feature_extraction.text import TfidfTransformer
|
||||
from collections import OrderedDict
|
||||
import numpy as np
|
||||
import re
|
||||
|
||||
input_string = [
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
]
|
||||
|
||||
smooth_idf = True
|
||||
|
||||
dictionary = OrderedDict()
|
||||
|
||||
count = 0
|
||||
for line in input_string:
|
||||
for word in list(line):
|
||||
if word and (not (word in dictionary)):
|
||||
dictionary[word] = count
|
||||
count += 1
|
||||
|
||||
def tokenizer(line):
|
||||
return list(line)
|
||||
|
||||
vectorizer = CountVectorizer(strip_accents=False, lowercase=False,
|
||||
preprocessor=None, tokenizer=tokenizer, stop_words=None,
|
||||
vocabulary=dictionary, binary=False)
|
||||
|
||||
count = vectorizer.fit_transform(input_string)
|
||||
|
||||
lens = np.array(list(map(len, input_string))).reshape(len(input_string), 1)
|
||||
|
||||
tf = count.toarray() / lens
|
||||
|
||||
transformer = TfidfTransformer(norm=None, smooth_idf=smooth_idf,
|
||||
sublinear_tf=False)
|
||||
|
||||
X = transformer.fit_transform(tf)
|
||||
|
||||
def format_result(value):
|
||||
if value == int(value):
|
||||
return str(int(value))
|
||||
else:
|
||||
return "{0:.16}".format(value)
|
||||
|
||||
for row in X.toarray():
|
||||
print("{ " + ", ".join(map(format_result, row)) + " },")
|
||||
*/
|
||||
arma::mat target = {
|
||||
{ 0.2575364144903562, 0.4, 0.5150728289807124, 0, 0 },
|
||||
{ 0, 0.2857142857142857, 0.3679091635576516, 0.3679091635576516,
|
||||
0.2418781686514208 },
|
||||
{ 0.4292273574839269, 0.3333333333333333, 0, 0.4292273574839269, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Tf-Idf encoding algorithm for individual characters with the
|
||||
* standard term frequency type and the non-smooth inverse document frequency
|
||||
* type.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(TermFrequencyTfIdfEncodingIndividualCharactersTest)
|
||||
{
|
||||
vector<string> input = {
|
||||
"GACCA",
|
||||
"ABCABCD",
|
||||
"GAB"
|
||||
};
|
||||
|
||||
arma::mat output;
|
||||
TfIdfEncoding<CharExtract::TokenType> encoder(
|
||||
TfIdfEncodingPolicy::TfTypes::TERM_FREQUENCY, false);
|
||||
|
||||
encoder.Encode(input, output, CharExtract());
|
||||
|
||||
/* The expected values were obtained by almost the same script as in
|
||||
TermFrequencySmoothIdfEncodingIndividualCharactersTest. The only difference
|
||||
is smooth_idf equals False. */
|
||||
arma::mat target = {
|
||||
{ 0.2810930216216329, 0.4, 0.5621860432432658, 0, 0 },
|
||||
{ 0, 0.2857142857142857, 0.4015614594594755, 0.4015614594594755,
|
||||
0.2998017555240157 },
|
||||
{ 0.4684883693693881, 0.3333333333333333, 0, 0.4684883693693881, 0 }
|
||||
};
|
||||
|
||||
CheckMatrices(output, target.t(), 1e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization test for the Tf-Idf encoding algorithm with
|
||||
* the SplitByAnyOf tokenizer.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SplitByAnyOfTfIdfEncodingSerialization)
|
||||
{
|
||||
using EncoderType = TfIdfEncoding<SplitByAnyOf::TokenType>;
|
||||
|
||||
EncoderType encoder;
|
||||
SplitByAnyOf tokenizer(" ,.\"");
|
||||
arma::mat output;
|
||||
|
||||
encoder.Encode(stringEncodingInput, output, tokenizer);
|
||||
|
||||
EncoderType xmlEncoder, textEncoder, binaryEncoder;
|
||||
arma::mat xmlOutput, textOutput, binaryOutput;
|
||||
|
||||
SerializeObjectAll(encoder, xmlEncoder, textEncoder, binaryEncoder);
|
||||
|
||||
CheckDictionaries(encoder.Dictionary(), xmlEncoder.Dictionary());
|
||||
CheckDictionaries(encoder.Dictionary(), textEncoder.Dictionary());
|
||||
CheckDictionaries(encoder.Dictionary(), binaryEncoder.Dictionary());
|
||||
|
||||
xmlEncoder.Encode(stringEncodingInput, xmlOutput, tokenizer);
|
||||
textEncoder.Encode(stringEncodingInput, textOutput, tokenizer);
|
||||
binaryEncoder.Encode(stringEncodingInput, binaryOutput, tokenizer);
|
||||
|
||||
CheckMatrices(output, xmlOutput, textOutput, binaryOutput);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user