Merge pull request #3091 from shrit/header-only
mlpack Header only initiative
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Author: Omar Shrit
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
TestForSTB
|
||||
----------
|
||||
|
||||
Test to verify if the available version of STB contains a working static
|
||||
implementation that can be used from multiple translation units.
|
||||
|
||||
::
|
||||
|
||||
CMAKE_HAS_WORKING_STATIC_STB - defined by the results
|
||||
#]=======================================================================]
|
||||
|
||||
if(NOT DEFINED CMAKE_HAS_WORKING_STATIC_STB)
|
||||
message(STATUS "Check that STB static implementation mode links correctly...")
|
||||
try_compile(CMAKE_HAS_WORKING_STATIC_STB
|
||||
${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/
|
||||
SOURCES
|
||||
${CMAKE_SOURCE_DIR}/CMake/stb/main.cpp
|
||||
${CMAKE_SOURCE_DIR}/CMake/stb/a.cpp
|
||||
${CMAKE_SOURCE_DIR}/CMake/stb/b.cpp
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${STB_IMAGE_INCLUDE_DIR}"
|
||||
OUTPUT_VARIABLE out)
|
||||
if (CMAKE_HAS_WORKING_STATIC_STB)
|
||||
message(STATUS "Check that STB static implementation mode links "
|
||||
"correctly... success")
|
||||
set(CMAKE_HAS_WORKING_STATIC_STB 1 CACHE INTERNAL
|
||||
"Does STB static implementation mode link correctly")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining if STB's static implementation can link correctly passed "
|
||||
"with the following output:\n${out}\n\n")
|
||||
else ()
|
||||
message(STATUS "Check that STB static implementation mode links "
|
||||
"correctly... fail")
|
||||
set(CMAKE_HAS_WORKING_STATIC_STB 0 CACHE INTERNAL
|
||||
"Does STB static implementation mode link correctly")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining if STB's static implementation can link correctly failed "
|
||||
"with the following output:\n${out}\n\n")
|
||||
endif ()
|
||||
endif()
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "a.hpp"
|
||||
|
||||
// Include the static implementation of all STB functions.
|
||||
#define STB_IMAGE_STATIC
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_STATIC
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
#include <stb_image.h>
|
||||
#include <stb_image_write.h>
|
||||
|
||||
void A::A()
|
||||
{
|
||||
// Do nothing, just to check if the STB library is a working version.
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef A_HPP
|
||||
#define A_HPP
|
||||
|
||||
namespace A {
|
||||
|
||||
void A();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "b.hpp"
|
||||
|
||||
// Include the static implementation of all STB functions.
|
||||
#define STB_IMAGE_STATIC
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_STATIC
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
#include <stb_image.h>
|
||||
#include <stb_image_write.h>
|
||||
|
||||
void B::B()
|
||||
{
|
||||
// Do nothing, just to check if the STB library is a working version.
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef B_HPP
|
||||
#define B_HPP
|
||||
|
||||
namespace B {
|
||||
|
||||
void B();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
// The purpose of this file is to include STB's implementation in two separate
|
||||
// translation units. One is a.cpp, and one is b.cpp. This file simply
|
||||
// includes both of those, so that when we get to the linking phase, we will
|
||||
// have to link both translation units.
|
||||
//
|
||||
// Some versions of STB fail to correctly define some functions as
|
||||
// static---which will cause a linking failure. Thus, if this fails to
|
||||
// compile, then mlpack's use of STB will fail.
|
||||
#include "a.hpp"
|
||||
#include "b.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
A::A();
|
||||
B::B();
|
||||
}
|
||||
@@ -340,6 +340,15 @@ if (STB_IMAGE_FOUND)
|
||||
add_definitions(-DHAS_STB)
|
||||
set(STB_AVAILABLE "1")
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} "${STB_IMAGE_INCLUDE_DIR}")
|
||||
|
||||
# Make sure that we can link STB in multiple translation units.
|
||||
include(CMake/TestStaticSTB.cmake)
|
||||
if (NOT CMAKE_HAS_WORKING_STATIC_STB)
|
||||
message(FATAL_ERROR "STB implementations's static mode cannot link across "
|
||||
"multiple translation units! Try upgrading your STB implementation, "
|
||||
"or using the auto-downloader (set DOWNLOAD_DEPENDENCIES=ON in the "
|
||||
"CMake configuration command.")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# Find ensmallen.
|
||||
|
||||
@@ -4,7 +4,7 @@ set(SOURCES
|
||||
dataset_mapper.hpp
|
||||
dataset_mapper_impl.hpp
|
||||
detect_file_type.hpp
|
||||
detect_file_type.cpp
|
||||
detect_file_type_impl.hpp
|
||||
extension.hpp
|
||||
format.hpp
|
||||
has_serialize.hpp
|
||||
@@ -14,7 +14,7 @@ set(SOURCES
|
||||
load_categorical_csv.hpp
|
||||
load.hpp
|
||||
load_image_impl.hpp
|
||||
load_image.cpp
|
||||
load_image.hpp
|
||||
load_model_impl.hpp
|
||||
load_vec_impl.hpp
|
||||
load_impl.hpp
|
||||
@@ -24,7 +24,8 @@ set(SOURCES
|
||||
normalize_labels_impl.hpp
|
||||
save.hpp
|
||||
save_impl.hpp
|
||||
save_image.cpp
|
||||
save_image.hpp
|
||||
save_image_impl.hpp
|
||||
split_data.hpp
|
||||
string_algorithms.hpp
|
||||
imputer.hpp
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace data {
|
||||
*
|
||||
* @param type Type to get the logical name of.
|
||||
*/
|
||||
std::string GetStringType(const FileType& type);
|
||||
inline std::string GetStringType(const FileType& type);
|
||||
|
||||
/**
|
||||
* Given an istream, attempt to guess the file type. This is taken originally
|
||||
@@ -38,7 +38,7 @@ std::string GetStringType(const FileType& type);
|
||||
*
|
||||
* @param f Opened istream to look into to guess the file type.
|
||||
*/
|
||||
FileType GuessFileType(std::istream& f);
|
||||
inline FileType GuessFileType(std::istream& f);
|
||||
|
||||
/**
|
||||
* Attempt to auto-detect the type of a file given its extension, and by
|
||||
@@ -53,8 +53,8 @@ FileType GuessFileType(std::istream& f);
|
||||
* @param filename Name of the file.
|
||||
* @return The detected file type. arma::file_type_unknown if unknown.
|
||||
*/
|
||||
FileType AutoDetect(std::fstream& stream,
|
||||
const std::string& filename);
|
||||
inline FileType AutoDetect(std::fstream& stream,
|
||||
const std::string& filename);
|
||||
|
||||
/**
|
||||
* Return the type based only on the extension.
|
||||
@@ -62,9 +62,11 @@ FileType AutoDetect(std::fstream& stream,
|
||||
* @param filename Name of the file whose type we should detect.
|
||||
* @return Detected type of file. arma::file_type_unknown if unknown.
|
||||
*/
|
||||
FileType DetectFromExtension(const std::string& filename);
|
||||
inline FileType DetectFromExtension(const std::string& filename);
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#include "detect_file_type_impl.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/data/detect_file_type.cpp
|
||||
* @file core/data/detect_file_type_impl.hpp
|
||||
* @author Conrad Sanderson
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
@@ -24,7 +24,7 @@ namespace data {
|
||||
*
|
||||
* @param type Type to get the logical name of.
|
||||
*/
|
||||
std::string GetStringType(const FileType& type)
|
||||
inline std::string GetStringType(const FileType& type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -50,7 +50,7 @@ std::string GetStringType(const FileType& type)
|
||||
*
|
||||
* @param f Opened istream to look into to guess the file type.
|
||||
*/
|
||||
FileType GuessFileType(std::istream& f)
|
||||
inline FileType GuessFileType(std::istream& f)
|
||||
{
|
||||
f.clear();
|
||||
const std::fstream::pos_type pos1 = f.tellg();
|
||||
@@ -186,7 +186,7 @@ FileType GuessFileType(std::istream& f)
|
||||
* @param filename Name of the file.
|
||||
* @return The detected file type.
|
||||
*/
|
||||
FileType AutoDetect(std::fstream& stream, const std::string& filename)
|
||||
inline FileType AutoDetect(std::fstream& stream, const std::string& filename)
|
||||
{
|
||||
// Get the extension.
|
||||
std::string extension = Extension(filename);
|
||||
@@ -304,7 +304,7 @@ FileType AutoDetect(std::fstream& stream, const std::string& filename)
|
||||
* @param filename Name of the file whose type we should detect.
|
||||
* @return Detected type of file.
|
||||
*/
|
||||
FileType DetectFromExtension(const std::string& filename)
|
||||
inline FileType DetectFromExtension(const std::string& filename)
|
||||
{
|
||||
const std::string extension = Extension(filename);
|
||||
|
||||
@@ -13,6 +13,23 @@
|
||||
#ifndef MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
|
||||
#define MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
inline const std::vector<std::string> LoadFileTypes()
|
||||
{
|
||||
return std::vector<std::string>({"jpg", "png", "tga", "bmp", "psd", "gif",
|
||||
"hdr", "pic", "pnm", "jpeg"});
|
||||
}
|
||||
|
||||
inline const std::vector<std::string> SaveFileTypes()
|
||||
{
|
||||
return std::vector<std::string>({"jpg", "png", "tga", "bmp", "hdr"});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAS_STB // Compile this only if stb is present.
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
@@ -21,18 +38,12 @@
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
static const std::vector<std::string> loadFileTypes({"jpg", "png", "tga",
|
||||
"bmp", "psd", "gif", "hdr", "pic", "pnm", "jpeg"});
|
||||
|
||||
static const std::vector<std::string> saveFileTypes({"jpg", "png", "tga",
|
||||
"bmp", "hdr"});
|
||||
|
||||
inline bool ImageFormatSupported(const std::string& fileName, const bool save)
|
||||
{
|
||||
if (save)
|
||||
{
|
||||
// Iterate over all supported file types that can be saved.
|
||||
for (auto extension : saveFileTypes)
|
||||
for (auto extension : SaveFileTypes())
|
||||
{
|
||||
if (extension == Extension(fileName))
|
||||
return true;
|
||||
@@ -41,7 +52,7 @@ inline bool ImageFormatSupported(const std::string& fileName, const bool save)
|
||||
else
|
||||
{
|
||||
// Iterate over all supported file types that can be loaded.
|
||||
for (auto extension : loadFileTypes)
|
||||
for (auto extension : LoadFileTypes())
|
||||
{
|
||||
if (extension == Extension(fileName))
|
||||
return true;
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
#include "format.hpp"
|
||||
#include "dataset_mapper.hpp"
|
||||
#include "detect_file_type.hpp"
|
||||
#include "image_info.hpp"
|
||||
#include "load_csv.hpp"
|
||||
#include "load_arff.hpp"
|
||||
#include "detect_file_type.hpp"
|
||||
#include "load_image.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data /** Functions to load and save matrices and models. */ {
|
||||
@@ -250,46 +251,6 @@ bool Load(const std::string& filename,
|
||||
const bool fatal = false,
|
||||
format f = format::autodetect);
|
||||
|
||||
/**
|
||||
* Image load/save interfaces.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
// Implementation found in load_image.cpp.
|
||||
bool LoadImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false);
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -299,7 +260,5 @@ bool LoadImage(const std::string& filename,
|
||||
#include "load_model_impl.hpp"
|
||||
// Include implementation of Load() for vectors.
|
||||
#include "load_vec_impl.hpp"
|
||||
// Include implementation of Load() for images.
|
||||
#include "load_image_impl.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/**
|
||||
* @file core/data/load_image.cpp
|
||||
* @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>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
bool LoadImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
unsigned char* image;
|
||||
|
||||
if (!ImageFormatSupported(filename))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Load(): file type " << Extension(filename) << " not supported. ";
|
||||
oss << "Currently it supports: ";
|
||||
for (auto extension : loadFileTypes)
|
||||
oss << " " << extension;
|
||||
oss << "." << std::endl;
|
||||
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << oss.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << oss.str();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Temporary variables needed as stb_image.h supports int parameters.
|
||||
int tempWidth, tempHeight, tempChannels;
|
||||
|
||||
// For grayscale images.
|
||||
if (info.Channels() == 1)
|
||||
{
|
||||
image = stbi_load(filename.c_str(), &tempWidth, &tempHeight, &tempChannels,
|
||||
STBI_grey);
|
||||
}
|
||||
else
|
||||
{
|
||||
image = stbi_load(filename.c_str(), &tempWidth, &tempHeight, &tempChannels,
|
||||
STBI_rgb);
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << "Load(): failed to load image '" << filename << "': "
|
||||
<< stbi_failure_reason() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << "Load(): failed to load image '" << filename << "': "
|
||||
<< stbi_failure_reason() << std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
info.Width() = tempWidth;
|
||||
info.Height() = tempHeight;
|
||||
info.Channels() = tempChannels;
|
||||
|
||||
// Copy image into armadillo Mat.
|
||||
matrix = arma::Mat<unsigned char>(image, info.Width() * info.Height() *
|
||||
info.Channels(), 1, true, true);
|
||||
|
||||
// Free the image pointer.
|
||||
free(image);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#else
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
bool LoadImage(const std::string& /* filename */,
|
||||
arma::Mat<unsigned char>& /* matrix */,
|
||||
ImageInfo& /* info */,
|
||||
const bool fatal)
|
||||
{
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << "Load(): mlpack was not compiled with STB support, so images "
|
||||
<< "cannot be loaded!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << "Load(): mlpack was not compiled with STB support, so images "
|
||||
<< "cannot be loaded!" << std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file core/data/load_image.hpp
|
||||
* @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.
|
||||
*/
|
||||
|
||||
#ifndef MLPACK_CORE_DATA_LOAD_IMAGE_HPP
|
||||
#define MLPACK_CORE_DATA_LOAD_IMAGE_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>
|
||||
|
||||
#endif // HAS_STB
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* Image load/save interfaces.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
// Implementation found in load_image.hpp.
|
||||
inline bool LoadImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false);
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation of Load() for images.
|
||||
#include "load_image_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -2,19 +2,19 @@
|
||||
* @file core/data/load_image_impl.hpp
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* An image loading utility implementation.
|
||||
* An image loading utility implementation 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.
|
||||
*/
|
||||
|
||||
#ifndef MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP
|
||||
#define MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
#include "load.hpp"
|
||||
#include "load_image.hpp"
|
||||
#include "image_info.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
@@ -90,6 +90,104 @@ bool Load(const std::vector<std::string>& files,
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAS_STB
|
||||
|
||||
inline bool LoadImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
unsigned char* image;
|
||||
|
||||
if (!ImageFormatSupported(filename))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Load(): file type " << Extension(filename) << " not supported. ";
|
||||
oss << "Currently it supports:";
|
||||
auto x = LoadFileTypes();
|
||||
for (auto extension : x)
|
||||
oss << " " << extension;
|
||||
oss << "." << std::endl;
|
||||
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << oss.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << oss.str();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Temporary variables needed as stb_image.h supports int parameters.
|
||||
int tempWidth, tempHeight, tempChannels;
|
||||
|
||||
// For grayscale images.
|
||||
if (info.Channels() == 1)
|
||||
{
|
||||
image = stbi_load(filename.c_str(), &tempWidth, &tempHeight, &tempChannels,
|
||||
STBI_grey);
|
||||
}
|
||||
else
|
||||
{
|
||||
image = stbi_load(filename.c_str(), &tempWidth, &tempHeight, &tempChannels,
|
||||
STBI_rgb);
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << "Load(): failed to load image '" << filename << "': "
|
||||
<< stbi_failure_reason() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << "Load(): failed to load image '" << filename << "': "
|
||||
<< stbi_failure_reason() << std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
info.Width() = tempWidth;
|
||||
info.Height() = tempHeight;
|
||||
info.Channels() = tempChannels;
|
||||
|
||||
// Copy image into armadillo Mat.
|
||||
matrix = arma::Mat<unsigned char>(image, info.Width() * info.Height() *
|
||||
info.Channels(), 1, true, true);
|
||||
|
||||
// Free the image pointer.
|
||||
free(image);
|
||||
return true;
|
||||
}
|
||||
|
||||
#else // HAS_STB
|
||||
|
||||
inline bool LoadImage(const std::string& /* filename */,
|
||||
arma::Mat<unsigned char>& /* matrix */,
|
||||
ImageInfo& /* info */,
|
||||
const bool fatal)
|
||||
{
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << "Load(): mlpack was not compiled with STB support, so images "
|
||||
<< "cannot be loaded!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << "Load(): mlpack was not compiled with STB support, so images "
|
||||
<< "cannot be loaded!" << std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -16,13 +16,12 @@
|
||||
// In case it hasn't already been included.
|
||||
#include "load.hpp"
|
||||
|
||||
#include <exception>
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <mlpack/core/util/timers.hpp>
|
||||
|
||||
#include "extension.hpp"
|
||||
#include "detect_file_type.hpp"
|
||||
|
||||
#include "string_algorithms.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef MLPACK_CORE_DATA_SAVE_HPP
|
||||
#define MLPACK_CORE_DATA_SAVE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/log.hpp>
|
||||
#include <mlpack/core/arma_extend/arma_extend.hpp> // Includes Armadillo.
|
||||
#include <string>
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "format.hpp"
|
||||
#include "image_info.hpp"
|
||||
#include "detect_file_type.hpp"
|
||||
#include "save_image.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data /** Functions to load and save matrices. */ {
|
||||
@@ -130,44 +132,6 @@ bool Save(const std::string& filename,
|
||||
const bool fatal = false,
|
||||
format f = format::autodetect);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
/**
|
||||
* Helper function to save files. Implementation in save_image.cpp.
|
||||
*/
|
||||
bool SaveImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& image,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false);
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file core/data/save_image.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of save 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.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_DATA_SAVE_IMAGE_HPP
|
||||
#define MLPACK_CORE_DATA_SAVE_IMAGE_HPP
|
||||
|
||||
#include "image_info.hpp"
|
||||
|
||||
#ifdef HAS_STB
|
||||
|
||||
#define STB_IMAGE_WRITE_STATIC
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <stb_image_write.h>
|
||||
|
||||
#endif // HAS_STB
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @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 = false);
|
||||
|
||||
/**
|
||||
* Helper function to save files. Implementation in save_image.hpp.
|
||||
*/
|
||||
inline bool SaveImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& image,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false);
|
||||
|
||||
} //namespace data
|
||||
} //namespace mlpack
|
||||
|
||||
// Include implementation of Save() for images.
|
||||
#include "save_image_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/data/save_image.cpp
|
||||
* @file core/data/save_image_impl.hpp
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* Implementation of image saving functionality via STB.
|
||||
@@ -9,31 +9,78 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#include "save.hpp"
|
||||
#ifndef MLPACK_CORE_DATA_SAVE_IMAGE_IMPL_HPP
|
||||
#define MLPACK_CORE_DATA_SAVE_IMAGE_IMPL_HPP
|
||||
|
||||
#ifdef HAS_STB
|
||||
|
||||
// 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
|
||||
#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
|
||||
// In case it hasn't been included yet.
|
||||
#include "save_image.hpp"
|
||||
#include "image_info.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
bool SaveImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& image,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
/**
|
||||
* Save the given image to the given filename.
|
||||
*
|
||||
* @param filename Filename to save to.
|
||||
* @param matrix Matrix containing image to be saved.
|
||||
* @param info Information about the image (width/height/channels/etc.).
|
||||
* @param fatal Whether an exception should be thrown on save failure.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
arma::Mat<unsigned char> tmpMatrix =
|
||||
arma::conv_to<arma::Mat<unsigned char>>::from(matrix);
|
||||
|
||||
return SaveImage(filename, tmpMatrix, info, fatal);
|
||||
}
|
||||
|
||||
// Image saving API for multiple files.
|
||||
template<typename eT>
|
||||
bool Save(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
{
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << "Save(): vector of image files is empty; nothing to save."
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << "Save(): vector of image files is empty; nothing to save."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
arma::Mat<unsigned char> img;
|
||||
bool status = true;
|
||||
|
||||
for (size_t i = 0; i < files.size() ; ++i)
|
||||
{
|
||||
arma::Mat<eT> colImg(matrix.colptr(i), matrix.n_rows, 1,
|
||||
false, true);
|
||||
status &= Save(files[i], colImg, info, fatal);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef HAS_STB
|
||||
|
||||
inline bool SaveImage(const std::string& filename,
|
||||
arma::Mat<unsigned char>& image,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
// Check to see if the file type is supported.
|
||||
if (!ImageFormatSupported(filename, true))
|
||||
@@ -41,8 +88,8 @@ bool SaveImage(const std::string& filename,
|
||||
std::ostringstream oss;
|
||||
oss << "Save(): file type " << Extension(filename) << " not supported.\n";
|
||||
oss << "Currently image saving supports ";
|
||||
for (auto extension : saveFileTypes)
|
||||
oss << ", " << extension;
|
||||
for (auto extension : SaveFileTypes())
|
||||
oss << " " << extension;
|
||||
oss << "." << std::endl;
|
||||
|
||||
if (fatal)
|
||||
@@ -119,18 +166,12 @@ bool SaveImage(const std::string& filename,
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
#else // HAS_STB
|
||||
|
||||
#else
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
bool SaveImage(const std::string& /* filename */,
|
||||
arma::Mat<unsigned char>& /* image */,
|
||||
ImageInfo& /* info */,
|
||||
const bool fatal)
|
||||
inline bool SaveImage(const std::string& /* filename */,
|
||||
arma::Mat<unsigned char>& /* image */,
|
||||
ImageInfo& /* info */,
|
||||
const bool fatal)
|
||||
{
|
||||
if (fatal)
|
||||
{
|
||||
@@ -146,6 +187,8 @@ bool SaveImage(const std::string& /* filename */,
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
#include "save.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
#include <cereal/archives/xml.hpp>
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <cereal/archives/binary.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
@@ -344,63 +340,6 @@ bool Save(const std::string& filename,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the given image to the given filename.
|
||||
*
|
||||
* @param filename Filename to save to.
|
||||
* @param matrix Matrix containing image to be saved.
|
||||
* @param info Information about the image (width/height/channels/etc.).
|
||||
* @param fatal Whether an exception should be thrown on save failure.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
arma::Mat<unsigned char> tmpMatrix =
|
||||
arma::conv_to<arma::Mat<unsigned char>>::from(matrix);
|
||||
|
||||
// Call out to .cpp implementation.
|
||||
return SaveImage(filename, tmpMatrix, info, fatal);
|
||||
}
|
||||
|
||||
// Image saving API for multiple files.
|
||||
template<typename eT>
|
||||
bool Save(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
{
|
||||
if (fatal)
|
||||
{
|
||||
Log::Fatal << "Save(): vector of image files is empty; nothing to save."
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Warn << "Save(): vector of image files is empty; nothing to save."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
arma::Mat<unsigned char> img;
|
||||
bool status = true;
|
||||
|
||||
for (size_t i = 0; i < files.size() ; ++i)
|
||||
{
|
||||
arma::Mat<eT> colImg(matrix.colptr(i), matrix.n_rows, 1,
|
||||
false, true);
|
||||
status &= Save(files[i], colImg, info, fatal);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ set(SOURCES
|
||||
cosine_distance_impl.hpp
|
||||
epanechnikov_kernel.hpp
|
||||
epanechnikov_kernel_impl.hpp
|
||||
epanechnikov_kernel.cpp
|
||||
example_kernel.hpp
|
||||
gaussian_kernel.hpp
|
||||
hyperbolic_tangent_kernel.hpp
|
||||
@@ -16,7 +15,6 @@ set(SOURCES
|
||||
polynomial_kernel.hpp
|
||||
pspectrum_string_kernel.hpp
|
||||
pspectrum_string_kernel_impl.hpp
|
||||
pspectrum_string_kernel.cpp
|
||||
spherical_kernel.hpp
|
||||
triangular_kernel.hpp
|
||||
)
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* @file core/kernels/epanechnikov_kernel.cpp
|
||||
* @author Neil Slagle
|
||||
*
|
||||
* Implementation of non-template Epanechnikov kernels.
|
||||
*
|
||||
* 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 "epanechnikov_kernel.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kernel;
|
||||
|
||||
/**
|
||||
* Compute the normalizer of this Epanechnikov kernel for the given dimension.
|
||||
*
|
||||
* @param dimension Dimension to calculate the normalizer for.
|
||||
*/
|
||||
double EpanechnikovKernel::Normalizer(const size_t dimension)
|
||||
{
|
||||
return 2.0 * pow(bandwidth, (double) dimension) *
|
||||
std::pow(M_PI, dimension / 2.0) /
|
||||
(std::tgamma(dimension / 2.0 + 1.0) * (dimension + 2.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the kernel not for two points but for a numerical value.
|
||||
*/
|
||||
double EpanechnikovKernel::Evaluate(const double distance) const
|
||||
{
|
||||
return std::max(0.0, 1 - std::pow(distance, 2.0) * inverseBandwidthSquared);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate gradient of the kernel not for two points
|
||||
* but for a numerical value.
|
||||
*/
|
||||
double EpanechnikovKernel::Gradient(const double distance) const
|
||||
{
|
||||
if (std::abs(bandwidth) < std::abs(distance))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (std::abs(bandwidth) > std::abs(distance))
|
||||
{
|
||||
return -2 * inverseBandwidthSquared * distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The gradient doesn't exist.
|
||||
return arma::datum::nan;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate gradient of the kernel not for two points
|
||||
* but for a numerical value.
|
||||
*/
|
||||
double EpanechnikovKernel::GradientForSquaredDistance(const double
|
||||
distanceSquared) const
|
||||
{
|
||||
double bandwidthSquared = bandwidth * bandwidth;
|
||||
if (distanceSquared < bandwidthSquared)
|
||||
{
|
||||
return -1 * inverseBandwidthSquared;
|
||||
}
|
||||
else if (distanceSquared > bandwidthSquared &&
|
||||
distanceSquared >= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The gradient doesn't exist.
|
||||
return arma::datum::nan;
|
||||
}
|
||||
}
|
||||
@@ -55,21 +55,21 @@ class EpanechnikovKernel
|
||||
* Evaluate the Epanechnikov kernel given that the distance between the two
|
||||
* input points is known.
|
||||
*/
|
||||
double Evaluate(const double distance) const;
|
||||
inline double Evaluate(const double distance) const;
|
||||
|
||||
/**
|
||||
* Evaluate the Gradient of Epanechnikov kernel
|
||||
* given that the distance between the two
|
||||
* input points is known.
|
||||
*/
|
||||
double Gradient(const double distance) const;
|
||||
inline double Gradient(const double distance) const;
|
||||
|
||||
/**
|
||||
* Evaluate the Gradient of Epanechnikov kernel
|
||||
* given that the squared distance between the two
|
||||
* input points is known.
|
||||
*/
|
||||
double GradientForSquaredDistance(const double distanceSquared) const;
|
||||
inline double GradientForSquaredDistance(const double distanceSquared) const;
|
||||
/**
|
||||
* Obtains the convolution integral [integral of K(||x-a||) K(||b-x||) dx]
|
||||
* for the two vectors.
|
||||
@@ -87,7 +87,7 @@ class EpanechnikovKernel
|
||||
*
|
||||
* @param dimension Dimension to calculate the normalizer for.
|
||||
*/
|
||||
double Normalizer(const size_t dimension);
|
||||
inline double Normalizer(const size_t dimension);
|
||||
|
||||
/**
|
||||
* Serialize the kernel.
|
||||
|
||||
@@ -41,8 +41,8 @@ inline double EpanechnikovKernel::Evaluate(const VecTypeA& a, const VecTypeB& b)
|
||||
* @return the convolution integral value.
|
||||
*/
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double EpanechnikovKernel::ConvolutionIntegral(const VecTypeA& a,
|
||||
const VecTypeB& b)
|
||||
inline double EpanechnikovKernel::ConvolutionIntegral(const VecTypeA& a,
|
||||
const VecTypeB& b)
|
||||
{
|
||||
double distance = sqrt(metric::SquaredEuclideanDistance::Evaluate(a, b));
|
||||
if (distance >= 2.0 * bandwidth)
|
||||
@@ -73,6 +73,70 @@ double EpanechnikovKernel::ConvolutionIntegral(const VecTypeA& a,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the normalizer of this Epanechnikov kernel for the given dimension.
|
||||
*
|
||||
* @param dimension Dimension to calculate the normalizer for.
|
||||
*/
|
||||
inline double EpanechnikovKernel::Normalizer(const size_t dimension)
|
||||
{
|
||||
return 2.0 * pow(bandwidth, (double) dimension) *
|
||||
std::pow(M_PI, dimension / 2.0) /
|
||||
(std::tgamma(dimension / 2.0 + 1.0) * (dimension + 2.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the kernel not for two points but for a numerical value.
|
||||
*/
|
||||
inline double EpanechnikovKernel::Evaluate(const double distance) const
|
||||
{
|
||||
return std::max(0.0, 1 - std::pow(distance, 2.0) * inverseBandwidthSquared);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate gradient of the kernel not for two points
|
||||
* but for a numerical value.
|
||||
*/
|
||||
inline double EpanechnikovKernel::Gradient(const double distance) const
|
||||
{
|
||||
if (std::abs(bandwidth) < std::abs(distance))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (std::abs(bandwidth) > std::abs(distance))
|
||||
{
|
||||
return -2 * inverseBandwidthSquared * distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The gradient doesn't exist.
|
||||
return arma::datum::nan;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate gradient of the kernel not for two points
|
||||
* but for a numerical value.
|
||||
*/
|
||||
inline double EpanechnikovKernel::GradientForSquaredDistance(
|
||||
const double distanceSquared) const
|
||||
{
|
||||
double bandwidthSquared = bandwidth * bandwidth;
|
||||
if (distanceSquared < bandwidthSquared)
|
||||
{
|
||||
return -1 * inverseBandwidthSquared;
|
||||
}
|
||||
else if (distanceSquared > bandwidthSquared &&
|
||||
distanceSquared >= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The gradient doesn't exist.
|
||||
return arma::datum::nan;
|
||||
}
|
||||
}
|
||||
//! Serialize the kernel.
|
||||
template<typename Archive>
|
||||
void EpanechnikovKernel::serialize(Archive& ar,
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/**
|
||||
* @file core/kernels/pspectrum_string_kernel.cpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of the p-spectrum string kernel, created for use with FastMKS.
|
||||
* Instead of passing a data matrix to FastMKS which stores the kernels, pass a
|
||||
* one-dimensional data matrix (data vector) to FastMKS which stores indices of
|
||||
* strings; then, the actual strings are given to the PSpectrumStringKernel at
|
||||
* construction time, and the kernel knows to map the indices to actual strings.
|
||||
*
|
||||
* 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 "pspectrum_string_kernel.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kernel;
|
||||
|
||||
/**
|
||||
* Initialize the PSpectrumStringKernel with the given string datasets. For
|
||||
* more information on this, see the general class documentation.
|
||||
*
|
||||
* @param datasets Sets of string data. @param p The length of substrings to
|
||||
* search.
|
||||
*/
|
||||
mlpack::kernel::PSpectrumStringKernel::PSpectrumStringKernel(
|
||||
const std::vector<std::vector<std::string> >& datasets,
|
||||
const size_t p) :
|
||||
p(p)
|
||||
{
|
||||
// We have to assemble the counts of substrings. This is not a particularly
|
||||
// fast operation, unfortunately, but it only needs to be done once.
|
||||
Log::Info << "Assembling counts of substrings of length " << p << "."
|
||||
<< std::endl;
|
||||
|
||||
// Resize for number of datasets.
|
||||
counts.resize(datasets.size());
|
||||
|
||||
for (size_t dataset = 0; dataset < datasets.size(); ++dataset)
|
||||
{
|
||||
const std::vector<std::string>& set = datasets[dataset];
|
||||
|
||||
// Resize for number of strings in dataset.
|
||||
counts[dataset].resize(set.size());
|
||||
|
||||
// Inspect each string in the dataset.
|
||||
for (size_t index = 0; index < set.size(); ++index)
|
||||
{
|
||||
// Convenience references.
|
||||
const std::string& str = set[index];
|
||||
std::map<std::string, int>& mapping = counts[dataset][index];
|
||||
|
||||
size_t start = 0;
|
||||
while ((start + p) <= str.length())
|
||||
{
|
||||
string sub = str.substr(start, p);
|
||||
|
||||
// Convert all characters to lowercase.
|
||||
bool invalid = false;
|
||||
for (size_t j = 0; j < p; ++j)
|
||||
{
|
||||
if (!isalnum(sub[j]))
|
||||
{
|
||||
invalid = true;
|
||||
break; // Only consider substrings with alphanumerics.
|
||||
}
|
||||
|
||||
sub[j] = tolower(sub[j]);
|
||||
}
|
||||
|
||||
// Increment position in string.
|
||||
++start;
|
||||
|
||||
if (!invalid)
|
||||
{
|
||||
// Add to the map.
|
||||
++mapping[sub];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log::Info << "Substring extraction complete." << std::endl;
|
||||
}
|
||||
@@ -72,8 +72,8 @@ class PSpectrumStringKernel
|
||||
* @param datasets Sets of string data.
|
||||
* @param p The length of substrings to search.
|
||||
*/
|
||||
PSpectrumStringKernel(const std::vector<std::vector<std::string> >& datasets,
|
||||
const size_t p);
|
||||
inline PSpectrumStringKernel(const std::vector<std::vector<std::string> >& datasets,
|
||||
const size_t p);
|
||||
|
||||
/**
|
||||
* Evaluate the kernel for the string indices given. As mentioned in the
|
||||
|
||||
@@ -22,6 +22,64 @@
|
||||
namespace mlpack {
|
||||
namespace kernel {
|
||||
|
||||
inline PSpectrumStringKernel::PSpectrumStringKernel(
|
||||
const std::vector<std::vector<std::string> >& datasets,
|
||||
const size_t p) : p(p)
|
||||
{
|
||||
// We have to assemble the counts of substrings. This is not a particularly
|
||||
// fast operation, unfortunately, but it only needs to be done once.
|
||||
Log::Info << "Assembling counts of substrings of length " << p << "."
|
||||
<< std::endl;
|
||||
|
||||
// Resize for number of datasets.
|
||||
counts.resize(datasets.size());
|
||||
|
||||
for (size_t dataset = 0; dataset < datasets.size(); ++dataset)
|
||||
{
|
||||
const std::vector<std::string>& set = datasets[dataset];
|
||||
|
||||
// Resize for number of strings in dataset.
|
||||
counts[dataset].resize(set.size());
|
||||
|
||||
// Inspect each string in the dataset.
|
||||
for (size_t index = 0; index < set.size(); ++index)
|
||||
{
|
||||
// Convenience references.
|
||||
const std::string& str = set[index];
|
||||
std::map<std::string, int>& mapping = counts[dataset][index];
|
||||
|
||||
size_t start = 0;
|
||||
while ((start + p) <= str.length())
|
||||
{
|
||||
std::string sub = str.substr(start, p);
|
||||
|
||||
// Convert all characters to lowercase.
|
||||
bool invalid = false;
|
||||
for (size_t j = 0; j < p; ++j)
|
||||
{
|
||||
if (!isalnum(sub[j]))
|
||||
{
|
||||
invalid = true;
|
||||
break; // Only consider substrings with alphanumerics.
|
||||
}
|
||||
|
||||
sub[j] = tolower(sub[j]);
|
||||
}
|
||||
|
||||
// Increment position in string.
|
||||
++start;
|
||||
|
||||
if (!invalid)
|
||||
{
|
||||
// Add to the map.
|
||||
++mapping[sub];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log::Info << "Substring extraction complete." << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the kernel for the string indices given. As mentioned in the class
|
||||
* documentation, a and b should be 2-element vectors, where the first element
|
||||
|
||||
@@ -7,7 +7,6 @@ set(SOURCES
|
||||
digamma.hpp
|
||||
lin_alg.hpp
|
||||
lin_alg_impl.hpp
|
||||
lin_alg.cpp
|
||||
log_add.hpp
|
||||
log_add_impl.hpp
|
||||
make_alias.hpp
|
||||
@@ -17,7 +16,7 @@ set(SOURCES
|
||||
random.hpp
|
||||
random.cpp
|
||||
random_basis.hpp
|
||||
random_basis.cpp
|
||||
random_basis_impl.hpp
|
||||
range.hpp
|
||||
range_impl.hpp
|
||||
round.hpp
|
||||
|
||||
@@ -1,279 +0,0 @@
|
||||
/**
|
||||
* @file core/math/lin_alg.cpp
|
||||
* @author Nishant Mehta
|
||||
*
|
||||
* Linear algebra utilities.
|
||||
*
|
||||
* 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 "lin_alg.hpp"
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace math;
|
||||
|
||||
/**
|
||||
* Auxiliary function to raise vector elements to a specific power. The sign
|
||||
* is ignored in the power operation and then re-added. Useful for
|
||||
* eigenvalues.
|
||||
*/
|
||||
void mlpack::math::VectorPower(arma::vec& vec, const double power)
|
||||
{
|
||||
for (size_t i = 0; i < vec.n_elem; ++i)
|
||||
{
|
||||
if (std::abs(vec(i)) > 1e-12)
|
||||
vec(i) = (vec(i) > 0) ? std::pow(vec(i), (double) power) :
|
||||
-std::pow(-vec(i), (double) power);
|
||||
else
|
||||
vec(i) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a centered matrix, where centering is done by subtracting
|
||||
* the sum over the columns (a column vector) from each column of the matrix.
|
||||
*
|
||||
* @param x Input matrix
|
||||
* @param xCentered Matrix to write centered output into
|
||||
*/
|
||||
void mlpack::math::Center(const arma::mat& x, arma::mat& xCentered)
|
||||
{
|
||||
// Get the mean of the elements in each row.
|
||||
arma::vec rowMean = arma::sum(x, 1) / x.n_cols;
|
||||
|
||||
xCentered = x - arma::repmat(rowMean, 1, x.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whitens a matrix using the singular value decomposition of the covariance
|
||||
* matrix. Whitening means the covariance matrix of the result is the identity
|
||||
* matrix.
|
||||
*/
|
||||
void mlpack::math::WhitenUsingSVD(const arma::mat& x,
|
||||
arma::mat& xWhitened,
|
||||
arma::mat& whiteningMatrix)
|
||||
{
|
||||
arma::mat covX, u, v, invSMatrix, temp1;
|
||||
arma::vec sVector;
|
||||
|
||||
covX = mlpack::math::ColumnCovariance(x);
|
||||
|
||||
svd(u, sVector, v, covX);
|
||||
|
||||
size_t d = sVector.n_elem;
|
||||
invSMatrix.zeros(d, d);
|
||||
invSMatrix.diag() = 1 / sqrt(sVector);
|
||||
|
||||
whiteningMatrix = v * invSMatrix * trans(u);
|
||||
|
||||
xWhitened = whiteningMatrix * x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites a dimension-N vector to a random vector on the unit sphere in R^N.
|
||||
*/
|
||||
void mlpack::math::RandVector(arma::vec& v)
|
||||
{
|
||||
v.zeros();
|
||||
|
||||
for (size_t i = 0; i + 1 < v.n_elem; i += 2)
|
||||
{
|
||||
double a = Random();
|
||||
double b = Random();
|
||||
double first_term = sqrt(-2 * log(a));
|
||||
double second_term = 2 * M_PI * b;
|
||||
v[i] = first_term * cos(second_term);
|
||||
v[i + 1] = first_term * sin(second_term);
|
||||
}
|
||||
|
||||
if ((v.n_elem % 2) == 1)
|
||||
{
|
||||
v[v.n_elem - 1] = sqrt(-2 * log(math::Random())) * cos(2 * M_PI *
|
||||
math::Random());
|
||||
}
|
||||
|
||||
v /= sqrt(dot(v, v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Orthogonalize x and return the result in W, using eigendecomposition.
|
||||
* We will be using the formula \f$ W = x (x^T x)^{-0.5} \f$.
|
||||
*/
|
||||
void mlpack::math::Orthogonalize(const arma::mat& x, arma::mat& W)
|
||||
{
|
||||
// For a matrix A, A^N = V * D^N * V', where VDV' is the
|
||||
// eigendecomposition of the matrix A.
|
||||
arma::mat eigenvalues, eigenvectors;
|
||||
arma::vec egval;
|
||||
eig_sym(egval, eigenvectors, mlpack::math::ColumnCovariance(x));
|
||||
VectorPower(egval, -0.5);
|
||||
|
||||
eigenvalues.zeros(egval.n_elem, egval.n_elem);
|
||||
eigenvalues.diag() = egval;
|
||||
|
||||
arma::mat at = (eigenvectors * eigenvalues * trans(eigenvectors));
|
||||
|
||||
W = at * x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orthogonalize x in-place. This could be sped up by a custom
|
||||
* implementation.
|
||||
*/
|
||||
void mlpack::math::Orthogonalize(arma::mat& x)
|
||||
{
|
||||
Orthogonalize(x, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a certain set of rows in a matrix while copying to a second matrix.
|
||||
*
|
||||
* @param input Input matrix to copy.
|
||||
* @param rowsToRemove Vector containing indices of rows to be removed.
|
||||
* @param output Matrix to copy non-removed rows into.
|
||||
*/
|
||||
void mlpack::math::RemoveRows(const arma::mat& input,
|
||||
const std::vector<size_t>& rowsToRemove,
|
||||
arma::mat& output)
|
||||
{
|
||||
const size_t nRemove = rowsToRemove.size();
|
||||
const size_t nKeep = input.n_rows - nRemove;
|
||||
|
||||
if (nRemove == 0)
|
||||
{
|
||||
output = input; // Copy everything.
|
||||
}
|
||||
else
|
||||
{
|
||||
output.set_size(nKeep, input.n_cols);
|
||||
|
||||
size_t curRow = 0;
|
||||
size_t removeInd = 0;
|
||||
// First, check 0 to first row to remove.
|
||||
if (rowsToRemove[0] > 0)
|
||||
{
|
||||
// Note that this implies that n_rows > 1.
|
||||
output.rows(0, rowsToRemove[0] - 1) = input.rows(0, rowsToRemove[0] - 1);
|
||||
curRow += rowsToRemove[0];
|
||||
}
|
||||
|
||||
// Now, check i'th row to remove to (i + 1)'th row to remove, until i is the
|
||||
// penultimate row.
|
||||
while (removeInd < nRemove - 1)
|
||||
{
|
||||
const size_t height = rowsToRemove[removeInd + 1] -
|
||||
rowsToRemove[removeInd] - 1;
|
||||
|
||||
if (height > 0)
|
||||
{
|
||||
output.rows(curRow, curRow + height - 1) =
|
||||
input.rows(rowsToRemove[removeInd] + 1,
|
||||
rowsToRemove[removeInd + 1] - 1);
|
||||
curRow += height;
|
||||
}
|
||||
|
||||
removeInd++;
|
||||
}
|
||||
|
||||
// Now that i is the last row to remove, check last row to remove to last
|
||||
// row.
|
||||
if (rowsToRemove[removeInd] < input.n_rows - 1)
|
||||
{
|
||||
output.rows(curRow, nKeep - 1) = input.rows(rowsToRemove[removeInd] + 1,
|
||||
input.n_rows - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mlpack::math::Svec(const arma::mat& input, arma::vec& output)
|
||||
{
|
||||
const size_t n = input.n_rows;
|
||||
const size_t n2bar = n * (n + 1) / 2;
|
||||
|
||||
output.zeros(n2bar);
|
||||
|
||||
size_t idx = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
for (size_t j = i; j < n; ++j)
|
||||
{
|
||||
if (i == j)
|
||||
output(idx++) = input(i, j);
|
||||
else
|
||||
output(idx++) = M_SQRT2 * input(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mlpack::math::Svec(const arma::sp_mat& input, arma::sp_vec& output)
|
||||
{
|
||||
const size_t n = input.n_rows;
|
||||
const size_t n2bar = n * (n + 1) / 2;
|
||||
|
||||
output.zeros(n2bar, 1);
|
||||
|
||||
for (auto it = input.begin(); it != input.end(); ++it)
|
||||
{
|
||||
const size_t i = it.row();
|
||||
const size_t j = it.col();
|
||||
if (i > j)
|
||||
continue;
|
||||
if (i == j)
|
||||
output(SvecIndex(i, j, n)) = *it;
|
||||
else
|
||||
output(SvecIndex(i, j, n)) = M_SQRT2 * (*it);
|
||||
}
|
||||
}
|
||||
|
||||
void mlpack::math::Smat(const arma::vec& input, arma::mat& output)
|
||||
{
|
||||
const size_t n = static_cast<size_t>
|
||||
(ceil((-1. + sqrt(1. + 8. * input.n_elem))/2.));
|
||||
|
||||
|
||||
output.zeros(n, n);
|
||||
|
||||
size_t idx = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
for (size_t j = i; j < n; ++j)
|
||||
{
|
||||
if (i == j)
|
||||
output(i, j) = input(idx++);
|
||||
else
|
||||
output(i, j) = output(j, i) = M_SQRT1_2 * input(idx++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mlpack::math::SymKronId(const arma::mat& A, arma::mat& op)
|
||||
{
|
||||
// TODO(stephentu): there's probably an easier way to build this operator
|
||||
|
||||
const size_t n = A.n_rows;
|
||||
const size_t n2bar = n * (n + 1) / 2;
|
||||
op.zeros(n2bar, n2bar);
|
||||
|
||||
size_t idx = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
for (size_t j = i; j < n; ++j)
|
||||
{
|
||||
for (size_t k = 0; k < n; ++k)
|
||||
{
|
||||
op(idx, SvecIndex(k, j, n)) +=
|
||||
((k == j) ? 1. : M_SQRT1_2) * A(i, k);
|
||||
op(idx, SvecIndex(i, k, n)) +=
|
||||
((k == i) ? 1. : M_SQRT1_2) * A(k, j);
|
||||
}
|
||||
op.row(idx) *= 0.5;
|
||||
if (i != j)
|
||||
op.row(idx) *= M_SQRT2;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@
|
||||
#define MLPACK_CORE_MATH_LIN_ALG_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include "ccov.hpp"
|
||||
#include "random.hpp"
|
||||
|
||||
/**
|
||||
* Linear algebra utility functions, generally performed on matrices or vectors.
|
||||
@@ -25,7 +27,7 @@ namespace math {
|
||||
* is ignored in the power operation and then re-added. Useful for
|
||||
* eigenvalues.
|
||||
*/
|
||||
void VectorPower(arma::vec& vec, const double power);
|
||||
inline void VectorPower(arma::vec& vec, const double power);
|
||||
|
||||
/**
|
||||
* Creates a centered matrix, where centering is done by subtracting
|
||||
@@ -34,34 +36,34 @@ void VectorPower(arma::vec& vec, const double power);
|
||||
* @param x Input matrix
|
||||
* @param xCentered Matrix to write centered output into
|
||||
*/
|
||||
void Center(const arma::mat& x, arma::mat& xCentered);
|
||||
inline void Center(const arma::mat& x, arma::mat& xCentered);
|
||||
|
||||
/**
|
||||
* Whitens a matrix using the singular value decomposition of the covariance
|
||||
* matrix. Whitening means the covariance matrix of the result is the identity
|
||||
* matrix.
|
||||
*/
|
||||
void WhitenUsingSVD(const arma::mat& x,
|
||||
arma::mat& xWhitened,
|
||||
arma::mat& whiteningMatrix);
|
||||
inline void WhitenUsingSVD(const arma::mat& x,
|
||||
arma::mat& xWhitened,
|
||||
arma::mat& whiteningMatrix);
|
||||
|
||||
|
||||
/**
|
||||
* Overwrites a dimension-N vector to a random vector on the unit sphere in R^N.
|
||||
*/
|
||||
void RandVector(arma::vec& v);
|
||||
inline void RandVector(arma::vec& v);
|
||||
|
||||
/**
|
||||
* Orthogonalize x and return the result in W, using eigendecomposition.
|
||||
* We will be using the formula \f$ W = x (x^T x)^{-0.5} \f$.
|
||||
*/
|
||||
void Orthogonalize(const arma::mat& x, arma::mat& W);
|
||||
inline void Orthogonalize(const arma::mat& x, arma::mat& W);
|
||||
|
||||
/**
|
||||
* Orthogonalize x in-place. This could be sped up by a custom
|
||||
* implementation.
|
||||
*/
|
||||
void Orthogonalize(arma::mat& x);
|
||||
inline void Orthogonalize(arma::mat& x);
|
||||
|
||||
/**
|
||||
* Remove a certain set of rows in a matrix while copying to a second matrix.
|
||||
@@ -70,9 +72,9 @@ void Orthogonalize(arma::mat& x);
|
||||
* @param rowsToRemove Vector containing indices of rows to be removed.
|
||||
* @param output Matrix to copy non-removed rows into.
|
||||
*/
|
||||
void RemoveRows(const arma::mat& input,
|
||||
const std::vector<size_t>& rowsToRemove,
|
||||
arma::mat& output);
|
||||
inline void RemoveRows(const arma::mat& input,
|
||||
const std::vector<size_t>& rowsToRemove,
|
||||
arma::mat& output);
|
||||
|
||||
/**
|
||||
* Upper triangular representation of a symmetric matrix, scaled such that,
|
||||
@@ -83,9 +85,9 @@ void RemoveRows(const arma::mat& input,
|
||||
* @param input A symmetric matrix
|
||||
* @param output
|
||||
*/
|
||||
void Svec(const arma::mat& input, arma::vec& output);
|
||||
inline void Svec(const arma::mat& input, arma::vec& output);
|
||||
|
||||
void Svec(const arma::sp_mat& input, arma::sp_vec& output);
|
||||
inline void Svec(const arma::sp_mat& input, arma::sp_vec& output);
|
||||
|
||||
/**
|
||||
* The inverse of Svec. That is, Smat(Svec(A)) == A.
|
||||
@@ -93,7 +95,7 @@ void Svec(const arma::sp_mat& input, arma::sp_vec& output);
|
||||
* @param input
|
||||
* @param output A symmetric matrix
|
||||
*/
|
||||
void Smat(const arma::vec& input, arma::mat& output);
|
||||
inline void Smat(const arma::vec& input, arma::mat& output);
|
||||
|
||||
/**
|
||||
* Return the index such that A[i,j] == factr(i, j) * svec(A)[pos(i, j)],
|
||||
@@ -115,7 +117,7 @@ inline size_t SvecIndex(size_t i, size_t j, size_t n);
|
||||
* @param A
|
||||
* @param op
|
||||
*/
|
||||
void SymKronId(const arma::mat& A, arma::mat& op);
|
||||
inline void SymKronId(const arma::mat& A, arma::mat& op);
|
||||
|
||||
/**
|
||||
* Signum function.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/**
|
||||
* @file core/math/lin_alg_impl.hpp
|
||||
* @author Stephen Tu
|
||||
* @author Nishant Mehta
|
||||
*
|
||||
* Linear algebra utilities.
|
||||
*
|
||||
* 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
|
||||
@@ -22,6 +25,267 @@ inline size_t SvecIndex(size_t i, size_t j, size_t n)
|
||||
return (j-i) + (n*(n+1) - (n-i)*(n-i+1))/2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auxiliary function to raise vector elements to a specific power. The sign
|
||||
* is ignored in the power operation and then re-added. Useful for
|
||||
* eigenvalues.
|
||||
*/
|
||||
inline void VectorPower(arma::vec& vec, const double power)
|
||||
{
|
||||
for (size_t i = 0; i < vec.n_elem; ++i)
|
||||
{
|
||||
if (std::abs(vec(i)) > 1e-12)
|
||||
{
|
||||
vec(i) = (vec(i) > 0) ? std::pow(vec(i), (double) power) :
|
||||
-std::pow(-vec(i), (double) power);
|
||||
}
|
||||
else
|
||||
vec(i) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a centered matrix, where centering is done by subtracting
|
||||
* the sum over the columns (a column vector) from each column of the matrix.
|
||||
*
|
||||
* @param x Input matrix
|
||||
* @param xCentered Matrix to write centered output into
|
||||
*/
|
||||
inline void Center(const arma::mat& x, arma::mat& xCentered)
|
||||
{
|
||||
// Get the mean of the elements in each row.
|
||||
arma::vec rowMean = arma::sum(x, 1) / x.n_cols;
|
||||
|
||||
xCentered = x - arma::repmat(rowMean, 1, x.n_cols);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whitens a matrix using the singular value decomposition of the covariance
|
||||
* matrix. Whitening means the covariance matrix of the result is the identity
|
||||
* matrix.
|
||||
*/
|
||||
inline void WhitenUsingSVD(const arma::mat& x,
|
||||
arma::mat& xWhitened,
|
||||
arma::mat& whiteningMatrix)
|
||||
{
|
||||
arma::mat covX, u, v, invSMatrix, temp1;
|
||||
arma::vec sVector;
|
||||
|
||||
covX = ColumnCovariance(x);
|
||||
|
||||
svd(u, sVector, v, covX);
|
||||
|
||||
size_t d = sVector.n_elem;
|
||||
invSMatrix.zeros(d, d);
|
||||
invSMatrix.diag() = 1 / sqrt(sVector);
|
||||
|
||||
whiteningMatrix = v * invSMatrix * trans(u);
|
||||
|
||||
xWhitened = whiteningMatrix * x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites a dimension-N vector to a random vector on the unit sphere in R^N.
|
||||
*/
|
||||
inline void RandVector(arma::vec& v)
|
||||
{
|
||||
for (size_t i = 0; i + 1 < v.n_elem; i += 2)
|
||||
{
|
||||
double a = math::Random();
|
||||
double b = math::Random();
|
||||
double first_term = sqrt(-2 * log(a));
|
||||
double second_term = 2 * M_PI * b;
|
||||
v[i] = first_term * cos(second_term);
|
||||
v[i + 1] = first_term * sin(second_term);
|
||||
}
|
||||
|
||||
if ((v.n_elem % 2) == 1)
|
||||
{
|
||||
v[v.n_elem - 1] = sqrt(-2 * log(math::Random())) * cos(2 * M_PI *
|
||||
math::Random());
|
||||
}
|
||||
|
||||
v /= sqrt(dot(v, v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Orthogonalize x and return the result in W, using eigendecomposition.
|
||||
* We will be using the formula \f$ W = x (x^T x)^{-0.5} \f$.
|
||||
*/
|
||||
inline void Orthogonalize(const arma::mat& x, arma::mat& W)
|
||||
{
|
||||
// For a matrix A, A^N = V * D^N * V', where VDV' is the
|
||||
// eigendecomposition of the matrix A.
|
||||
arma::mat eigenvalues, eigenvectors;
|
||||
arma::vec egval;
|
||||
eig_sym(egval, eigenvectors, ColumnCovariance(x));
|
||||
VectorPower(egval, -0.5);
|
||||
|
||||
eigenvalues.zeros(egval.n_elem, egval.n_elem);
|
||||
eigenvalues.diag() = egval;
|
||||
|
||||
arma::mat at = (eigenvectors * eigenvalues * trans(eigenvectors));
|
||||
|
||||
W = at * x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orthogonalize x in-place. This could be sped up by a custom
|
||||
* implementation.
|
||||
*/
|
||||
inline void Orthogonalize(arma::mat& x)
|
||||
{
|
||||
Orthogonalize(x, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a certain set of rows in a matrix while copying to a second matrix.
|
||||
*
|
||||
* @param input Input matrix to copy.
|
||||
* @param rowsToRemove Vector containing indices of rows to be removed.
|
||||
* @param output Matrix to copy non-removed rows into.
|
||||
*/
|
||||
inline void RemoveRows(const arma::mat& input,
|
||||
const std::vector<size_t>& rowsToRemove,
|
||||
arma::mat& output)
|
||||
{
|
||||
const size_t nRemove = rowsToRemove.size();
|
||||
const size_t nKeep = input.n_rows - nRemove;
|
||||
|
||||
if (nRemove == 0)
|
||||
{
|
||||
output = input; // Copy everything.
|
||||
}
|
||||
else
|
||||
{
|
||||
output.set_size(nKeep, input.n_cols);
|
||||
|
||||
size_t curRow = 0;
|
||||
size_t removeInd = 0;
|
||||
// First, check 0 to first row to remove.
|
||||
if (rowsToRemove[0] > 0)
|
||||
{
|
||||
// Note that this implies that n_rows > 1.
|
||||
output.rows(0, rowsToRemove[0] - 1) = input.rows(0, rowsToRemove[0] - 1);
|
||||
curRow += rowsToRemove[0];
|
||||
}
|
||||
|
||||
// Now, check i'th row to remove to (i + 1)'th row to remove, until i is the
|
||||
// penultimate row.
|
||||
while (removeInd < nRemove - 1)
|
||||
{
|
||||
const size_t height = rowsToRemove[removeInd + 1] -
|
||||
rowsToRemove[removeInd] - 1;
|
||||
|
||||
if (height > 0)
|
||||
{
|
||||
output.rows(curRow, curRow + height - 1) =
|
||||
input.rows(rowsToRemove[removeInd] + 1,
|
||||
rowsToRemove[removeInd + 1] - 1);
|
||||
curRow += height;
|
||||
}
|
||||
|
||||
removeInd++;
|
||||
}
|
||||
|
||||
// Now that i is the last row to remove, check last row to remove to last
|
||||
// row.
|
||||
if (rowsToRemove[removeInd] < input.n_rows - 1)
|
||||
{
|
||||
output.rows(curRow, nKeep - 1) = input.rows(rowsToRemove[removeInd] + 1,
|
||||
input.n_rows - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Svec(const arma::mat& input, arma::vec& output)
|
||||
{
|
||||
const size_t n = input.n_rows;
|
||||
const size_t n2bar = n * (n + 1) / 2;
|
||||
|
||||
output.zeros(n2bar);
|
||||
|
||||
size_t idx = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
for (size_t j = i; j < n; ++j)
|
||||
{
|
||||
if (i == j)
|
||||
output(idx++) = input(i, j);
|
||||
else
|
||||
output(idx++) = M_SQRT2 * input(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Svec(const arma::sp_mat& input, arma::sp_vec& output)
|
||||
{
|
||||
const size_t n = input.n_rows;
|
||||
const size_t n2bar = n * (n + 1) / 2;
|
||||
|
||||
output.zeros(n2bar, 1);
|
||||
|
||||
for (auto it = input.begin(); it != input.end(); ++it)
|
||||
{
|
||||
const size_t i = it.row();
|
||||
const size_t j = it.col();
|
||||
if (i > j)
|
||||
continue;
|
||||
if (i == j)
|
||||
output(SvecIndex(i, j, n)) = *it;
|
||||
else
|
||||
output(SvecIndex(i, j, n)) = M_SQRT2 * (*it);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Smat(const arma::vec& input, arma::mat& output)
|
||||
{
|
||||
const size_t n = static_cast<size_t>
|
||||
(ceil((-1. + sqrt(1. + 8. * input.n_elem)) / 2.));
|
||||
|
||||
output.zeros(n, n);
|
||||
|
||||
size_t idx = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
for (size_t j = i; j < n; ++j)
|
||||
{
|
||||
if (i == j)
|
||||
output(i, j) = input(idx++);
|
||||
else
|
||||
output(i, j) = output(j, i) = M_SQRT1_2 * input(idx++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void SymKronId(const arma::mat& A, arma::mat& op)
|
||||
{
|
||||
// TODO(stephentu): there's probably an easier way to build this operator
|
||||
|
||||
const size_t n = A.n_rows;
|
||||
const size_t n2bar = n * (n + 1) / 2;
|
||||
op.zeros(n2bar, n2bar);
|
||||
|
||||
size_t idx = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
for (size_t j = i; j < n; ++j)
|
||||
{
|
||||
for (size_t k = 0; k < n; ++k)
|
||||
{
|
||||
op(idx, SvecIndex(k, j, n)) +=
|
||||
((k == j) ? 1. : M_SQRT1_2) * A(i, k);
|
||||
op(idx, SvecIndex(i, k, n)) +=
|
||||
((k == i) ? 1. : M_SQRT1_2) * A(k, j);
|
||||
}
|
||||
op.row(idx) *= 0.5;
|
||||
if (i != j)
|
||||
op.row(idx) *= M_SQRT2;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -24,9 +24,12 @@ namespace math {
|
||||
* @param basis Matrix to store basis in.
|
||||
* @param d Desired number of dimensions in the basis.
|
||||
*/
|
||||
void RandomBasis(arma::mat& basis, const size_t d);
|
||||
inline void RandomBasis(arma::mat& basis, const size_t d);
|
||||
|
||||
} // namespace math
|
||||
} // namespace mlpack
|
||||
|
||||
//! Include the implementation file.
|
||||
#include "random_basis_impl.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/math/random_basis.cpp
|
||||
* @file core/math/random_basis_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Generate a random d-dimensional basis.
|
||||
@@ -11,21 +11,19 @@
|
||||
*/
|
||||
#include "random_basis.hpp"
|
||||
|
||||
using namespace arma;
|
||||
|
||||
namespace mlpack {
|
||||
namespace math {
|
||||
|
||||
void RandomBasis(mat& basis, const size_t d)
|
||||
inline void RandomBasis(arma::mat& basis, const size_t d)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// [Q, R] = qr(randn(d, d));
|
||||
// Q = Q * diag(sign(diag(R)));
|
||||
mat r;
|
||||
if (qr(basis, r, randn<mat>(d, d)))
|
||||
arma::mat r;
|
||||
if (qr(basis, r, arma::randn<arma::mat>(d, d)))
|
||||
{
|
||||
vec rDiag(r.n_rows);
|
||||
arma::vec rDiag(r.n_rows);
|
||||
for (size_t i = 0; i < rDiag.n_elem; ++i)
|
||||
{
|
||||
if (r(i, i) < 0)
|
||||
@@ -17,8 +17,6 @@
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
using namespace mlpack::math;
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
@@ -55,7 +53,7 @@ class GaussianInitialization
|
||||
if (W.is_empty())
|
||||
W.set_size(rows, cols);
|
||||
|
||||
W.imbue( [&]() { return arma::as_scalar(RandNormal(mean, variance)); } );
|
||||
W.imbue( [&]() { return arma::as_scalar(mlpack::math::RandNormal(mean, variance)); } );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +67,7 @@ class GaussianInitialization
|
||||
if (W.is_empty())
|
||||
Log::Fatal << "Cannot initialize an empty matrix." << std::endl;
|
||||
|
||||
W.imbue( [&]() { return arma::as_scalar(RandNormal(mean, variance)); } );
|
||||
W.imbue( [&]() { return arma::as_scalar(mlpack::math::RandNormal(mean, variance)); } );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#include "random_init.hpp"
|
||||
#include "gaussian_init.hpp"
|
||||
|
||||
using namespace mlpack::math;
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <string>
|
||||
|
||||
using namespace mlpack::ann;
|
||||
|
||||
/**
|
||||
* Implementation of a class that returns the string representation of the
|
||||
* name of the given layer.
|
||||
@@ -36,7 +34,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type AdaptiveMaxPooling.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(AdaptiveMaxPooling<> * /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::AdaptiveMaxPooling<> * /*layer*/) const
|
||||
{
|
||||
return "adaptivemaxpooling";
|
||||
}
|
||||
@@ -47,7 +45,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type AdaptiveMeanPooling.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(AdaptiveMeanPooling<> * /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::AdaptiveMeanPooling<> * /*layer*/) const
|
||||
{
|
||||
return "adaptivemeanpooling";
|
||||
}
|
||||
@@ -58,7 +56,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type AtrousConvolution.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(AtrousConvolution<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::AtrousConvolution<>* /*layer*/) const
|
||||
{
|
||||
return "atrousconvolution";
|
||||
}
|
||||
@@ -69,7 +67,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type AlphaDropout.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(AlphaDropout<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::AlphaDropout<>* /*layer*/) const
|
||||
{
|
||||
return "alphadropout";
|
||||
}
|
||||
@@ -80,7 +78,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type BatchNorm.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(BatchNorm<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::BatchNorm<>* /*layer*/) const
|
||||
{
|
||||
return "batchnorm";
|
||||
}
|
||||
@@ -91,7 +89,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type Constant.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(Constant<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::Constant<>* /*layer*/) const
|
||||
{
|
||||
return "constant";
|
||||
}
|
||||
@@ -102,7 +100,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type Convolution.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(Convolution<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::Convolution<>* /*layer*/) const
|
||||
{
|
||||
return "convolution";
|
||||
}
|
||||
@@ -113,7 +111,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type DropConnect.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(DropConnect<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::DropConnect<>* /*layer*/) const
|
||||
{
|
||||
return "dropconnect";
|
||||
}
|
||||
@@ -124,7 +122,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type Dropout.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(Dropout<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::Dropout<>* /*layer*/) const
|
||||
{
|
||||
return "dropout";
|
||||
}
|
||||
@@ -135,7 +133,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type FlexibleReLU.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(FlexibleReLU<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::FlexibleReLU<>* /*layer*/) const
|
||||
{
|
||||
return "flexiblerelu";
|
||||
}
|
||||
@@ -146,7 +144,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type LayerNorm.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(LayerNorm<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::LayerNorm<>* /*layer*/) const
|
||||
{
|
||||
return "layernorm";
|
||||
}
|
||||
@@ -157,7 +155,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type Linear.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(Linear<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::Linear<>* /*layer*/) const
|
||||
{
|
||||
return "linear";
|
||||
}
|
||||
@@ -168,7 +166,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type LinearNoBias.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(LinearNoBias<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::LinearNoBias<>* /*layer*/) const
|
||||
{
|
||||
return "linearnobias";
|
||||
}
|
||||
@@ -179,7 +177,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type NoisyLinear.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(NoisyLinear<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::NoisyLinear<>* /*layer*/) const
|
||||
{
|
||||
return "noisylinear";
|
||||
}
|
||||
@@ -190,7 +188,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type MaxPooling.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(MaxPooling<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::MaxPooling<>* /*layer*/) const
|
||||
{
|
||||
return "maxpooling";
|
||||
}
|
||||
@@ -201,7 +199,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type MeanPooling.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(MeanPooling<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::MeanPooling<>* /*layer*/) const
|
||||
{
|
||||
return "meanpooling";
|
||||
}
|
||||
@@ -212,7 +210,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type LpPooling.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(LpPooling<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::LpPooling<>* /*layer*/) const
|
||||
{
|
||||
return "lppooling";
|
||||
}
|
||||
@@ -223,7 +221,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type MultiplyConstant.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(MultiplyConstant<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::MultiplyConstant<>* /*layer*/) const
|
||||
{
|
||||
return "multiplyconstant";
|
||||
}
|
||||
@@ -234,7 +232,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type ReLULayer.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(ReLULayer<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::ReLULayer<>* /*layer*/) const
|
||||
{
|
||||
return "relu";
|
||||
}
|
||||
@@ -246,7 +244,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type TransposedConvolution.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(TransposedConvolution<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::TransposedConvolution<>* /*layer*/) const
|
||||
{
|
||||
return "transposedconvolution";
|
||||
}
|
||||
@@ -257,7 +255,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type IdentityLayer.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(IdentityLayer<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::IdentityLayer<>* /*layer*/) const
|
||||
{
|
||||
return "identity";
|
||||
}
|
||||
@@ -268,7 +266,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type TanHLayer.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(TanHLayer<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::TanHLayer<>* /*layer*/) const
|
||||
{
|
||||
return "tanh";
|
||||
}
|
||||
@@ -279,7 +277,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type ELU.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(ELU<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::ELU<>* /*layer*/) const
|
||||
{
|
||||
return "elu";
|
||||
}
|
||||
@@ -290,7 +288,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type HardTanH.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(HardTanH<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::HardTanH<>* /*layer*/) const
|
||||
{
|
||||
return "hardtanh";
|
||||
}
|
||||
@@ -301,7 +299,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type LeakyReLU.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(LeakyReLU<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::LeakyReLU<>* /*layer*/) const
|
||||
{
|
||||
return "leakyrelu";
|
||||
}
|
||||
@@ -312,7 +310,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type PReLU.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(PReLU<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::PReLU<>* /*layer*/) const
|
||||
{
|
||||
return "prelu";
|
||||
}
|
||||
@@ -323,7 +321,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type SigmoidLayer.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(SigmoidLayer<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::SigmoidLayer<>* /*layer*/) const
|
||||
{
|
||||
return "sigmoid";
|
||||
}
|
||||
@@ -334,7 +332,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type LogSoftMax.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(LogSoftMax<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::LogSoftMax<>* /*layer*/) const
|
||||
{
|
||||
return "logsoftmax";
|
||||
}
|
||||
@@ -345,7 +343,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type LSTM.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(LSTM<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::LSTM<>* /*layer*/) const
|
||||
{
|
||||
return "lstm";
|
||||
}
|
||||
@@ -356,7 +354,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type CReLU.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(CReLU<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::CReLU<>* /*layer*/) const
|
||||
{
|
||||
return "crelu";
|
||||
}
|
||||
@@ -367,7 +365,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type Highway.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(Highway<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::Highway<>* /*layer*/) const
|
||||
{
|
||||
return "highway";
|
||||
}
|
||||
@@ -378,7 +376,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type GRU.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(GRU<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::GRU<>* /*layer*/) const
|
||||
{
|
||||
return "gru";
|
||||
}
|
||||
@@ -389,7 +387,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type Glimpse.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(Glimpse<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::Glimpse<>* /*layer*/) const
|
||||
{
|
||||
return "glimpse";
|
||||
}
|
||||
@@ -400,7 +398,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type FastLSTM.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(FastLSTM<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::FastLSTM<>* /*layer*/) const
|
||||
{
|
||||
return "fastlstm";
|
||||
}
|
||||
@@ -411,7 +409,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
* @param * Given layer of type WeightNorm.
|
||||
* @return The string representation of the layer.
|
||||
*/
|
||||
std::string LayerString(WeightNorm<>* /*layer*/) const
|
||||
std::string LayerString(mlpack::ann::WeightNorm<>* /*layer*/) const
|
||||
{
|
||||
return "weightnorm";
|
||||
}
|
||||
@@ -429,7 +427,7 @@ class LayerNameVisitor : public boost::static_visitor<std::string>
|
||||
}
|
||||
|
||||
//! Overload function call.
|
||||
std::string operator()(MoreTypes layer) const
|
||||
std::string operator()(mlpack::ann::MoreTypes layer) const
|
||||
{
|
||||
return layer.apply_visitor(*this);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <mlpack/methods/cf/neighbor_search_policies/pearson_search.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::cf;
|
||||
using namespace mlpack::amf;
|
||||
using namespace mlpack::svd;
|
||||
@@ -202,9 +203,9 @@ PARAM_STRING_IN("neighbor_search", "Algorithm used for neighbor search.",
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") == 0)
|
||||
math::RandomSeed(std::time(NULL));
|
||||
RandomSeed(std::time(NULL));
|
||||
else
|
||||
math::RandomSeed(params.Get<int>("seed"));
|
||||
RandomSeed(params.Get<int>("seed"));
|
||||
|
||||
// Validate parameters.
|
||||
RequireOnlyOnePassed(params, { "training", "input_model" }, true);
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace det;
|
||||
|
||||
namespace details
|
||||
{
|
||||
namespace mlpack {
|
||||
namespace det {
|
||||
namespace details {
|
||||
|
||||
/**
|
||||
* This one sorts and scand the given per-dimension extract and puts all splits
|
||||
@@ -552,10 +550,11 @@ bool DTree<MatType, TagType>::FindSplit(const MatType& data,
|
||||
}
|
||||
|
||||
template<typename MatType, typename TagType>
|
||||
size_t DTree<MatType, TagType>::SplitData(MatType& data,
|
||||
const size_t splitDim,
|
||||
const ElemType splitValue,
|
||||
arma::Col<size_t>& oldFromNew) const
|
||||
size_t DTree<MatType, TagType>::SplitData(
|
||||
MatType& data,
|
||||
const size_t splitDim,
|
||||
const ElemType splitValue,
|
||||
arma::Col<size_t>& oldFromNew) const
|
||||
{
|
||||
// Swap all columns such that any columns with value in dimension splitDim
|
||||
// less than or equal to splitValue are on the left side, and all others are
|
||||
@@ -933,8 +932,8 @@ TagType DTree<MatType, TagType>::FindBucket(const VecType& query) const
|
||||
}
|
||||
|
||||
template<typename MatType, typename TagType>
|
||||
void DTree<MatType, TagType>::ComputeVariableImportance(arma::vec& importances)
|
||||
const
|
||||
void DTree<MatType, TagType>::ComputeVariableImportance(
|
||||
arma::vec& importances) const
|
||||
{
|
||||
// Clear and set to right size.
|
||||
importances.zeros(maxVals.n_elem);
|
||||
@@ -1036,3 +1035,6 @@ void DTree<MatType, TagType>::serialize(Archive& ar,
|
||||
FillMinMax(minVals, maxVals);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace det
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#ifdef BINDING_NAME
|
||||
#undef BINDING_NAME
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::gmm;
|
||||
using namespace mlpack::util;
|
||||
|
||||
@@ -74,9 +76,9 @@ void BINDING_FUNCTION(util::Params& params, util::Timers& /* timers */)
|
||||
"no results will be saved");
|
||||
|
||||
if (params.Get<int>("seed") == 0)
|
||||
mlpack::math::RandomSeed(time(NULL));
|
||||
RandomSeed(time(NULL));
|
||||
else
|
||||
mlpack::math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
|
||||
RequireParamValue<int>(params, "samples", [](int x) { return x > 0; }, true,
|
||||
"number of samples must be greater than 0");
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define BINDING_NAME gmm_train
|
||||
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#include "gmm.hpp"
|
||||
#include "diagonal_gmm.hpp"
|
||||
@@ -27,6 +28,7 @@
|
||||
#include <mlpack/methods/kmeans/refined_start.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::gmm;
|
||||
using namespace mlpack::util;
|
||||
using namespace mlpack::kmeans;
|
||||
@@ -155,9 +157,9 @@ void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
// Check parameters and load data.
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
RequireParamValue<int>(params, "gaussians", [](int x) { return x > 0; }, true,
|
||||
"number of Gaussians must be positive");
|
||||
|
||||
@@ -78,18 +78,16 @@ void LoadHMMAndPerformActionHelper(const std::string& modelFile,
|
||||
char type;
|
||||
ar(CEREAL_NVP(type));
|
||||
|
||||
using namespace mlpack::distribution;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case HMMType::DiscreteHMM:
|
||||
DeserializeHMMAndPerformAction<ActionType, ArchiveType,
|
||||
HMM<DiscreteDistribution>>(ar, x);
|
||||
HMM<distribution::DiscreteDistribution>>(ar, x);
|
||||
break;
|
||||
|
||||
case HMMType::GaussianHMM:
|
||||
DeserializeHMMAndPerformAction<ActionType, ArchiveType,
|
||||
HMM<GaussianDistribution>>(ar, x);
|
||||
HMM<distribution::GaussianDistribution>>(ar, x);
|
||||
break;
|
||||
|
||||
case HMMType::GaussianMixtureModelHMM:
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#ifdef BINDING_NAME
|
||||
#undef BINDING_NAME
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "dual_tree_kmeans.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::kmeans;
|
||||
using namespace mlpack::util;
|
||||
using namespace std;
|
||||
@@ -191,9 +193,9 @@ void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
// Initialize random seed.
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
RequireOnlyOnePassed(params, { "refined_start", "kmeans_plus_plus" }, true,
|
||||
"Only one initialization strategy can be specified!", true);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::svm;
|
||||
using namespace mlpack::util;
|
||||
|
||||
@@ -178,9 +179,9 @@ PARAM_MATRIX_OUT("probabilities", "If test data is specified, this "
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
// Collect command-line options.
|
||||
const double lambda = params.Get<double>("lambda");
|
||||
|
||||
@@ -187,6 +187,7 @@ PARAM_INT_IN("range", "Number of iterations after which impostors needs to be "
|
||||
PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0);
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::lmnn;
|
||||
using namespace mlpack::metric;
|
||||
using namespace mlpack::util;
|
||||
@@ -238,9 +239,9 @@ double KNNAccuracy(const arma::mat& dataset,
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
RequireAtLeastOnePassed(params, { "output" }, false,
|
||||
"no output will be saved");
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#ifdef BINDING_NAME
|
||||
#undef BINDING_NAME
|
||||
@@ -19,13 +20,13 @@
|
||||
#define BINDING_NAME lsh
|
||||
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
|
||||
#include "lsh_search.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::neighbor;
|
||||
using namespace mlpack::util;
|
||||
|
||||
@@ -114,9 +115,9 @@ PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0);
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) time(NULL));
|
||||
RandomSeed((size_t) time(NULL));
|
||||
|
||||
// Get all the parameters after checking them.
|
||||
if (params.Has("k"))
|
||||
|
||||
@@ -144,6 +144,7 @@ PARAM_DOUBLE_IN("max_step", "Maximum step of line search for L-BFGS.", "M",
|
||||
PARAM_INT_IN("seed", "Random seed. If 0, 'std::time(NULL)' is used.", "s", 0);
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::nca;
|
||||
using namespace mlpack::metric;
|
||||
using namespace mlpack::util;
|
||||
@@ -152,9 +153,9 @@ using namespace std;
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
RequireAtLeastOnePassed(params, { "output" }, false,
|
||||
"no output will be saved");
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#ifdef BINDING_NAME
|
||||
#undef BINDING_NAME
|
||||
@@ -30,6 +31,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::neighbor;
|
||||
using namespace mlpack::tree;
|
||||
using namespace mlpack::metric;
|
||||
@@ -124,9 +126,9 @@ PARAM_DOUBLE_IN("percentage", "If specified, will do approximate furthest "
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
// A user cannot specify both reference data and a model.
|
||||
RequireOnlyOnePassed(params, { "reference", "input_model" }, true);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#ifdef BINDING_NAME
|
||||
#undef BINDING_NAME
|
||||
@@ -32,6 +33,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::neighbor;
|
||||
using namespace mlpack::tree;
|
||||
using namespace mlpack::metric;
|
||||
@@ -132,9 +134,9 @@ PARAM_DOUBLE_IN("epsilon", "If specified, will do approximate nearest neighbor "
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
// A user cannot specify both reference data and a model.
|
||||
RequireOnlyOnePassed(params, { "reference", "input_model" }, true);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#ifdef BINDING_NAME
|
||||
#undef BINDING_NAME
|
||||
@@ -29,6 +30,7 @@
|
||||
#include <mlpack/methods/amf/termination_policies/simple_residue_termination.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::amf;
|
||||
using namespace mlpack::util;
|
||||
using namespace std;
|
||||
@@ -217,9 +219,9 @@ void BINDING_FUNCTION(util::Params& params, util::Timers& /* timers */)
|
||||
{
|
||||
// Initialize random seed.
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
// Gather parameters.
|
||||
const size_t r = params.Get<int>("rank");
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "mlpack/methods/preprocess/scaling_model.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::util;
|
||||
using namespace mlpack::data;
|
||||
using namespace arma;
|
||||
@@ -122,9 +123,9 @@ void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
const std::string scalerMethod = params.Get<string>("scaler_method");
|
||||
|
||||
if (params.Get<int>("seed") == 0)
|
||||
mlpack::math::RandomSeed(std::time(NULL));
|
||||
RandomSeed(std::time(NULL));
|
||||
else
|
||||
mlpack::math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
|
||||
// Make sure the user specified output filenames.
|
||||
RequireAtLeastOnePassed(params, { "output", "output_model"}, false,
|
||||
|
||||
@@ -106,6 +106,7 @@ PARAM_FLAG("no_shuffle", "Avoid shuffling the data before splitting.", "S");
|
||||
PARAM_FLAG("stratify_data", "Stratify the data according to labels", "z")
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::data;
|
||||
using namespace mlpack::util;
|
||||
using namespace arma;
|
||||
@@ -119,9 +120,9 @@ void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
const bool stratifyData = params.Get<bool>("stratify_data");
|
||||
|
||||
if (params.Get<int>("seed") == 0)
|
||||
mlpack::math::RandomSeed(std::time(NULL));
|
||||
RandomSeed(std::time(NULL));
|
||||
else
|
||||
mlpack::math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
|
||||
// Make sure the user specified output filenames.
|
||||
RequireAtLeastOnePassed(params, { "training" }, false, "no training set will "
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
#define BINDING_NAME random_forest
|
||||
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
#include <mlpack/methods/random_forest/random_forest.hpp>
|
||||
#include <mlpack/methods/decision_tree/random_dimension_select.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::tree;
|
||||
using namespace mlpack::util;
|
||||
using namespace std;
|
||||
@@ -171,9 +173,9 @@ void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
// Initialize random seed if needed.
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
// Check for incompatible input parameters.
|
||||
if (!params.Has("warm_start"))
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#ifdef BINDING_NAME
|
||||
#undef BINDING_NAME
|
||||
@@ -28,6 +29,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::range;
|
||||
using namespace mlpack::tree;
|
||||
using namespace mlpack::metric;
|
||||
@@ -123,9 +125,9 @@ PARAM_FLAG("single_mode", "If true, single-tree search is used (as opposed to "
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
// A user cannot specify both reference data and a model.
|
||||
RequireOnlyOnePassed(params, { "reference", "input_model" }, true);
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
#define BINDING_NAME krann
|
||||
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
#include <mlpack/methods/neighbor_search/unmap.hpp>
|
||||
#include "ra_search.hpp"
|
||||
#include "ra_model.hpp"
|
||||
#include <mlpack/methods/neighbor_search/unmap.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
using namespace mlpack::neighbor;
|
||||
using namespace mlpack::tree;
|
||||
using namespace mlpack::metric;
|
||||
@@ -127,9 +128,9 @@ PARAM_INT_IN("single_sample_limit", "The limit on the maximum number of "
|
||||
void BINDING_FUNCTION(util::Params& params, util::Timers& timers)
|
||||
{
|
||||
if (params.Get<int>("seed") != 0)
|
||||
math::RandomSeed((size_t) params.Get<int>("seed"));
|
||||
RandomSeed((size_t) params.Get<int>("seed"));
|
||||
else
|
||||
math::RandomSeed((size_t) std::time(NULL));
|
||||
RandomSeed((size_t) std::time(NULL));
|
||||
|
||||
// A user cannot specify both reference data and a model.
|
||||
RequireOnlyOnePassed(params, { "reference", "input_model" }, true);
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
namespace mlpack {
|
||||
namespace rl {
|
||||
|
||||
using namespace mlpack::ann;
|
||||
|
||||
/**
|
||||
* Implementation of the Categorical Deep Q-Learning network.
|
||||
* For more information, see the following.
|
||||
@@ -43,9 +41,9 @@ using namespace mlpack::ann;
|
||||
* @tparam NetworkType The type of network used for simple dqn.
|
||||
*/
|
||||
template<
|
||||
typename OutputLayerType = EmptyLoss<>,
|
||||
typename InitType = GaussianInitialization,
|
||||
typename NetworkType = FFN<OutputLayerType, InitType>
|
||||
typename OutputLayerType = ann::EmptyLoss<>,
|
||||
typename InitType = ann::GaussianInitialization,
|
||||
typename NetworkType = ann::FFN<OutputLayerType, InitType>
|
||||
>
|
||||
class CategoricalDQN
|
||||
{
|
||||
@@ -83,21 +81,21 @@ class CategoricalDQN
|
||||
vMax(config.VMax()),
|
||||
isNoisy(isNoisy)
|
||||
{
|
||||
network.Add(new Linear<>(inputDim, h1));
|
||||
network.Add(new ReLULayer<>());
|
||||
network.Add(new ann::Linear<>(inputDim, h1));
|
||||
network.Add(new ann::ReLULayer<>());
|
||||
if (isNoisy)
|
||||
{
|
||||
noisyLayerIndex.push_back(network.Model().size());
|
||||
network.Add(new NoisyLinear<>(h1, h2));
|
||||
network.Add(new ReLULayer<>());
|
||||
network.Add(new ann::NoisyLinear<>(h1, h2));
|
||||
network.Add(new ann::ReLULayer<>());
|
||||
noisyLayerIndex.push_back(network.Model().size());
|
||||
network.Add(new NoisyLinear<>(h2, outputDim * atomSize));
|
||||
network.Add(new ann::NoisyLinear<>(h2, outputDim * atomSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
network.Add(new Linear<>(h1, h2));
|
||||
network.Add(new ReLULayer<>());
|
||||
network.Add(new Linear<>(h2, outputDim * atomSize));
|
||||
network.Add(new ann::Linear<>(h1, h2));
|
||||
network.Add(new ann::ReLULayer<>());
|
||||
network.Add(new ann::Linear<>(h2, outputDim * atomSize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,9 +179,9 @@ class CategoricalDQN
|
||||
*/
|
||||
void ResetNoise()
|
||||
{
|
||||
for (size_t i = 0; i < noisyLayerIndex.size(); i++)
|
||||
for (size_t i = 0; i < noisyLayerIndex.size(); ++i)
|
||||
{
|
||||
boost::get<NoisyLinear<>*>
|
||||
boost::get<ann::NoisyLinear<>*>
|
||||
(network.Model()[noisyLayerIndex[i]])->ResetNoise();
|
||||
}
|
||||
}
|
||||
@@ -236,7 +234,7 @@ class CategoricalDQN
|
||||
std::vector<size_t> noisyLayerIndex;
|
||||
|
||||
//! Locally-stored softmax activation function.
|
||||
Softmax<> softMax;
|
||||
ann::Softmax<> softMax;
|
||||
|
||||
//! Locally-stored activations from softMax.
|
||||
arma::mat activations;
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
namespace mlpack {
|
||||
namespace rl {
|
||||
|
||||
using namespace mlpack::ann;
|
||||
|
||||
/**
|
||||
* Implementation of the Dueling Deep Q-Learning network.
|
||||
* For more information, see the following.
|
||||
@@ -46,12 +44,12 @@ using namespace mlpack::ann;
|
||||
* @tparam ValueNetworkType The type of network used for value network.
|
||||
*/
|
||||
template <
|
||||
typename OutputLayerType = EmptyLoss<>,
|
||||
typename InitType = GaussianInitialization,
|
||||
typename CompleteNetworkType = FFN<OutputLayerType, InitType>,
|
||||
typename FeatureNetworkType = Sequential<>,
|
||||
typename AdvantageNetworkType = Sequential<>,
|
||||
typename ValueNetworkType = Sequential<>
|
||||
typename OutputLayerType = ann::EmptyLoss<>,
|
||||
typename InitType = ann::GaussianInitialization,
|
||||
typename CompleteNetworkType = ann::FFN<OutputLayerType, InitType>,
|
||||
typename FeatureNetworkType = ann::Sequential<>,
|
||||
typename AdvantageNetworkType = ann::Sequential<>,
|
||||
typename ValueNetworkType = ann::Sequential<>
|
||||
>
|
||||
class DuelingDQN
|
||||
{
|
||||
@@ -59,14 +57,14 @@ class DuelingDQN
|
||||
//! Default constructor.
|
||||
DuelingDQN() : isNoisy(false)
|
||||
{
|
||||
featureNetwork = new Sequential<>();
|
||||
valueNetwork = new Sequential<>();
|
||||
advantageNetwork = new Sequential<>();
|
||||
concat = new Concat<>(true);
|
||||
featureNetwork = new ann::Sequential<>();
|
||||
valueNetwork = new ann::Sequential<>();
|
||||
advantageNetwork = new ann::Sequential<>();
|
||||
concat = new ann::Concat<>(true);
|
||||
|
||||
concat->Add(valueNetwork);
|
||||
concat->Add(advantageNetwork);
|
||||
completeNetwork.Add(new IdentityLayer<>());
|
||||
completeNetwork.Add(new ann::IdentityLayer<>());
|
||||
completeNetwork.Add(featureNetwork);
|
||||
completeNetwork.Add(concat);
|
||||
}
|
||||
@@ -92,42 +90,42 @@ class DuelingDQN
|
||||
completeNetwork(outputLayer, init),
|
||||
isNoisy(isNoisy)
|
||||
{
|
||||
featureNetwork = new Sequential<>();
|
||||
featureNetwork->Add(new Linear<>(inputDim, h1));
|
||||
featureNetwork->Add(new ReLULayer<>());
|
||||
featureNetwork = new ann::Sequential<>();
|
||||
featureNetwork->Add(new ann::Linear<>(inputDim, h1));
|
||||
featureNetwork->Add(new ann::ReLULayer<>());
|
||||
|
||||
valueNetwork = new Sequential<>();
|
||||
advantageNetwork = new Sequential<>();
|
||||
valueNetwork = new ann::Sequential<>();
|
||||
advantageNetwork = new ann::Sequential<>();
|
||||
|
||||
if (isNoisy)
|
||||
{
|
||||
noisyLayerIndex.push_back(valueNetwork->Model().size());
|
||||
valueNetwork->Add(new NoisyLinear<>(h1, h2));
|
||||
advantageNetwork->Add(new NoisyLinear<>(h1, h2));
|
||||
valueNetwork->Add(new ann::NoisyLinear<>(h1, h2));
|
||||
advantageNetwork->Add(new ann::NoisyLinear<>(h1, h2));
|
||||
|
||||
valueNetwork->Add(new ReLULayer<>());
|
||||
advantageNetwork->Add(new ReLULayer<>());
|
||||
valueNetwork->Add(new ann::ReLULayer<>());
|
||||
advantageNetwork->Add(new ann::ReLULayer<>());
|
||||
|
||||
noisyLayerIndex.push_back(valueNetwork->Model().size());
|
||||
valueNetwork->Add(new NoisyLinear<>(h2, 1));
|
||||
advantageNetwork->Add(new NoisyLinear<>(h2, outputDim));
|
||||
valueNetwork->Add(new ann::NoisyLinear<>(h2, 1));
|
||||
advantageNetwork->Add(new ann::NoisyLinear<>(h2, outputDim));
|
||||
}
|
||||
else
|
||||
{
|
||||
valueNetwork->Add(new Linear<>(h1, h2));
|
||||
valueNetwork->Add(new ReLULayer<>());
|
||||
valueNetwork->Add(new Linear<>(h2, 1));
|
||||
valueNetwork->Add(new ann::Linear<>(h1, h2));
|
||||
valueNetwork->Add(new ann::ReLULayer<>());
|
||||
valueNetwork->Add(new ann::Linear<>(h2, 1));
|
||||
|
||||
advantageNetwork->Add(new Linear<>(h1, h2));
|
||||
advantageNetwork->Add(new ReLULayer<>());
|
||||
advantageNetwork->Add(new Linear<>(h2, outputDim));
|
||||
advantageNetwork->Add(new ann::Linear<>(h1, h2));
|
||||
advantageNetwork->Add(new ann::ReLULayer<>());
|
||||
advantageNetwork->Add(new ann::Linear<>(h2, outputDim));
|
||||
}
|
||||
|
||||
concat = new Concat<>(true);
|
||||
concat = new ann::Concat<>(true);
|
||||
concat->Add(valueNetwork);
|
||||
concat->Add(advantageNetwork);
|
||||
|
||||
completeNetwork.Add(new IdentityLayer<>());
|
||||
completeNetwork.Add(new ann::IdentityLayer<>());
|
||||
completeNetwork.Add(featureNetwork);
|
||||
completeNetwork.Add(concat);
|
||||
this->ResetParameters();
|
||||
@@ -150,10 +148,10 @@ class DuelingDQN
|
||||
valueNetwork(valueNetwork),
|
||||
isNoisy(isNoisy)
|
||||
{
|
||||
concat = new Concat<>(true);
|
||||
concat = new ann::Concat<>(true);
|
||||
concat->Add(valueNetwork);
|
||||
concat->Add(advantageNetwork);
|
||||
completeNetwork.Add(new IdentityLayer<>());
|
||||
completeNetwork.Add(new ann::IdentityLayer<>());
|
||||
completeNetwork.Add(featureNetwork);
|
||||
completeNetwork.Add(concat);
|
||||
this->ResetParameters();
|
||||
@@ -245,9 +243,9 @@ class DuelingDQN
|
||||
{
|
||||
for (size_t i = 0; i < noisyLayerIndex.size(); i++)
|
||||
{
|
||||
boost::get<NoisyLinear<>*>
|
||||
boost::get<ann::NoisyLinear<>*>
|
||||
(valueNetwork->Model()[noisyLayerIndex[i]])->ResetNoise();
|
||||
boost::get<NoisyLinear<>*>
|
||||
boost::get<ann::NoisyLinear<>*>
|
||||
(advantageNetwork->Model()[noisyLayerIndex[i]])->ResetNoise();
|
||||
}
|
||||
}
|
||||
@@ -262,7 +260,7 @@ class DuelingDQN
|
||||
CompleteNetworkType completeNetwork;
|
||||
|
||||
//! Locally-stored concat network.
|
||||
Concat<>* concat;
|
||||
ann::Concat<>* concat;
|
||||
|
||||
//! Locally-stored feature network.
|
||||
FeatureNetworkType* featureNetwork;
|
||||
@@ -283,7 +281,7 @@ class DuelingDQN
|
||||
arma::mat actionValues;
|
||||
|
||||
//! Locally-stored loss function.
|
||||
MeanSquaredError<> lossFunction;
|
||||
ann::MeanSquaredError<> lossFunction;
|
||||
};
|
||||
|
||||
} // namespace rl
|
||||
|
||||
@@ -21,17 +21,15 @@
|
||||
namespace mlpack {
|
||||
namespace rl {
|
||||
|
||||
using namespace mlpack::ann;
|
||||
|
||||
/**
|
||||
* @tparam OutputLayerType The output layer type of the network.
|
||||
* @tparam InitType The initialization type used for the network.
|
||||
* @tparam NetworkType The type of network used for simple dqn.
|
||||
*/
|
||||
template<
|
||||
typename OutputLayerType = MeanSquaredError<>,
|
||||
typename InitType = GaussianInitialization,
|
||||
typename NetworkType = FFN<OutputLayerType, InitType>
|
||||
typename OutputLayerType = ann::MeanSquaredError<>,
|
||||
typename InitType = ann::GaussianInitialization,
|
||||
typename NetworkType = ann::FFN<OutputLayerType, InitType>
|
||||
>
|
||||
class SimpleDQN
|
||||
{
|
||||
@@ -63,21 +61,21 @@ class SimpleDQN
|
||||
network(outputLayer, init),
|
||||
isNoisy(isNoisy)
|
||||
{
|
||||
network.Add(new Linear<>(inputDim, h1));
|
||||
network.Add(new ReLULayer<>());
|
||||
network.Add(new ann::Linear<>(inputDim, h1));
|
||||
network.Add(new ann::ReLULayer<>());
|
||||
if (isNoisy)
|
||||
{
|
||||
noisyLayerIndex.push_back(network.Model().size());
|
||||
network.Add(new NoisyLinear<>(h1, h2));
|
||||
network.Add(new ReLULayer<>());
|
||||
network.Add(new ann::NoisyLinear<>(h1, h2));
|
||||
network.Add(new ann::ReLULayer<>());
|
||||
noisyLayerIndex.push_back(network.Model().size());
|
||||
network.Add(new NoisyLinear<>(h2, outputDim));
|
||||
network.Add(new ann::NoisyLinear<>(h2, outputDim));
|
||||
}
|
||||
else
|
||||
{
|
||||
network.Add(new Linear<>(h1, h2));
|
||||
network.Add(new ReLULayer<>());
|
||||
network.Add(new Linear<>(h2, outputDim));
|
||||
network.Add(new ann::Linear<>(h1, h2));
|
||||
network.Add(new ann::ReLULayer<>());
|
||||
network.Add(new ann::Linear<>(h2, outputDim));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +132,7 @@ class SimpleDQN
|
||||
{
|
||||
for (size_t i = 0; i < noisyLayerIndex.size(); i++)
|
||||
{
|
||||
boost::get<NoisyLinear<>*>
|
||||
boost::get<ann::NoisyLinear<>*>
|
||||
(network.Model()[noisyLayerIndex[i]])->ResetNoise();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user