Merge branch 'master' into FAIL-Messages

This commit is contained in:
Ryan Birmingham
2021-02-24 12:24:02 -05:00
committed by GitHub
300 changed files with 10363 additions and 7834 deletions
-1
View File
@@ -71,7 +71,6 @@ build_script:
-DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY%
-DCEREAL_INCLUDE_DIR="C:/projects/mlpack/unofficial-flayan-cereal.1.2.2/build/native/include"
-DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE%
-DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack/boost_libs"
-DDEBUG=OFF
-DPROFILE=OFF
-DBUILD_PYTHON_BINDINGS=OFF
-19
View File
@@ -59,25 +59,6 @@ jobs:
steps:
- template: macos-steps.yaml
# - job: WindowsVS15
# timeoutInMinutes: 360
# displayName: Windows VS15
# pool:
# vmImage: vs2017-win2016
# strategy:
# matrix:
# Plain:
# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
# python.version: '2.7'
# CMakeGenerator: '-G "Visual Studio 15 2017 Win64"'
# MSBuildVersion: '15.0'
# ArchiveNoLibs: 'mlpack-windows-vs15-no-libs.zip'
# ArchiveLibs: 'mlpack-windows-vs15.zip'
# ArchiveTests: 'mlpack_test-vs15.xml'
# steps:
# - template: windows-steps.yaml
- job: WindowsVS16
timeoutInMinutes: 360
displayName: Windows VS16
+1 -1
View File
@@ -21,7 +21,7 @@ steps:
unset BOOST_ROOT
echo "##vso[task.setvariable variable=BOOST_ROOT]"$BOOST_ROOT
sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost1.70-dev libarmadillo-dev xz-utils
sudo apt-get install -y --allow-unauthenticated libopenblas-dev g++ libboost1.70-dev xz-utils
if [ "$(binding)" == "python" ]; then
export PYBIN=$(which python)
+1 -1
View File
@@ -22,7 +22,7 @@ steps:
fi
if [ "a$(julia.version)" != "a" ]; then
brew cask install julia
brew install --cask julia
fi
git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf
+55
View File
@@ -116,6 +116,56 @@ steps:
replaceExistingArchive: true
displayName: 'Build artifacts'
# Build MSI installer.
- powershell: |
# Pull the documentation for the installer.
try {
$url = "http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip"
(new-object net.webclient).DownloadFile($url, 'dist\win-installer\jenkinsdoc.zip')
}
catch {
Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!"
}
try {
(Add-Type -AssemblyName System.IO.Compression.FileSystem);
[System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\mlpack-win-installer\Sources\doc')
}
catch{Write-Output "Unable to add doc to installer, skipping!"}
# Preparing installer staging.
mkdir dist\win-installer\mlpack-win-installer\Sources\lib
cp build\Release\*.lib dist\win-installer\mlpack-win-installer\Sources\lib\
cp build\Release\*.exp dist\win-installer\mlpack-win-installer\Sources\lib\
cp build\Release\*.dll dist\win-installer\mlpack-win-installer\Sources\
cp build\Release\*.exe dist\win-installer\mlpack-win-installer\Sources\
cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\mlpack-win-installer\Sources\
cp build\include\mlpack dist\win-installer\mlpack-win-installer\Sources -recurse
cp doc\examples dist\win-installer\mlpack-win-installer\Sources -recurse
cp src\mlpack\tests\data\german.csv dist\win-installer\mlpack-win-installer\Sources\examples\sample-ml-app\sample-ml-app\data\
# Check current git version or mlpack version.
$ver = (Get-Content "src\mlpack\core\util\version.hpp" | where {$_ -like "*MLPACK_VERSION*"});
$env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.';
$env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.';
$env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1);
if (Test-Path "src/mlpack/core/util/gitversion.hpp")
{
$ver = (Get-Content "src/mlpack/core/util/gitversion.hpp");
$env:INSTALL_VERSION = $ver.Split('"')[1].Split(' ')[1];
}
else
{
$env:INSTALL_VERSION = $env:MLPACK_VERSION;
}
# Build the MSI installer.
cd dist\win-installer\mlpack-win-installer
& 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' `
-t:rebuild `
-p:Configuration=Release `
-p:TreatWarningsAsErrors=True `
mlpack-win-installer.wixproj
displayName: 'Build MSI Windows installer'
# Publish artifacts to Azure Pipelines
- task: PublishBuildArtifacts@1
inputs:
@@ -132,6 +182,11 @@ steps:
pathtoPublish: 'build/Testing/'
artifactName: 'Tests'
displayName: 'Publish artifacts test results'
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\Release\mlpack-windows.msi'
artifactName: mlpack-windows-installer
displayName: 'Publish Windows MSI installer'
# Publish test results to Azure Pipelines
- task: PublishTestResults@2
@@ -0,0 +1,81 @@
name: Update Boost Version
on:
workflow_dispatch:
schedule:
- cron: '0 10 * * *'
jobs:
updateBoostVersion:
if: ${{ github.repository == 'mlpack/mlpack' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Build Dependencies
run: |
sudo apt-get update
sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev libcereal-dev
curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*
cmake . && make && sudo make install && cd .. && rm -r armadillo*
- name: Get Latest Boost Tagged Release
id: boost-version
run: |
# CMake for extracting present boost version.
mkdir build && cd build
cmake ..
# Ping version information upstream.
BOOST_RELEASE_JSON=$(curl -sL https://api.github.com/repos/boostorg/boost/tags)
FOUND_NEW="NO"
# Compare present and upstream boost version.
for i in `jq -r .[].name <<< "$BOOST_RELEASE_JSON" | awk '!/.beta/' | \
grep -Po "(\d+\.)+\d+"`
do
FOUND_SIMILAR="NO"
for j in `grep Boost_ADDITIONAL_VERSIONS_LAST CMakeCache.txt | \
cut -d "=" -f2 | sed "s/;/ /g"`
do
if [[ "$i" == "$j" ]];
then
FOUND_SIMILAR="YES"
break
fi
done
if [[ "$FOUND_SIMILAR" != "YES" ]];
then
FOUND_NEW="YES"
BOOST_VERSION="$BOOST_VERSION\"$i\" "
fi
FOUND_SIMILAR="NO"
for j in `grep Boost_ADDITIONAL_VERSIONS_LAST CMakeCache.txt | \
cut -d "=" -f2 | sed "s/;/ /g"`
do
if [[ $(echo $i | grep -Po "(\d+)\.\d+") == "$j" ]];
then
FOUND_SIMILAR="YES"
break
fi
done
if [[ "$FOUND_SIMILAR" != "YES" ]];
then
FOUND_NEW="YES"
BOOST_VERSION="$BOOST_VERSION\"$(echo $i | grep -Po "(\d+)\.\d+")\" "
fi
done
# If found the new boost version, then update the CMake script.
if [[ "$FOUND_NEW" == "YES" ]]
then
sed --in-place "s/set(Boost_ADDITIONAL_VERSIONS/set(Boost_ADDITIONAL_VERSIONS\n ${BOOST_VERSION: : -1}/" ../CMakeLists.txt
fi
- name: Create Pull Request For Boost Version
uses: peter-evans/create-pull-request@v3
with:
commit-message: Upgrade Boost Version in CMake script.
title: Upgrade Boost Version in CMake script.
body: |
Updates [boostorg/boost](https://github.com/boostorg/boost) in CMake script.
Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request).
labels: update dependencies, automated PR
branch: boost-version-updates
+1 -1
View File
@@ -35,7 +35,7 @@ if(CEREAL_INCLUDE_DIR)
set(CEREAL_VERSION_MAJOR 1)
set(CEREAL_VERSION_MINOR 1)
set(CEREAL_VERSION_PATCH 2)
elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/cereal.hpp")
elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/cereal.hpp")
set(CEREAL_VERSION_MAJOR 1)
set(CEREAL_VERSION_MINOR 1)
+12 -1
View File
@@ -32,8 +32,19 @@ function(append_type TYPES_FILE PROGRAM_NAME PROGRAM_MAIN_FILE)
# function.
file(APPEND
"${TYPES_FILE}"
"struct ${MODEL_SAFE_TYPE}\n"
"mutable struct ${MODEL_SAFE_TYPE}\n"
" ptr::Ptr{Nothing}\n"
"\n"
" # Construct object and set finalizer to free memory if `finalize` is true.\n"
" function ${MODEL_SAFE_TYPE}(ptr::Ptr{Nothing}; finalize::Bool = false)::${MODEL_SAFE_TYPE}\n"
" result = new(ptr)\n"
" if finalize\n"
" finalizer(\n"
" x -> _Internal.${PROGRAM_NAME}_internal.Delete${MODEL_SAFE_TYPE}(x.ptr),\n"
" result)\n"
" end\n"
" return result\n"
" end\n"
"end\n"
"\n")
endif ()
+9
View File
@@ -29,6 +29,8 @@ if (${NUM_MODEL_TYPES} GREATER 0)
void* IO_GetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName);
// Set the pointer to a ${MODEL_TYPE} parameter.
void IO_SetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName, void* ptr);
// Delete a ${MODEL_TYPE} pointer.
void Delete${MODEL_SAFE_TYPE}Ptr(void* ptr);
// Serialize a ${MODEL_TYPE} pointer.
char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length);
// Deserialize a ${MODEL_TYPE} pointer.
@@ -50,6 +52,13 @@ void IO_SetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName, void* ptr)
IO::SetPassed(paramName);
}
// Delete a ${MODEL_TYPE} pointer.
void Delete${MODEL_SAFE_TYPE}Ptr(void* ptr)
{
${MODEL_TYPE}* modelPtr = (${MODEL_TYPE}*) ptr;
delete modelPtr;
}
// Serialize a ${MODEL_TYPE} pointer.
char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length)
{
+47 -64
View File
@@ -17,6 +17,7 @@ option(DISABLE_DOWNLOADS "Disable downloads of dependencies during build." OFF)
option(DOWNLOAD_ENSMALLEN "If ensmallen is not found, download it." ON)
option(DOWNLOAD_STB_IMAGE "Download stb_image for image loading." ON)
option(BUILD_GO_SHLIB "Build Go shared library." OFF)
option(BUILD_DOCS "Build doxygen documentation (if doxygen is available)." ON)
# Set minimum library version required by mlpack.
set(ARMADILLO_VERSION "8.400.0")
@@ -51,7 +52,7 @@ if (BUILD_JULIA_BINDINGS)
else()
set(FORCE_BUILD_JULIA_BINDINGS OFF)
endif()
option(BUILD_JULIA_BINDINGS "Build Julia bindings." ON)
option(BUILD_JULIA_BINDINGS "Build Julia bindings." OFF)
# Detect whether the user passed BUILD_GO_BINDINGS in order to determine if
# we should fail if Go isn't found.
@@ -60,7 +61,7 @@ if (BUILD_GO_BINDINGS)
else()
set(FORCE_BUILD_GO_BINDINGS OFF)
endif()
option(BUILD_GO_BINDINGS "Build Go bindings." ON)
option(BUILD_GO_BINDINGS "Build Go bindings." OFF)
# If building Go bindings then build go shared libraries.
if (BUILD_GO_BINDINGS)
@@ -74,7 +75,7 @@ if (BUILD_R_BINDINGS)
else()
set(FORCE_BUILD_R_BINDINGS OFF)
endif()
option(BUILD_R_BINDINGS "Build R bindings." ON)
option(BUILD_R_BINDINGS "Build R bindings." OFF)
# Build Markdown bindings for documentation. This is used as part of website
# generation.
option(BUILD_MARKDOWN_BINDINGS "Build Markdown bindings for website documentation." OFF)
@@ -288,7 +289,6 @@ endif()
# ARMADILLO_INCLUDE_DIRS - directories necessary for Armadillo includes
# BOOST_ROOT - root of Boost installation
# BOOST_INCLUDEDIR - include directory for Boost
# BOOST_LIBRARYDIR - library directory for Boost
# ENSMALLEN_INCLUDE_DIR - include directory for ensmallen
# STB_IMAGE_INCLUDE_DIR - include directory for STB image library
# MATHJAX_ROOT - root of MathJax installation
@@ -419,8 +419,9 @@ set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${CEREAL_INCLUDE_DIR})
# Unfortunately this configuration variable is necessary and will need to be
# updated as time goes on and new versions are released.
set(Boost_ADDITIONAL_VERSIONS
"1.74.0" "1.74"
"17.3.0" "17.3"
"1.75.0" "1.75"
"1.74.0" "1.74"
"1.73.0" "1.73"
"1.72.0" "1.72"
"1.71.0" "1.71"
"1.70.0" "1.70"
@@ -442,31 +443,11 @@ set(Boost_ADDITIONAL_VERSIONS
# TODO for the brave: transition all mlpack's CMake to 'target-based modern
# CMake'. Good luck! You'll need it.
set(Boost_NO_BOOST_CMAKE 1)
find_package(Boost "${BOOST_VERSION}"
COMPONENTS
REQUIRED
)
link_directories(${Boost_LIBRARY_DIRS})
# In Visual Studio, automatic linking is performed, so we don't need to worry
# about it. Clear the list of libraries to link against and let Visual Studio
# handle it.
if (MSVC)
link_directories(${Boost_LIBRARY_DIRS})
set(CMAKE_MSVCIDE_RUN_PATH ${CMAKE_MSVCIDE_RUN_PATH} ${Boost_LIBRARY_DIRS})
message("boost lib dirs ${Boost_LIBRARY_DIRS}")
set(Boost_LIBRARIES "")
endif ()
find_package(Boost "${BOOST_VERSION}")
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${Boost_LIBRARIES})
set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
# For Boost testing framework (will have no effect on non-testing executables).
# This specifies to Boost that we are dynamically linking to the Boost test
# library.
add_definitions(-DBOOST_TEST_DYN_LINK)
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES})
set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS})
# Detect OpenMP support in a compiler. If the compiler supports OpenMP, flags
# to compile with OpenMP are returned and added and the HAS_OPENMP definition
@@ -617,43 +598,45 @@ add_dependencies(mlpack_headers mlpack_arma_config)
# Make a target to generate the documentation. If Doxygen isn't installed, then
# I guess this option will just be unavailable.
find_package(Doxygen)
if (DOXYGEN_FOUND)
if (MATHJAX)
find_package(MathJax)
if (NOT MATHJAX_FOUND)
message(STATUS "Using MathJax at the MathJax Content Delivery Network. "
"Be careful, formulas will not be shown without the internet.")
if (BUILD_DOCS)
find_package(Doxygen)
if (DOXYGEN_FOUND)
if (MATHJAX)
find_package(MathJax)
if (NOT MATHJAX_FOUND)
message(STATUS "Using MathJax at the MathJax Content Delivery Network. "
"Be careful, formulas will not be shown without the internet.")
endif ()
endif ()
# Preprocess the Doxyfile. This is done before 'make doc'.
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Doxyfile
PRE_BUILD
COMMAND ${CMAKE_COMMAND}
-D DESTDIR=${CMAKE_BINARY_DIR}
-D MATHJAX="${MATHJAX}"
-D MATHJAX_FOUND="${MATHJAX_FOUND}"
-D MATHJAX_PATH="${MATHJAX_PATH}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GenerateDoxyfile.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile"
COMMENT "Creating Doxyfile to generate Doxygen documentation"
)
# Generate documentation.
add_custom_target(doc
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile"
DEPENDS "${CMAKE_BINARY_DIR}/Doxyfile"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Generating API documentation with Doxygen"
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html"
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
COMPONENT doc
OPTIONAL
)
endif ()
# Preprocess the Doxyfile. This is done before 'make doc'.
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Doxyfile
PRE_BUILD
COMMAND ${CMAKE_COMMAND}
-D DESTDIR=${CMAKE_BINARY_DIR}
-D MATHJAX="${MATHJAX}"
-D MATHJAX_FOUND="${MATHJAX_FOUND}"
-D MATHJAX_PATH="${MATHJAX_PATH}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GenerateDoxyfile.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile"
COMMENT "Creating Doxyfile to generate Doxygen documentation"
)
# Generate documentation.
add_custom_target(doc
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile"
DEPENDS "${CMAKE_BINARY_DIR}/Doxyfile"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Generating API documentation with Doxygen"
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html"
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
COMPONENT doc
OPTIONAL
)
endif ()
endif()
# Create the pkg-config file, if we have pkg-config.
find_package(PkgConfig)
+16 -11
View File
@@ -7,7 +7,7 @@ Source:
Files: *
Copyright:
Copyright 2008-2018, Ryan Curtin <ryan@ratml.org>
Copyright 2008-2021, Ryan Curtin <ryan@ratml.org>
Copyright 2008-2013, Bill March <march@gatech.edu>
Copyright 2008-2012, Dongryeol Lee <dongryel@cc.gatech.edu>
Copyright 2008-2013, Nishant Mehta <niche@cc.gatech.edu>
@@ -22,11 +22,11 @@ Copyright:
Copyright 2012, Rajendran Mohan <rmohan88@gatech.edu>
Copyright 2012, Trironk Kiatkungwanglai <trironk@gmail.com>
Copyright 2012, Patrick Mason <patrick.s.mason@gmail.com>
Copyright 2013-2018, Marcus Edel <marcus.edel@fu-berlin.de>
Copyright 2013-2020, Marcus Edel <marcus.edel@fu-berlin.de>
Copyright 2013, Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
Copyright 2013-2018, Sumedh Ghaisas <sumedhghaisas@gmail.com>
Copyright 2014, Michael Fox <michaelfox99@gmail.com>
Copyright 2014, Ryan Birmingham <birm@gatech.edu>
Copyright 2014,2020 Ryan Birmingham <birm@gatech.edu>
Copyright 2014, Siddharth Agrawal <siddharth.950@gmail.com>
Copyright 2014, Saheb Motiani <saheb210692@gmail.com>
Copyright 2014, Yash Vadalia <yashdv@gmail.com>
@@ -37,7 +37,7 @@ Copyright:
Copyright 2014, Udit Saxena <saxenda.udit@gmail.com>
Copyright 2014-2015, Stephen Tu <tu.stephenl@gmail.com>
Copyright 2014-2015, Jaskaran Singh <jaskaranvirdi@ymail.com>
Copyright 2015&2017, Shangtong Zhang <zhangshangtong.cpp@gmail.com>
Copyright 2015,2017, Shangtong Zhang <zhangshangtong.cpp@gmail.com>
Copyright 2015, Hritik Jain <hritik.jain.cse13@itbhu.ac.in>
Copyright 2015, Vladimir Glazachev <glazachev.vladimir@gmail.com>
Copyright 2015, QiaoAn Chen <kazenoyumechen@gmail.com>
@@ -55,7 +55,7 @@ Copyright:
Copyright 2016, Palash Ahuja <abhor902@gmail.com>
Copyright 2016, Yannis Mentekidis <mentekid@gmail.com>
Copyright 2016, Ranjan Mondal <ranjan.rev@gmail.com>
Copyright 2016-2018, Mikhail Lozhnikov <lozhnikovma@gmail.com>
Copyright 2016-2020, Mikhail Lozhnikov <lozhnikovma@gmail.com>
Copyright 2016, Marcos Pividori <marcos.pividori@gmail.com>
Copyright 2016, Keon Kim <kwk236@gmail.com>
Copyright 2016, Nilay Jain <nilayjain13@gmail.com>
@@ -84,14 +84,14 @@ Copyright:
Copyright 2017, N Rajiv Vaidyanathan <rajivvaidyanathan4@gmail.com>
Copyright 2017, Kartik Nighania <kartiknighania@gmail.com>
Copyright 2017-2018, Eugene Freyman <evg.freyman@gmail.com>
Copyright 2017-2018, Manish Kumar <manish887kr@gmail.com>
Copyright 2017-2019, Manish Kumar <manish887kr@gmail.com>
Copyright 2017-2018, Haritha Sreedharan Nair <haritha1313@gmail.com>
Copyright 2017-2018, Sourabh Varshney <sourabhvarshney111@gmail.com>
Copyright 2018, Projyal Dev <projyal@gmail.com>
Copyright 2018, Nikhil Goel <nikhilgoel199797@gmail.com>
Copyright 2018, Shikhar Jaiswal <jaiswalshikhar87@gmail.com>
Copyright 2018-2020 Shikhar Jaiswal <jaiswalshikhar87@gmail.com>
Copyright 2018, B Kartheek Reddy <bkartheekreddy@gmail.com>
Copyright 2018, Atharva Khandait <akhandait45@gmail.com>
Copyright 2018-2019 Atharva Khandait <akhandait45@gmail.com>
Copyright 2018, Wenhao Huang <wenhao.huang.work@gmail.com>
Copyright 2018-2019, Roberto Hueso <robertohueso96@gmail.com>
Copyright 2018, Prabhat Sharma <prabhatsharma7298@gmail.com>
@@ -114,9 +114,9 @@ Copyright:
Copyright 2019, Miguel Canteras <mcanteras@gmail.com>
Copyright 2019, Bishwa Karki <karkeebishwa1@gmail.com>
Copyright 2019, Mehul Kumar Nirala <mehulkumarnirala@gmail.com>
Copyright 2019, Yashwant Singh Parihar <yashwantsingh.sngh@gmail.com>
Copyright 2019-2020 Yashwant Singh Parihar <yashwantsingh.sngh@gmail.com>
Copyright 2019, Heet Sankesara <heetsankesara3@gmail.com>
Copyright 2019, Jeffin Sam <sam.jeffin@gmail.com>
Copyright 2019-2020 Jeffin Sam <sam.jeffin@gmail.com>
Copyright 2019, Vikas S Shetty <shettyvikas209@gmail.com>
Copyright 2019, Khizir Siddiqui <khizirsiddiqui@gmail.com>
Copyright 2019, Tejasvi Tomar <tstomar@outlook.com>
@@ -124,7 +124,7 @@ Copyright:
Copyright 2019, Ziyang Jiang <zij004@alumni.stanford.edu>
Copyright 2019, Rohit Kartik <rohit.audrey@gmail.com>
Copyright 2019, Aditya Viki <adityaviki01@gmail.com>
Copyright 2019, Kartik Dutt <kartikdutt@live.in>
Copyright 2019-2020 Kartik Dutt <kartikdutt@live.in>
Copyright 2020, Sriram S K <sriramsk1999@gmail.com>
Copyright 2020, Manoranjan Kumar Bharti ( Nakul Bharti ) <knakul853@gmail.com>
Copyright 2020, Saraansh Tandon <saraanshtandon1999@gmail.com>
@@ -136,6 +136,11 @@ Copyright:
Copyright 2020, Aakash Kaushik <kaushikaakash7539@gmail.com>
Copyright 2020, Anush Kini <anushkini@gmail.com>
Copyright 2020, Nippun Sharma <inbox.nippun@gmail.com>
Copyright 2020, Rishabh Garg <rishabhgarg108@gmail.com>
Copyright 2020, Sudhakar Brar <dxhrmhall1449@tutanota.com>
Copyright 2020, Alex Nguyen <alexvn.edu@gmail.com>
Copyright 2020, Gaurav Ghati <gauravghatii@gmail.com>
Copyright 2020, Anmolpreet Singh <anmol323c@gmail.com>
License: BSD-3-clause
All rights reserved.
+2 -1
View File
@@ -75,7 +75,8 @@ FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_AS_ERROR = YES
# This will be set to YES for the Jenkins doxygen check build.
WARN_AS_ERROR = NO
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = YES
+30
View File
@@ -1,7 +1,37 @@
### mlpack ?.?.?
###### ????-??-??
* Add "check_input_matrices" option to python bindings that checks
for NaN and inf values in all the input matrices (#2787).
* Add Adjusted R squared functionality to R2Score::Evaluate (#2624).
* Disabled all the bindings by default in CMake (#2782).
* Added an implementation to Stratify Data (#2671).
* Add `BUILD_DOCS` CMake option to control whether Doxygen documentation is
built (default ON) (#2730).
* Add Triplet Margin Loss function (#2762).
* Add finalizers to Julia binding model types to fix memory handling (#2756).
* HMM: add functions to calculate likelihood for data stream with/without
pre-calculated emission probability (#2142).
* Replace Boost serialization library with Cereal (#2458).
* Add `PYTHON_INSTALL_PREFIX` CMake option to specify installation root for
Python bindings (#2797).
* Removed `boost::visitor` from model classes for `knn`, `kfn`, `cf`,
`range_search`, `krann`, and `kde` bindings (#2803).
* Add k-means++ initialization strategy (#2813).
* `NegativeLogLikelihood<>` now expects classes in the range `0` to
`numClasses - 1` (#2534).
### mlpack 3.4.2
###### 2020-10-26
* Added Mean Absolute Percentage Error.
+9 -2
View File
@@ -146,9 +146,13 @@ This document discusses how to build mlpack from source. These build directions
will work for any Linux-like shell environment (for example Ubuntu, macOS,
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
and so it may be easier to use the package manager for your system. For example,
on Ubuntu, you can install mlpack with the following command:
on Ubuntu, you can install the mlpack library and command-line executables (e.g.
mlpack_pca, mlpack_kmeans etc.) with the following command:
$ sudo apt-get install libmlpack-dev
$ sudo apt-get install libmlpack-dev mlpack-bin
On Fedora or Red Hat (EPEL):
$ sudo dnf install mlpack-devel mlpack-bin
Note: Older Ubuntu versions may not have the most recent version of mlpack
available---for instance, at the time of this writing, Ubuntu 16.04 only has
@@ -199,6 +203,7 @@ Options are specified with the -D flag. The allowed options include:
BUILD_CLI_EXECUTABLES=(ON/OFF): whether or not to build command-line programs
BUILD_PYTHON_BINDINGS=(ON/OFF): whether or not to build Python bindings
PYTHON_EXECUTABLE=(/path/to/python_version): Path to specific Python executable
PYTHON_INSTALL_PREFIX=(/path/to/python/): Path to root of Python installation
BUILD_JULIA_BINDINGS=(ON/OFF): whether or not to build Julia bindings
JULIA_EXECUTABLE=(/path/to/julia): Path to specific Julia executable
BUILD_GO_BINDINGS=(ON/OFF): whether or not to build Go bindings
@@ -217,6 +222,8 @@ Options are specified with the -D flag. The allowed options include:
STB_IMAGE_INCLUDE_DIR=(/path/to/stb/include): path to include directory for
STB image library
USE_OPENMP=(ON/OFF): whether or not to use OpenMP if available
BUILD_DOCS=(ON/OFF): build Doxygen documentation, if Doxygen is available
(default ON)
Other tools can also be used to configure CMake, but those are not documented
here. See [this section of the build guide](https://www.mlpack.org/doc/mlpack-git/doxygen/build.html#build_config)
+30 -39
View File
@@ -2,47 +2,38 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!-- 1) DO NOT CHANGE the product GUID! It is forever -->
<!-- 2) %MLPACK_VERSION env var is set by .appveyor.yml -->
<Product Id="02A00C77-197D-4E91-B7D9-5836220E92E9"
UpgradeCode="6C2D7EC0-6F10-40CB-9703-1DC160A62662"
Name="mlpack"
Language="1033"
Version="$(env.MLPACK_VERSION)"
Manufacturer="mlpack">
<Package InstallerVersion="200"
Description="mlpack Windows Installer"
Compressed="yes"
InstallScope="perMachine"
Platform="x64"/>
<Product Id="02A00C77-197D-4E91-B7D9-5836220E92E9"
UpgradeCode="6C2D7EC0-6F10-40CB-9703-1DC160A62662"
Name="mlpack"
Language="1033"
Version="$(env.MLPACK_VERSION)"
Manufacturer="mlpack">
<Package InstallerVersion="200"
Description="mlpack Windows Installer"
Compressed="yes"
InstallScope="perMachine"
Platform="x64"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Feature Id="ProductFeature" Title="mlpackWindows" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Property Id="MLPACK_VERSION">$(env.MLPACK_VERSION)</Property>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<WixVariable Id="WixUILicenseRtf" Value="..\staging\license.rtf"/>
<WixVariable Id="WixUIBannerBmp" Value="..\res\banner.jpg"/>
<WixVariable Id="WixUIDialogBmp" Value="..\res\dialog_white.jpg"/>
<UIRef Id="WixUI_InstallDir" />
</Product>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="mlpack">
<Directory Id="Sources" />
</Directory>
</Directory>
</Directory>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="mlpack" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- This references the list of mlpack files automatically generated using Heat (see .wixproj BeforeBuild Target) -->
<ComponentGroupRef Id="HeatGenerated"/>
</ComponentGroup>
</Fragment>
<Feature Id="ProductFeature" Title="mlpackWindows" ConfigurableDirectory="INSTALLDIR" Level="1">
<ComponentGroupRef Id="Sources" />
</Feature>
<Property Id="MLPACK_VERSION">$(env.MLPACK_VERSION)</Property>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
<WixVariable Id="WixUILicenseRtf" Value="..\staging\license.rtf"/>
<WixVariable Id="WixUIBannerBmp" Value="..\res\banner.jpg"/>
<WixVariable Id="WixUIDialogBmp" Value="..\res\dialog_white.jpg"/>
<UIRef Id="WixUI_InstallDir" />
</Product>
</Wix>
@@ -9,33 +9,36 @@
<OutputName>mlpack-windows</OutputName>
<OutputType>Package</OutputType>
<Name>mlpack-win-installer</Name>
<DefineSolutionProperties>false</DefineSolutionProperties>
<DefineConstants>SourceDir=.\Sources</DefineConstants>
<WixTargetsPath Condition=" '$(WixTargetsPath' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
<DefineConstants>Debug;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DefineConstants>Debug</DefineConstants>
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>HarvestPath=..\staging</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="Product.wxs" />
<Compile Include="HeatGeneratedFileList.wxs" />
</ItemGroup>
<ItemGroup>
<HarvestDirectory Include=".\Sources">
<DirectoryRefId>Sources</DirectoryRefId>
<ComponentGroupName>Sources</ComponentGroupName>
<PreprocessorVariable>var.SourceDir</PreprocessorVariable>
<SuppressRegistry>true</SuppressRegistry>
</HarvestDirectory>
<WixExtension Include="WixUIExtension">
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
@@ -46,14 +49,4 @@
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
</Target>
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.-->
<Target Name="BeforeBuild">
<HeatDirectory Directory="..\staging" PreprocessorVariable="var.HarvestPath" OutputFile="HeatGeneratedFileList.wxs" ComponentGroupName="HeatGenerated" DirectoryRefId="INSTALLFOLDER" AutogenerateGuids="true" ToolPath="$(WixToolPath)" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" />
</Target>
<!--
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
+61 -17
View File
@@ -2,11 +2,25 @@
@section build_buildintro Introduction
This document discusses how to build mlpack from source. These build directions
This document discusses how to build mlpack from source. These build directions
will work for any Linux-like shell environment (for example Ubuntu, macOS,
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
and so it may be easier to use the package manager for your system. For example,
on Ubuntu, you can install mlpack with the following command:
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
and so it may be easier to use the package manager for your system. For example,
on Ubuntu, you can install the mlpack library and command-line executables (e.g.
mlpack_pca, mlpack_kmeans, etc.) with the following command:
@code
$ sudo apt-get install libmlpack-dev mlpack-bin
@endcode
On Fedora or Red Hat(EPEL):
@code
$ sudo dnf install mlpack-devel mlpack-bin
@endcode
For installing only the header files and library for building C++ applications
on top of mlpack, one could use:
@code
$ sudo apt-get install libmlpack-dev
@@ -25,7 +39,7 @@ mlpack uses CMake as a build system and allows several flexible build
configuration options. One can consult any of numerous CMake tutorials for
further documentation, but this tutorial should be enough to get mlpack built
and installed on most Linux and UNIX-like systems (including OS X). If you want
to build mlpack on Windows, see \ref build_windows (alternatively, you can read
to build mlpack on Windows, see \ref build_windows (alternatively, you can read
<a href="https://keon.io/mlpack-on-windows/">Keon's excellent tutorial</a> which
is based on older versions).
@@ -78,7 +92,7 @@ mlpack depends on the following libraries, which need to be installed on the
system and have headers present:
- Armadillo >= 8.400.0 (with LAPACK support)
- Boost (math_c99, unit_test_framework, heap, spirit) >= 1.58
- Boost (math_c99, spirit) >= 1.58
- cereal >= 1.1.2
- ensmallen >= 2.10.0 (will be downloaded if not found)
@@ -95,11 +109,11 @@ For Python bindings, the following packages are required:
- pandas >= 0.15.0
- pytest-runner
In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be
In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be
installed through apt:
@code
# apt-get install libboost-math-dev libboost-test-dev libcereal-dev
# apt-get install libboost-math-dev libcereal-dev
libarmadillo-dev binutils-dev python3-pandas python3-numpy cython3
python3-setuptools
@endcode
@@ -112,18 +126,18 @@ packages:
# apt-get install libensmallen-dev libstb-dev
@endcode
@note For older versions of Ubuntu and Debian, Armadillo needs to be built from
source as apt installs an older version. So you need to omit
@note For older versions of Ubuntu and Debian, Armadillo needs to be built from
source as apt installs an older version. So you need to omit
\c libarmadillo-dev from the code snippet above and instead use
<a href="http://arma.sourceforge.net/download.html">this link</a>
to download the required file. Extract this file and follow the README in the
to download the required file. Extract this file and follow the README in the
uncompressed folder to build and install Armadillo.
On Fedora, Red Hat, or CentOS, these same dependencies can be obtained via dnf:
@code
# dnf install boost-devel boost-test boost-math armadillo-devel binutils-devel
python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel
# dnf install boost-devel boost-math armadillo-devel binutils-devel
python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel
stbi-devel cereal-devel
@endcode
@@ -176,9 +190,12 @@ The full list of options mlpack allows:
- BUILD_WITH_COVERAGE=(ON/OFF): Build with support for code coverage tools
(gcc only) (default OFF)
- PYTHON_EXECUTABLE=(/path/to/python_version): Path to specific Python executable
- PYTHON_INSTALL_PREFIX=(/path/to/python/): Path to root of Python installation
- JULIA_EXECUTABLE=(/path/to/julia): Path to specific Julia executable
- BUILD_MARKDOWN_BINDINGS=(ON/OFF): Build Markdown bindings for website
documentation (default OFF)
- BUILD_DOCS=(ON/OFF): build Doxygen documentation, if Doxygen is available
(default ON)
- MATHJAX=(ON/OFF): use MathJax for generated Doxygen documentation (default
OFF)
- FORCE_CXX11=(ON/OFF): assume that the compiler supports C++11 instead of
@@ -217,7 +234,8 @@ src/mlpack/CMakeFiles/mlpack.dir/core/optimizers/aug_lagrangian/aug_lagrangian_t
@endcode
It's often useful to specify \c -jN to the \c make command, which will build on
\c N processor cores. That can accelerate the build significantly.
\c N processor cores. That can accelerate the build significantly. Sometimes
using many cores may exhaust the memory so choose accordingly.
You can specify individual components which you want to build, if you do not
want to build everything in the library:
@@ -233,11 +251,37 @@ suite. You can build this component with
$ make mlpack_test
@endcode
and then run all of the tests, or an individual test suite:
We use <a href="https://github.com/catchorg/Catch2">Catch2</a> to write our tests.
To run all tests, you can simply run:
@code
$ bin/mlpack_test
$ bin/mlpack_test -t KNNTest
$ ./bin/mlpack_test
@endcode
To run all tests in a particular file you can run:
@code
$ ./bin/mlpack_test "[testname]"
@endcode
where testname is the name of the test suite.
For example to run all collaborative filtering tests implemented in cf_test.cpp you can run:
@code
./bin/mlpack_test "[CFTest]"
@endcode
Now similarly you can run all the binding related tests using:
@code
./bin/mlpack_test "[BindingTests]"
@endcode
To run a single test, you can explicitly provide the name of the test; for example,
to run BinaryClassificationMetricsTest implemented in cv_test.cpp you can run the following:
@code
./bin/mlpack_test BinaryClassificationMetricsTest
@endcode
If the build fails and you cannot figure out why, register an account on Github
+115 -10
View File
@@ -9,8 +9,13 @@
@section build_windows_intro Introduction
This tutorial will show you how to build mlpack for Windows from source, so you can
later create your own C++ applications. Before you try building mlpack, you may
This tutorial will show you how to build mlpack for Windows from source, so
you can later create your own C++ applications, using two different ways:
- Using CMake to generate an intermeditate Visual Studio solution (`.sln`).
- @ref build_visual_studio_cmake_integration "Use Visual Studio's CMake integration to directly build from the `CMakeLists`."
Before you try building mlpack, you may
want to install mlpack using vcpkg for Windows. If you don't want to install
using vcpkg, skip this section and continue with the build tutorial.
@@ -78,6 +83,23 @@ system environment variables or manually set the PATH before running CMake)
- Click on OpenBlas and check the mlpack project, then click Install
- Once it has finished installing, close Visual Studio
<b> Building OpenBLAS from Source </b>
Unfortunately, the support for building `LAPACK` and `BLAS` on Windows is quite poor, due to the need for Fortran
compiler and libraries. The easiest method to get the necessary `BLAS/LAPACK` libraries built on Windows is to
compile OpenBLAS with LLVM's `clang-cl` and `flang` to produce the required static library (`.lib`) files
compatible with the MSVC compiler. A comprehensive guide on the
<a href="https://github.com/xianyi/OpenBLAS/wiki/How-to-use-OpenBLAS-in-Microsoft-Visual-Studio">compilation
of OpenBLAS for Windows can be found here</a>.
One could always download prebuilt `LAPACK` and `BLAS` libraries for Windows. However, there are few official
sources, and some of those libraries may require further `dll`s at runtime which may not be available in your
system.
It you choose to build `OpenBLAS` from source, make sure that `LAPACK` functions are also built. Finally, make
sure that the `openblas.lib` library is linked in your `Armadillo` build (see below), as well as the library
path used for the CMake options `BLAS_LIBRARIES` and `LAPACK_LIBRARIES` in the mlpack CMake project.
<b> Boost Dependency </b>
You can either get Boost via NuGet or you can download the prebuilt Windows binaries separately.
@@ -110,7 +132,7 @@ compiler version, check if the Visual Studio compiler and Windows SDK are instal
- Build > Build Solution
- Once it has successfully finished, close Visual Studio
@section build_windows_mlpack Building mlpack
@section build_windows_mlpack Building mlpack with CMake-Generated Solution
- Create a "build" directory into "C:\mlpack\mlpack\"
- You can generate the project using either cmake via command line or GUI. If you prefer to use GUI, refer to the \ref build_windows_appendix "appendix"
@@ -129,6 +151,96 @@ cmake -G "Visual Studio 16 2019" -A x64 -DBLAS_LIBRARIES:FILEPATH="C:/mlpack/mlp
You are ready to create your first application, take a look at the @ref sample_ml_app "Sample C++ ML App"
@section build_visual_studio_cmake_integration Building mlpack with Visual Studio's CMake Integration
This project can be directly built from the `CMakeLists.txt` with the latest version of MS Visual Studio,
given you have CMake integration via the
<a href="https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-160">C++
CMake tools for Windows</a>. To open the CMake project with Visual Studio, select File->Open->CMake
in the top menu, followed by selecting the root `CMakeLists.txt` located in mlpack's root directory.
In order to allow Visual Studio to configure the CMake project, the CMake configuration json will have
to be edited to provide the <a href="https://github.com/mlpack/mlpack#3-dependencies">relevant options
shown in the `README`</a> needed to find all the dependencies. The options that you
must provide to Visual Studio's CMake are:
- `ARMADILLO_INCLUDE_DIR`
- `ARMADILLO_LIBRARY`
- `BOOST_ROOT`
- `CEREAL_INCLUDE_DIR`
- `BLAS_LIBRARIES`
- `LAPACK_LIBRARIES`
The CMake configuration json can be editted in Visual Studio by right clicking the root `CMakeLists.txt`
in the project view, selecting <b>CMake settings for mlpack</b> and finally clicking on <b>edit JSON</b>.
Adding a new CMake option can be done by adding object fields with the following format to the variables
array in the `CMakeSettings.json`:
@code
{
"name": "options_name_string",
"value": "options_value_string",
"type" : "{BOOL|FILEPATH|PATH|STRING}"
}
@endcode
Here is a full example of the `CMakeSettings.json`file:
@code
{
"configurations": [
{
"name": "x64-Debug (default)",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"variables": [
{
"name": "ARMADILLO_INCLUDE_DIR",
"value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/include",
"type": "PATH"
},
{
"name": "ARMADILLO_LIBBRARY",
"value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/lib/armadillo.lib",
"type": "PATH"
},
{
"name": "CEREAL_INCLUDE_DIR",
"value": "PATH/TO/CPP/DEPENDENCY/cereal-1.3.0/include",
"type": "PATH"
},
{
"name": "BUILD_ROOT",
"value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0",
"type": "PATH"
},
{
"name": "BOOST_INCLUDEDIR",
"value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0",
"type": "PATH"
},
{
"name": "BLAS_LIBRARIES",
"value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib",
"type": "PATH"
},
{
"name": "LAPACK_LIBRARIES",
"value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib",
"type": "PATH"
}
]
}
]
}
@endcode
@section build_windows_appendix Appendix
If you prefer to use cmake GUI, follow these instructions:
@@ -147,13 +259,6 @@ If you prefer to use cmake GUI, follow these instructions:
following variables and reconfigure:
- Name: `BOOST_INCLUDEDIR`; type `PATH`; value `C:/boost/`
- Name: `BOOST_LIBRARYDIR`; type `PATH`; value `C:/boost/lib64-msvc-14.2`
- If Boost is still not found, try adding the following variables and
reconfigure:
- Name: `Boost_INCLUDE_DIR`; type `PATH`; value `C:/boost/`
- Name: `Boost_SERIALIZATION_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-gd-x64-1_71.lib`
- Name: `Boost_SERIALIZATION_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-x64-1_71.lib`
- Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-gd-x64-1_71.lib`
- Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-x64-1_71.lib`
- Once CMake has configured successfully, hit "Generate" to create the `.sln` file.
@section build_windows_additional_information Additional Information
-1
View File
@@ -34,7 +34,6 @@ mlpack and dependencies in Release Mode).
- Under Linker > Input > Additional Dependencies add:
@code
- C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.lib
- C:\boost\boost_1_71_0\lib64-msvc-14.2\libboost_serialization-vc142-mt-gd-x64-1_71.lib
@endcode
- Under Build Events > Post-Build Event > Command Line add:
@code
+7 -6
View File
@@ -210,8 +210,9 @@ int main()
data::Load("thyroid_test.csv", testData, true);
// Split the labels from the training set and testing set respectively.
arma::mat trainLabels = trainData.row(trainData.n_rows - 1);
arma::mat testLabels = testData.row(testData.n_rows - 1);
// Decrement the labels by 1, so they are in the range 0 to (numClasses - 1).
arma::mat trainLabels = trainData.row(trainData.n_rows - 1) - 1;
arma::mat testLabels = testData.row(testData.n_rows - 1) - 1;
trainData.shed_row(trainData.n_rows - 1);
testData.shed_row(testData.n_rows - 1);
@@ -246,9 +247,8 @@ int main()
// Find index of max prediction for each data point and store in "prediction"
for (size_t i = 0; i < predictionTemp.n_cols; ++i)
{
// we add 1 to the max index, so that it matches the actual test labels.
prediction(i) = arma::as_scalar(arma::find(
arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1)) + 1;
arma::max(predictionTemp.col(i)) == predictionTemp.col(i), 1));
}
/*
@@ -311,7 +311,7 @@ void RNNModel()
for (size_t i = 0; i < labelsTemp.n_cols; ++i)
{
const int value = arma::as_scalar(arma::find(
arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1)) + 1;
arma::max(labelsTemp.col(i)) == labelsTemp.col(i), 1));
labels.col(i).fill(value);
}
@@ -589,8 +589,9 @@ arma::mat trainData = dataset.submat(0, 0, dataset.n_rows - 4,
dataset.n_cols - 1);
// Split the data from the training set.
// Subtract 1 so the labels are the range from 0 to (numClasses - 1).
arma::mat trainLabels = dataset.submat(dataset.n_rows - 3, 0,
dataset.n_rows - 1, dataset.n_cols - 1);
dataset.n_rows - 1, dataset.n_cols - 1) - 1;
// Initialize the network.
FFN<> model;
+106 -25
View File
@@ -87,6 +87,93 @@ if (BUILD_R_BINDINGS)
string(TIMESTAMP PACKAGE_DATE "%Y-%m-%d")
# We need to generate an Authors@R list using every single contributor in
# COPYRIGHT.txt. That takes a little bit of processing.
file(READ "${CMAKE_SOURCE_DIR}/COPYRIGHT.txt" COPYRIGHT_TXT_CONTENTS)
string(REGEX MATCHALL " Copyright [0-9-]*, ([^\n]*)\n" CONTRIBUTORS_LIST
"${COPYRIGHT_TXT_CONTENTS}")
# These are the authors meant to be listed as 'authors' and not
# 'contributors'. If you contributed specifically to the R bindings, you
# should probably be listed here, so if you're not, open a PR to fix it! :)
set(SPECIAL_AUTHORS "Yashwant Singh Parihar" "Ryan Curtin" "Dirk Eddelbuettel"
"James Balamuta")
string(CONCAT AUTHORS_R "c(\n"
" person(\"Yashwant\", \"Singh Parihar\", "
"email = \"yashwantsingh.sngh@gmail.com\", "
"role = c(\"aut\", \"ctb\", \"cph\")),\n"
" person(\"Ryan\", \"Curtin\", email = \"ryan@ratml.org\", "
"role = c(\"aut\", \"ctb\", \"cph\", \"cre\")),\n"
" person(\"Dirk\", \"Eddelbuettel\", email = \"edd@debian.org\", "
"role = c(\"aut\", \"ctb\", \"cph\")),\n"
" person(\"James\", \"Balamuta\", "
"email = \"james.balamuta@gmail.com\", "
"role = c(\"aut\", \"ctb\", \"cph\")),")
foreach (CONTRIBUTOR_LINE ${CONTRIBUTORS_LIST})
# Strip 'Copyright XXXX-YYYY, '.
string(REGEX REPLACE "^ Copyright [0-9-]*, (.*)\n$" "\\1"
CONTRIBUTOR_FILTERED "${CONTRIBUTOR_LINE}")
# Extract the email if it exists.
string(REGEX MATCH "^[^<]*<(.*)>.*$" HAS_EMAIL "${CONTRIBUTOR_FILTERED}")
# The first name is just the first space-delimited word. (That may not
# always be right, but we have no way to know what is a first name and last
# name and therefore must assume.)
string(REGEX REPLACE "^([^ ]*) .*$" "\\1" CONTRIBUTOR_FIRST_NAME
"${CONTRIBUTOR_FILTERED}")
# Extracting the last name is just the rest of the tokens, but the regex is
# different depending on whether we managed to get an email.
if (HAS_EMAIL)
string(REGEX REPLACE "^[^<]*<(.*)>.*$" "\\1" CONTRIBUTOR_EMAIL
"${CONTRIBUTOR_FILTERED}")
string(REGEX MATCH "^[^ ]* (.*) <.*$" CONTRIBUTOR_LAST_NAME
"${CONTRIBUTOR_FILTERED}")
if (NOT CONTRIBUTOR_LAST_NAME)
set (CONTRIBUTOR_LAST_NAME "")
else ()
string(REGEX REPLACE "^[^ ]* (.*) <.*$" "\\1" CONTRIBUTOR_LAST_NAME
"${CONTRIBUTOR_FILTERED}")
endif ()
# Skip anyone already listed as an author.
if ("${CONTRIBUTOR_FIRST_NAME} ${CONTRIBUTOR_LAST_NAME}" IN_LIST
SPECIAL_AUTHORS)
continue()
endif ()
string(CONCAT AUTHORS_R "${AUTHORS_R}\n "
"person(\"${CONTRIBUTOR_FIRST_NAME}\", \"${CONTRIBUTOR_LAST_NAME}\", "
"email = \"${CONTRIBUTOR_EMAIL}\", role = c(\"ctb\", \"cph\")),")
else ()
# No email is available. So just get the last name.
string(REGEX MATCH "^[^ ]* (.*)$" CONTRIBUTOR_LAST_NAME
"${CONTRIBUTOR_FILTERED}")
if (NOT CONTRIBUTOR_LAST_NAME)
set (CONTRIBUTOR_LAST_NAME "")
else ()
string(REGEX REPLACE "^[^ ]* (.*)$" "\\1" CONTRIBUTOR_LAST_NAME
"${CONTRIBUTOR_FILTERED}")
endif ()
# Skip anyone already listed as an author.
if ("${CONTRIBUTOR_FIRST_NAME} ${CONTRIBUTOR_LAST_NAME}" IN_LIST
SPECIAL_AUTHORS)
continue()
endif ()
string(CONCAT AUTHORS_R "${AUTHORS_R}\n "
"person(\"${CONTRIBUTOR_FIRST_NAME}\", \"${CONTRIBUTOR_LAST_NAME}\", "
"role = c(\"ctb\", \"cph\")),")
endif ()
endforeach ()
# We also have to remove the final comma...
string(REGEX REPLACE ",$" "" AUTHORS_R_OUT "${AUTHORS_R}")
set(AUTHORS_R "${AUTHORS_R_OUT})")
configure_file(${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/mlpack/DESCRIPTION.in
${CMAKE_CURRENT_BINARY_DIR}/mlpack/DESCRIPTION
@ONLY)
@@ -136,9 +223,11 @@ if (BUILD_R_BINDINGS)
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/tests/testthat.R"
)
set(LICENSE_SOURCES
"${CMAKE_SOURCE_DIR}/LICENSE.txt"
)
# Configure the license file.
string(TIMESTAMP LICENSE_YEAR "%Y")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/mlpack/LICENSE.in"
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE")
add_custom_target(r_copy ALL)
# First we have to create all the required directories for copy.
@@ -160,22 +249,22 @@ if (BUILD_R_BINDINGS)
# Copy all necessary files for building package.
foreach(cpp_file ${CPP_SOURCES})
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${cpp_file}
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/)
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${cpp_file}
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/)
endforeach()
foreach(r_file ${R_SOURCES})
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${r_file}
${CMAKE_CURRENT_BINARY_DIR}/mlpack/R/)
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${r_file}
${CMAKE_CURRENT_BINARY_DIR}/mlpack/R/)
endforeach()
foreach(bindings_file ${BINDINGS_SOURCES})
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${bindings_file}
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R)
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${bindings_file}
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R)
endforeach()
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
@@ -185,14 +274,6 @@ if (BUILD_R_BINDINGS)
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${R_TESTS_SOURCES}
${CMAKE_CURRENT_BINARY_DIR}/mlpack/tests)
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
${LICENSE_SOURCES}
${CMAKE_CURRENT_BINARY_DIR}/mlpack)
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E rename
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE.txt"
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE")
# This file will take care of multiple definition of functions in .cpp files.
add_custom_command(TARGET r_copy PRE_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E touch
@@ -229,8 +310,8 @@ if (BUILD_R_BINDINGS)
# Installation script for the packagae.
install(CODE
"execute_process(
COMMAND R CMD INSTALL mlpack_${PACKAGE_VERSION}.tar.gz
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}"
COMMAND ${R_EXECUTABLE} CMD INSTALL mlpack_${PACKAGE_VERSION}.tar.gz
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})"
)
add_dependencies(R r_build)
+5 -5
View File
@@ -2,11 +2,11 @@ Package: mlpack
Title: 'Rcpp' Integration for the 'mlpack' Library
Version: @PACKAGE_VERSION@
Date: @PACKAGE_DATE@
Author: mlpack Team
Maintainer: Ryan Curtin <ryan@ratml.org>
Description: 'mlpack' is a fast, flexible machine learning library, written
in C++, that aims to provide fast, extensible implementations of
cutting-edge machine learning algorithms.
Authors@R: @AUTHORS_R@
Description: A fast, flexible machine learning library, written in C++, that
aims to provide fast, extensible implementations of cutting-edge
machine learning algorithms. See also Curtin et al. (2018)
<doi:10.21105/joss.00726>.
SystemRequirements: A C++11 compiler. Versions 4.8.*, 4.9.* or later of GCC
will be fine.
License: BSD_3_clause + file LICENSE
+3
View File
@@ -0,0 +1,3 @@
YEAR: ${LICENSE_YEAR}
COPYRIGHT HOLDER: mlpack Team
ORGANIZATION: mlpack
-1
View File
@@ -53,7 +53,6 @@ if (BUILD_CLI_EXECUTABLES)
target_link_libraries(mlpack_${name}
mlpack
${ARMADILLO_LIBRARIES}
${Boost_LIBRARIES}
${COMPILER_SUPPORT_LIBRARIES}
)
# Make sure that we set BINDING_TYPE to cli so the command-line program is
@@ -98,17 +98,8 @@ inline std::string GetPrintableType(
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
{
std::string type = "*mat.Dense";
if (std::is_same<typename T::elem_type, double>::value)
{
if (T::is_row || T::is_col)
type = "*mat.Dense (1d)";
}
else if (std::is_same<typename T::elem_type, size_t>::value)
{
type = "*mat.Dense (with ints)";
if (T::is_row || T::is_col)
type = "*mat.Dense (1d with ints)";
}
if (T::is_row || T::is_col)
type = "*mat.Dense (1d)";
return type;
}
@@ -37,6 +37,11 @@ inline typename T::elem_type* GetMemory(T& m)
else
{
arma::access::rw(m.mem_state) = 1;
// With Armadillo 10 and newer, we must set `n_alloc` to 0 so that
// Armadillo does not deallocate the memory.
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(m.n_alloc) = 0;
#endif
return m.memptr();
}
}
+5 -25
View File
@@ -87,35 +87,15 @@ std::string PrintTypeDoc(
util::ParamData& data,
const typename std::enable_if<arma::is_arma_type<T>::value>::type*)
{
if (std::is_same<typename T::elem_type, double>::value)
if (T::is_col || T::is_row)
{
if (T::is_col || T::is_row)
{
return "A 1-d gonum Matrix (that is, a Matrix where either the number"
" of rows or number of columns is 1).";
}
else
{
return "A 2-d gonum Matrix. If the type is not already `float64`, it "
"will be converted.";
}
}
else if (std::is_same<typename T::elem_type, size_t>::value)
{
if (T::is_col || T::is_row)
{
return "A 1-d gonum Matrix (that is, a Matrix where either the number"
" of rows or number of columns is 1).";
}
else
{
return "A 2-d gonum Matrix. If the type is not already `int64`, it "
"will be converted.";
}
return "A 1-d gonum Matrix (that is, a Matrix where either the number"
" of rows or number of columns is 1).";
}
else
{
throw std::invalid_argument("unknown matrix type " + data.cppType);
return "A 2-d gonum Matrix. If the type is not already `float64`, it "
"will be converted.";
}
}
+49 -30
View File
@@ -66,7 +66,7 @@ void IO_SetParamBool(const char* paramName, bool paramValue)
* Call IO::SetParam<std::vector<std::string>>() to set the length.
*/
void IO_SetParamVectorStrLen(const char* paramName,
const size_t length)
const size_t length)
{
IO::GetParam<std::vector<std::string>>(paramName).clear();
IO::GetParam<std::vector<std::string>>(paramName).resize(length);
@@ -77,8 +77,8 @@ void IO_SetParamVectorStrLen(const char* paramName,
* Call IO::SetParam<std::vector<std::string>>() to set an individual element.
*/
void IO_SetParamVectorStrStr(const char* paramName,
const char* str,
const size_t element)
const char* str,
const size_t element)
{
IO::GetParam<std::vector<std::string>>(paramName)[element] =
std::string(str);
@@ -88,8 +88,8 @@ void IO_SetParamVectorStrStr(const char* paramName,
* Call IO::SetParam<std::vector<int>>().
*/
void IO_SetParamVectorInt(const char* paramName,
int* ints,
const size_t length)
int* ints,
const size_t length)
{
// Create a std::vector<int> object; unfortunately this requires copying the
// vector elements.
@@ -106,10 +106,10 @@ void IO_SetParamVectorInt(const char* paramName,
* Call IO::SetParam<arma::mat>().
*/
void IO_SetParamMat(const char* paramName,
double* memptr,
const size_t rows,
const size_t cols,
const bool pointsAsRows)
double* memptr,
const size_t rows,
const size_t cols,
const bool pointsAsRows)
{
// Create the matrix as an alias.
arma::mat m(memptr, arma::uword(rows), arma::uword(cols), false, true);
@@ -121,10 +121,10 @@ void IO_SetParamMat(const char* paramName,
* Call IO::SetParam<arma::Mat<size_t>>().
*/
void IO_SetParamUMat(const char* paramName,
size_t* memptr,
const size_t rows,
const size_t cols,
const bool pointsAsRows)
size_t* memptr,
const size_t rows,
const size_t cols,
const bool pointsAsRows)
{
// Create the matrix as an alias.
arma::Mat<size_t> m(memptr, arma::uword(rows), arma::uword(cols), false,
@@ -138,8 +138,8 @@ void IO_SetParamUMat(const char* paramName,
* Call IO::SetParam<arma::rowvec>().
*/
void IO_SetParamRow(const char* paramName,
double* memptr,
const size_t cols)
double* memptr,
const size_t cols)
{
arma::rowvec m(memptr, arma::uword(cols), false, true);
IO::GetParam<arma::rowvec>(paramName) = std::move(m);
@@ -150,8 +150,8 @@ void IO_SetParamRow(const char* paramName,
* Call IO::SetParam<arma::Row<size_t>>().
*/
void IO_SetParamURow(const char* paramName,
size_t* memptr,
const size_t cols)
size_t* memptr,
const size_t cols)
{
arma::Row<size_t> m(memptr, arma::uword(cols), false, true);
IO::GetParam<arma::Row<size_t>>(paramName) = std::move(m);
@@ -162,8 +162,8 @@ void IO_SetParamURow(const char* paramName,
* Call IO::SetParam<arma::vec>().
*/
void IO_SetParamCol(const char* paramName,
double* memptr,
const size_t rows)
double* memptr,
const size_t rows)
{
arma::vec m(memptr, arma::uword(rows), false, true);
IO::GetParam<arma::vec>(paramName) = std::move(m);
@@ -174,8 +174,8 @@ void IO_SetParamCol(const char* paramName,
* Call IO::SetParam<arma::Row<size_t>>().
*/
void IO_SetParamUCol(const char* paramName,
size_t* memptr,
const size_t rows)
size_t* memptr,
const size_t rows)
{
arma::Col<size_t> m(memptr, arma::uword(rows), false, true);
IO::GetParam<arma::Col<size_t>>(paramName) = std::move(m);
@@ -186,11 +186,11 @@ void IO_SetParamUCol(const char* paramName,
* Call IO::SetParam<std::tuple<data::DatasetInfo, arma::mat>>().
*/
void IO_SetParamMatWithInfo(const char* paramName,
bool* dimensions,
double* memptr,
const size_t rows,
const size_t cols,
const bool pointsAreRows)
bool* dimensions,
double* memptr,
const size_t rows,
const size_t cols,
const bool pointsAreRows)
{
data::DatasetInfo d(pointsAreRows ? cols : rows);
for (size_t i = 0; i < d.Dimensionality(); ++i)
@@ -316,6 +316,9 @@ double* IO_GetParamMat(const char* paramName)
else
{
arma::access::rw(mat.mem_state) = 1;
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(mat.n_alloc) = 0;
#endif
return mat.memptr();
}
}
@@ -352,12 +355,14 @@ size_t* IO_GetParamUMat(const char* paramName)
// Copy the memory to something that we can give back to Julia.
size_t* newMem = new size_t[mat.n_elem];
arma::arrayops::copy(newMem, mat.mem, mat.n_elem);
// We believe Julia will free it. Hopefully we are right.
return newMem;
return newMem; // We believe Julia will free it. Hopefully we are right.
}
else
{
arma::access::rw(mat.mem_state) = 1;
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(mat.n_alloc) = 0;
#endif
return mat.memptr();
}
}
@@ -390,6 +395,9 @@ double* IO_GetParamCol(const char* paramName)
else
{
arma::access::rw(vec.mem_state) = 1;
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(vec.n_alloc) = 0;
#endif
return vec.memptr();
}
}
@@ -418,12 +426,14 @@ size_t* IO_GetParamUCol(const char* paramName)
// Copy the memory to something we can give back to Julia.
size_t* newMem = new size_t[vec.n_elem];
arma::arrayops::copy(newMem, vec.mem, vec.n_elem);
// We believe Julia will free it. Hopefully we are right.
return newMem;
return newMem; // We believe Julia will free it. Hopefully we are right.
}
else
{
arma::access::rw(vec.mem_state) = 1;
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(vec.n_alloc) = 0;
#endif
return vec.memptr();
}
}
@@ -456,6 +466,9 @@ double* IO_GetParamRow(const char* paramName)
else
{
arma::access::rw(vec.mem_state) = 1;
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(vec.n_alloc) = 0;
#endif
return vec.memptr();
}
}
@@ -489,6 +502,9 @@ size_t* IO_GetParamURow(const char* paramName)
else
{
arma::access::rw(vec.mem_state) = 1;
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(vec.n_alloc) = 0;
#endif
return vec.memptr();
}
}
@@ -547,6 +563,9 @@ double* IO_GetParamMatWithInfoPtr(const char* paramName)
else
{
arma::access::rw(m.mem_state) = 1;
#if ARMA_VERSION_MAJOR >= 10
arma::access::rw(m.n_alloc) = 0;
#endif
return m.memptr();
}
}
@@ -127,6 +127,13 @@ void PrintInputProcessing(
// "type" is a reserved keyword or function.
const std::string juliaName = (d.name == "type") ? "type_" : d.name;
// For a non-required argument, this gives code like the following:
//
// if !ismissing(<param_name>)
// push!(model_ptrs, convert(<type>, <param_name>).ptr)
// IOSetParam("<param_name>", convert(<type>, <param_name>))
// end
// If the argument is not required, then we have to encase the code in an if.
size_t extraIndent = 0;
if (!d.required)
@@ -137,6 +144,9 @@ void PrintInputProcessing(
std::string indent(extraIndent + 2, ' ');
std::string type = util::StripType(d.cppType);
std::cout << indent << "push!(modelPtrs, convert("
<< GetJuliaType<typename std::remove_pointer<T>::type>(d) << ", "
<< juliaName << ").ptr)" << std::endl;
std::cout << indent << functionName << "_internal.IOSetParam" << type
<< "(\"" << d.name << "\", convert("
<< GetJuliaType<typename std::remove_pointer<T>::type>(d) << ", "
+6
View File
@@ -251,6 +251,12 @@ void PrintJL(const util::BindingDetails& doc,
<< endl;
cout << endl;
// Create the set of model pointers.
cout << " # Create the set of model pointers to avoid setting multiple "
<< "finalizers." << endl;
cout << " modelPtrs = Set{Ptr{Nothing}}()" << endl;
cout << endl;
// Restore IO settings.
cout << " IORestoreSettings(\"" << programName << "\")" << endl;
cout << endl;
@@ -107,7 +107,7 @@ void PrintOutputProcessing(
{
std::string type = util::StripType(d.cppType);
std::cout << functionName << "_internal.IOGetParam"
<< type << "(\"" << d.name << "\")";
<< type << "(\"" << d.name << "\", modelPtrs)";
}
/**
+25 -8
View File
@@ -58,16 +58,22 @@ void PrintParamDefn(
//
// import ...<Type>
//
// function IOGetParam<Type>(paramName::String)
// <Type>(ccall((:IOGetParam<Type>Ptr, <programName>Library),
// Ptr{Nothing}, (Cstring,), paramName))
// function IOGetParam<Type>(paramName::String, modelPtrs::Set{Ptr{Nothing}})
// ptr = ccall((:IO_GetParam<Type>Ptr, <programName>Library),
// Ptr{Nothing}, (Cstring,), paramName)
// return <Type>(ptr; finalize=!(ptr in modelPtrs))
// end
//
// function IOSetParam<Type>(paramName::String, model::<Type>)
// ccall((:IOSetParam<Type>Ptr, <programName>Library), Nothing,
// ccall((:IO_SetParam<Type>Ptr, <programName>Library), Nothing,
// (Cstring, Ptr{Nothing}), paramName, model.ptr)
// end
//
// function Delete<Type>(ptr::Ptr{Nothing})
// ccall((:Delete<Type>Ptr, <programName>Library), Nothing,
// (Ptr{Nothing},), ptr)
// end
//
// function serialize<Type>(stream::IO, model::<Type>)
// buf_len = UInt[0]
// buffer = ccall((:Serialize<Type>Ptr, <programName>Library),
@@ -92,11 +98,13 @@ void PrintParamDefn(
// Now, IOGetParam<Type>().
std::cout << "# Get the value of a model pointer parameter of type " << type
<< "." << std::endl;
std::cout << "function IOGetParam" << type << "(paramName::String)::"
<< type << std::endl;
std::cout << " " << type << "(ccall((:IO_GetParam" << type
std::cout << "function IOGetParam" << type << "(paramName::String, "
<< "modelPtrs::Set{Ptr{Nothing}})::" << type << std::endl;
std::cout << " ptr = ccall((:IO_GetParam" << type
<< "Ptr, " << programName << "Library), Ptr{Nothing}, (Cstring,), "
<< "paramName))" << std::endl;
<< "paramName)" << std::endl;
std::cout << " return " << type << "(ptr; finalize=!(ptr in modelPtrs))"
<< std::endl;
std::cout << "end" << std::endl;
std::cout << std::endl;
@@ -111,6 +119,15 @@ void PrintParamDefn(
std::cout << "end" << std::endl;
std::cout << std::endl;
// Next, Delete<Type>().
std::cout << "# Delete an instantiated model pointer." << std::endl;
std::cout << "function Delete" << type << "(ptr::Ptr{Nothing})"
<< std::endl;
std::cout << " ccall((:Delete" << type << "Ptr, " << programName
<< "Library), Nothing, (Ptr{Nothing},), ptr)" << std::endl;
std::cout << "end" << std::endl;
std::cout << std::endl;
// Now the serialization functionality.
std::cout << "# Serialize a model to the given stream." << std::endl;
std::cout << "function serialize" << type << "(stream::IO, model::" << type
@@ -377,3 +377,20 @@ end
Filesystem.rm("model.bin")
end
# Ensure that we don't accidentally free a model multiple times.
@testset "TestMultipleModelDealloc" begin
_, _, _, _, _, _, model, _, _, _, _, _, _, _ =
test_julia_binding(4.0, 12, "hello", build_model=true)
begin
for i = 1:100
out = test_julia_binding(4.0, 12, "hello", model_in=model,
duplicate_model=true)
end
end
# This should free the other models. It's likely to crash if a model might be
# freed multiple times.
GC.gc()
end
@@ -47,6 +47,8 @@ PARAM_VECTOR_IN(int, "vector_in", "Input vector of numbers.", "");
PARAM_VECTOR_IN(string, "str_vector_in", "Input vector of strings.", "");
PARAM_MODEL_IN(GaussianKernel, "model_in", "Input model.", "");
PARAM_FLAG("build_model", "If true, a model will be returned.", "");
PARAM_FLAG("duplicate_model", "If true, return the input model as the output "
"model.", "");
PARAM_STRING_OUT("string_out", "Output string, will be 'hello2'.", "S");
PARAM_INT_OUT("int_out", "Output int, will be 13.");
@@ -194,4 +196,11 @@ static void mlpackMain()
IO::GetParam<double>("model_bw_out") =
IO::GetParam<GaussianKernel*>("model_in")->Bandwidth() * 2.0;
}
// If requested, duplicate the input model as the output model.
if (IO::HasParam("duplicate_model"))
{
IO::GetParam<GaussianKernel*>("model_out") =
IO::GetParam<GaussianKernel*>("model_in");
}
}
+8 -11
View File
@@ -18,7 +18,6 @@ macro (post_python_bindings)
-D GENERATE_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/setup.py.in
-D GENERATE_CPP_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py
-D PACKAGE_VERSION="${PACKAGE_VERSION}"
-D Boost_LIBRARY_DIRS="${Boost_LIBRARY_DIRS}"
-D ARMADILLO_LIBRARIES="${ARMADILLO_LIBRARIES}"
-D MLPACK_LIBRARY=$<TARGET_LINKER_FILE:mlpack>
-D MLPACK_LIBDIR=$<TARGET_LINKER_FILE_DIR:mlpack>
@@ -215,14 +214,20 @@ add_custom_command(TARGET python POST_BUILD
add_dependencies(python python_configured)
# Configure installation script file.
if (NOT PYTHON_INSTALL_PREFIX)
set(PYTHON_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
endif ()
execute_process(COMMAND ${PYTHON_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/print_python_version.py" "${CMAKE_INSTALL_PREFIX}"
"${CMAKE_CURRENT_SOURCE_DIR}/print_python_version.py"
"${PYTHON_INSTALL_PREFIX}"
OUTPUT_VARIABLE CMAKE_PYTHON_PATH)
string(STRIP "${CMAKE_PYTHON_PATH}" CMAKE_PYTHON_PATH)
install(CODE "set(ENV{PYTHONPATH} ${CMAKE_PYTHON_PATH})")
install(CODE "set(PYTHON_EXECUTABLE \"${PYTHON_EXECUTABLE}\")")
install(CODE "set(CMAKE_BINARY_DIR \"${CMAKE_BINARY_DIR}\")")
install(CODE "set(CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\")")
install(CODE "set(PYTHON_INSTALL_PREFIX \"${PYTHON_INSTALL_PREFIX}\")")
install(CODE "execute_process(COMMAND mkdir -p $ENV{DESTDIR}${CMAKE_PYTHON_PATH})")
install(SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/PythonInstall.cmake")
@@ -240,14 +245,6 @@ if (WIN32)
foreach (dll ${DLL_COPY_LIBS})
file(COPY ${dll} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
endforeach ()
# We also need to copy the boost DLLs over.
file(GLOB boost_ser_dll_files "${Boost_LIBRARY_DIRS}/*serialization*.dll")
file(COPY ${boost_ser_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
file(GLOB boost_po_dll_files "${Boost_LIBRARY_DIRS}/*program*options*.dll")
file(COPY ${boost_po_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
file(GLOB boost_utf_dll_files "${Boost_LIBRARY_DIRS}/*unit*test*framework*.dll")
file(COPY ${boost_utf_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
endif ()
# Add a macro to build a python binding.
@@ -5,13 +5,13 @@
if (DEFINED ENV{DESTDIR})
execute_process(COMMAND ${PYTHON_EXECUTABLE}
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py" install
--prefix=${CMAKE_INSTALL_PREFIX} --root=$ENV{DESTDIR}
--prefix=${PYTHON_INSTALL_PREFIX} --root=$ENV{DESTDIR}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/"
RESULT_VARIABLE setup_res)
else ()
execute_process(COMMAND ${PYTHON_EXECUTABLE}
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py" install
--prefix=${CMAKE_INSTALL_PREFIX}
--prefix=${PYTHON_INSTALL_PREFIX}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/"
RESULT_VARIABLE setup_res)
endif ()
@@ -22,6 +22,12 @@ template<typename T>
void SetMemState(T& t, int state)
{
const_cast<arma::uhword&>(t.mem_state) = state;
// If we just "released" the memory, so that the matrix does not own it, with
// Armadillo 10 we must also ensure that the matrix does not deallocate the
// memory by specifying `n_alloc = 0`.
#if ARMA_VERSION_MAJOR >= 10
const_cast<arma::uword&>(t.n_alloc) = 0;
#endif
}
/**
+3
View File
@@ -38,6 +38,9 @@ cdef extern from "<mlpack/core/util/io.hpp>" namespace "mlpack" nogil:
@staticmethod
void ClearSettings() nogil except +
@staticmethod
void CheckInputMatrices() nogil except +
cdef extern from "<mlpack/bindings/python/mlpack/io_util.hpp>" \
namespace "mlpack::util" nogil:
void SetParam[T](string, T&) nogil except +
+10
View File
@@ -224,6 +224,16 @@ void PrintPYX(const util::BindingDetails& doc,
cout << " IO.SetPassed(<const string> '" << d.name << "')" << endl;
}
// Checking the type of check_input_matrices parameter.
cout << " if not isinstance(check_input_matrices, bool):" << endl;
cout << " raise TypeError(" <<"\"'check_input_matrices\' must have type "
<< "\'bool'!\")" << endl;
cout << endl;
// Before calling mlpackMain(), we check input matrices for NaN values if needed.
cout << " if check_input_matrices:" << endl;
cout << " IO.CheckInputMatrices()" << endl;
// Call the method.
cout << " # Call the mlpack program." << endl;
cout << " mlpackMain()" << endl;
+4 -2
View File
@@ -64,8 +64,10 @@ class PyOption
data.required = required;
data.input = input;
data.loaded = false;
// Only "verbose" and "copy_all_inputs" will be persistent.
if (identifier == "verbose" || identifier == "copy_all_inputs")
// Only "verbose", "copy_all_inputs" and "check_input_matrices"
// will be persistent.
if (identifier == "verbose" || identifier == "copy_all_inputs" ||
identifier == "check_input_matrices")
data.persistent = true;
else
data.persistent = false;
+1 -2
View File
@@ -34,8 +34,7 @@ else:
# directories with a (valid) space in the name will be given to us as '\ '; so,
# in order to split these right, we first convert all spaces to ';', then
# convert '\;' back to ' ', then split on ';'.
library_dirs = list(filter(None, ['${MLPACK_LIBDIR}'] +
'${Boost_LIBRARY_DIRS}'.replace(' ', ';').replace('\;', ' ').split(' ')))
library_dirs = ['${MLPACK_LIBDIR}']
# We'll link with the exact paths to each library using extra_objects, instead
# of linking with 'libraries' and 'library_dirs', because of differences in
@@ -1336,5 +1336,101 @@ class TestPythonBinding(unittest.TestCase):
self.assertEqual(output2['model_bw_out'], 20.0)
self.assertEqual(output3['model_bw_out'], 20.0)
def testCheckInputMatricesNaN(self):
"""
Checks that an exception is thrown if the input matrix contains
NaN values.
"""
x = np.random.rand(100, 5)
a = np.random.randint(low=0, high=100)
b = np.random.randint(low=0, high=5)
x[a][b] = np.nan
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
matrix_in=x,
check_input_matrices=True))
x_vec = np.random.rand(100)
a = np.random.randint(low=0, high=100)
x_vec[a] = np.nan
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
row_in=x_vec,
check_input_matrices=True))
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
col_in=x_vec,
check_input_matrices=True))
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
matrix_and_info_in=x,
check_input_matrices=True))
def testCheckInputMatricesInf(self):
"""
Checks that an exception is thrown if the input matrix contains
inf values.
"""
x = np.random.rand(100, 5)
a = np.random.randint(low=0, high=100)
b = np.random.randint(low=0, high=5)
x[a][b] = np.inf
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
matrix_in=x,
check_input_matrices=True))
x_vec = np.random.rand(100)
a = np.random.randint(low=0, high=100)
x_vec[a] = np.inf
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
row_in=x_vec,
check_input_matrices=True))
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
col_in=x_vec,
check_input_matrices=True))
self.assertRaises(RuntimeError,
lambda : test_python_binding(string_in="hello",
int_in=12,
double_in=4.0,
mat_req_in=[[1.0]],
col_req_in=[1.0],
matrix_and_info_in=x,
check_input_matrices=True))
if __name__ == '__main__':
unittest.main()
+6 -1
View File
@@ -42,12 +42,17 @@ namespace cv {
* where @f$ \bar{y} = frac{1}{y}\sum_{i=1}^{n} y_i @f$.
* For example, a model having R2Score = 0.85, explains 85 \% variability of
* the response data around its mean.
*
* @tparam AdjustedR2 If true, then the Adjusted R2 score will be used.
* Otherwise, the regular R2 score is used.
*/
template<bool AdjustedR2>
class R2Score
{
public:
/**
* Run prediction and calculate the R squared error.
* Run prediction and calculate the R squared or Adjusted R squared error.
*
* @param model A regression model.
* @param data Column-major data containing test items.
+16 -4
View File
@@ -15,10 +15,11 @@
namespace mlpack {
namespace cv {
template<bool AdjustedR2>
template<typename MLAlgorithm, typename DataType, typename ResponsesType>
double R2Score::Evaluate(MLAlgorithm& model,
const DataType& data,
const ResponsesType& responses)
double R2Score<AdjustedR2>::Evaluate(MLAlgorithm& model,
const DataType& data,
const ResponsesType& responses)
{
if (data.n_cols != responses.n_cols)
{
@@ -46,7 +47,18 @@ double R2Score::Evaluate(MLAlgorithm& model,
if (residualSumSquared == 0.0)
return totalSumSquared ? 1.0 : DBL_MIN;
return 1 - residualSumSquared / totalSumSquared;
if (AdjustedR2)
{
// Returning adjusted R-squared.
double rsq = 1 - (residualSumSquared / totalSumSquared);
return (1 - ((1 - rsq) * ((data.n_cols - 1) /
(data.n_cols - data.n_rows - 1))));
}
else
{
// Returning R-squared
return 1 - residualSumSquared / totalSumSquared;
}
}
} // namespace cv
+76 -76
View File
@@ -1,77 +1,77 @@
/**
/**
* @file core/data/image_info_impl.hpp
* @author Mehul Kumar Nirala
*
* An image information holder implementation.
*
* 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_IMAGE_INFO_IMPL_HPP
#define MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
#ifdef HAS_STB // Compile this only if stb is present.
// In case it hasn't been included yet.
#include "image_info.hpp"
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)
{
if (extension == Extension(fileName))
return true;
}
}
else
{
// Iterate over all supported file types that can be loaded.
for (auto extension : loadFileTypes)
{
if (extension == Extension(fileName))
return true;
}
}
return false;
}
} // namespace data
} // namespace mlpack
#endif // HAS_STB.
namespace mlpack {
namespace data {
inline ImageInfo::ImageInfo(const size_t width,
const size_t height,
const size_t channels,
const size_t quality) :
width(width),
height(height),
channels(channels),
quality(quality)
{
// Do nothing.
}
} // namespace data
} // namespace mlpack
#endif
* @author Mehul Kumar Nirala
*
* An image information holder implementation.
*
* 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_IMAGE_INFO_IMPL_HPP
#define MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
#ifdef HAS_STB // Compile this only if stb is present.
// In case it hasn't been included yet.
#include "image_info.hpp"
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)
{
if (extension == Extension(fileName))
return true;
}
}
else
{
// Iterate over all supported file types that can be loaded.
for (auto extension : loadFileTypes)
{
if (extension == Extension(fileName))
return true;
}
}
return false;
}
} // namespace data
} // namespace mlpack
#endif // HAS_STB.
namespace mlpack {
namespace data {
inline ImageInfo::ImageInfo(const size_t width,
const size_t height,
const size_t channels,
const size_t quality) :
width(width),
height(height),
channels(channels),
quality(quality)
{
// Do nothing.
}
} // namespace data
} // namespace mlpack
#endif
+95 -95
View File
@@ -1,96 +1,96 @@
/**
/**
* @file core/data/load_image_impl.hpp
* @author Mehul Kumar Nirala
*
* An image loading utility implementation.
*
* 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"
namespace mlpack {
namespace data {
// Image loading API.
template<typename eT>
bool Load(const std::string& filename,
arma::Mat<eT>& matrix,
ImageInfo& info,
const bool fatal)
{
Timer::Start("loading_image");
// STB loads into unsigned char matrices, so we may have to convert once
// loaded.
arma::Mat<unsigned char> tempMatrix;
const bool result = LoadImage(filename, tempMatrix, info, fatal);
// If fatal is true, then the program will have already thrown an exception.
if (!result)
{
Timer::Stop("loading_image");
return false;
}
matrix = arma::conv_to<arma::Mat<eT>>::from(tempMatrix);
Timer::Stop("loading_image");
return true;
}
// Image loading API for multiple files.
template<typename eT>
bool Load(const std::vector<std::string>& files,
arma::Mat<eT>& matrix,
ImageInfo& info,
const bool fatal)
{
if (files.size() == 0)
{
std::ostringstream oss;
oss << "Load(): vector of image files is empty." << std::endl;
if (fatal)
Log::Fatal << oss.str();
else
Log::Warn << oss.str();
return false;
}
arma::Mat<unsigned char> img;
bool status = LoadImage(files[0], img, info, fatal);
if (!status)
return false;
// Decide matrix dimension using the image height and width.
arma::Mat<unsigned char> tmpMatrix(
info.Width() * info.Height() * info.Channels(), files.size());
tmpMatrix.col(0) = img;
for (size_t i = 1; i < files.size() ; ++i)
{
arma::Mat<unsigned char> colImg(tmpMatrix.colptr(i), tmpMatrix.n_rows, 1,
false, true);
status = LoadImage(files[i], colImg, info, fatal);
if (!status)
return false;
}
matrix = arma::conv_to<arma::Mat<eT>>::from(tmpMatrix);
return true;
}
} // namespace data
} // namespace mlpack
#endif
* @author Mehul Kumar Nirala
*
* An image loading utility implementation.
*
* 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"
namespace mlpack {
namespace data {
// Image loading API.
template<typename eT>
bool Load(const std::string& filename,
arma::Mat<eT>& matrix,
ImageInfo& info,
const bool fatal)
{
Timer::Start("loading_image");
// STB loads into unsigned char matrices, so we may have to convert once
// loaded.
arma::Mat<unsigned char> tempMatrix;
const bool result = LoadImage(filename, tempMatrix, info, fatal);
// If fatal is true, then the program will have already thrown an exception.
if (!result)
{
Timer::Stop("loading_image");
return false;
}
matrix = arma::conv_to<arma::Mat<eT>>::from(tempMatrix);
Timer::Stop("loading_image");
return true;
}
// Image loading API for multiple files.
template<typename eT>
bool Load(const std::vector<std::string>& files,
arma::Mat<eT>& matrix,
ImageInfo& info,
const bool fatal)
{
if (files.size() == 0)
{
std::ostringstream oss;
oss << "Load(): vector of image files is empty." << std::endl;
if (fatal)
Log::Fatal << oss.str();
else
Log::Warn << oss.str();
return false;
}
arma::Mat<unsigned char> img;
bool status = LoadImage(files[0], img, info, fatal);
if (!status)
return false;
// Decide matrix dimension using the image height and width.
arma::Mat<unsigned char> tmpMatrix(
info.Width() * info.Height() * info.Channels(), files.size());
tmpMatrix.col(0) = img;
for (size_t i = 1; i < files.size() ; ++i)
{
arma::Mat<unsigned char> colImg(tmpMatrix.colptr(i), tmpMatrix.n_rows, 1,
false, true);
status = LoadImage(files[i], colImg, info, fatal);
if (!status)
return false;
}
matrix = arma::conv_to<arma::Mat<eT>>::from(tmpMatrix);
return true;
}
} // namespace data
} // namespace mlpack
#endif
+4 -4
View File
@@ -66,10 +66,10 @@ namespace math {
* @code
* // This matrix has two columns.
* arma::mat input;
* input << -1.0000 << 0.1429 << arma::endr
* << -0.7143 << 0.4286 << arma::endr
* << -0.4286 << 0.7143 << arma::endr
* << -0.1429 << 1.0000 << arma::endr;
* input = { { -1.0000, 0.1429 },
* { -0.7143, 0.4286 },
* { -0.4286, 0.7143 },
* { -0.1429, 1.0000 } };
*
* arma::mat output;
* ColumnsToBlocks ctb(1, 2);
+3
View File
@@ -81,6 +81,9 @@ class BallBound
//! Move constructor: take possession of another bound.
BallBound(BallBound&& other);
//! Move assignment operator.
BallBound& operator=(BallBound&& other);
//! Destructor to release allocated memory.
~BallBound();
+28 -4
View File
@@ -71,10 +71,14 @@ template<typename MetricType, typename VecType>
BallBound<MetricType, VecType>& BallBound<MetricType, VecType>::operator=(
const BallBound& other)
{
radius = other.radius;
center = other.center;
metric = other.metric;
ownsMetric = false;
if (this != &other)
{
radius = other.radius;
center = other.center;
metric = other.metric;
ownsMetric = false;
}
return *this;
}
//! Move constructor.
@@ -92,6 +96,26 @@ BallBound<MetricType, VecType>::BallBound(BallBound&& other) :
other.ownsMetric = false;
}
//! Move assignment operator.
template<typename MetricType, typename VecType>
BallBound<MetricType, VecType>& BallBound<MetricType, VecType>::operator=(
BallBound&& other)
{
if (this != &other)
{
radius = other.radius;
center = std::move(other.center);
metric = other.metric;
ownsMetric = other.ownsMetric;
other.radius = 0.0;
other.center = VecType();
other.metric = nullptr;
other.ownsMetric = false;
}
return *this;
}
//! Destructor to release allocated memory.
template<typename MetricType, typename VecType>
BallBound<MetricType, VecType>::~BallBound()
@@ -86,6 +86,9 @@ class HollowBallBound
//! Move constructor: take possession of another bound.
HollowBallBound(HollowBallBound&& other);
//! Move assignment operator.
HollowBallBound& operator=(HollowBallBound&& other);
//! Destructor to release allocated memory.
~HollowBallBound();
@@ -80,15 +80,17 @@ template<typename TMetricType, typename ElemType>
HollowBallBound<TMetricType, ElemType>& HollowBallBound<TMetricType, ElemType>::
operator=(const HollowBallBound& other)
{
if (ownsMetric)
delete metric;
radii = other.radii;
center = other.center;
hollowCenter = other.hollowCenter;
metric = other.metric;
ownsMetric = false;
if (this != &other)
{
if (ownsMetric)
delete metric;
radii = other.radii;
center = other.center;
hollowCenter = other.hollowCenter;
metric = other.metric;
ownsMetric = false;
}
return *this;
}
@@ -111,6 +113,29 @@ HollowBallBound<TMetricType, ElemType>::HollowBallBound(
other.ownsMetric = false;
}
//! Move assignment operator.
template<typename TMetricType, typename ElemType>
HollowBallBound<TMetricType, ElemType>& HollowBallBound<TMetricType, ElemType>::
operator=(HollowBallBound&& other)
{
if (this != &other)
{
radii = other.radii;
center = std::move(other.center);
hollowCenter = std::move(other.hollowCenter);
metric = other.metric;
ownsMetric = other.ownsMetric;
other.radii.Hi() = 0.0;
other.radii.Lo() = 0.0;
other.center = arma::Col<ElemType>();
other.hollowCenter = arma::Col<ElemType>();
other.metric = nullptr;
other.ownsMetric = false;
}
return *this;
}
//! Destructor to release allocated memory.
template<typename TMetricType, typename ElemType>
HollowBallBound<TMetricType, ElemType>::~HollowBallBound()
+4
View File
@@ -73,12 +73,16 @@ class HRectBound
//! Copy constructor; necessary to prevent memory leaks.
HRectBound(const HRectBound& other);
//! Same as copy constructor; necessary to prevent memory leaks.
HRectBound& operator=(const HRectBound& other);
//! Move constructor: take possession of another bound's information.
HRectBound(HRectBound&& other);
//! Move assignment operator.
HRectBound& operator=(HRectBound&& other);
//! Destructor: clean up memory.
~HRectBound();
+20
View File
@@ -103,6 +103,26 @@ inline HRectBound<MetricType, ElemType>::HRectBound(
other.minWidth = 0.0;
}
/**
* Move assignment operator.
*/
template<typename MetricType, typename ElemType>
inline HRectBound<MetricType, ElemType>&
HRectBound<MetricType, ElemType>::operator=(
HRectBound<MetricType, ElemType>&& other)
{
if (this != &other)
{
bounds = other.bounds;
minWidth = other.minWidth;
dim = other.dim;
other.dim = 0;
other.bounds = nullptr;
other.minWidth = 0.0;
}
return *this;
}
/**
* Destructor: clean up memory.
*/
@@ -177,10 +177,18 @@ class DiscreteHilbertValue
/**
* Copy the local Hilbert value's pointer.
*
* @param val The DiscreteHilbertValue object from which the dataset
* @param other The DiscreteHilbertValue object from which the dataset
* will be copied.
*/
DiscreteHilbertValue& operator=(const DiscreteHilbertValue& val);
DiscreteHilbertValue& operator=(const DiscreteHilbertValue& other);
/**
* Move the local Hilbert object.
*
* @param other The DiscreteHilbertValue object from which the dataset
* will be copied.
*/
DiscreteHilbertValue& operator=(DiscreteHilbertValue&& other);
/**
* Nullify the localHilbertValues pointer in order to prevent an invalid free.
@@ -434,22 +434,43 @@ RemoveNode(TreeType* node, const size_t nodeIndex)
template<typename TreeElemType>
DiscreteHilbertValue<TreeElemType>& DiscreteHilbertValue<TreeElemType>::
operator=(const DiscreteHilbertValue& val)
operator=(const DiscreteHilbertValue& other)
{
if (this == &val)
if (this == &other)
return *this;
if (ownsLocalHilbertValues)
delete localHilbertValues;
localHilbertValues = const_cast<arma::Mat<HilbertElemType>* >
(val.LocalHilbertValues());
(other.LocalHilbertValues());
ownsLocalHilbertValues = false;
numValues = val.NumValues();
numValues = other.NumValues();
return *this;
}
template<typename TreeElemType>
DiscreteHilbertValue<TreeElemType>& DiscreteHilbertValue<TreeElemType>::
operator=(DiscreteHilbertValue&& other)
{
if (this != &other)
{
localHilbertValues = other.localHilbertValues;
ownsLocalHilbertValues = other.ownsLocalHilbertValues;
numValues = other.numValues;
valueToInsert = other.valueToInsert;
ownsValueToInsert = other.ownsValueToInsert;
other.localHilbertValues = nullptr;
other.ownsLocalHilbertValues = false;
other.numValues = 0;
other.valueToInsert = nullptr;
other.ownsValueToInsert = false;
}
return *this;
}
template<typename TreeElemType>
void DiscreteHilbertValue<TreeElemType>::NullifyData()
{
+29
View File
@@ -267,3 +267,32 @@ void IO::ClearSettings()
GetSingleton().aliases = persistentAliases;
GetSingleton().functionMap = persistentFunctions;
}
void IO::CheckInputMatrices()
{
typedef typename std::tuple<data::DatasetInfo, arma::mat> TupleType;
std::map<std::string, util::ParamData>::iterator itr;
for (itr = IO::Parameters().begin(); itr != IO::Parameters().end(); ++itr)
{
std::string paramName = itr->first;
std::string paramType = itr->second.cppType;
if (paramType == "arma::mat")
{
IO::CheckInputMatrix(IO::GetParam<arma::mat>(paramName), paramName);
}
else if (paramType == "arma::vec")
{
IO::CheckInputMatrix(IO::GetParam<arma::vec>(paramName), paramName);
}
else if (paramType == "arma::rowvec")
{
IO::CheckInputMatrix(IO::GetParam<arma::rowvec>(paramName), paramName);
}
else if (paramType == "std::tuple<mlpack::data::DatasetInfo, arma::mat>")
{
IO::CheckInputMatrix(
std::get<1>(IO::GetParam<TupleType>(paramName)), paramName);
}
}
}
+14
View File
@@ -219,6 +219,15 @@ class IO
template<typename T>
static T& GetRawParam(const std::string& identifier);
/**
* Utility function for CheckInputMatrices().
*
* @param matrix Matrix to check.
* @param identifier Name of the parameter in question.
*/
template<typename T>
static void CheckInputMatrix(const T& matrix, const std::string& identifier);
/**
* Given two (matrix) parameters, ensure that the first is an in-place copy of
* the second. This will generally do nothing (as the bindings already do
@@ -285,6 +294,11 @@ class IO
*/
static void ClearSettings();
/**
* Checks all input matrices for NaN and inf values, exits if found any.
*/
static void CheckInputMatrices();
private:
//! Convenience map from alias values to names.
std::map<char, std::string> aliases;
+12
View File
@@ -145,6 +145,18 @@ T& IO::GetRawParam(const std::string& identifier)
}
}
template<typename T>
void IO::CheckInputMatrix(const T& matrix, const std::string& identifier)
{
std::string errMsg1 = "The input " + identifier + " has NaN values.";
std::string errMsg2 = "The input " + identifier + " has inf values.";
if (matrix.has_nan())
Log::Fatal << errMsg1 << std::endl;
if (matrix.has_inf())
Log::Fatal << errMsg2 << std::endl;
}
} // namespace mlpack
#endif
+2
View File
@@ -230,6 +230,8 @@ PARAM_FLAG("copy_all_inputs", "If specified, all input parameters will be deep"
" copied before the method is run. This is useful for debugging problems "
"where the input parameters are being modified by the algorithm, but can "
"slow down the code.", "");
PARAM_FLAG("check_input_matrices", "If specified, the input matrix is checked for"
" NaN and inf values; an exception is thrown if any are found.", "");
// Nothing else needs to be defined---the binding will use mlpackMain() as-is.
+45 -92
View File
@@ -1015,7 +1015,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
*/
#define TUPLE_TYPE std::tuple<mlpack::data::DatasetInfo, arma::mat>
#define PARAM_MATRIX_AND_INFO_IN(ID, DESC, ALIAS) \
PARAM_IN(TUPLE_TYPE, ID, DESC, ALIAS, TUPLE_TYPE(), false)
PARAM(TUPLE_TYPE, ID, DESC, ALIAS, \
"std::tuple<mlpack::data::DatasetInfo, arma::mat>", false, true, true, \
TUPLE_TYPE())
/**
* Define an input model. From the command line, the user can specify the file
@@ -1207,11 +1209,44 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
PARAM_IN(std::vector<T>, ID, DESC, ALIAS, std::vector<T>(), true);
/**
* Define an input parameter. Don't use this function; use the other ones above
* that call it. Note that we are using the __LINE__ macro for naming these
* actual parameters when __COUNTER__ does not exist, which is a bit of an ugly
* hack... but this is the preprocessor, after all. We don't have much choice
* other than ugliness.
* Defining useful macros using PARAM macro defined later.
*/
#define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \
PARAM(T, ID, DESC, ALIAS, #T, REQ, true, false, DEF);
#define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \
PARAM(T, ID, DESC, ALIAS, #T, REQ, false, false, DEF);
#define PARAM_MATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \
PARAM(arma::mat, ID, DESC, ALIAS, "arma::mat", REQ, IN, \
TRANS, arma::mat());
#define PARAM_UMATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \
PARAM(arma::Mat<size_t>, ID, DESC, ALIAS, "arma::Mat<size_t>", \
REQ, IN, TRANS, arma::Mat<size_t>());
#define PARAM_COL(ID, DESC, ALIAS, REQ, TRANS, IN) \
PARAM(arma::vec, ID, DESC, ALIAS, "arma::vec", REQ, IN, TRANS, \
arma::vec());
#define PARAM_UCOL(ID, DESC, ALIAS, REQ, TRANS, IN) \
PARAM(arma::Col<size_t>, ID, DESC, ALIAS, "arma::Col<size_t>", \
REQ, IN, TRANS, arma::Col<size_t>());
#define PARAM_ROW(ID, DESC, ALIAS, REQ, TRANS, IN) \
PARAM(arma::rowvec, ID, DESC, ALIAS, "arma::rowvec", REQ, IN, \
TRANS, arma::rowvec());
#define PARAM_UROW(ID, DESC, ALIAS, REQ, TRANS, IN) \
PARAM(arma::Row<size_t>, ID, DESC, ALIAS, "arma::Row<size_t>", \
REQ, IN, TRANS, arma::Row<size_t>());
/**
* Define the PARAM(), PARAM_MODEL() macro. Don't use this function;
* use the other ones above that call it. Note that we are using the __LINE__
* macro for naming these actual parameters when __COUNTER__ does not exist,
* which is a bit of an ugly hack... but this is the preprocessor, after all.
* We don't have much choice other than ugliness.
*
* @param T Type of the parameter.
* @param ID Name of the parameter.
@@ -1223,51 +1258,10 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
* @param REQ Whether or not parameter is required (boolean value).
*/
#ifdef __COUNTER__
#define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \
#define PARAM(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \
static mlpack::util::Option<T> \
JOIN(io_option_dummy_object_in_, __COUNTER__) \
(DEF, ID, DESC, ALIAS, #T, REQ, true, false, testName);
#define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \
static mlpack::util::Option<T> \
JOIN(io_option_dummy_object_out_, __COUNTER__) \
(DEF, ID, DESC, ALIAS, #T, REQ, false, false, testName);
#define PARAM_MATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::mat> \
JOIN(io_option_dummy_matrix_, __COUNTER__) \
(arma::mat(), ID, DESC, ALIAS, "arma::mat", \
REQ, IN, !TRANS, testName);
#define PARAM_UMATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::Mat<size_t>> \
JOIN(io_option_dummy_umatrix_, __COUNTER__) \
(arma::Mat<size_t>(), ID, DESC, ALIAS, "arma::Mat<size_t>", \
REQ, IN, !TRANS, testName);
#define PARAM_COL(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::vec> \
JOIN(io_option_dummy_col_, __COUNTER__) \
(arma::vec(), ID, DESC, ALIAS, "arma::vec", \
REQ, IN, !TRANS, testName);
#define PARAM_UCOL(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::Col<size_t>> \
JOIN(io_option_dummy_ucol_, __COUNTER__) \
(arma::Col<size_t>(), ID, DESC, ALIAS, "arma::Col<size_t>", \
REQ, IN, !TRANS, testName);
#define PARAM_ROW(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::rowvec> \
JOIN(io_option_dummy_row_, __COUNTER__) \
(arma::rowvec(), ID, DESC, ALIAS, "arma::rowvec", \
REQ, IN, !TRANS, testName);
#define PARAM_UROW(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::Row<size_t>> \
JOIN(io_option_dummy_urow_, __COUNTER__) \
(arma::Row<size_t>(), ID, DESC, ALIAS, "arma::Row<size_t>", \
REQ, IN, !TRANS, testName);
(DEF, ID, DESC, ALIAS, NAME, REQ, IN, !TRANS, testName);
// There are no uses of required models, so that is not an option to this
// macro (it would be easy to add).
@@ -1280,51 +1274,10 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
// don't think we can absolutely guarantee success, but it should be "good
// enough". We use the __LINE__ macro and the type of the parameter to try
// and get a good guess at something unique.
#define PARAM_IN(T, ID, DESC, ALIAS, DEF, REQ) \
#define PARAM(T, ID, DESC, ALIAS, NAME, REQ, IN, TRANS, DEF) \
static mlpack::util::Option<T> \
JOIN(JOIN(io_option_dummy_object_in_, __LINE__), opt) \
(DEF, ID, DESC, ALIAS, #T, REQ, true, false, testName);
#define PARAM_OUT(T, ID, DESC, ALIAS, DEF, REQ) \
static mlpack::util::Option<T> \
JOIN(JOIN(io_option_dummy_object_out_, __LINE__), opt) \
(DEF, ID, DESC, ALIAS, #T, REQ, false, false, testName);
#define PARAM_MATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::mat> \
JOIN(JOIN(io_option_dummy_object_matrix_, __LINE__), opt) \
(arma::mat(), ID, DESC, ALIAS, "arma::mat", REQ, IN, !TRANS, \
testName);
#define PARAM_UMATRIX(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::Mat<size_t>> \
JOIN(JOIN(io_option_dummy_object_umatrix_, __LINE__), opt) \
(arma::Mat<size_t>(), ID, DESC, ALIAS, "arma::Mat<size_t>", REQ, IN, \
!TRANS, testName);
#define PARAM_COL(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::vec> \
JOIN(io_option_dummy_object_col_, __LINE__) \
(arma::vec(), ID, DESC, ALIAS, "arma::vec", REQ, IN, !TRANS, \
testName);
#define PARAM_UCOL(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::Col<size_t>> \
JOIN(io_option_dummy_object_ucol_, __LINE__) \
(arma::Col<size_t>(), ID, DESC, ALIAS, "arma::Col<size_t>", REQ, IN, \
!TRANS, testName);
#define PARAM_ROW(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::rowvec> \
JOIN(io_option_dummy_object_row_, __LINE__) \
(arma::rowvec(), ID, DESC, ALIAS, "arma::rowvec", REQ, IN, !TRANS, \
testName);
#define PARAM_UROW(ID, DESC, ALIAS, REQ, TRANS, IN) \
static mlpack::util::Option<arma::Row<size_t>> \
JOIN(io_option_dummy_object_urow_, __LINE__) \
(arma::Row<size_t>(), ID, DESC, ALIAS, "arma::Row<size_t>", REQ, IN, \
!TRANS, testName);
(DEF, ID, DESC, ALIAS, NAME, REQ, IN, !TRANS, testName);
#define PARAM_MODEL(TYPE, ID, DESC, ALIAS, REQ, IN) \
static mlpack::util::Option<TYPE*> \
+4 -1
View File
@@ -43,11 +43,14 @@ namespace util {
* @param fatal If true, output goes to Log::Fatal instead of Log::Warn and an
* exception is thrown.
* @param customErrorMessage Error message to append.
* @param allowNone If true, then no error message will be thrown if none of the
* parameters in the constraints were passed.
*/
void RequireOnlyOnePassed(
const std::vector<std::string>& constraints,
const bool fatal = true,
const std::string& customErrorMessage = "");
const std::string& customErrorMessage = "",
const bool allowNone = false);
/**
* Require that at least one of the given parameters in the constraints set was
+3 -2
View File
@@ -21,7 +21,8 @@ namespace util {
inline void RequireOnlyOnePassed(
const std::vector<std::string>& constraints,
const bool fatal,
const std::string& errorMessage)
const std::string& errorMessage,
const bool allowNone)
{
if (BINDING_IGNORE_CHECK(constraints))
return;
@@ -57,7 +58,7 @@ inline void RequireOnlyOnePassed(
stream << "; " << errorMessage;
stream << "!" << std::endl;
}
else if (set == 0)
else if (set == 0 && !allowNone)
{
stream << (fatal ? "Must " : "Should ");
@@ -178,8 +178,7 @@ PrefixedOutStream::BaseLogic(const T& val)
if (maxVal == 0.0)
maxVal = 1;
int maxLog = log10(maxVal);
maxLog = (maxLog > 0) ? floor(maxLog) + 1 : 1;
const int maxLog = int(log10(maxVal)) + 1;
const int padding = 4;
convert.width(convert.precision() + maxLog + padding);
printVal.raw_print(convert);
-1
View File
@@ -10,7 +10,6 @@ set(DIRS
block_krylov_svd
cf
dbscan
decision_stump
decision_tree
det
emst
+1 -1
View File
@@ -71,7 +71,7 @@ namespace adaboost {
* @endcode
*
* For more information on and examples of weak learners, see
* perceptron::Perceptron<> and decision_stump::DecisionStump<>.
* perceptron::Perceptron<> and tree::ID3DecisionStump.
*
* @tparam MatType Data matrix type (i.e. arma::mat or arma::sp_mat).
* @tparam WeakLearnerType Type of weak learner to use.
+30 -9
View File
@@ -72,19 +72,40 @@ AdaBoostModel::AdaBoostModel(AdaBoostModel&& other) :
//! Copy assignment operator.
AdaBoostModel& AdaBoostModel::operator=(const AdaBoostModel& other)
{
mappings = other.mappings;
weakLearnerType = other.weakLearnerType;
if (this != &other)
{
mappings = other.mappings;
weakLearnerType = other.weakLearnerType;
delete dsBoost;
dsBoost = (other.dsBoost == NULL) ? NULL :
new AdaBoost<ID3DecisionStump>(*other.dsBoost);
delete dsBoost;
dsBoost = (other.dsBoost == NULL) ? NULL :
new AdaBoost<ID3DecisionStump>(*other.dsBoost);
delete pBoost;
pBoost = (other.pBoost == NULL) ? NULL :
new AdaBoost<Perceptron<>>(*other.pBoost);
delete pBoost;
pBoost = (other.pBoost == NULL) ? NULL :
new AdaBoost<Perceptron<>>(*other.pBoost);
dimensionality = other.dimensionality;
dimensionality = other.dimensionality;
}
return *this;
}
//! Move assignment operator.
AdaBoostModel& AdaBoostModel::operator=(AdaBoostModel&& other)
{
if (this != &other)
{
mappings = std::move(other.mappings);
weakLearnerType = other.weakLearnerType;
dsBoost = other.dsBoost;
other.dsBoost = nullptr;
pBoost = other.pBoost;
other.pBoost = nullptr;
dimensionality = other.dimensionality;
}
return *this;
}
@@ -61,6 +61,9 @@ class AdaBoostModel
//! Copy assignment operator.
AdaBoostModel& operator=(const AdaBoostModel& other);
//! Move assignment operator.
AdaBoostModel& operator=(AdaBoostModel&& other);
//! Clean up memory.
~AdaBoostModel();
@@ -36,7 +36,8 @@ class CompleteIncrementalTermination
*/
CompleteIncrementalTermination(
TerminationPolicy tPolicy = TerminationPolicy()) :
tPolicy(tPolicy) { }
tPolicy(tPolicy), incrementalIndex(0), iteration(0)
{ /* Nothing to do here. */ }
/**
* Initializes the termination policy before stating the factorization.
@@ -119,4 +120,3 @@ class CompleteIncrementalTermination
} // namespace mlpack
#endif // MLPACK_METHODS_AMF_COMPLETE_INCREMENTAL_TERMINATION_HPP
@@ -35,7 +35,8 @@ class IncompleteIncrementalTermination
*/
IncompleteIncrementalTermination(
TerminationPolicy tPolicy = TerminationPolicy()) :
tPolicy(tPolicy) { }
tPolicy(tPolicy), incrementalIndex(0), iteration(0)
{ /* Nothing to do here. */ }
/**
* Initializes the termination policy before stating the factorization.
@@ -40,8 +40,16 @@ class SimpleResidueTermination
* @param maxIterations Maximum number of iterations.
*/
SimpleResidueTermination(const double minResidue = 1e-5,
const size_t maxIterations = 10000)
: minResidue(minResidue), maxIterations(maxIterations) { }
const size_t maxIterations = 10000) :
minResidue(minResidue),
maxIterations(maxIterations),
residue(0.0),
iteration(0),
nm(0),
normOld(0)
{
// Nothing to do here.
}
/**
* Initializes the termination policy before stating the factorization.
@@ -56,7 +56,7 @@ class SVDCompleteIncrementalLearning
SVDCompleteIncrementalLearning(double u = 0.0001,
double kw = 0,
double kh = 0)
: u(u), kw(kw), kh(kh)
: u(u), kw(kw), kh(kh), currentUserIndex(0), currentItemIndex(0)
{
// Nothing to do.
}
@@ -172,7 +172,7 @@ class SVDCompleteIncrementalLearning<arma::sp_mat>
SVDCompleteIncrementalLearning(double u = 0.01,
double kw = 0,
double kh = 0)
: u(u), kw(kw), kh(kh), it(NULL)
: u(u), kw(kw), kh(kh), it(NULL), m(0), n(0), isStart(false)
{}
~SVDCompleteIncrementalLearning()
@@ -53,7 +53,7 @@ class SVDIncompleteIncrementalLearning
SVDIncompleteIncrementalLearning(double u = 0.001,
double kw = 0,
double kh = 0)
: u(u), kw(kw), kh(kh)
: u(u), kw(kw), kh(kh), currentUserIndex(0)
{
// Nothing to do.
}
+1
View File
@@ -20,6 +20,7 @@ add_subdirectory(gan)
add_subdirectory(rbm)
add_subdirectory(augmented)
add_subdirectory(regularizer)
add_subdirectory(util)
# Add directory name to sources.
set(DIR_SRCS)
@@ -19,6 +19,7 @@ set(SOURCES
multi_quadratic_function.hpp
poisson1_function.hpp
gaussian_function.hpp
hard_swish_function.hpp
)
# Add directory name to sources.
@@ -0,0 +1,116 @@
/**
* @file methods/ann/activation_functions/hard_swish_function.hpp
* @author Anush Kini
*
* Definition and implementation of the Hard Swish function as described by
* Howard A, Sandler M, Chu G, Chen LC, Chen B, Tan M, Wang W, Zhu Y, Pang R,
* Vasudevan V and Le QV.
* For more information, see the following paper.
*
* @code
* @misc{
* author = {Howard A, Sandler M, Chu G, Chen LC, Chen B, Tan M, Wang W,
* Zhu Y, Pang R, Vasudevan V and Le QV},
* title = {Searching for MobileNetV3},
* year = {2019}
* }
* @endcode
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_METHODS_ANN_ACTIVATION_FUNCTIONS_HARD_SWISH_FUNCTION_HPP
#define MLPACK_METHODS_ANN_ACTIVATION_FUNCTIONS_HARD_SWISH_FUNCTION_HPP
#include <mlpack/prereqs.hpp>
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
/**
* The Hard Swish function, defined by
*
* @f{eqnarray*}{
* f(x) &=& \begin{cases}
* 0 & x \leq -3\\
* x & x \geq +3\\
* \frac{x * (x + 3)}{6} & otherwise\\
* \end{cases} \\
* f'(x) &=& \begin{cases}
* 0 & x \leq -3\\
* 1 & x \geq +3\\
* \frac{2x + 3}{6} & otherwise\\
* \end{cases}
* @f}
*/
class HardSwishFunction
{
public:
/**
* Computes the Hard Swish function.
*
* @param x Input data.
* @return f(x).
*/
static double Fn(const double x)
{
if (x <= -3)
return 0;
else if (x >= 3)
return x;
return x * (x + 3) / 6;
}
/**
* Computes the Hard Swish function.
*
* @param x Input data.
* @param y The resulting output activation.
*/
template <typename InputVecType, typename OutputVecType>
static void Fn(const InputVecType &x, OutputVecType &y)
{
y.set_size(size(x));
for (size_t i = 0; i < x.n_elem; i++)
y(i) = Fn(x(i));
}
/**
* Computes the first derivative of the Hard Swish function.
*
* @param y Input data.
* @return f'(x).
*/
static double Deriv(const double y)
{
if (y <= -3)
return 0;
else if (y >= 3)
return 1;
return (2 * y + 3.0) / 6.0;
}
/**
* Computes the first derivatives of the Hard Swish function.
*
* @param y Input data.
* @param x The resulting derivatives.
*/
template <typename InputVecType, typename OutputVecType>
static void Deriv(const InputVecType &y, OutputVecType &x)
{
x.set_size(size(y));
for (size_t i = 0; i < y.n_elem; i++)
x(i) = Deriv(y(i));
}
}; // class HardSwishFunction
} // namespace ann
} // namespace mlpack
#endif
+18
View File
@@ -23,6 +23,8 @@
#include "visitor/set_input_height_visitor.hpp"
#include "visitor/set_input_width_visitor.hpp"
#include "util/check_input_shape.hpp"
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
@@ -109,6 +111,10 @@ double FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Train(
OptimizerType& optimizer,
CallbackTypes&&... callbacks)
{
CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(network,
predictors.n_rows,
"FFN<>::Train()");
ResetData(std::move(predictors), std::move(responses));
WarnMessageMaxIterations<OptimizerType>(optimizer, this->predictors.n_cols);
@@ -131,6 +137,10 @@ double FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Train(
arma::mat responses,
CallbackTypes&&... callbacks)
{
CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(network,
predictors.n_rows,
"FFN<>::Train()");
ResetData(std::move(predictors), std::move(responses));
OptimizerType optimizer;
@@ -217,6 +227,10 @@ template<typename OutputLayerType, typename InitializationRuleType,
void FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Predict(
arma::mat predictors, arma::mat& results)
{
CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(network,
predictors.n_rows,
"FFN<>::Predict()");
if (parameter.is_empty())
ResetParameters();
@@ -250,6 +264,10 @@ template<typename PredictorsType, typename ResponsesType>
double FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Evaluate(
const PredictorsType& predictors, const ResponsesType& responses)
{
CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(network,
predictors.n_rows,
"FFN<>::Evaluate()");
if (parameter.is_empty())
ResetParameters();
@@ -63,6 +63,8 @@ set(SOURCES
log_softmax_impl.hpp
lookup.hpp
lookup_impl.hpp
lp_pooling.hpp
lp_pooling_impl.hpp
lstm.hpp
lstm_impl.hpp
max_pooling.hpp
@@ -114,6 +114,9 @@ class AdaptiveMaxPooling
//! Get the output size.
size_t OutputSize() const { return poolingLayer.OutputSize(); }
//! Get the size of the weights.
size_t WeightSize() const { return 0; }
/**
* Serialize the layer.
*/
@@ -115,6 +115,9 @@ class AdaptiveMeanPooling
//! Get the output size.
size_t OutputSize() const { return poolingLayer.OutputSize(); }
//! Get the size of the weights.
size_t WeightSize() const { return 0; }
/**
* Serialize the layer.
*/
@@ -263,6 +263,12 @@ class AtrousConvolution
return (outSize * inSize * kernelWidth * kernelHeight) + outSize;
}
//! Get the shape of the input.
size_t InputShape() const
{
return inputHeight * inputWidth * inSize;
}
/**
* Serialize the layer.
*/
@@ -27,6 +27,7 @@
#include <mlpack/methods/ann/activation_functions/elliot_function.hpp>
#include <mlpack/methods/ann/activation_functions/elish_function.hpp>
#include <mlpack/methods/ann/activation_functions/gaussian_function.hpp>
#include <mlpack/methods/ann/activation_functions/hard_swish_function.hpp>
namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
@@ -50,6 +51,7 @@ namespace ann /** Artificial Neural Network. */ {
* - ELiSHLayer
* - ElliotLayer
* - GaussianLayer
* - HardSwishLayer
*
* @tparam ActivationFunction Activation function used for the embedding layer.
* @tparam InputDataType Type of the input data (arma::colvec, arma::mat,
@@ -277,6 +279,17 @@ template <
using GaussianFunctionLayer = BaseLayer<
ActivationFunction, InputDataType, OutputDataType>;
/**
* Standard HardSwish-Layer using the HardSwish activation function.
*/
template <
class ActivationFunction = HardSwishFunction,
typename InputDataType = arma::mat,
typename OutputDataType = arma::mat
>
using HardSwishFunctionLayer = BaseLayer<
ActivationFunction, InputDataType, OutputDataType>;
} // namespace ann
} // namespace mlpack
@@ -118,6 +118,12 @@ class BilinearInterpolation
//! Modify the depth of the input.
size_t& InDepth() { return depth; }
//! Get the shape of the input.
size_t InputShape() const
{
return inRowSize;
}
/**
* Serialize the layer.
*/
+3
View File
@@ -88,6 +88,9 @@ class CReLU
//! Modify the delta.
OutputDataType& Delta() { return delta; }
//! Get size of weights.
size_t WeightSize() const { return 0; }
/**
* Serialize the layer.
*/
+3
View File
@@ -111,6 +111,9 @@ class CELU
//! Modify the value of deterministic parameter.
bool& Deterministic() { return deterministic; }
//! Get size of weights.
size_t WeightSize() { return 0; }
/**
* Serialize the layer.
*/
+13 -1
View File
@@ -41,6 +41,18 @@ class Concatenate
*/
Concatenate();
//! Copy constructor.
Concatenate(const Concatenate& layer);
//! Move constructor.
Concatenate(Concatenate&& layer);
//! Operator= copy constructor.
Concatenate& operator=(const Concatenate& layer);
//! Operator= move constructor.
Concatenate& operator=(Concatenate&& layer);
/**
* Ordinary feed forward pass of a neural network, evaluating the function
* f(x) by propagating the activity forward through f.
@@ -82,7 +94,7 @@ class Concatenate
//! Get the concat matrix.
OutputDataType const& Concat() const { return concat; }
//! Modify the delta.
//! Modify the concat.
OutputDataType& Concat() { return concat; }
/**
@@ -20,11 +20,63 @@ namespace mlpack {
namespace ann /** Artificial Neural Network. */ {
template<typename InputDataType, typename OutputDataType>
Concatenate<InputDataType, OutputDataType>::Concatenate()
Concatenate<InputDataType, OutputDataType>::Concatenate() :
inRows(0)
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
Concatenate<InputDataType, OutputDataType>::Concatenate(const Concatenate& layer) :
inRows(layer.inRows),
weights(layer.weights),
delta(layer.delta),
concat(layer.concat)
{
// Nothing to to here.
}
template<typename InputDataType, typename OutputDataType>
Concatenate<InputDataType, OutputDataType>::Concatenate(Concatenate&& layer) :
inRows(layer.inRows),
weights(std::move(layer.weights)),
delta(std::move(layer.delta)),
concat(std::move(layer.concat))
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
Concatenate<InputDataType, OutputDataType>&
Concatenate<InputDataType, OutputDataType>::
operator=(const Concatenate& layer)
{
if (this != &layer)
{
inRows = layer.inRows;
weights = layer.weights;
delta = layer.delta;
concat = layer.concat;
}
return *this;
}
template<typename InputDataType, typename OutputDataType>
Concatenate<InputDataType, OutputDataType>&
Concatenate<InputDataType, OutputDataType>::
operator=(Concatenate&& layer)
{
if (this != &layer)
{
inRows = layer.inRows;
weights = std::move(layer.weights);
delta = std::move(layer.delta);
concat = std::move(layer.concat);
}
return *this;
}
template<typename InputDataType, typename OutputDataType>
template<typename eT>
void Concatenate<InputDataType, OutputDataType>::Forward(
+37 -2
View File
@@ -29,6 +29,35 @@ namespace ann /** Artificial Neural Network. */ {
/**
* Implementation of the Convolution class. The Convolution class represents a
* single layer of a neural network.
* Example usage:
*
* Suppose we want to pass a matrix M (2744x100) to a `Convolution` layer;
* in this example, `M` was obtained from "flattening" 100 images (or Mel
* cepstral coefficients, if we talk about speech, or whatever you like) of
* dimension 196x14. In other words, the first 196 columns of each row of M
* will be made of the 196 columns of the first row of each of the 100 images
* (or Mel cepstral coefficients). Then the next 295 columns of M (196 - 393)
* will be made of the 196 columns of the second row of the 100 images (or Mel
* cepstral coefficients), etc. Given that the size of our 2-D input images is
* 196x14, the parameters for our `Convolution` layer will be something like
* this:
*
* ```
* Convolution<> c(1, // Number of input activation maps.
* 14, // Number of output activation maps.
* 3, // Filter width.
* 3, // Filter height.
* 1, // Stride along width.
* 1, // Stride along height.
* 0, // Padding width.
* 0, // Padding height.
* 196, // Input width.
* 14); // Input height.
* ```
*
* This `Convolution<>` layer will treat each column of the input matrix `M` as
* a 2-D image (or object) of the original 196x14 size, using this as the input
* for the 14 filters of this example.
*
* @tparam ForwardConvolutionRule Convolution to perform forward process.
* @tparam BackwardConvolutionRule Convolution to perform backward process.
@@ -207,10 +236,10 @@ class Convolution
//! Modify the output height.
size_t& OutputHeight() { return outputHeight; }
//! Get the input size.
//! Get the number of input maps.
size_t InputSize() const { return inSize; }
//! Get the output size.
//! Get the number of output maps.
size_t OutputSize() const { return outSize; }
//! Get the kernel width.
@@ -259,6 +288,12 @@ class Convolution
return (outSize * inSize * kernelWidth * kernelHeight) + outSize;
}
//! Get the shape of the input.
size_t InputShape() const
{
return inputHeight * inputWidth * inSize;
}
/**
* Serialize the layer.
*/
+12
View File
@@ -60,6 +60,18 @@ class Dropout
*/
Dropout(const double ratio = 0.5);
//! Copy Constructor
Dropout(const Dropout& layer);
//! Move Constructor
Dropout(const Dropout&&);
//! Copy assignment operator
Dropout& operator=(const Dropout& layer);
//! Move assignment operator
Dropout& operator=(Dropout&& layer);
/**
* Ordinary feed forward pass of the dropout layer.
*
@@ -29,6 +29,54 @@ Dropout<InputDataType, OutputDataType>::Dropout(
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
Dropout<InputDataType, OutputDataType>::Dropout(
const Dropout& layer) :
ratio(layer.ratio),
scale(layer.scale),
deterministic(layer.deterministic)
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
Dropout<InputDataType, OutputDataType>::Dropout(
const Dropout&& layer) :
ratio(std::move(layer.ratio)),
scale(std::move(scale)),
deterministic(std::move(deterministic))
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
Dropout<InputDataType, OutputDataType>&
Dropout<InputDataType, OutputDataType>::
operator=(const Dropout& layer)
{
if (this != &layer)
{
ratio = layer.ratio;
scale = layer.scale;
deterministic = layer.deterministic;
}
return *this;
}
template<typename InputDataType, typename OutputDataType>
Dropout<InputDataType, OutputDataType>&
Dropout<InputDataType, OutputDataType>::
operator=(Dropout&& layer)
{
if (this != &layer)
{
ratio = std::move(layer.ratio);
scale = std::move(layer.scale);
deterministic = std::move(layer.deterministic);
}
return *this;
}
template<typename InputDataType, typename OutputDataType>
template<typename eT>
void Dropout<InputDataType, OutputDataType>::Forward(
@@ -73,6 +73,18 @@ class FastLSTM
//! Create the Fast LSTM object.
FastLSTM();
//! Copy Constructor
FastLSTM(const FastLSTM& layer);
//! Move Constructor
FastLSTM(FastLSTM&& layer);
//! Copy assignment operator
FastLSTM& operator=(const FastLSTM& layer);
//! Move assignment operator
FastLSTM& operator=(FastLSTM&& layer);
/**
* Create the Fast LSTM layer object using the specified parameters.
*
@@ -170,6 +182,12 @@ class FastLSTM
return 4 * outSize * inSize + 4 * outSize + 4 * outSize * outSize;
}
//! Get the shape of the input.
size_t InputShape() const
{
return inSize;
}
/**
* Serialize the layer
*/
+97 -26
View File
@@ -45,6 +45,90 @@ FastLSTM<InputDataType, OutputDataType>::FastLSTM(
weights.set_size(WeightSize(), 1);
}
template<typename InputDataType, typename OutputDataType>
FastLSTM<InputDataType, OutputDataType>::FastLSTM(const FastLSTM& layer) :
inSize(layer.inSize),
outSize(layer.outSize),
rho(layer.rho),
forwardStep(layer.forwardStep),
backwardStep(layer.backwardStep),
gradientStep(layer.gradientStep),
weights(layer.weights),
batchSize(layer.batchSize),
batchStep(layer.batchStep),
gradientStepIdx(layer.gradientStepIdx),
grad(layer.grad),
rhoSize(layer.rho),
bpttSteps(layer.bpttSteps)
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
FastLSTM<InputDataType, OutputDataType>::FastLSTM(FastLSTM&& layer) :
inSize(std::move(layer.inSize)),
outSize(std::move(layer.outSize)),
rho(std::move(layer.rho)),
forwardStep(std::move(layer.forwardStep)),
backwardStep(std::move(layer.backwardStep)),
gradientStep(std::move(layer.gradientStep)),
weights(std::move(layer.weights)),
batchSize(std::move(layer.batchSize)),
batchStep(std::move(layer.batchStep)),
gradientStepIdx(std::move(layer.gradientStepIdx)),
grad(std::move(layer.grad)),
rhoSize(std::move(layer.rho)),
bpttSteps(std::move(layer.bpttSteps))
{
// Nothing to do here.
}
template<typename InputDataType, typename OutputDataType>
FastLSTM<InputDataType, OutputDataType>&
FastLSTM<InputDataType, OutputDataType>::operator=(const FastLSTM& layer)
{
if (this != &layer)
{
inSize = layer.inSize;
outSize = layer.outSize;
rho = layer.rho;
forwardStep = layer.forwardStep;
backwardStep = layer.backwardStep;
gradientStep = layer.gradientStep;
weights = layer.weights;
batchSize = layer.batchSize;
batchStep = layer.batchStep;
gradientStepIdx = layer.gradientStepIdx;
grad = layer.grad;
rhoSize = layer.rho;
bpttSteps = layer.bpttSteps;
}
return *this;
}
template<typename InputDataType, typename OutputDataType>
FastLSTM<InputDataType, OutputDataType>&
FastLSTM<InputDataType, OutputDataType>::operator=(FastLSTM&& layer)
{
if (this != &layer)
{
inSize = std::move(layer.inSize);
outSize = std::move(layer.outSize);
rho = std::move(layer.rho);
forwardStep = std::move(layer.forwardStep);
backwardStep = std::move(layer.backwardStep);
gradientStep = std::move(layer.gradientStep);
weights = std::move(layer.weights);
batchSize = std::move(layer.batchSize);
batchStep = std::move(layer.batchStep);
gradientStepIdx = std::move(layer.gradientStepIdx);
grad = std::move(layer.grad);
rhoSize = std::move(layer.rho);
bpttSteps = std::move(layer.bpttSteps);
}
return *this;
}
template<typename InputDataType, typename OutputDataType>
void FastLSTM<InputDataType, OutputDataType>::Reset()
{
@@ -79,33 +163,20 @@ void FastLSTM<InputDataType, OutputDataType>::ResetCell(const size_t size)
gradientStep = batchSize * size - 1;
const size_t rhoBatchSize = size * batchSize;
if (gate.is_empty() || gate.n_cols != rhoBatchSize)
{
gate.set_size(4 * outSize, rhoBatchSize);
gateActivation.set_size(outSize * 3, rhoBatchSize);
stateActivation.set_size(outSize, rhoBatchSize);
cellActivation.set_size(outSize, rhoBatchSize);
prevError.set_size(4 * outSize, batchSize);
if (prevOutput.is_empty())
{
prevOutput = arma::zeros<OutputDataType>(outSize, batchSize);
cell = arma::zeros(outSize, size * batchSize);
cellActivationError = arma::zeros<OutputDataType>(outSize, batchSize);
outParameter = arma::zeros<OutputDataType>(
outSize, (size + 1) * batchSize);
}
else
{
// To preserve the leading zeros, recreate the object according to given
// size specifications, while preserving the elements as well as the
// layout of the elements.
prevOutput.resize(outSize, batchSize);
cell.resize(outSize, size * batchSize);
cellActivationError.resize(outSize, batchSize);
outParameter.resize(outSize, (size + 1) * batchSize);
}
}
// Make sure all of the matrices we use to store state are at least as large
// as we need.
gate.set_size(4 * outSize, rhoBatchSize);
gateActivation.set_size(outSize * 3, rhoBatchSize);
stateActivation.set_size(outSize, rhoBatchSize);
cellActivation.set_size(outSize, rhoBatchSize);
prevError.set_size(4 * outSize, batchSize);
// Reset stored state to zeros.
prevOutput.zeros(outSize, batchSize);
cell.zeros(outSize, size * batchSize);
cellActivationError.zeros(outSize, batchSize);
outParameter.zeros(outSize, (size + 1) * batchSize);
}
template<typename InputDataType, typename OutputDataType>
+6
View File
@@ -182,6 +182,12 @@ class Glimpse
//! Get the used glimpse size (height = width).
size_t GlimpseSize() const { return size;}
//! Get the shape of the input.
size_t InputShape() const
{
return inSize;
}
/**
* Serialize the layer.
*/
+6
View File
@@ -155,6 +155,12 @@ class GRU
//! Get the number of output units.
size_t OutSize() const { return outSize; }
//! Get the shape of the input.
size_t InputShape() const
{
return inSize;
}
/**
* Serialize the layer
*/
+6
View File
@@ -177,6 +177,12 @@ class Highway
//! Get the number of input units.
size_t InSize() const { return inSize; }
//! Get the shape of the input.
size_t InputShape() const
{
return inSize;
}
/**
* Serialize the layer.
*/
+1
View File
@@ -47,6 +47,7 @@
#include "linear3d.hpp"
#include "log_softmax.hpp"
#include "lookup.hpp"
#include "lp_pooling.hpp"
#include "lstm.hpp"
#include "max_pooling.hpp"
#include "mean_pooling.hpp"
@@ -148,6 +148,12 @@ class LayerNorm
//! Get the value of epsilon.
double Epsilon() const { return eps; }
//! Get the shape of the input.
size_t InputShape() const
{
return size;
}
/**
* Serialize the layer.
*/
@@ -120,6 +120,10 @@ HAS_MEM_FUNC(Bias, HasBiasCheck);
// we can use with SFINAE to catch when a type has a MaxIterations() function.
HAS_MEM_FUNC(MaxIterations, HasMaxIterations);
// This gives us a HasInShapeCheck<T> type we can use with SFINAE to catch when
// a type has a function named InputShape.
HAS_ANY_METHOD_FORM(InputShape, HasInputShapeCheck);
} // namespace ann
} // namespace mlpack
@@ -38,6 +38,7 @@
#include <mlpack/methods/ann/layer/multiply_constant.hpp>
#include <mlpack/methods/ann/layer/max_pooling.hpp>
#include <mlpack/methods/ann/layer/mean_pooling.hpp>
#include <mlpack/methods/ann/layer/lp_pooling.hpp>
#include <mlpack/methods/ann/layer/noisylinear.hpp>
#include <mlpack/methods/ann/layer/adaptive_max_pooling.hpp>
#include <mlpack/methods/ann/layer/adaptive_mean_pooling.hpp>
@@ -219,6 +220,7 @@ class AdaptiveMeanPooling;
using MoreTypes = boost::variant<
Linear3D<arma::mat, arma::mat, NoRegularizer>*,
LpPooling<arma::mat, arma::mat>*,
Glimpse<arma::mat, arma::mat>*,
Highway<arma::mat, arma::mat>*,
MultiheadAttention<arma::mat, arma::mat, NoRegularizer>*,
@@ -90,6 +90,9 @@ class LeakyReLU
//! Modify the non zero gradient.
double& Alpha() { return alpha; }
//! Get size of weights.
size_t WeightSize() const { return 0; }
/**
* Serialize the layer.
*/
+6
View File
@@ -152,6 +152,12 @@ class Linear
return (inSize * outSize) + outSize;
}
//! Get the shape of the input.
size_t InputShape() const
{
return inSize;
}
/**
* Serialize the layer
*/

Some files were not shown because too many files have changed in this diff Show More