Merge branch 'master' into FAIL-Messages
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
YEAR: ${LICENSE_YEAR}
|
||||
COPYRIGHT HOLDER: mlpack Team
|
||||
ORGANIZATION: mlpack
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) << ", "
|
||||
|
||||
@@ -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)";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 +
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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*> \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -10,7 +10,6 @@ set(DIRS
|
||||
block_krylov_svd
|
||||
cf
|
||||
dbscan
|
||||
decision_stump
|
||||
decision_tree
|
||||
det
|
||||
emst
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user