Merge remote-tracking branch 'origin/master' into julia-bindings
This commit is contained in:
+19
-13
@@ -11,9 +11,8 @@ environment:
|
||||
boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*"
|
||||
BOOST_UNIT_TEST : "C:/projects/mlpack/\
|
||||
boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*"
|
||||
ARMADILLO_DOWNLOAD : "http://sourceforge.net/projects/arma/files/\
|
||||
armadillo-7.800.2.tar.xz"
|
||||
ARMADILLO_LIBRARY : "C:/projects/mlpack/armadillo-7.800.2/\
|
||||
ARMADILLO_DOWNLOAD : "http://ftp.fau.de/macports/distfiles/armadillo/armadillo-8.400.0.tar.xz"
|
||||
ARMADILLO_LIBRARY : "C:/projects/mlpack/armadillo-8.400.0/\
|
||||
build/Debug/armadillo.lib"
|
||||
BLAS_LIBRARY : "%APPVEYOR_BUILD_FOLDER%/OpenBLAS.0.2.14.1/lib/native/lib/x64/\
|
||||
libopenblas.dll.a"
|
||||
@@ -25,8 +24,15 @@ environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
VSVER: Visual Studio 14 2015 Win64
|
||||
MSBUILD: C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
VSVER: Visual Studio 15 2017 Win64
|
||||
MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
|
||||
# Currently, the VS2019 build seems to always time out. This seems to be an
|
||||
# AppVeyor issue.
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
# VSVER: Visual Studio 16 2019
|
||||
# MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe
|
||||
|
||||
|
||||
configuration: Release
|
||||
@@ -62,28 +68,26 @@ build_script:
|
||||
- ps: cp ${env:BOOST_UNIT_TEST} C:\projects\mlpack\boost_libs\
|
||||
- echo TEST_ARMA is %ARMADILLO_DOWNLOAD%
|
||||
- >
|
||||
if not exist armadillo.tar.xz
|
||||
appveyor DownloadFile %ARMADILLO_DOWNLOAD%
|
||||
-FileName armadillo.tar.xz
|
||||
- 7z x armadillo.tar.xz -so | 7z x -si -ttar > nul
|
||||
- cd armadillo-7.800.2 && mkdir build && cd build
|
||||
- 7z x armadillo.tar.xz -so -txz | 7z x -si -ttar > nul
|
||||
- cd armadillo-8.400.0 && mkdir build && cd build
|
||||
- >
|
||||
cmake -G "Visual Studio 14 2015 Win64"
|
||||
cmake -G "%VSVER%"
|
||||
-DBLAS_LIBRARY:FILEPATH=%BLAS_LIBRARY%
|
||||
-DLAPACK_LIBRARY:FILEPATH=%BLAS_LIBRARY%
|
||||
-DCMAKE_PREFIX:FILEPATH="%APPVEYOR_BUILD_FOLDER%/armadillo"
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DCMAKE_BUILD_TYPE=Release ..
|
||||
- >
|
||||
"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
|
||||
"C:\projects\mlpack\armadillo-7.800.2\build\armadillo.sln"
|
||||
"%MSBUILD%" "C:\projects\mlpack\armadillo-8.400.0\build\armadillo.sln"
|
||||
/m /verbosity:quiet /p:Configuration=Release;Platform=x64
|
||||
- cd C:\projects\mlpack && mkdir build && cd build
|
||||
- >
|
||||
cmake -G "Visual Studio 14 2015 Win64"
|
||||
cmake -G "%VSVER%"
|
||||
-DBLAS_LIBRARY:FILEPATH=%BLAS_LIBRARY%
|
||||
-DLAPACK_LIBRARY:FILEPATH=%BLAS_LIBRARY%
|
||||
-DARMADILLO_INCLUDE_DIR="C:/projects/mlpack/armadillo-7.800.2/include"
|
||||
-DARMADILLO_INCLUDE_DIR="C:/projects/mlpack/armadillo-8.400.0/include"
|
||||
-DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY%
|
||||
-DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE%
|
||||
-DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack/boost_libs"
|
||||
@@ -92,8 +96,7 @@ build_script:
|
||||
-DBUILD_PYTHON_BINDINGS=OFF
|
||||
-DCMAKE_BUILD_TYPE=Release ..
|
||||
- >
|
||||
"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
|
||||
"C:\projects\mlpack\build\mlpack.sln"
|
||||
"%MSBUILD%" "C:\projects\mlpack\build\mlpack.sln"
|
||||
/m /verbosity:minimal /nologo /p:BuildInParallel=true
|
||||
/p:Configuration=Release;Platform=x64
|
||||
|
||||
@@ -143,6 +146,9 @@ build_script:
|
||||
- ps: >
|
||||
cp C:\projects\mlpack\doc\examples
|
||||
C:\projects\mlpack\dist\win-installer\staging -recurse
|
||||
- ps: >
|
||||
cp C:\projects\mlpack\src\mlpack\tests\data\german.csv
|
||||
C:\projects\mlpack\dist\win-installer\staging\examples\sample-ml-app\sample-ml-app\data\
|
||||
|
||||
# Checking current gitversion or mlpack version.
|
||||
- ps: >
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
jobs:
|
||||
- job: Linux
|
||||
timeoutInMinutes: 360
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF'
|
||||
python.version: '2.7'
|
||||
Python27:
|
||||
python.version: '2.7'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DPYTHON_EXECUTABLE=/usr/bin/python'
|
||||
Python37:
|
||||
python.version: '3.7'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DPYTHON_EXECUTABLE=/usr/bin/python3'
|
||||
Markdown:
|
||||
python.version: '2.7'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF'
|
||||
|
||||
steps:
|
||||
- template: linux-steps.yaml
|
||||
|
||||
- job: macOS
|
||||
timeoutInMinutes: 360
|
||||
pool:
|
||||
vmImage: macOS-10.13
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF'
|
||||
python.version: '2.7'
|
||||
Python27:
|
||||
python.version: '2.7'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF'
|
||||
Python37:
|
||||
python.version: '3.7'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF'
|
||||
|
||||
steps:
|
||||
- template: macos-steps.yaml
|
||||
|
||||
- job: WindowsVS14
|
||||
timeoutInMinutes: 360
|
||||
displayName: Windows VS14
|
||||
pool:
|
||||
vmImage: vs2015-win2012r2
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF'
|
||||
CMakeGenerator: '-G "Visual Studio 14 2015 Win64"'
|
||||
MSBuildVersion: '14.0'
|
||||
ArchiveNoLibs: 'mlpack-windows-vs14-no-libs.zip'
|
||||
ArchiveLibs: 'mlpack-windows-vs14.zip'
|
||||
ArchiveTests: 'mlpack_test-vs14.xml'
|
||||
steps:
|
||||
- template: windows-steps.yaml
|
||||
|
||||
- job: WindowsVS15
|
||||
timeoutInMinutes: 360
|
||||
displayName: Windows VS15
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_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
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF'
|
||||
python.version: '2.7'
|
||||
CMakeGenerator: '-G "Visual Studio 16 2019"'
|
||||
MSBuildVersion: '16.0'
|
||||
ArchiveNoLibs: 'mlpack-windows-vs16-no-libs.zip'
|
||||
ArchiveLibs: 'mlpack-windows-vs16.zip'
|
||||
ArchiveTests: 'mlpack_test-vs16.xml'
|
||||
|
||||
steps:
|
||||
- template: windows-steps.yaml
|
||||
@@ -0,0 +1,73 @@
|
||||
steps:
|
||||
# Checkout repository
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
# Set python version
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '$(python.version)'
|
||||
|
||||
# Install build dependencies
|
||||
- script: |
|
||||
git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf
|
||||
|
||||
sudo add-apt-repository ppa:mhier/libboost-latest
|
||||
sudo apt-get update
|
||||
|
||||
# Remove BOOST_ROOT from the environment to prevent attempting to use a
|
||||
# boost which is incompatible with the compiler.
|
||||
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
|
||||
|
||||
if [ '$(python.version)' == '2.7' ]; then
|
||||
sudo apt-get install -y --allow-unauthenticated python-pip cython python-numpy python-pandas
|
||||
sudo pip install --upgrade --ignore-installed setuptools cython
|
||||
fi
|
||||
|
||||
if [ '$(python.version)' == '3.7' ]; then
|
||||
sudo apt-get install -y --allow-unauthenticated python3-pip cython3 python3-numpy
|
||||
sudo pip3 install --upgrade --ignore-installed setuptools cython pandas
|
||||
fi
|
||||
|
||||
# Install armadillo.
|
||||
curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*
|
||||
cmake . && make && sudo make install && cd ..
|
||||
sudo cp .travis/config.hpp /usr/include/armadillo_bits/config.hpp
|
||||
displayName: 'Install Build Dependencies'
|
||||
|
||||
# Configure mlpack (CMake)
|
||||
- script: unset BOOST_ROOT && mkdir build && cd build && cmake $(CMakeArgs) ..
|
||||
displayName: 'CMake'
|
||||
|
||||
# Build mlpack
|
||||
- script: cd build && make -j2
|
||||
displayName: 'Build'
|
||||
|
||||
# Run tests
|
||||
- script: cd build && bin/mlpack_test --result_code=no --report_level=detailed --log_level=test_suite --log_format=HRF --log_sink=res.txt
|
||||
displayName: 'Run tests'
|
||||
|
||||
# Process test results
|
||||
- bash: |
|
||||
python conf/ci/convert.py > mlpack_test.xml
|
||||
displayName: 'Process test results'
|
||||
|
||||
# Publish test results to Azure Pipelines
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: JUnit
|
||||
testResultsFiles: 'mlpack_test.xml'
|
||||
failTaskOnFailedTests: true
|
||||
displayName: 'Publish tests'
|
||||
|
||||
# Publish build artifacts to Azure Pipelines
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: 'mlpack_test.xml'
|
||||
artifactName: 'mlpack_test_linux.xml'
|
||||
displayName: 'Publish artifacts test results'
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
steps:
|
||||
# Checkout repository
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
# Set python version.
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '$(python.version)'
|
||||
|
||||
# Install Build Dependencies
|
||||
- script: |
|
||||
set -e
|
||||
sudo xcode-select --switch /Applications/Xcode_10.1.app/Contents/Developer
|
||||
unset BOOST_ROOT
|
||||
pip install cython numpy pandas
|
||||
brew install openblas armadillo boost
|
||||
|
||||
git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf
|
||||
displayName: 'Install Build Dependencies'
|
||||
|
||||
# Configure mlpack (CMake)
|
||||
- script: |
|
||||
unset BOOST_ROOT
|
||||
mkdir build && cd build
|
||||
export PYPATH=$(which python)
|
||||
cmake $(CMakeArgs) -DPYTHON_EXECUTABLE=$PYPATH ..
|
||||
displayName: 'CMake'
|
||||
|
||||
# Build mlpack
|
||||
- script: cd build && make -j2
|
||||
displayName: 'Build'
|
||||
|
||||
# Run tests
|
||||
- script: cd build && bin/mlpack_test --result_code=no --report_level=detailed --log_level=test_suite --log_format=HRF --log_sink=res.txt
|
||||
displayName: 'Run tests'
|
||||
|
||||
# Process test results
|
||||
- bash: |
|
||||
python conf/ci/convert.py > mlpack_test.xml
|
||||
displayName: 'Process test results'
|
||||
|
||||
# Publish test results to Azure Pipelines
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: JUnit
|
||||
testResultsFiles: 'mlpack_test.xml'
|
||||
failTaskOnFailedTests: true
|
||||
displayName: 'Publish tests'
|
||||
|
||||
# Publish build artifacts to Azure Pipelines
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: 'mlpack_test.xml'
|
||||
artifactName: 'mlpack_test_macos.xml'
|
||||
displayName: 'Publish artifacts test results'
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
- task: NuGetToolInstaller@0
|
||||
inputs:
|
||||
versionSpec: '5.3.0'
|
||||
|
||||
# Fetch build dependencies
|
||||
- powershell: |
|
||||
nuget install OpenBLAS -o $(Agent.ToolsDirectory)
|
||||
nuget install boost -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_unit_test_framework-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_program_options-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_random-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_serialization-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_math_c99-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install OpenBLAS -o $(Agent.ToolsDirectory)
|
||||
|
||||
mkdir -p $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_program_options-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
displayName: 'Fetch build dependencies'
|
||||
|
||||
# Configure armadillo
|
||||
- bash: |
|
||||
git clone --depth 1 https://github.com/mlpack/jenkins-conf.git conf
|
||||
|
||||
curl http://masterblaster.mlpack.org:5005/armadillo-8.400.0.tar.gz | tar xvz
|
||||
|
||||
cd armadillo-8.400.0/ && cmake $(CMakeGenerator) \
|
||||
-DBLAS_LIBRARY:FILEPATH=$(Agent.ToolsDirectory)/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a \
|
||||
-DLAPACK_LIBRARY:FILEPATH=$(Agent.ToolsDirectory)/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a \
|
||||
-DCMAKE_PREFIX:FILEPATH=../../armadillo \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release .
|
||||
displayName: 'Configure armadillo'
|
||||
|
||||
# Build armadillo
|
||||
- task: MSBuild@1
|
||||
inputs:
|
||||
solution: 'armadillo-8.400.0/*.sln'
|
||||
msbuildLocationMethod: 'location'
|
||||
msbuildVersion: $(MSBuildVersion)
|
||||
configuration: 'Release'
|
||||
msbuildArchitecture: 'x64'
|
||||
msbuildArguments: /m /p:BuildInParallel=true
|
||||
clean: false
|
||||
maximumCpuCount: false
|
||||
displayName: 'Build armadillo'
|
||||
|
||||
# Configure mlpack
|
||||
- powershell: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake $(CMakeGenerator) `
|
||||
$(CMakeArgs) `
|
||||
-DBLAS_LIBRARY:FILEPATH=$(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\libopenblas.dll.a `
|
||||
-DLAPACK_LIBRARY:FILEPATH=$(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\libopenblas.dll.a `
|
||||
-DARMADILLO_INCLUDE_DIR="..\armadillo-8.400.0\include" `
|
||||
-DARMADILLO_LIBRARY="..\armadillo-8.400.0\Release\armadillo.lib" `
|
||||
-DBOOST_INCLUDEDIR=$(Agent.ToolsDirectory)\boost.1.60.0.0\lib\native\include `
|
||||
-DBOOST_LIBRARYDIR=$(Agent.ToolsDirectory)\boost_libs `
|
||||
-DCMAKE_BUILD_TYPE=Release ..
|
||||
displayName: 'Configure mlpack'
|
||||
|
||||
# Build mlpack
|
||||
- task: MSBuild@1
|
||||
inputs:
|
||||
solution: 'build/*.sln'
|
||||
msbuildLocationMethod: 'location'
|
||||
msbuildVersion: $(MSBuildVersion)
|
||||
configuration: 'Release'
|
||||
msbuildArchitecture: 'x64'
|
||||
msbuildArguments: /m /p:BuildInParallel=true
|
||||
maximumCpuCount: false
|
||||
clean: false
|
||||
displayName: 'Build mlpack'
|
||||
|
||||
# Configure mlpack
|
||||
- powershell: |
|
||||
cp $(Agent.ToolsDirectory)\boost_libs\*.* build\Release\
|
||||
cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\lib\x64\*.* build\Release\
|
||||
cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.* build\Release\
|
||||
displayName: 'Configure mlpack'
|
||||
|
||||
# Run tests
|
||||
- bash: |
|
||||
cd build
|
||||
ls
|
||||
Release/mlpack_test.exe --result_code=no --report_level=detailed --log_level=test_suite --log_format=HRF --log_sink=res.txt
|
||||
displayName: 'Run tests'
|
||||
|
||||
# Process test results
|
||||
- bash: |
|
||||
python conf/ci/convert.py > mlpack_test.xml
|
||||
displayName: 'Process test results'
|
||||
|
||||
# Copy artifacts
|
||||
- powershell: |
|
||||
mkdir exe-archive
|
||||
cp build\Release\*.exe exe-archive\
|
||||
displayName: 'Copy artifacts'
|
||||
|
||||
# Build artifacts archive
|
||||
- task: ArchiveFiles@2
|
||||
inputs:
|
||||
rootFolderOrFile: 'exe-archive\'
|
||||
includeRootFolder: false
|
||||
archiveType: 'zip'
|
||||
archiveFile: $(ArchiveNoLibs)
|
||||
replaceExistingArchive: true
|
||||
displayName: 'Build artifacts'
|
||||
|
||||
- task: ArchiveFiles@2
|
||||
inputs:
|
||||
rootFolderOrFile: 'build\Release\'
|
||||
includeRootFolder: false
|
||||
archiveType: 'zip'
|
||||
archiveFile: $(ArchiveLibs)
|
||||
replaceExistingArchive: true
|
||||
displayName: 'Build artifacts'
|
||||
|
||||
# Publish artifacts to Azure Pipelines
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: $(ArchiveNoLibs)
|
||||
artifactName: $(ArchiveNoLibs)
|
||||
displayName: 'Publish artifacts no-libs'
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: $(ArchiveLibs)
|
||||
artifactName: $(ArchiveLibs)
|
||||
displayName: 'Publish artifacts complete'
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: 'mlpack_test.xml'
|
||||
artifactName: $(ArchiveTests)
|
||||
displayName: 'Publish artifacts test results'
|
||||
|
||||
# Publish test results to Azure Pipelines
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: JUnit
|
||||
testResultsFiles: 'mlpack_test.xml'
|
||||
failTaskOnFailedTests: true
|
||||
displayName: 'Publish tests'
|
||||
@@ -0,0 +1,2 @@
|
||||
github: [numfocus]
|
||||
custom: https://numfocus.org/donate-to-mlpack
|
||||
@@ -6,3 +6,4 @@ src/mlpack/core/util/arma_config.hpp
|
||||
.idea
|
||||
cmake-build-*
|
||||
*.pyc
|
||||
Testing/
|
||||
|
||||
+7
-8
@@ -1,4 +1,3 @@
|
||||
sudo: required
|
||||
language: cpp
|
||||
|
||||
matrix:
|
||||
@@ -8,9 +7,9 @@ matrix:
|
||||
env: CMAKE_OPTIONS="-DDEBUG=OFF -DPROFILE=OFF -DPYTHON_EXECUTABLE=/usr/bin/python"
|
||||
before_install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev python-pip cython python-numpy python-pandas
|
||||
- sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev python-pip cython python-numpy python-pandas xz-utils
|
||||
- sudo pip install --upgrade --ignore-installed setuptools cython
|
||||
- curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-6.500.5.tar.gz | tar xvz && cd armadillo*
|
||||
- curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*
|
||||
- cmake . && make && sudo make install && cd ..
|
||||
- sudo cp .travis/config.hpp /usr/include/armadillo_bits/config.hpp
|
||||
|
||||
@@ -19,9 +18,9 @@ matrix:
|
||||
env: CMAKE_OPTIONS="-DDEBUG=OFF -DPROFILE=OFF -DPYTHON_EXECUTABLE=/usr/bin/python3"
|
||||
before_install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev python3-pip cython3 python3-numpy
|
||||
- sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev python3-pip cython3 python3-numpy xz-utils
|
||||
- sudo pip3 install --upgrade --ignore-installed setuptools cython pandas
|
||||
- curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-6.500.5.tar.gz | tar xvz && cd armadillo*
|
||||
- curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*
|
||||
- cmake . && make && sudo make install && cd ..
|
||||
- sudo cp .travis/config.hpp /usr/include/armadillo_bits/config.hpp
|
||||
|
||||
@@ -30,8 +29,8 @@ matrix:
|
||||
env: CMAKE_OPTIONS="-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF"
|
||||
before_install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev
|
||||
- curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-6.500.5.tar.gz | tar xvz && cd armadillo*
|
||||
- sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev xz-utils
|
||||
- curl https://ftp.fau.de/macports/distfiles/armadillo/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*
|
||||
- cmake . && make && sudo make install && cd ..
|
||||
- sudo cp .travis/config.hpp /usr/include/armadillo_bits/config.hpp
|
||||
|
||||
@@ -54,7 +53,7 @@ matrix:
|
||||
- brew install openblas armadillo || brew install openblas armadillo
|
||||
|
||||
install:
|
||||
- mkdir build && cd build && cmake $CMAKE_OPTIONS .. && travis_wait 60 make -j2
|
||||
- mkdir build && cd build && cmake $CMAKE_OPTIONS .. && travis_wait 75 make -j2
|
||||
|
||||
script:
|
||||
- CTEST_OUTPUT_ON_FAILURE=1 travis_wait 30 ctest -j2
|
||||
|
||||
+177
-49
@@ -1,35 +1,65 @@
|
||||
// Copyright (C) 2008-2012 NICTA (www.nicta.com.au)
|
||||
// Copyright (C) 2008-2012 Conrad Sanderson
|
||||
//
|
||||
// This file is part of the Armadillo C++ library.
|
||||
// It is provided without any warranty of fitness
|
||||
// for any purpose. You can redistribute this file
|
||||
// and/or modify it under the terms of the GNU
|
||||
// Lesser General Public License (LGPL) as published
|
||||
// by the Free Software Foundation, either version 3
|
||||
// of the License or (at your option) any later version.
|
||||
// (see http://www.opensource.org/licenses for more info)
|
||||
// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
|
||||
// Copyright 2008-2016 National ICT Australia (NICTA)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#if !defined(ARMA_USE_LAPACK)
|
||||
#define ARMA_USE_LAPACK
|
||||
//// Uncomment the above line if you have LAPACK or a high-speed replacement for LAPACK,
|
||||
//// such as Intel's MKL, AMD's ACML, or the Accelerate framework.
|
||||
//// Comment out the above line if you don't have LAPACK or a high-speed replacement for LAPACK,
|
||||
//// such as Intel MKL, AMD ACML, or the Accelerate framework.
|
||||
//// LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse.
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_USE_BLAS)
|
||||
#define ARMA_USE_BLAS
|
||||
//// Uncomment the above line if you have BLAS or a high-speed replacement for BLAS,
|
||||
//// such as GotoBLAS, Intel's MKL, AMD's ACML, or the Accelerate framework.
|
||||
//// Comment out the above line if you don't have BLAS or a high-speed replacement for BLAS,
|
||||
//// such as OpenBLAS, GotoBLAS, Intel MKL, AMD ACML, or the Accelerate framework.
|
||||
//// BLAS is used for matrix multiplication.
|
||||
//// Without BLAS, matrix multiplication will still work, but might be slower.
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_USE_NEWARP)
|
||||
#define ARMA_USE_NEWARP
|
||||
//// Uncomment the above line to enable the built-in partial emulation of ARPACK.
|
||||
//// This is used for eigen decompositions of real (non-complex) sparse matrices, eg. eigs_sym(), svds()
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_USE_ARPACK)
|
||||
// #define ARMA_USE_ARPACK
|
||||
//// Uncomment the above line if you have ARPACK or a high-speed replacement for ARPACK.
|
||||
//// ARPACK is required for eigen decompositions of complex sparse matrices
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_USE_SUPERLU)
|
||||
// #define ARMA_USE_SUPERLU
|
||||
//// Uncomment the above line if you have SuperLU.
|
||||
//// SuperLU is used for solving sparse linear systems via spsolve()
|
||||
//// Caveat: only SuperLU version 5.2 can be used!
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_SUPERLU_INCLUDE_DIR)
|
||||
// #define ARMA_SUPERLU_INCLUDE_DIR /usr/include/
|
||||
//// If you're using SuperLU and want to explicitly include the SuperLU headers,
|
||||
//// uncomment the above define and specify the appropriate include directory.
|
||||
//// Make sure the directory has a trailing /
|
||||
#endif
|
||||
|
||||
#define ARMA_USE_WRAPPER
|
||||
//// Comment out the above line if you prefer to directly link with LAPACK and/or BLAS (eg. -llapack -lblas)
|
||||
//// instead of linking indirectly with LAPACK and/or BLAS via Armadillo's run-time wrapper library.
|
||||
//// Comment out the above line if you're getting linking errors when compiling your programs,
|
||||
//// or if you prefer to directly link with LAPACK, BLAS + etc instead of the Armadillo runtime library.
|
||||
//// You will then need to link your programs directly with -llapack -lblas instead of -larmadillo
|
||||
|
||||
// #define ARMA_BLAS_CAPITALS
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries have capitalised function names (eg. ACML on 64-bit Windows)
|
||||
@@ -45,31 +75,49 @@
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int"
|
||||
|
||||
// #define ARMA_USE_TBB_ALLOC
|
||||
//// Uncomment the above line if you want to use Intel TBB scalable_malloc() and scalable_free() instead of standard new[] and delete[]
|
||||
//// Uncomment the above line if you want to use Intel TBB scalable_malloc() and scalable_free() instead of standard malloc() and free()
|
||||
|
||||
// #define ARMA_USE_MKL_ALLOC
|
||||
//// Uncomment the above line if you want to use Intel MKL mkl_malloc() and mkl_free() instead of standard new[] and delete[]
|
||||
//// Uncomment the above line if you want to use Intel MKL mkl_malloc() and mkl_free() instead of standard malloc() and free()
|
||||
|
||||
/* #undef ARMA_USE_ATLAS */
|
||||
#define ARMA_ATLAS_INCLUDE_DIR /
|
||||
// #define ARMA_USE_ATLAS
|
||||
// #define ARMA_ATLAS_INCLUDE_DIR /usr/include/
|
||||
//// If you're using ATLAS and the compiler can't find cblas.h and/or clapack.h
|
||||
//// uncomment the above define and specify the appropriate include directory.
|
||||
//// Make sure the directory has a trailing /
|
||||
|
||||
#define ARMA_64BIT_WORD
|
||||
//// Uncomment the above line if you require matrices/vectors capable of holding more than 4 billion elements.
|
||||
//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long")
|
||||
|
||||
#if !defined(ARMA_USE_CXX11)
|
||||
#define ARMA_USE_CXX11
|
||||
//// Uncomment the above line if you have a C++ compiler that supports the C++11 standard
|
||||
//// This will enable additional features, such as use of initialiser lists
|
||||
//// Uncomment the above line to forcefully enable use of C++11 features (eg. initialiser lists).
|
||||
//// Note that ARMA_USE_CXX11 is automatically enabled when a C++11 compiler is detected.
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_USE_OPENMP)
|
||||
// #define ARMA_USE_OPENMP
|
||||
//// Uncomment the above line to forcefully enable use of OpenMP for parallelisation.
|
||||
//// Note that ARMA_USE_OPENMP is automatically enabled when a compiler supporting OpenMP 3.1 is detected.
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_64BIT_WORD)
|
||||
#define ARMA_64BIT_WORD
|
||||
//// Uncomment the above line if you require matrices/vectors capable of holding more than 4 billion elements.
|
||||
//// Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long").
|
||||
//// Note that ARMA_64BIT_WORD is automatically enabled when a C++11 compiler is detected.
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_USE_HDF5)
|
||||
/* #undef ARMA_USE_HDF5 */
|
||||
//// Uncomment the above line if you want the ability to save and load matrices stored in the HDF5 format;
|
||||
//// the hdf5.h header file must be available on your system and you will need to link with the hdf5 library (eg. -lhdf5)
|
||||
// #define ARMA_USE_HDF5
|
||||
//// Uncomment the above line to allow the ability to save and load matrices stored in HDF5 format;
|
||||
//// the hdf5.h header file must be available on your system,
|
||||
//// and you will need to link with the hdf5 library (eg. -lhdf5)
|
||||
#endif
|
||||
|
||||
// #define ARMA_USE_HDF5_ALT
|
||||
#if defined(ARMA_USE_HDF5_ALT) && defined(ARMA_USE_WRAPPER)
|
||||
#undef ARMA_USE_HDF5
|
||||
#define ARMA_USE_HDF5
|
||||
|
||||
// #define ARMA_HDF5_INCLUDE_DIR /usr/include/
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_MAT_PREALLOC)
|
||||
@@ -80,6 +128,18 @@
|
||||
//// If you mainly use lots of very small vectors (eg. <= 4 elements),
|
||||
//// change the number to the size of your vectors.
|
||||
|
||||
#if !defined(ARMA_OPENMP_THRESHOLD)
|
||||
#define ARMA_OPENMP_THRESHOLD 320
|
||||
#endif
|
||||
//// The minimum number of elements in a matrix to allow OpenMP based parallelisation;
|
||||
//// it must be an integer that is at least 1.
|
||||
|
||||
#if !defined(ARMA_OPENMP_THREADS)
|
||||
#define ARMA_OPENMP_THREADS 10
|
||||
#endif
|
||||
//// The maximum number of threads to use for OpenMP based parallelisation;
|
||||
//// it must be an integer that is at least 1.
|
||||
|
||||
#if !defined(ARMA_SPMAT_CHUNKSIZE)
|
||||
#define ARMA_SPMAT_CHUNKSIZE 256
|
||||
#endif
|
||||
@@ -99,27 +159,39 @@
|
||||
//// This is mainly useful for debugging of the library.
|
||||
|
||||
|
||||
// #define ARMA_USE_BOOST
|
||||
// #define ARMA_USE_BOOST_DATE
|
||||
|
||||
|
||||
#if !defined(ARMA_DEFAULT_OSTREAM)
|
||||
#define ARMA_DEFAULT_OSTREAM std::cout
|
||||
#if defined(ARMA_DEFAULT_OSTREAM)
|
||||
#pragma message ("WARNING: support for ARMA_DEFAULT_OSTREAM is deprecated and will be removed;")
|
||||
#pragma message ("WARNING: use ARMA_COUT_STREAM and ARMA_CERR_STREAM instead")
|
||||
#endif
|
||||
|
||||
#define ARMA_PRINT_LOGIC_ERRORS
|
||||
#define ARMA_PRINT_RUNTIME_ERRORS
|
||||
//#define ARMA_PRINT_HDF5_ERRORS
|
||||
|
||||
#define ARMA_HAVE_STD_ISFINITE
|
||||
#define ARMA_HAVE_STD_ISINF
|
||||
#define ARMA_HAVE_STD_ISNAN
|
||||
#define ARMA_HAVE_STD_SNPRINTF
|
||||
#if !defined(ARMA_COUT_STREAM)
|
||||
#if defined(ARMA_DEFAULT_OSTREAM)
|
||||
// for compatibility with earlier versions of Armadillo
|
||||
#define ARMA_COUT_STREAM ARMA_DEFAULT_OSTREAM
|
||||
#else
|
||||
#define ARMA_COUT_STREAM std::cout
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ARMA_HAVE_LOG1P
|
||||
#define ARMA_HAVE_GETTIMEOFDAY
|
||||
#if !defined(ARMA_CERR_STREAM)
|
||||
#if defined(ARMA_DEFAULT_OSTREAM)
|
||||
// for compatibility with earlier versions of Armadillo
|
||||
#define ARMA_CERR_STREAM ARMA_DEFAULT_OSTREAM
|
||||
#else
|
||||
#define ARMA_CERR_STREAM std::cerr
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(ARMA_PRINT_ERRORS)
|
||||
#define ARMA_PRINT_ERRORS
|
||||
//// Comment out the above line if you don't want errors and warnings printed (eg. failed decompositions)
|
||||
#endif
|
||||
|
||||
#if !defined(ARMA_PRINT_HDF5_ERRORS)
|
||||
// #define ARMA_PRINT_HDF5_ERRORS
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_LAPACK)
|
||||
#undef ARMA_USE_LAPACK
|
||||
@@ -129,15 +201,71 @@
|
||||
#undef ARMA_USE_BLAS
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_NEWARP) || !defined(ARMA_USE_LAPACK)
|
||||
#undef ARMA_USE_NEWARP
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_ARPACK)
|
||||
#undef ARMA_USE_ARPACK
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_SUPERLU)
|
||||
#undef ARMA_USE_SUPERLU
|
||||
#undef ARMA_SUPERLU_INCLUDE_DIR
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_ATLAS)
|
||||
#undef ARMA_USE_ATLAS
|
||||
#undef ARMA_ATLAS_INCLUDE_DIR
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_PRINT_LOGIC_ERRORS)
|
||||
#undef ARMA_PRINT_LOGIC_ERRORS
|
||||
#if defined(ARMA_DONT_USE_WRAPPER)
|
||||
#undef ARMA_USE_WRAPPER
|
||||
#undef ARMA_USE_HDF5_ALT
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_PRINT_RUNTIME_ERRORS)
|
||||
#undef ARMA_PRINT_RUNTIME_ERRORS
|
||||
#if defined(ARMA_DONT_USE_CXX11)
|
||||
#undef ARMA_USE_CXX11
|
||||
#undef ARMA_USE_EXTERN_CXX11_RNG
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_OPENMP)
|
||||
#undef ARMA_USE_OPENMP
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_USE_WRAPPER)
|
||||
#if defined(ARMA_USE_CXX11)
|
||||
#if !defined(ARMA_USE_EXTERN_CXX11_RNG)
|
||||
// #define ARMA_USE_EXTERN_CXX11_RNG
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_EXTERN_CXX11_RNG)
|
||||
#undef ARMA_USE_EXTERN_CXX11_RNG
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_32BIT_WORD)
|
||||
#undef ARMA_64BIT_WORD
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_HDF5)
|
||||
#undef ARMA_USE_HDF5
|
||||
#undef ARMA_USE_HDF5_ALT
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_PRINT_ERRORS)
|
||||
#undef ARMA_PRINT_ERRORS
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_PRINT_HDF5_ERRORS)
|
||||
#undef ARMA_PRINT_HDF5_ERRORS
|
||||
#endif
|
||||
|
||||
|
||||
// if Armadillo was installed on this system via CMake and ARMA_USE_WRAPPER is not defined,
|
||||
// ARMA_AUX_LIBS lists the libraries required by Armadillo on this system, and
|
||||
// ARMA_AUX_INCDIRS lists the include directories required by Armadillo on this system.
|
||||
// Do not use these unless you know what you are doing.
|
||||
#define ARMA_AUX_LIBS
|
||||
#define ARMA_AUX_INCDIRS
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Validate md5 hash given md5file url and the file directory.
|
||||
|
||||
# This module does the following on hash failure:
|
||||
# Set HASH_CHECK_FAIL to 1.
|
||||
# Remove the downloaded files.
|
||||
|
||||
macro (check_hash MD5_URL DIR HASH_CHECK_FAIL)
|
||||
set(HASH_CHECK_FAIL 0)
|
||||
file(DOWNLOAD ${MD5_URL}
|
||||
"${DIR}/hash.md5"
|
||||
STATUS MD5_DOWNLOAD_STATUS_LIST)
|
||||
list(GET MD5_DOWNLOAD_STATUS_LIST 0 MD5_DOWNLOAD_STATUS)
|
||||
if (MD5_DOWNLOAD_STATUS EQUAL 0)
|
||||
file(STRINGS "${DIR}/hash.md5" HASH_DATA NEWLINE_CONSUME)
|
||||
string(REGEX REPLACE "\n" ";" HASH_LIST "${HASH_DATA}")
|
||||
foreach(item ${HASH_LIST})
|
||||
string(SUBSTRING ${item} 0 32 EXPECTED_HASH)
|
||||
string(SUBSTRING ${item} 34 -1 FILE_NAME)
|
||||
file(MD5 "${DIR}/${FILE_NAME}" LOCAL_HASH)
|
||||
if (NOT LOCAL_HASH STREQUAL EXPECTED_HASH)
|
||||
set(HASH_CHECK_FAIL 1)
|
||||
file(REMOVE_RECURSE ${DIR})
|
||||
message(WARNING
|
||||
"md5sum verification error for ${item}! Got ${LOCAL_HASH}, expected ${EXPECTED_HASH}.")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
else ()
|
||||
set(HASH_CHECK_FAIL 1)
|
||||
file(REMOVE_RECURSE ${DIR})
|
||||
list(GET MD5_DOWNLOAD_STATUS_LIST 1 MD5_DOWNLOAD_ERROR)
|
||||
message(WARNING
|
||||
"Could not download the md5 for hash verification! Error code ${MD5_DOWNLOAD_STATUS}: ${MD5_DOWNLOAD_ERROR}!")
|
||||
endif ()
|
||||
endmacro (check_hash)
|
||||
@@ -52,7 +52,7 @@ endif ()
|
||||
|
||||
# Checks 'REQUIRED', 'QUIET' and versions.
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(ensmallen
|
||||
find_package_handle_standard_args(Ensmallen
|
||||
REQUIRED_VARS ENSMALLEN_INCLUDE_DIR
|
||||
VERSION_VAR ENSMALLEN_VERSION_STRING)
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# - Find STB_IMAGE
|
||||
# Find the STB_IMAGE C++ library
|
||||
#
|
||||
# This module sets the following variables:
|
||||
# STB_IMAGE_FOUND - set to true if the library is found
|
||||
# STB_IMAGE_INCLUDE_DIR - list of required include directories
|
||||
|
||||
file(GLOB STB_IMAGE_SEARCH_PATHS
|
||||
${CMAKE_BINARY_DIR}/deps/stb)
|
||||
find_path(STB_IMAGE_INCLUDE_DIR
|
||||
NAMES stb_image.h stb_image_write.h
|
||||
PATHS ${STB_IMAGE_SEARCH_PATHS})
|
||||
|
||||
if(STB_IMAGE_INCLUDE_DIR)
|
||||
set(STB_IMAGE_FOUND YES)
|
||||
endif ()
|
||||
|
||||
# Checks 'REQUIRED'.
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(STB_IMAGE
|
||||
REQUIRED_VARS STB_IMAGE_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(STB_IMAGE_INCLUDE_DIR)
|
||||
@@ -5,4 +5,9 @@
|
||||
#
|
||||
# PROGRAM: the program to run to.
|
||||
# OUTPUT_FILE: the file to store the output in.
|
||||
execute_process(COMMAND ${PROGRAM} OUTPUT_FILE ${OUTPUT_FILE})
|
||||
execute_process(COMMAND ${PROGRAM} OUTPUT_FILE ${OUTPUT_FILE}
|
||||
ERROR_VARIABLE err)
|
||||
|
||||
if (err)
|
||||
message(FATAL_ERROR "Fatal error running ${PROGRAM}: ${err}!")
|
||||
endif ()
|
||||
|
||||
+113
-18
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.3.2)
|
||||
project(mlpack C CXX)
|
||||
|
||||
include(CMake/cotire.cmake)
|
||||
include(CMake/CheckHash.cmake)
|
||||
|
||||
# First, define all the compilation options.
|
||||
# We default to debugging mode for developers.
|
||||
@@ -13,16 +14,16 @@ option(TEST_VERBOSE "Run test cases with verbose output." OFF)
|
||||
option(BUILD_TESTS "Build tests." ON)
|
||||
option(BUILD_CLI_EXECUTABLES "Build command-line executables." ON)
|
||||
option(DOWNLOAD_ENSMALLEN "If ensmallen is not found, download it." ON)
|
||||
option(DOWNLOAD_STB_IMAGE "Download stb_image for image loading." ON)
|
||||
option(BUILD_PYTHON_BINDINGS "Build Python bindings." ON)
|
||||
|
||||
# Currently Python bindings aren't known to build successfully on Windows, so
|
||||
# set BUILD_PYTHON_BINDINGS to OFF when the platform is Windows.
|
||||
if (WIN32)
|
||||
option(BUILD_PYTHON_BINDINGS "Build Python bindings." OFF)
|
||||
option(BUILD_SHARED_LIBS
|
||||
"Compile shared libraries (if OFF, static libraries are compiled)." OFF)
|
||||
message(WARNING "By default Python bindings are not compiled for Windows because they are not known to work. Set BUILD_PYTHON_BINDINGS to ON if you want them built.")
|
||||
|
||||
set(DLL_COPY_DIRS "" CACHE STRING "List of directories (separated by ';') containing DLLs to copy for runtime.")
|
||||
set(DLL_COPY_LIBS "" CACHE STRING "List of DLLs (separated by ';') that should be copied for runtime.")
|
||||
else ()
|
||||
option(BUILD_PYTHON_BINDINGS "Build Python bindings." ON)
|
||||
option(BUILD_SHARED_LIBS
|
||||
"Compile shared libraries (if OFF, static libraries are compiled)." ON)
|
||||
endif()
|
||||
@@ -84,6 +85,10 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -ftemplate-depth=1000")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
|
||||
|
||||
# To remove unused functions warnings.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
||||
endif()
|
||||
|
||||
# These support libraries are used if we need to link against something
|
||||
@@ -148,7 +153,7 @@ endif()
|
||||
|
||||
# Setup build for test coverage
|
||||
if(BUILD_WITH_COVERAGE)
|
||||
# Currently coverage only works with GNU g++
|
||||
# Currently coverage only works with GNU g++.
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
# Find gcov and lcov
|
||||
find_program(GCOV gcov)
|
||||
@@ -160,6 +165,7 @@ if(BUILD_WITH_COVERAGE)
|
||||
endif()
|
||||
|
||||
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} "supc++")
|
||||
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} "quadmath")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fno-inline -fno-inline-small-functions -fno-default-inline -fprofile-arcs -fkeep-inline-functions")
|
||||
message(STATUS "Adding debug compile options for code coverage.")
|
||||
# Remove optimizations for better line coverage
|
||||
@@ -242,7 +248,7 @@ endif()
|
||||
# ENSMALLEN_INCLUDE_DIR - include directory for ensmallen
|
||||
# MATHJAX_ROOT - root of MathJax installation
|
||||
|
||||
find_package(Armadillo 6.500.0 REQUIRED)
|
||||
find_package(Armadillo 8.400.0 REQUIRED)
|
||||
|
||||
# If Armadillo was compiled without ARMA_64BIT_WORD and we are on a 64-bit
|
||||
# system (where size_t will be 64 bits), suggest to the user that they should
|
||||
@@ -312,22 +318,93 @@ if (WIN32)
|
||||
|
||||
# Piggyback LAPACK and BLAS linking into Armadillo link.
|
||||
set(ARMADILLO_LIBRARIES
|
||||
${ARMADILLO_LIBRARIES} ${BLAS_LIBRARY} ${LAPACK_LIBRARY})
|
||||
${ARMADILLO_LIBRARIES} ${BLAS_LIBRARY} ${LAPACK_LIBRARY})
|
||||
|
||||
# Ensure that the libraries are added to the MSVC IDE runtime path.
|
||||
get_filename_component(BLAS_DIR ${BLAS_LIBRARY} DIRECTORY)
|
||||
get_filename_component(LAPACK_DIR ${LAPACK_LIBRARY} DIRECTORY)
|
||||
|
||||
# Sometimes, especially with an OpenBLAS install via nuget, the DLLs are
|
||||
# actually in ../../bin/x64/. Automatically add these.
|
||||
if (EXISTS "${BLAS_DIR}/../../bin/x64/")
|
||||
get_filename_component(BLAS_DLL_DIR "${BLAS_DIR}/../../bin/x64" ABSOLUTE)
|
||||
set(DLL_COPY_DIRS ${DLL_COPY_DIRS} "${BLAS_DLL_DIR}")
|
||||
endif ()
|
||||
|
||||
if (EXISTS "${LAPACK_DIR}/../../bin/x64/")
|
||||
get_filename_component(LAPACK_DLL_DIR "${LAPACK_DIR}/../../bin/x64" ABSOLUTE)
|
||||
set(DLL_COPY_DIRS ${DLL_COPY_DIRS} "${BLAS_DLL_DIR}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Include directories for the previous dependencies.
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS})
|
||||
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${ARMADILLO_LIBRARIES})
|
||||
|
||||
# Find stb_image.h and stb_image_write.h.
|
||||
find_package(StbImage)
|
||||
# Download stb_image for image loading.
|
||||
if (NOT STB_IMAGE_FOUND)
|
||||
if (DOWNLOAD_STB_IMAGE)
|
||||
set(STB_DIR "stb")
|
||||
install(DIRECTORY DESTINATION "${CMAKE_BINARY_DIR}/deps/${STB_DIR}")
|
||||
file(DOWNLOAD http://mlpack.org/files/stb-2.22/stb_image.h
|
||||
"${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image.h"
|
||||
STATUS STB_IMAGE_DOWNLOAD_STATUS_LIST LOG STB_IMAGE_DOWNLOAD_LOG
|
||||
SHOW_PROGRESS)
|
||||
list(GET STB_IMAGE_DOWNLOAD_STATUS_LIST 0 STB_IMAGE_DOWNLOAD_STATUS)
|
||||
file(DOWNLOAD http://mlpack.org/files/stb-1.13/stb_image_write.h
|
||||
"${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image_write.h"
|
||||
STATUS STB_IMAGE_WRITE_DOWNLOAD_STATUS_LIST
|
||||
LOG STB_IMAGE_WRITE_DOWNLOAD_LOG
|
||||
SHOW_PROGRESS)
|
||||
list(GET STB_IMAGE_WRITE_DOWNLOAD_STATUS_LIST 0
|
||||
STB_IMAGE_WRITE_DOWNLOAD_STATUS)
|
||||
if (STB_IMAGE_DOWNLOAD_STATUS EQUAL 0 AND
|
||||
STB_IMAGE_WRITE_DOWNLOAD_STATUS EQUAL 0)
|
||||
check_hash (http://mlpack.org/files/stb/hash.md5 "${CMAKE_BINARY_DIR}/deps/${STB_DIR}"
|
||||
HASH_CHECK_FAIL)
|
||||
if (HASH_CHECK_FAIL EQUAL 0)
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS}
|
||||
"${CMAKE_BINARY_DIR}/deps/${STB_DIR}/")
|
||||
message(STATUS
|
||||
"Successfully downloaded stb into ${CMAKE_BINARY_DIR}/deps/${STB_DIR}/")
|
||||
# Now we have to also ensure these header files get installed.
|
||||
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
install(FILES "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/stb_image_write.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
add_definitions(-DHAS_STB)
|
||||
else ()
|
||||
message(WARNING
|
||||
"stb/stb_image.h is not installed. Image utilities will not be available!")
|
||||
endif ()
|
||||
else ()
|
||||
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/deps/${STB_DIR}/")
|
||||
list(GET STB_IMAGE_DOWNLOAD_STATUS_LIST 1 STB_DOWNLOAD_ERROR)
|
||||
message(WARNING
|
||||
"Could not download stb! Error code ${STB_DOWNLOAD_STATUS}: ${STB_DOWNLOAD_ERROR}! Error log: ${STB_DOWNLOAD_LOG}")
|
||||
message(WARNING
|
||||
"stb/stb_image.h is not installed. Image utilities will not be available!")
|
||||
endif ()
|
||||
else ()
|
||||
message(WARNING
|
||||
"stb/stb_image.h is not installed. Image utilities will not be available!")
|
||||
endif ()
|
||||
else ()
|
||||
# Already has STB installed.
|
||||
add_definitions(-DHAS_STB)
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${STB_IMAGE_INCLUDE_DIR})
|
||||
endif ()
|
||||
|
||||
|
||||
# Find ensmallen.
|
||||
# Once ensmallen is readily available in package repos, the automatic downloader
|
||||
# here can be removed.
|
||||
find_package(Ensmallen 1.10.0)
|
||||
find_package(Ensmallen 2.10.0)
|
||||
if (NOT ENSMALLEN_FOUND)
|
||||
if (DOWNLOAD_ENSMALLEN)
|
||||
file(DOWNLOAD http://www.ensmallen.org/files/ensmallen-latest.tar.gz
|
||||
"${CMAKE_BINARY_DIR}/deps/ensmallen-latest.tar.gz"
|
||||
STATUS ENS_DOWNLOAD_STATUS_LIST LOG ENS_DOWBLOAD_LOG
|
||||
STATUS ENS_DOWNLOAD_STATUS_LIST LOG ENS_DOWNLOAD_LOG
|
||||
SHOW_PROGRESS)
|
||||
list(GET ENS_DOWNLOAD_STATUS_LIST 0 ENS_DOWNLOAD_STATUS)
|
||||
if (ENS_DOWNLOAD_STATUS EQUAL 0)
|
||||
@@ -338,6 +415,7 @@ if (NOT ENSMALLEN_FOUND)
|
||||
# Get the name of the directory.
|
||||
file (GLOB ENS_DIRECTORIES RELATIVE "${CMAKE_BINARY_DIR}/deps/"
|
||||
"${CMAKE_BINARY_DIR}/deps/ensmallen-[0-9]*.[0-9]*.[0-9]*")
|
||||
list(FILTER ENS_DIRECTORIES EXCLUDE REGEX "ensmallen-.*\.tar\.gz")
|
||||
list(LENGTH ENS_DIRECTORIES ENS_DIRECTORIES_LEN)
|
||||
if (ENS_DIRECTORIES_LEN EQUAL 1)
|
||||
list(GET ENS_DIRECTORIES 0 ENSMALLEN_INCLUDE_DIR)
|
||||
@@ -347,8 +425,8 @@ if (NOT ENSMALLEN_FOUND)
|
||||
"Successfully downloaded ensmallen into ${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/")
|
||||
|
||||
# Now we have to also ensure these header files get installed.
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/include/ensmallen_bits/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ensmallen_bits)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/include/ensmallen.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/include/ensmallen_bits/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ensmallen_bits")
|
||||
install(FILES "${CMAKE_BINARY_DIR}/deps/${ENSMALLEN_INCLUDE_DIR}/include/ensmallen.hpp" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
else ()
|
||||
message(FATAL_ERROR "Problem unpacking ensmallen! Expected only one directory ensmallen-x.y.z/; found ${ENS_DIRECTORIES}. Try removing the directory ${CMAKE_BINARY_DIR}/deps and reconfiguring.")
|
||||
endif ()
|
||||
@@ -411,6 +489,8 @@ link_directories(${Boost_LIBRARY_DIRS})
|
||||
# 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 ()
|
||||
|
||||
@@ -463,6 +543,21 @@ if (WIN32)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
# Copy all necessary DLLs for runtime to the build directory.
|
||||
# This is a little hackish, but I can't figure out clear ways to make CMake
|
||||
# consistently link everything 100% statically across platforms or set the
|
||||
# runtime path right always, so this is the best I know how to do for now.
|
||||
foreach(dir ${DLL_COPY_DIRS})
|
||||
file(GLOB dir_dll_list "${dir}/*.dll")
|
||||
file(COPY ${dir_dll_list} DESTINATION ${CMAKE_BINARY_DIR}/Release/)
|
||||
file(COPY ${dir_dll_list} DESTINATION ${CMAKE_BINARY_DIR}/Debug/)
|
||||
endforeach ()
|
||||
|
||||
foreach(file ${DLL_COPY_LIBS})
|
||||
file(COPY ${file} DESTINATION ${CMAKE_BINARY_DIR}/Release/)
|
||||
file(COPY ${file} DESTINATION ${CMAKE_BINARY_DIR}/Debug/)
|
||||
endforeach()
|
||||
else ()
|
||||
# If not on Windows, put them under more standard UNIX-like places. This is
|
||||
# necessary, otherwise they would all end up in
|
||||
@@ -536,8 +631,8 @@ if (BUILD_CLI_EXECUTABLES AND UNIX)
|
||||
)
|
||||
|
||||
# Set the rules to install the documentation.
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/share/man/
|
||||
DESTINATION ${CMAKE_INSTALL_MANDIR})
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/share/man/"
|
||||
DESTINATION "${CMAKE_INSTALL_MANDIR}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
@@ -588,8 +683,8 @@ if (DOXYGEN_FOUND)
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/doc/html
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html"
|
||||
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
|
||||
COMPONENT doc
|
||||
OPTIONAL
|
||||
)
|
||||
@@ -668,6 +763,6 @@ if (PKG_CONFIG_FOUND)
|
||||
DEPENDS mlpack_headers
|
||||
COMMENT "Generating mlpack.pc (pkg-config) file.")
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/mlpack.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig/)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/mlpack.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
|
||||
endif ()
|
||||
|
||||
@@ -113,7 +113,13 @@ Copyright:
|
||||
Copyright 2019, Dan Timson
|
||||
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, Heet Sankesara <heetsankesara3@gmail.com>
|
||||
Copyright 2019, Jeffin Sam <sam.jeffin@gmail.com>
|
||||
Copyright 2019, Vikas S Shetty <shettyvikas209@gmail.com>
|
||||
Copyright 2019, Tejasvi Tomar <tstomar@outlook.com>
|
||||
Copyright 2019, Jai Agarwal <jai.bhageria@gmail.com>
|
||||
|
||||
License: BSD-3-clause
|
||||
All rights reserved.
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
# mlpack governance structure (DRAFT)
|
||||
|
||||
Revised Oct. 21st, 2019.
|
||||
|
||||
## Introduction
|
||||
|
||||
mlpack has grown much since its initial inception as a small project out of a
|
||||
university research lab. Now that there are over 150 contributors, it's
|
||||
important that we have a clearly defined process for making our decisions and
|
||||
organizing ourselves.
|
||||
|
||||
This document aims to clarify the governance of mlpack. This is a living
|
||||
document: it may change over time. The process for making these changes is
|
||||
detailed in the "Governance Changes" section.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
mlpack aims to be an open and welcoming environment, and as such, we have a
|
||||
code of conduct that helps foster this environment. See
|
||||
(here)[https://github.com/mlpack/mlpack/blob/master/CODE_OF_CONDUCT.md] for
|
||||
more information.
|
||||
|
||||
## Teams & Roles
|
||||
|
||||
To keep overhead minimal, mlpack's teams and roles are simple: there is only
|
||||
the [Committers](https://github.com/orgs/mlpack/teams/contributors) team, and
|
||||
the [NumFOCUS leadership team](TODO:link).
|
||||
|
||||
Members of the Committers team have commit access to all mlpack repositories
|
||||
and help guide the development directions and goals of mlpack. Committers
|
||||
should be familiar with the [contribution
|
||||
process](https://github.com/mlpack/mlpack/blob/master/CONTRIBUTING.md) and
|
||||
follow it when merging code and reviewing pull requests; this is important for
|
||||
the continued stability and quality of mlpack's codebase. Responsibilities and
|
||||
activities of Committers team members can include:
|
||||
|
||||
* Welcoming new members to the community: helping support users and point
|
||||
potential contributors in the correct direction.
|
||||
|
||||
* Reviewing pull requests and approving them when they are ready.
|
||||
|
||||
* Merging pull requests after they have been approved by others for merge.
|
||||
|
||||
* Communicating and coordinating with contributors to help get code merged and
|
||||
improve the software.
|
||||
|
||||
* Helping map out mlpack's development directions and processes.
|
||||
|
||||
* Maintaining mlpack infrastructure (build systems, continuous integration,
|
||||
etc.).
|
||||
|
||||
Membership on the Committers team does not expire. Contributors who have
|
||||
repeatedly shown that their code quality is high, demonstrated adherence to the
|
||||
code of conduct, and shown that they have a strong interest in the project can
|
||||
be added to the Committers team using the organizational decision process in
|
||||
the next section.
|
||||
|
||||
The NumFOCUS leadership team is a subset of the Committers team whose
|
||||
additional responsibilities are to coordinate with NumFOCUS and maintain this
|
||||
governance document. Membership in the NumFOCUS leadership team is limited to
|
||||
five people, and does not confer any special voting power or decision rights.
|
||||
|
||||
## Voting and Organizational Decisions
|
||||
|
||||
Historically, mlpack organizational decisions have not been controversial and
|
||||
this has allowed efficient decision making. Therefore, a vote on a proposal is
|
||||
not required unless there is any explicit disagreement or concern with the
|
||||
proposal. The topics of a proposal might be:
|
||||
|
||||
* Adding/removing a new member to/from the Committers team.
|
||||
|
||||
* Participating in a program such as Google Summer of Code or Outreachy.
|
||||
|
||||
* A change to some part of the mlpack infrastructure or contribution process.
|
||||
|
||||
* Refactoring or change of an important public part of the API.
|
||||
|
||||
* Use of funds for a particular project.
|
||||
|
||||
That list is not inclusive. Introducing a proposal or idea can be done
|
||||
informally in a public place, such as the mlpack mailing list or on Github as
|
||||
an issue. It's a good idea (but not mandatory) to make the proposal discussion
|
||||
fully public so that people who are not on the Committers team can also comment
|
||||
and provide opinions---after all, this is a community-led project so we should
|
||||
be sure to include the *entire* community whenever possible.
|
||||
|
||||
If there is any disagreement or concern with the proposal, the person who
|
||||
introduced the proposal should work to try and find a resolution or compromise
|
||||
if possible. If that is not possible, then the proposal can be brought to a
|
||||
vote.
|
||||
|
||||
For a proposal to pass, a simple majority vote suffices. Each Committer has
|
||||
one equal vote, and they may choose to abstain from voting if they do prefer.
|
||||
Since some Committers may be inactive or busy, it is not required for every
|
||||
Committer to participate in every vote; instead, someone who has a proposal
|
||||
should make a good-faith effort to post the proposal in a public location so
|
||||
that interested and active Committers can respond. Voting for any proposal
|
||||
should be open for at least five days to allow sufficient time.
|
||||
|
||||
If a proposal passes despite votes against it, it is generally a good idea for
|
||||
the Committer who introduced the proposal to spend some time considering and
|
||||
understanding the arguments that were presented against the proposal, or if
|
||||
appropriate, for the Committer to try and find an acceptable compromise or
|
||||
alternate strategy that addresses the given feedback.
|
||||
|
||||
## Governance Changes
|
||||
|
||||
The NumFOCUS leadership team is responsible for this governance document, and
|
||||
thus any changes to this document, NumFOCUS membership, or the NumFOCUS
|
||||
leadership team must be approved by that team, also by a simple majority vote.
|
||||
Because every member of the NumFOCUS leadership team should be an active
|
||||
Committer, any proposal requires votes (or abstentions) by all five members.
|
||||
+63
-6
@@ -1,20 +1,77 @@
|
||||
### mlpack 4.0.0
|
||||
### mlpack ?.?.?
|
||||
###### ????-??-??
|
||||
* Add Multiple Pole Balancing Environment (#1901).
|
||||
* Add `valid` and `same` padding option in `Convolution` and `Atrous
|
||||
Convolution` layer (#1988).
|
||||
|
||||
* Add Model() to the FFN class to access individual layers (#2043).
|
||||
|
||||
* Update documentation for pip and conda installation packages (#2044).
|
||||
|
||||
* Add bindings for linear SVM (#1935); `mlpack_linear_svm` from the
|
||||
command-line, `linear_svm()` from Python.
|
||||
|
||||
* Add support to return the layer name as `std::string` (#1987).
|
||||
|
||||
* Speed and memory improvements for the Transposed Convolution layer (#1493).
|
||||
|
||||
* Fix Windows Python build configuration (#1885).
|
||||
|
||||
* Validate md5 of STB library after download (#2087).
|
||||
|
||||
* Add `__version__` to `__init__.py` (#2092).
|
||||
|
||||
### mlpack 3.2.1
|
||||
###### 2019-10-01
|
||||
* Enforce CMake version check for ensmallen (#2032).
|
||||
|
||||
* Fix CMake check for Armadillo version (#2029).
|
||||
|
||||
* Better handling of when STB is not installed (#2033).
|
||||
|
||||
* Fix Naive Bayes classifier computations in high dimensions (#2022).
|
||||
|
||||
### mlpack 3.2.0
|
||||
###### 2019-09-25
|
||||
* Fix some potential infinity errors in Naive Bayes Classifier (#2022).
|
||||
|
||||
* Fix occasionally-failing RADICAL test (#1924).
|
||||
|
||||
* Fix gcc 9 OpenMP compilation issue (#1970).
|
||||
|
||||
* Added support for loading and saving of images (#1903).
|
||||
|
||||
* Add Multiple Pole Balancing Environment (#1901, #1951).
|
||||
|
||||
* Added functionality for scaling of data (#1876); see the command-line
|
||||
binding `mlpack_preprocess_scale` or Python binding `preprocess_scale()`.
|
||||
|
||||
* Add new parameter `maximum_depth` to decision tree and random forest
|
||||
bindings (#1916).
|
||||
|
||||
* Fix prediction output of softmax regression when test set accuracy is
|
||||
calculated (#1922).
|
||||
|
||||
* Action struct in continuous RL environments now stores the action as a
|
||||
`double` instead of `double[1]` (#1941, #1931).
|
||||
|
||||
|
||||
* Pendulum environment now checks for termination. All RL environments now
|
||||
have an option to terminate after a set number of time steps (no limit
|
||||
by default) (#1941).
|
||||
|
||||
* Add support for probabilistic KDE (kernel density estimation) error bounds
|
||||
when using the Gaussian kernel (#1934).
|
||||
|
||||
* Fix negative distances for cover tree computation (#1979).
|
||||
|
||||
* Fix cover tree building when all pairwise distances are 0 (#1986).
|
||||
|
||||
* Improve KDE pruning by reclaiming not used error tolerance (#1954, #1984).
|
||||
|
||||
* Optimizations for sparse matrix accesses in z-score normalization for CF
|
||||
(#1989).
|
||||
|
||||
* Add `kmeans_max_iterations` option to GMM training binding `gmm_train_main`.
|
||||
|
||||
* Bump minimum Armadillo version to 8.400.0 due to ensmallen dependency
|
||||
requirement (#2015).
|
||||
|
||||
### mlpack 3.1.1
|
||||
###### 2019-05-26
|
||||
* Fix random forest bug for numerical-only data (#1887).
|
||||
|
||||
@@ -12,6 +12,10 @@ licensed under the Boost Software License, version 1.0. This code is found in
|
||||
src/mlpack/core/boost_backport/ and more details on the licensing are available
|
||||
there.
|
||||
|
||||
mlpack may contain some usage of the source code of stb, which is licensed
|
||||
under the MIT License and the Public Domain (www.unlicense.org). This code
|
||||
is used in src/mlpack/core/data/load_image.hpp.
|
||||
|
||||
----
|
||||
Copyright (c) 2007-2018, mlpack contributors (see COPYRIGHT.txt)
|
||||
All rights reserved.
|
||||
|
||||
@@ -23,7 +23,7 @@ src="https://cdn.rawgit.com/mlpack/mlpack.org/e7d36ed8/mlpack-black.svg" style="
|
||||
<p align="center">
|
||||
<em>
|
||||
Download:
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.1.1.tar.gz">current stable version (3.1.1)</a>
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.2.2.tar.gz">current stable version (3.2.2)</a>
|
||||
</em>
|
||||
</p>
|
||||
|
||||
@@ -34,6 +34,21 @@ functions as a "swiss army knife" for machine learning researchers. In addition
|
||||
to its powerful C++ interface, mlpack also provides command-line programs and
|
||||
Python bindings.
|
||||
|
||||
mlpack uses an [open governance model](./GOVERNANCE.md) and is fiscally
|
||||
sponsored by [NumFOCUS](https://numfocus.org/). Consider making a
|
||||
[tax-deductible donation](https://numfocus.org/donate-to-mlpack) to help the
|
||||
project pay for developer time, professional services, travel, workshops, and a
|
||||
variety of other needs.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://numfocus.org/donate-to-mlpack">
|
||||
<img height="60px"
|
||||
src="https://raw.githubusercontent.com/numfocus/templates/master/images/numfocus-logo.png"
|
||||
align="center">
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
### 0. Contents
|
||||
|
||||
1. [Introduction](#1-introduction)
|
||||
@@ -83,10 +98,11 @@ Citations are beneficial for the growth and improvement of mlpack.
|
||||
|
||||
mlpack has the following dependencies:
|
||||
|
||||
Armadillo >= 6.500.0
|
||||
Armadillo >= 8.400.0
|
||||
Boost (program_options, math_c99, unit_test_framework, serialization,
|
||||
spirit)
|
||||
CMake >= 3.3.2
|
||||
ensmallen >= 2.10.0
|
||||
|
||||
All of those should be available in your distribution's package manager. If
|
||||
not, you will have to compile each of them by hand. See the documentation for
|
||||
@@ -100,12 +116,15 @@ following Python packages are installed:
|
||||
numpy
|
||||
pandas >= 0.15.0
|
||||
|
||||
If the STB library headers are available, image loading support will be
|
||||
compiled.
|
||||
|
||||
If you are compiling Armadillo by hand, ensure that LAPACK and BLAS are enabled.
|
||||
|
||||
### 4. Building mlpack from source
|
||||
|
||||
This section discusses how to build mlpack from source. However, mlpack is in
|
||||
the repositories of many Linux distributions and so it may be easier to use the
|
||||
the repositories of many Linux distributions, 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:
|
||||
|
||||
@@ -116,13 +135,13 @@ available---for instance, at the time of this writing, Ubuntu 16.04 only has
|
||||
mlpack 2.0.1 available. Options include upgrading your Ubuntu version, finding
|
||||
a PPA or other non-official sources, or installing with a manual build.
|
||||
|
||||
There are some other useful pages to consult in addition to this section:
|
||||
There are some useful pages to consult in addition to this section:
|
||||
|
||||
- [Building mlpack From Source](https://www.mlpack.org/doc/mlpack-git/doxygen/build.html)
|
||||
- [Building mlpack From Source on Windows](https://www.mlpack.org/doc/mlpack-git/doxygen/build_windows.html)
|
||||
|
||||
mlpack uses CMake as a build system and allows several flexible build
|
||||
configuration options. One can consult any of numerous CMake tutorials for
|
||||
configuration options. You can consult any of the CMake tutorials for
|
||||
further documentation, but this tutorial should be enough to get mlpack built
|
||||
and installed.
|
||||
|
||||
@@ -132,21 +151,20 @@ use mlpack-x.y.z where x.y.z is the version.
|
||||
$ tar -xzf mlpack-x.y.z.tar.gz
|
||||
$ cd mlpack-x.y.z
|
||||
|
||||
Then, make a build directory. The directory can have any name, not just
|
||||
'build', but 'build' is sufficient.
|
||||
Then, make a build directory. The directory can have any name, but 'build' is
|
||||
sufficient.
|
||||
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
|
||||
The next step is to run CMake to configure the project. Running CMake is the
|
||||
equivalent to running `./configure` with autotools. If you run CMake with no
|
||||
options, it will configure the project to build with no debugging symbols and no
|
||||
profiling information:
|
||||
options, it will configure the project to build with no debugging symbols and
|
||||
no profiling information:
|
||||
|
||||
$ cmake ../
|
||||
|
||||
You can specify options to compile with debugging information and profiling
|
||||
information:
|
||||
Options can be specified to compile with debugging information and profiling information:
|
||||
|
||||
$ cmake -D DEBUG=ON -D PROFILE=ON ../
|
||||
|
||||
@@ -160,10 +178,12 @@ Options are specified with the -D flag. The allowed options include:
|
||||
ARMADILLO_LIBRARY=(/path/to/armadillo/libarmadillo.so): Armadillo library
|
||||
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
|
||||
BUILD_TESTS=(ON/OFF): whether or not to build tests
|
||||
BUILD_SHARED_LIBS=(ON/OFF): compile shared libraries as opposed to
|
||||
static libraries
|
||||
DOWNLOAD_ENSMALLEN=(ON/OFF): If ensmallen is not found, download it
|
||||
DOWNLOAD_STB_IMAGE=(ON/OFF): If STB is not found, download it
|
||||
ENSMALLEN_INCLUDE_DIR=(/path/to/ensmallen/include): path to include directory
|
||||
for ensmallen
|
||||
USE_OPENMP=(ON/OFF): whether or not to use OpenMP if available
|
||||
@@ -181,22 +201,21 @@ Once CMake is configured, building the library is as simple as typing 'make'.
|
||||
This will build all library components as well as 'mlpack_test'.
|
||||
|
||||
$ make
|
||||
|
||||
You can specify individual components which you want to build, if you do not
|
||||
want to build everything in the library:
|
||||
If you do not want to build everything in the library, individual components
|
||||
of the build can be specified:
|
||||
|
||||
$ make mlpack_pca mlpack_knn mlpack_kfn
|
||||
|
||||
If the build fails and you cannot figure out why, register an account on Github
|
||||
and submit an issue; the mlpack developers will quickly help you figure it out:
|
||||
and submit an issue. The mlpack developers will quickly help you figure it out:
|
||||
|
||||
[mlpack on Github](https://www.github.com/mlpack/mlpack/)
|
||||
|
||||
Alternately, mlpack help can be found in IRC at `#mlpack` on irc.freenode.net.
|
||||
|
||||
If you wish to install mlpack to `/usr/local/include/mlpack/` and `/usr/local/lib/`
|
||||
and `/usr/local/bin/`, once it has built, make sure you have root privileges (or
|
||||
write permissions to those three directories), and simply type
|
||||
If you wish to install mlpack to `/usr/local/include/mlpack/`, `/usr/local/lib/`,
|
||||
and `/usr/local/bin/`, make sure you have root privileges (or write permissions
|
||||
to those three directories), and simply type
|
||||
|
||||
$ make install
|
||||
|
||||
@@ -204,7 +223,7 @@ You can now run the executables by name; you can link against mlpack with
|
||||
`-lmlpack`
|
||||
and the mlpack headers are found in
|
||||
`/usr/local/include/mlpack/`
|
||||
and if Python bindings were built, they will be accessible with the `mlpack`
|
||||
and if Python bindings were built, you can access them with the `mlpack`
|
||||
package in Python.
|
||||
|
||||
If running the programs (i.e. `$ mlpack_knn -h`) gives an error of the form
|
||||
|
||||
@@ -104,16 +104,16 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.1.1\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.2.1\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>C:\mlpack\mlpack-3.1.1\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_program_options-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>C:\mlpack\mlpack-3.2.1\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_program_options-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y "C:\mlpack\mlpack-3.1.1\build\Debug\mlpack.dll" $(OutDir)
|
||||
xcopy /y "C:\mlpack\mlpack-3.1.1\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
<Command>xcopy /y "C:\mlpack\mlpack-3.2.1\build\Debug\mlpack.dll" $(OutDir)
|
||||
xcopy /y "C:\mlpack\mlpack-3.2.1\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
xcopy /y "$(ProjectDir)..\..\..\..\src\mlpack\tests\data\german.csv" "$(ProjectDir)data\german.csv*"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
+20
-10
@@ -29,7 +29,7 @@ to build mlpack on Windows, see \ref build_windows (alternatively, you can read
|
||||
is based on older versions).
|
||||
|
||||
You can download the latest mlpack release from here:
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.1.1.tar.gz">mlpack-3.1.1</a>
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.2.1.tar.gz">mlpack-3.2.1</a>
|
||||
|
||||
@section build_simple Simple Linux build instructions
|
||||
|
||||
@@ -37,9 +37,9 @@ Assuming all dependencies are installed in the system, you can run the commands
|
||||
below directly to build and install mlpack.
|
||||
|
||||
@code
|
||||
$ wget https://www.mlpack.org/files/mlpack-3.1.1.tar.gz
|
||||
$ tar -xvzpf mlpack-3.1.1.tar.gz
|
||||
$ mkdir mlpack-3.1.1/build && cd mlpack-3.1.1/build
|
||||
$ wget https://www.mlpack.org/files/mlpack-3.2.1.tar.gz
|
||||
$ tar -xvzpf mlpack-3.2.1.tar.gz
|
||||
$ mkdir mlpack-3.2.1/build && cd mlpack-3.2.1/build
|
||||
$ cmake ../
|
||||
$ make -j4 # The -j is the number of cores you want to use for a build.
|
||||
$ sudo make install
|
||||
@@ -64,8 +64,8 @@ configure mlpack.
|
||||
First we should unpack the mlpack source and create a build directory.
|
||||
|
||||
@code
|
||||
$ tar -xvzpf mlpack-3.1.1.tar.gz
|
||||
$ cd mlpack-3.1.1
|
||||
$ tar -xvzpf mlpack-3.2.1.tar.gz
|
||||
$ cd mlpack-3.2.1
|
||||
$ mkdir build
|
||||
@endcode
|
||||
|
||||
@@ -76,9 +76,15 @@ The directory can have any name, not just 'build', but 'build' is sufficient.
|
||||
mlpack depends on the following libraries, which need to be installed on the
|
||||
system and have headers present:
|
||||
|
||||
- Armadillo >= 6.500.0 (with LAPACK support)
|
||||
- Armadillo >= 8.400.0 (with LAPACK support)
|
||||
- Boost (math_c99, program_options, serialization, unit_test_framework, heap,
|
||||
spirit) >= 1.49
|
||||
- ensmallen >= 2.10.0 (will be downloaded if not found)
|
||||
|
||||
In addition, mlpack has the following optional dependencies:
|
||||
|
||||
- STB: this will allow loading of images; the library is downloaded if not
|
||||
found and the CMake variable DOWNLOAD_STB_IMAGE is set to ON (the default)
|
||||
|
||||
For Python bindings, the following packages are required:
|
||||
|
||||
@@ -93,7 +99,8 @@ In Ubuntu and Debian, you can get all of these dependencies through apt:
|
||||
@code
|
||||
# apt-get install libboost-math-dev libboost-program-options-dev
|
||||
libboost-test-dev libboost-serialization-dev libarmadillo-dev binutils-dev
|
||||
python-pandas python-numpy cython python-setuptools
|
||||
python-pandas python-numpy cython python-setuptools libensmallen-dev
|
||||
libstb-dev
|
||||
@endcode
|
||||
|
||||
On Fedora, Red Hat, or CentOS, these same dependencies can be obtained via dnf:
|
||||
@@ -101,11 +108,12 @@ On Fedora, Red Hat, or CentOS, these same dependencies can be obtained via dnf:
|
||||
@code
|
||||
# dnf install boost-devel boost-test boost-program-options boost-math
|
||||
armadillo-devel binutils-devel python2-Cython python2-setuptools
|
||||
python2-numpy python2-pandas
|
||||
python2-numpy python2-pandas ensmallen-devel stbi-devel
|
||||
@endcode
|
||||
|
||||
(It's also possible to use python3 packages from the package manager---mlpack
|
||||
will work with either.)
|
||||
will work with either. Also, the ensmallen-devel package is only available in
|
||||
Fedora 29 or RHEL7 or newer.)
|
||||
|
||||
@section build_config Configuring CMake
|
||||
|
||||
@@ -146,8 +154,10 @@ The full list of options mlpack allows:
|
||||
(default OFF)
|
||||
- DOWNLOAD_ENSMALLEN=(ON/OFF): If ensmallen is not found, download it
|
||||
(default ON)
|
||||
- DOWNLOAD_STB_IMAGE=(ON/OFF): If STB is not found, download it (default ON)
|
||||
- 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
|
||||
- BUILD_MARKDOWN_BINDINGS=(ON/OFF): Build Markdown bindings for website
|
||||
documentation (default OFF)
|
||||
- MATHJAX=(ON/OFF): use MathJax for generated Doxygen documentation (default
|
||||
|
||||
@@ -17,11 +17,11 @@ Installing the mlpack bindings for Python is straightforward. It's easy to use
|
||||
conda or pip to do this:
|
||||
|
||||
@code{.sh}
|
||||
pip install mlpack3
|
||||
pip install mlpack
|
||||
@endcode
|
||||
|
||||
@code{.sh}
|
||||
conda install -c mlpack mlpack
|
||||
conda install -c conda-forge mlpack
|
||||
@endcode
|
||||
|
||||
Otherwise, we can build the Python bindings from scratch, as follows. First we
|
||||
@@ -31,9 +31,9 @@ build and install mlpack. You can copy-paste the commands into your shell.
|
||||
@code{.sh}
|
||||
sudo apt-get install libboost-all-dev g++ cmake libarmadillo-dev python-pip wget
|
||||
sudo pip install cython setuptools distutils numpy pandas
|
||||
wget https://www.mlpack.org/files/mlpack-3.1.1.tar.gz
|
||||
tar -xvzpf mlpack-3.1.1.tar.gz
|
||||
mkdir -p mlpack-3.1.1/build/ && cd mlpack-3.1.1/build/
|
||||
wget https://www.mlpack.org/files/mlpack-3.2.1.tar.gz
|
||||
tar -xvzpf mlpack-3.2.1.tar.gz
|
||||
mkdir -p mlpack-3.2.1/build/ && cd mlpack-3.2.1/build/
|
||||
cmake ../ && make -j4 && sudo make install
|
||||
@endcode
|
||||
|
||||
|
||||
@@ -29,18 +29,18 @@ mlpack and dependencies in Release Mode).
|
||||
@code
|
||||
- C:\boost\boost_1_66_0
|
||||
- C:\mlpack\armadillo-8.500.1\include
|
||||
- C:\mlpack\mlpack-3.1.1\build\include
|
||||
- C:\mlpack\mlpack-3.2.1\build\include
|
||||
@endcode
|
||||
- Under Linker > Input > Additional Dependencies add:
|
||||
@code
|
||||
- C:\mlpack\mlpack-3.1.1\build\Debug\mlpack.lib
|
||||
- C:\mlpack\mlpack-3.2.1\build\Debug\mlpack.lib
|
||||
- C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib
|
||||
- C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_program_options-vc141-mt-gd-x64-1_66.lib
|
||||
@endcode
|
||||
- Under Build Events > Post-Build Event > Command Line add:
|
||||
@code
|
||||
- xcopy /y "C:\mlpack\mlpack-3.1.1\build\Debug\mlpack.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.1.1\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.2.1\build\Debug\mlpack.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.2.1\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
@endcode
|
||||
|
||||
@note Recent versions of Visual Studio set "Conformance Mode" enabled by default. This causes some issues with
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
/*!
|
||||
@file image.txt
|
||||
@author Mehul Kumar Nirala
|
||||
@brief Tutorial for how to load and save images in mlpack.
|
||||
|
||||
@page imagetutorial Image Utilities tutorial
|
||||
|
||||
@section intro_imagetut Introduction
|
||||
|
||||
Image datasets are becoming increasingly popular in deep learning.
|
||||
|
||||
mlpack's image saving/loading functionality is based on [stb/](https://github.com/nothings/stb).
|
||||
|
||||
@section toc_imagetut Table of Contents
|
||||
|
||||
This tutorial is split into the following sections:
|
||||
|
||||
- \ref intro_imagetut
|
||||
- \ref toc_imagetut
|
||||
- \ref model_api_imagetut
|
||||
- \ref imageinfo_api_imagetut
|
||||
- \ref load_api_imagetut
|
||||
- \ref save_api_imagetut
|
||||
|
||||
@section model_api_imagetut Model API
|
||||
|
||||
Image utilities supports loading and saving of images.
|
||||
|
||||
It supports filetypes "jpg", "png", "tga","bmp", "psd", "gif", "hdr", "pic", "pnm" for loading and "jpg", "png", "tga", "bmp", "hdr" for saving.
|
||||
|
||||
The datatype associated is unsigned char to support RGB values in the range 1-255. To feed data into the network typecast of `arma::Mat` may be required. Images are stored in matrix as (width * height * channels, NumberOfImages). Therefore imageMatrix.col(0) would be the first image if images are loaded in imageMatrix.
|
||||
|
||||
@section imageinfo_api_imagetut ImageInfo
|
||||
|
||||
ImageInfo class contains the metadata of the images.
|
||||
@code
|
||||
/**
|
||||
* Instantiate the ImageInfo object with the image width, height, channels.
|
||||
*
|
||||
* @param width Image width.
|
||||
* @param height Image height.
|
||||
* @param channels number of channels in the image.
|
||||
*/
|
||||
ImageInfo(const size_t width,
|
||||
const size_t height,
|
||||
const size_t channels);
|
||||
@endcode
|
||||
Other public memebers include:
|
||||
- flipVertical Flip the image vertical upon loading.
|
||||
- quality Compression of the image if saved as jpg (0-100).
|
||||
|
||||
@section load_api_imagetut Load
|
||||
|
||||
|
||||
Standalone loading of images.
|
||||
@code
|
||||
/**
|
||||
* Load the image file into the given matrix.
|
||||
*
|
||||
* @param filename Name of the image file.
|
||||
* @param matrix Matrix to load the image into.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Load(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
Loading a test image. It also fills up the ImageInfo class object.
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
data::Load("test_image.png", matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
ImageInfo requires height, width, number of channels of the image.
|
||||
|
||||
@code
|
||||
size_t height = 64, width = 64, channels = 1;
|
||||
data::ImageInfo info(width, height, channels);
|
||||
@endcode
|
||||
|
||||
More than one image can be loaded into the same matrix.
|
||||
|
||||
Loading multiple images:
|
||||
|
||||
@code
|
||||
/**
|
||||
* Load the image file into the given matrix.
|
||||
*
|
||||
* @param files A vector consisting of filenames.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Load(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
std::vector<std::string>> files{"test_image1.bmp","test_image2.bmp"};
|
||||
data::load(files, matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
@section save_api_imagetut Save
|
||||
|
||||
Save images expects a matrix of type unsigned char in the form (width * height * channels, NumberOfImages).
|
||||
Just like load it can be used to save one image or multiple images. Besides image data it also expects the shape of the image as input (width, height, channels).
|
||||
|
||||
Saving one image:
|
||||
|
||||
@code
|
||||
/**
|
||||
* Save the image file from the given matrix.
|
||||
*
|
||||
* @param filename Name of the image file.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
info.width = info.height = 25;
|
||||
info.channels = 3;
|
||||
info.quality = 90;
|
||||
data::Save("test_image.bmp", matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
If the matrix contains more than one image, only the first one is saved.
|
||||
|
||||
Saving multiple images:
|
||||
|
||||
@code
|
||||
/**
|
||||
* Save the image file from the given matrix.
|
||||
*
|
||||
* @param files A vector consisting of filenames.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose);
|
||||
@endcode
|
||||
|
||||
@code
|
||||
data::ImageInfo info;
|
||||
info.width = info.height = 25;
|
||||
info.channels = 3;
|
||||
info.quality = 90;
|
||||
std::vector<std::string>> files{"test_image1.bmp", "test_image2.bmp"};
|
||||
data::Save(files, matrix, info, false, true);
|
||||
@endcode
|
||||
|
||||
Multiple images are saved according to the vector of filenames specified.
|
||||
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ target_link_libraries(mlpack ${MLPACK_LIBRARIES})
|
||||
|
||||
set_target_properties(mlpack
|
||||
PROPERTIES
|
||||
VERSION 3.1
|
||||
VERSION 3.2
|
||||
SOVERSION 3
|
||||
)
|
||||
|
||||
@@ -90,21 +90,21 @@ endforeach()
|
||||
|
||||
# At install time, we simply install that directory of header files we
|
||||
# collected to include/.
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/include/mlpack DESTINATION
|
||||
${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/include/mlpack" DESTINATION
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
# Set generated executables to be installed. Unfortunately they must manually
|
||||
# be entered...
|
||||
install(TARGETS mlpack
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
add_dependencies(mlpack mlpack_headers)
|
||||
|
||||
# If we are building Python bindings, we have to configure setup.py but only
|
||||
# after we've recursed into methods/.
|
||||
if (BUILD_PYTHON_BINDINGS)
|
||||
if (BUILDING_PYTHON_BINDINGS)
|
||||
# Extract the version number.
|
||||
file(READ "${CMAKE_SOURCE_DIR}/src/mlpack/core/util/version.hpp"
|
||||
VERSION_HPP_CONTENTS)
|
||||
@@ -120,8 +120,30 @@ if (BUILD_PYTHON_BINDINGS)
|
||||
|
||||
get_property(CYTHON_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PROPERTY INCLUDE_DIRECTORIES)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/setup.py.in
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py)
|
||||
add_custom_target(python_configure
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D SETUP_PY_IN="${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/setup.py.in"
|
||||
-D SETUP_PY_OUT="${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py"
|
||||
-D PACKAGE_VERSION="${PACKAGE_VERSION}"
|
||||
-D Boost_SERIALIZATION_LIBRARY="${Boost_SERIALIZATION_LIBRARY_RELEASE}"
|
||||
-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>"
|
||||
-D MLPACK_PYXS="${MLPACK_PYXS}"
|
||||
-D OpenMP_CXX_FLAGS="${OpenMP_CXX_FLAGS}"
|
||||
-D DISABLE_CFLAGS="${DISABLE_CFLAGS}"
|
||||
-D CYTHON_INCLUDE_DIRECTORIES="${CYTHON_INCLUDE_DIRECTORIES}"
|
||||
-D OUTPUT_DIR="${CMAKE_BINARY_DIR}"
|
||||
-P "${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/ConfigureSetup.cmake"
|
||||
BYPRODUCTS "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py"
|
||||
COMMENT "Configuring setup.py...")
|
||||
add_dependencies(python_configure python_copy)
|
||||
add_dependencies(python_configured python_configure)
|
||||
|
||||
# Append the package version to __init__.py after all the imports are loaded.
|
||||
file(APPEND ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/__init__.py
|
||||
"__version__='${PACKAGE_VERSION}'\n")
|
||||
endif ()
|
||||
|
||||
# If we are building Julia bindings, we have to end the 'module' declaration in
|
||||
|
||||
@@ -15,3 +15,4 @@ set(MARKDOWN_CATEGORIES ${MARKDOWN_CATEGORIES} PARENT_SCOPE)
|
||||
set(MLPACK_SRCS ${MLPACK_SRCS} PARENT_SCOPE)
|
||||
set(MLPACK_PYXS ${MLPACK_PYXS} PARENT_SCOPE)
|
||||
set(DISABLE_CFLAGS ${DISABLE_CFLAGS} PARENT_SCOPE)
|
||||
set(BUILDING_PYTHON_BINDINGS ${BUILDING_PYTHON_BINDINGS} PARENT_SCOPE)
|
||||
|
||||
@@ -59,7 +59,7 @@ if (BUILD_CLI_EXECUTABLES)
|
||||
# compiled with the correct int main() call.
|
||||
set_target_properties(mlpack_${name} PROPERTIES COMPILE_FLAGS
|
||||
-DBINDING_TYPE=BINDING_TYPE_CLI)
|
||||
install(TARGETS mlpack_${name} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
install(TARGETS mlpack_${name} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
|
||||
# If man documentation is being generated, make sure this is a dependency.
|
||||
if (TXT2MAN)
|
||||
|
||||
@@ -40,6 +40,8 @@ if (NOT PY_PANDAS)
|
||||
not_found_return("pandas not found; not building Python bindings.")
|
||||
endif ()
|
||||
|
||||
set(BUILDING_PYTHON_BINDINGS ON PARENT_SCOPE)
|
||||
|
||||
# Nothing in this directory will be compiled into mlpack.
|
||||
set(BINDING_SOURCES
|
||||
default_param.hpp
|
||||
@@ -105,6 +107,8 @@ endif ()
|
||||
|
||||
add_custom_target(python ALL DEPENDS mlpack)
|
||||
add_custom_target(python_copy ALL DEPENDS mlpack)
|
||||
# The python_configure target is added later; this is a dummy target.
|
||||
add_custom_target(python_configured ALL)
|
||||
|
||||
# Copy necessary files after making the mlpack/ directory.
|
||||
add_custom_command(TARGET python_copy PRE_BUILD
|
||||
@@ -137,7 +141,7 @@ if (BUILD_TESTS)
|
||||
endif ()
|
||||
|
||||
# Install any dependencies via setuptools automatically.
|
||||
add_custom_command(TARGET python_copy POST_BUILD
|
||||
add_custom_command(TARGET python_configured POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E env NO_BUILD=1 ${PYTHON_EXECUTABLE}
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py build
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/)
|
||||
@@ -162,7 +166,7 @@ add_custom_command(TARGET python POST_BUILD
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/copy_artifacts.py
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/)
|
||||
|
||||
add_dependencies(python python_copy)
|
||||
add_dependencies(python python_configured)
|
||||
|
||||
# Configure installation script file.
|
||||
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
||||
@@ -174,12 +178,32 @@ 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 "execute_process(COMMAND mkdir -p $ENV{DESTDIR}${CMAKE_PYTHON_PATH})")
|
||||
install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/PythonInstall.cmake)
|
||||
install(SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/PythonInstall.cmake")
|
||||
|
||||
# Prepare __init__.py for having all of the convenience imports appended to it.
|
||||
file(COPY mlpack/__init__.py DESTINATION
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
|
||||
|
||||
if (WIN32)
|
||||
# Copy all necessary DLLs to the Python build directory.
|
||||
foreach (dir ${DLL_COPY_DIRS})
|
||||
file(GLOB dll_dir_files "${dir}/*.dll")
|
||||
file(COPY ${dll_dir_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
|
||||
endforeach ()
|
||||
|
||||
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.
|
||||
macro (add_python_binding name)
|
||||
if (BUILD_PYTHON_BINDINGS)
|
||||
@@ -204,7 +228,7 @@ if (BUILD_PYTHON_BINDINGS)
|
||||
-DBINDING_TYPE=BINDING_TYPE_PYX)
|
||||
add_custom_command(TARGET generate_pyx_${name} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DPROGRAM=${CMAKE_BINARY_DIR}/bin/generate_pyx_${name}
|
||||
-DPROGRAM=$<TARGET_FILE:generate_pyx_${name}>
|
||||
-DOUTPUT_FILE=${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/${name}.pyx
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/RunProgram.cmake)
|
||||
|
||||
@@ -221,7 +245,7 @@ if (BUILD_PYTHON_BINDINGS)
|
||||
|
||||
add_dependencies(python build_pyx_${name})
|
||||
add_dependencies(build_pyx_${name} generate_pyx_${name})
|
||||
add_dependencies(generate_pyx_${name} python_copy)
|
||||
add_dependencies(generate_pyx_${name} python_configured)
|
||||
|
||||
# Add the convenience import to __init__.py. Note that this happens during
|
||||
# configuration.
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# ConfigureSetup.cmake: generate the setup.py file given several environment
|
||||
# variables.
|
||||
#
|
||||
# This file depends on the following variables being set:
|
||||
#
|
||||
# - SETUP_PY_IN: location of input file
|
||||
# - SETUP_PY_OUT: location of output file
|
||||
# - PACKAGE_VERSION: version of package
|
||||
# - Boost_SERIALIZATION_LIBRARY: location of Boost serialization library
|
||||
# - Boost_LIBRARY_DIRS: paths to boost libraries
|
||||
# - ARMADILLO_LIBRARIES: space-separated list of Armadillo dependencies
|
||||
# - MLPACK_LIBRARY: location of mlpack library
|
||||
# - MLPACK_PYXS: list of pyx files
|
||||
# - OpenMP_CXX_FLAGS: OpenMP C++ compilation flags
|
||||
# - DISABLE_CFLAGS: list of CFLAGS or CXXFLAGS to be disabled
|
||||
# - CYTHON_INCLUDE_DIRECTORIES: include directories for Cython
|
||||
# - MLPACK_LIBDIR: path to mlpack libraries
|
||||
# - OUTPUT_DIR: binary output directory for CMake
|
||||
|
||||
# It's possible that the FindBoost CMake script may have returned a Boost
|
||||
# library with "lib" improperly prepended to it. So we need to see if the file
|
||||
# exists, and if it doesn't, but it has a "lib" in it, then we will try
|
||||
# stripping the "lib" off the front.
|
||||
message(STATUS "Run with ${Boost_SERIALIZATION_LIBRARY}.")
|
||||
if (NOT EXISTS "${Boost_SERIALIZATION_LIBRARY}")
|
||||
message(STATUS "Did not find serialization library ${Boost_SERIALIZATION_LIBRARY}!")
|
||||
# Split the filename to see if it starts with lib.
|
||||
set(Boost_SERIALIZATION_LIBRARY_ORIG "${Boost_SERIALIZATION_LIBRARY}")
|
||||
get_filename_component(SER_LIB_DIRECTORY "${Boost_SERIALIZATION_LIBRARY}"
|
||||
DIRECTORY)
|
||||
get_filename_component(SER_LIB_FILENAME "${Boost_SERIALIZATION_LIBRARY}" NAME)
|
||||
message(STATUS "Name component is ${SER_LIB_FILENAME}, and directory is ${SER_LIB_DIRECTORY}.")
|
||||
|
||||
# Strip any preceding "lib/".
|
||||
string(REGEX REPLACE "^lib" "" STRIPPED_FILENAME "${SER_LIB_FILENAME}")
|
||||
message(STATUS "Regex gave us ${STRIPPED_FILENAME}.")
|
||||
set(Boost_SERIALIZATION_LIBRARY "${SER_LIB_DIRECTORY}/${STRIPPED_FILENAME}")
|
||||
message(STATUS "New library ${Boost_SERIALIZATION_LIBRARY}.")
|
||||
|
||||
if (NOT EXISTS "${Boost_SERIALIZATION_LIBRARY}")
|
||||
# We didn't find it, so for ease of debugging just revert to the original.
|
||||
set (Boost_SERIALIZATION_LIBRARY "${Boost_SERIALIZATION_LIBRARY_ORIG}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
configure_file("${SETUP_PY_IN}" "${SETUP_PY_OUT}")
|
||||
@@ -5,7 +5,7 @@
|
||||
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=${CMAKE_INSTALL_PREFIX} --root=$ENV{DESTDIR}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/"
|
||||
RESULT_VARIABLE setup_res)
|
||||
else ()
|
||||
|
||||
@@ -26,6 +26,9 @@ numpy.import_array()
|
||||
cimport arma
|
||||
from libcpp cimport bool
|
||||
|
||||
import platform
|
||||
isWin = (platform.system() == "Windows")
|
||||
|
||||
cdef extern from "numpy/arrayobject.h":
|
||||
void PyArray_ENABLEFLAGS(numpy.ndarray arr, int flags)
|
||||
void PyArray_CLEARFLAGS(numpy.ndarray arr, int flags)
|
||||
@@ -45,16 +48,16 @@ cdef arma.Mat[double]* numpy_to_mat_d(numpy.ndarray[numpy.double_t, ndim=2] X, \
|
||||
"""
|
||||
Convert a numpy ndarray to a matrix. The memory will still be owned by numpy.
|
||||
"""
|
||||
if not (X.flags.c_contiguous or X.flags.owndata):
|
||||
if not X.flags.c_contiguous or (not X.flags.owndata and not isWin):
|
||||
# If needed, make a copy where we own the memory.
|
||||
X = X.copy(order="C")
|
||||
takeOwnership = True
|
||||
|
||||
cdef arma.Mat[double]* m = new arma.Mat[double](<double*> X.data, X.shape[1],\
|
||||
X.shape[0], False, False)
|
||||
X.shape[0], isWin, False)
|
||||
|
||||
# Take ownership of the memory, if we need to.
|
||||
if takeOwnership:
|
||||
# Take ownership of the memory, if we need to and we are not on Windows.
|
||||
if takeOwnership and not isWin:
|
||||
PyArray_CLEARFLAGS(X, numpy.NPY_OWNDATA)
|
||||
SetMemState[arma.Mat[double]](m[0], 0)
|
||||
|
||||
@@ -65,16 +68,17 @@ cdef arma.Mat[size_t]* numpy_to_mat_s(numpy.ndarray[numpy.npy_intp, ndim=2] X, \
|
||||
"""
|
||||
Convert a numpy ndarray to a matrix. The memory will still be owned by numpy.
|
||||
"""
|
||||
if not (X.flags.c_contiguous or X.flags.owndata):
|
||||
# If needed, make a copy where we own the memory.
|
||||
if not X.flags.c_contiguous or (not X.flags.owndata and not isWin):
|
||||
# If needed, make a copy where we own the memory, except on Windows where
|
||||
# we never copy.
|
||||
X = X.copy(order="C")
|
||||
takeOwnership = True
|
||||
|
||||
cdef arma.Mat[size_t]* m = new arma.Mat[size_t](<size_t*> X.data, X.shape[1],
|
||||
X.shape[0], False, False)
|
||||
X.shape[0], isWin, False)
|
||||
|
||||
# Take ownership of the memory, if we need to.
|
||||
if takeOwnership:
|
||||
if takeOwnership and not isWin:
|
||||
PyArray_CLEARFLAGS(X, numpy.NPY_OWNDATA)
|
||||
SetMemState[arma.Mat[size_t]](m[0], 0)
|
||||
|
||||
@@ -91,9 +95,11 @@ cdef numpy.ndarray[numpy.double_t, ndim=2] mat_to_numpy_d(arma.Mat[double]& X) \
|
||||
dims[1] = <numpy.npy_intp> X.n_rows
|
||||
cdef numpy.ndarray[numpy.double_t, ndim=2] output = \
|
||||
numpy.PyArray_SimpleNewFromData(2, &dims[0], numpy.NPY_DOUBLE, GetMemory(X))
|
||||
if isWin:
|
||||
output = output.copy(order="C")
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if GetMemState[arma.Mat[double]](X) == 0:
|
||||
if GetMemState[arma.Mat[double]](X) == 0 and not isWin:
|
||||
SetMemState[arma.Mat[double]](X, 1)
|
||||
PyArray_ENABLEFLAGS(output, numpy.NPY_OWNDATA)
|
||||
|
||||
@@ -110,9 +116,11 @@ cdef numpy.ndarray[numpy.npy_intp, ndim=2] mat_to_numpy_s(arma.Mat[size_t]& X) \
|
||||
dims[1] = <numpy.npy_intp> X.n_rows
|
||||
cdef numpy.ndarray[numpy.npy_intp, ndim=2] output = \
|
||||
numpy.PyArray_SimpleNewFromData(2, &dims[0], numpy.NPY_INTP, GetMemory(X))
|
||||
if isWin:
|
||||
output = output.copy(order="C")
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if GetMemState[arma.Mat[size_t]](X) == 0:
|
||||
if GetMemState[arma.Mat[size_t]](X) == 0 and not isWin:
|
||||
SetMemState[arma.Mat[size_t]](X, 1)
|
||||
PyArray_ENABLEFLAGS(output, numpy.NPY_OWNDATA)
|
||||
|
||||
@@ -124,16 +132,17 @@ cdef arma.Row[double]* numpy_to_row_d(numpy.ndarray[numpy.double_t, ndim=1] X, \
|
||||
Convert a numpy one-dimensional ndarray to a row. The memory will still be
|
||||
owned by numpy.
|
||||
"""
|
||||
if not (X.flags.c_contiguous or X.flags.owndata):
|
||||
# If needed, make a copy where we own the memory.
|
||||
if not X.flags.c_contiguous or (not X.flags.owndata and not isWin):
|
||||
# If needed, make a copy where we own the memory, except on Windows where
|
||||
# we never copy.
|
||||
X = X.copy(order="C")
|
||||
takeOwnership = True
|
||||
|
||||
cdef arma.Row[double]* m = new arma.Row[double](<double*> X.data, X.shape[0],
|
||||
False, False)
|
||||
isWin, False)
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if takeOwnership:
|
||||
if takeOwnership and not isWin:
|
||||
PyArray_CLEARFLAGS(X, numpy.NPY_OWNDATA)
|
||||
SetMemState[arma.Row[double]](m[0], 0)
|
||||
|
||||
@@ -145,16 +154,17 @@ cdef arma.Row[size_t]* numpy_to_row_s(numpy.ndarray[numpy.npy_intp, ndim=1] X, \
|
||||
Convert a numpy one-dimensional ndarray to a row. The memory will still be
|
||||
owned by numpy.
|
||||
"""
|
||||
if not (X.flags.c_contiguous or X.flags.owndata):
|
||||
# If needed, make a copy where we own the memory.
|
||||
if not X.flags.c_contiguous or (not X.flags.owndata and not isWin):
|
||||
# If needed, make a copy where we own the memory, except on Windows where
|
||||
# we never copy.
|
||||
X = X.copy(order="C")
|
||||
takeOwnership = True
|
||||
|
||||
cdef arma.Row[size_t]* m = new arma.Row[size_t](<size_t*> X.data, X.shape[0],
|
||||
False, False)
|
||||
isWin, False)
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if takeOwnership:
|
||||
if takeOwnership and not isWin:
|
||||
PyArray_CLEARFLAGS(X, numpy.NPY_OWNDATA)
|
||||
SetMemState[arma.Row[size_t]](m[0], 0)
|
||||
|
||||
@@ -169,9 +179,11 @@ cdef numpy.ndarray[numpy.double_t, ndim=1] row_to_numpy_d(arma.Row[double]& X) \
|
||||
cdef numpy.npy_intp dim = <numpy.npy_intp> X.n_elem
|
||||
cdef numpy.ndarray[numpy.double_t, ndim=1] output = \
|
||||
numpy.PyArray_SimpleNewFromData(1, &dim, numpy.NPY_DOUBLE, GetMemory(X))
|
||||
if isWin:
|
||||
output = output.copy(order="C")
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if GetMemState[arma.Row[double]](X) == 0:
|
||||
if GetMemState[arma.Row[double]](X) == 0 and not isWin:
|
||||
SetMemState[arma.Row[double]](X, 1)
|
||||
PyArray_ENABLEFLAGS(output, numpy.NPY_OWNDATA)
|
||||
|
||||
@@ -182,13 +194,16 @@ cdef numpy.ndarray[numpy.npy_intp, ndim=1] row_to_numpy_s(arma.Row[size_t]& X) \
|
||||
"""
|
||||
Convert an Armadillo row vector to a one-dimensional numpy ndarray.
|
||||
"""
|
||||
# print("called row_to_numpy_s()\n")
|
||||
# Extract dimensions.
|
||||
cdef numpy.npy_intp dim = <numpy.npy_intp> X.n_elem
|
||||
cdef numpy.ndarray[numpy.npy_intp, ndim=1] output = \
|
||||
numpy.PyArray_SimpleNewFromData(1, &dim, numpy.NPY_INTP, GetMemory(X))
|
||||
if isWin:
|
||||
output = output.copy(order="C")
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if GetMemState[arma.Row[size_t]](X) == 0:
|
||||
if GetMemState[arma.Row[size_t]](X) == 0 and not isWin:
|
||||
SetMemState[arma.Row[size_t]](X, 1)
|
||||
PyArray_ENABLEFLAGS(output, numpy.NPY_OWNDATA)
|
||||
|
||||
@@ -200,16 +215,17 @@ cdef arma.Col[double]* numpy_to_col_d(numpy.ndarray[numpy.double_t, ndim=1] X, \
|
||||
Convert a numpy one-dimensional ndarray to a column vector. The memory will
|
||||
still be owned by numpy.
|
||||
"""
|
||||
if not (X.flags.c_contiguous or X.flags.owndata):
|
||||
# If needed, make a copy where we own the memory.
|
||||
if not X.flags.c_contiguous or (not X.flags.owndata and not isWin):
|
||||
# If needed, make a copy where we own the memory, except on Windows where
|
||||
# we never copy.
|
||||
X = X.copy(order="C")
|
||||
takeOwnership = True
|
||||
|
||||
cdef arma.Col[double]* m = new arma.Col[double](<double*> X.data, X.shape[0],
|
||||
False, True)
|
||||
isWin, False)
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if takeOwnership:
|
||||
if takeOwnership and not isWin:
|
||||
PyArray_CLEARFLAGS(X, numpy.NPY_OWNDATA)
|
||||
SetMemState[arma.Col[double]](m[0], 0)
|
||||
|
||||
@@ -221,15 +237,17 @@ cdef arma.Col[size_t]* numpy_to_col_s(numpy.ndarray[numpy.npy_intp, ndim=1] X, \
|
||||
Convert a numpy one-dimensional ndarray to a column vector. The memory will
|
||||
still be owned by numpy.
|
||||
"""
|
||||
if not (X.flags.c_contiguous or X.flags.owndata):
|
||||
# If needed, make a copy where we own the memory.
|
||||
if not X.flags.c_contiguous or (not X.flags.owndata and not isWin):
|
||||
# If needed, make a copy where we own the memory, except on Windows where
|
||||
# we never copy.
|
||||
X = X.copy(order="C")
|
||||
takeOwnership = True
|
||||
|
||||
cdef arma.Col[size_t]* m = new arma.Col[size_t](<size_t*> X.data, X.shape[0],
|
||||
False, False)
|
||||
isWin, False)
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if takeOwnership:
|
||||
if takeOwnership and not isWin:
|
||||
PyArray_CLEARFLAGS(X, numpy.NPY_OWNDATA)
|
||||
SetMemState[arma.Col[size_t]](m[0], 0)
|
||||
|
||||
@@ -244,9 +262,11 @@ cdef numpy.ndarray[numpy.double_t, ndim=1] col_to_numpy_d(arma.Col[double]& X) \
|
||||
cdef numpy.npy_intp dim = <numpy.npy_intp> X.n_elem
|
||||
cdef numpy.ndarray[numpy.double_t, ndim=1] output = \
|
||||
numpy.PyArray_SimpleNewFromData(1, &dim, numpy.NPY_DOUBLE, GetMemory(X))
|
||||
if isWin:
|
||||
output = output.copy(order="C")
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if GetMemState[arma.Col[double]](X) == 0:
|
||||
if GetMemState[arma.Col[double]](X) == 0 and not isWin:
|
||||
SetMemState[arma.Col[double]](X, 1)
|
||||
PyArray_ENABLEFLAGS(output, numpy.NPY_OWNDATA)
|
||||
|
||||
@@ -261,9 +281,11 @@ cdef numpy.ndarray[numpy.npy_intp, ndim=1] col_to_numpy_s(arma.Col[size_t]& X) \
|
||||
cdef numpy.npy_intp dim = <numpy.npy_intp> X.n_elem
|
||||
cdef numpy.ndarray[numpy.npy_intp, ndim=1] output = \
|
||||
numpy.PyArray_SimpleNewFromData(1, &dim, numpy.NPY_INTP, GetMemory(X))
|
||||
if isWin:
|
||||
output = output.copy(order="C")
|
||||
|
||||
# Transfer memory ownership, if needed.
|
||||
if GetMemState[arma.Col[size_t]](X) == 0:
|
||||
if GetMemState[arma.Col[size_t]](X) == 0 and not isWin:
|
||||
SetMemState[arma.Col[size_t]](X, 1)
|
||||
PyArray_ENABLEFLAGS(output, numpy.NPY_OWNDATA)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import os
|
||||
import sys
|
||||
import numpy as np
|
||||
import re
|
||||
import platform
|
||||
|
||||
# Process input argument --module={name} first if needed.
|
||||
module = None
|
||||
@@ -22,57 +23,79 @@ from setuptools import setup
|
||||
from setuptools.extension import Extension
|
||||
from Cython.Distutils import build_ext
|
||||
|
||||
pyxs='${MLPACK_PYXS}'.split(';')
|
||||
pyxs='${MLPACK_PYXS}'.split(' ')
|
||||
|
||||
if not '${OpenMP_CXX_FLAGS}':
|
||||
extra_link_args=[]
|
||||
else:
|
||||
extra_link_args=['${OpenMP_CXX_FLAGS}']
|
||||
|
||||
# Get list of library dirs.
|
||||
library_dirs = list(filter(None, ['${MLPACK_LIBDIR}'] +
|
||||
'${Boost_LIBRARY_DIRS}'.split(' ')))
|
||||
|
||||
# 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
|
||||
# Windows and Linux linking behavior.
|
||||
libraries = ['${MLPACK_LIBRARY}',
|
||||
'${Boost_SERIALIZATION_LIBRARY}'] + \
|
||||
'${ARMADILLO_LIBRARIES}'.split(' ')
|
||||
|
||||
# Potentially faulty assumption: we can always link against libraries directly
|
||||
# by just specifying the full path to them on the command line.
|
||||
extra_link_args += libraries
|
||||
|
||||
# Only build the extensions if we are asked to.
|
||||
if os.getenv('NO_BUILD') == '1':
|
||||
modules = []
|
||||
else:
|
||||
cxx_flags = '${CMAKE_CXX_FLAGS}'.strip()
|
||||
cxx_flags = re.sub(' +', ' ', cxx_flags)
|
||||
extra_args = ['-DBINDING_TYPE=BINDING_TYPE_PYX',
|
||||
'-std=c++11'] + cxx_flags.split(' ')
|
||||
if cxx_flags:
|
||||
extra_args = ['-DBINDING_TYPE=BINDING_TYPE_PYX',
|
||||
'-std=c++11',
|
||||
'${OpenMP_CXX_FLAGS}'] + cxx_flags.split(' ')
|
||||
else:
|
||||
extra_args = ['-DBINDING_TYPE=BINDING_TYPE_PYX',
|
||||
'-std=c++11',
|
||||
'${OpenMP_CXX_FLAGS}']
|
||||
|
||||
# Extra options for MSVC compiler.
|
||||
if platform.system() == 'Windows':
|
||||
extra_args = extra_args + ['/MD', '/O2', '/Ob2', '/DNDEBUG']
|
||||
|
||||
# This is used for parallel builds; CMake will set PYX_TO_BUILD accordingly.
|
||||
if module is not None:
|
||||
modules=[\
|
||||
Extension('mlpack.' + name.split('.')[0],
|
||||
['${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/' +
|
||||
name],
|
||||
['mlpack/' + name],
|
||||
language='c++',
|
||||
include_dirs=[ \
|
||||
np.get_include(), \
|
||||
'${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/'] +
|
||||
'${CYTHON_INCLUDE_DIRECTORIES}'.split(';'),
|
||||
libraries=['mlpack', 'boost_serialization'],
|
||||
library_dirs=['${CMAKE_BINARY_DIR}/lib/'],
|
||||
'${OUTPUT_DIR}/src/mlpack/bindings/python/'] +
|
||||
'${CYTHON_INCLUDE_DIRECTORIES}'.split(' '),
|
||||
library_dirs=library_dirs,
|
||||
# CMAKE_CXX_FLAGS seems to have an extra space.
|
||||
extra_compile_args=extra_args,
|
||||
extra_link_args=extra_link_args,
|
||||
undef_macros=[] if len("${DISABLE_CFLAGS}") == 0 \
|
||||
else '${DISABLE_CFLAGS}'.split(';')) \
|
||||
else '${DISABLE_CFLAGS}'.split(' ')) \
|
||||
for name in pyxs if name == module]
|
||||
else:
|
||||
modules=[\
|
||||
Extension('mlpack.' + name.split('.')[0],
|
||||
['${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/' +
|
||||
name],
|
||||
['mlpack/' + name],
|
||||
language='c++',
|
||||
include_dirs=[ \
|
||||
np.get_include(), \
|
||||
'${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/'] +
|
||||
'${CYTHON_INCLUDE_DIRECTORIES}'.split(';'),
|
||||
libraries=['mlpack', 'boost_serialization'],
|
||||
library_dirs=['${CMAKE_BINARY_DIR}/lib/'],
|
||||
'${OUTPUT_DIR}/src/mlpack/bindings/python/'] +
|
||||
'${CYTHON_INCLUDE_DIRECTORIES}'.split(' '),
|
||||
library_dirs=library_dirs,
|
||||
# CMAKE_CXX_FLAGS seems to have an extra space.
|
||||
extra_compile_args=extra_args,
|
||||
extra_link_args=extra_link_args,
|
||||
undef_macros=[] if len("${DISABLE_CFLAGS}") == 0 \
|
||||
else '${DISABLE_CFLAGS}'.split(';')) \
|
||||
else '${DISABLE_CFLAGS}'.split(' ')) \
|
||||
for name in pyxs]
|
||||
|
||||
setup(name='mlpack',
|
||||
@@ -103,7 +126,7 @@ setup(name='mlpack',
|
||||
'Source': 'https://github.com/mlpack/mlpack/',
|
||||
'Tracker': 'https://github.com/mlpack/mlpack/issues'},
|
||||
install_requires=['cython>=0.24', 'numpy', 'pandas'],
|
||||
package_dir={ '': '${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/' },
|
||||
package_dir={ '': '.' }, # Might be superfluous.
|
||||
packages=['mlpack'],
|
||||
cmdclass={ 'build_ext': build_ext },
|
||||
ext_modules = modules,
|
||||
|
||||
@@ -60,7 +60,8 @@ class TestToMatrix(unittest.TestCase):
|
||||
"""
|
||||
d = pd.DataFrame({'a': range(50)})
|
||||
d['b'] = np.random.randn(50, 1)
|
||||
self.assertEqual(d['a'].dtype, int)
|
||||
self.assertTrue((d['a'].dtype == np.dtype('int32')) or
|
||||
(d['a'].dtype == np.dtype('int64')))
|
||||
self.assertEqual(d['b'].dtype, np.dtype(np.double))
|
||||
|
||||
m, _ = to_matrix(d)
|
||||
@@ -190,7 +191,8 @@ class TestToMatrixWithInfo(unittest.TestCase):
|
||||
"""
|
||||
d = pd.DataFrame({'a': range(50)})
|
||||
d['b'] = np.random.randn(50, 1)
|
||||
self.assertEqual(d['a'].dtype, int)
|
||||
self.assertTrue((d['a'].dtype == np.dtype('int32')) or
|
||||
(d['a'].dtype == np.dtype('int64')))
|
||||
self.assertEqual(d['b'].dtype, np.dtype(np.double))
|
||||
|
||||
m, _, dims = to_matrix_with_info(d, np.double)
|
||||
|
||||
@@ -263,7 +263,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
s_umatrix_in=z)
|
||||
|
||||
self.assertEqual(output['s_umatrix_out'].shape[0], 100)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(100):
|
||||
self.assertEqual(output['s_umatrix_out'][i, 0], x.iloc[i] * 2)
|
||||
@@ -284,7 +284,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
copy_all_inputs=True)
|
||||
|
||||
self.assertEqual(output['s_umatrix_out'].shape[0], 100)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(100):
|
||||
self.assertEqual(output['s_umatrix_out'][i, 0], x.iloc[i] * 2)
|
||||
@@ -460,7 +460,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
|
||||
self.assertEqual(output['umatrix_out'].shape[0], 100)
|
||||
self.assertEqual(output['umatrix_out'].shape[1], 4)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.dtype('intp'))
|
||||
for i in [0, 1, 3]:
|
||||
for j in range(100):
|
||||
self.assertEqual(x[j, i], output['umatrix_out'][j, i])
|
||||
@@ -484,7 +484,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
|
||||
self.assertEqual(output['umatrix_out'].shape[0], 100)
|
||||
self.assertEqual(output['umatrix_out'].shape[1], 4)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.dtype('intp'))
|
||||
for i in [0, 1, 3]:
|
||||
for j in range(100):
|
||||
self.assertEqual(x[j, i], output['umatrix_out'][j, i])
|
||||
@@ -509,7 +509,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
|
||||
self.assertEqual(output['umatrix_out'].shape[0], 3)
|
||||
self.assertEqual(output['umatrix_out'].shape[1], 4)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.dtype('intp'))
|
||||
self.assertEqual(output['umatrix_out'][0, 0], 1)
|
||||
self.assertEqual(output['umatrix_out'][0, 1], 2)
|
||||
self.assertEqual(output['umatrix_out'][0, 2], 6)
|
||||
@@ -543,7 +543,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
self.assertEqual(output['umatrix_out'].shape[1], 4)
|
||||
self.assertEqual(len(x), 3)
|
||||
self.assertEqual(len(x[0]), 5)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['umatrix_out'].dtype, np.dtype('intp'))
|
||||
self.assertEqual(output['umatrix_out'][0, 0], 1)
|
||||
self.assertEqual(output['umatrix_out'][0, 1], 2)
|
||||
self.assertEqual(output['umatrix_out'][0, 2], 6)
|
||||
@@ -612,7 +612,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
ucol_in=z)
|
||||
|
||||
self.assertEqual(output['ucol_out'].shape[0], 100)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.long)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.dtype('intp'))
|
||||
for i in range(100):
|
||||
self.assertEqual(output['ucol_out'][i], x[i] * 2)
|
||||
|
||||
@@ -631,7 +631,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
copy_all_inputs=True)
|
||||
|
||||
self.assertEqual(output['ucol_out'].shape[0], 100)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.long)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.dtype('intp'))
|
||||
for i in range(100):
|
||||
self.assertEqual(output['ucol_out'][i], x[i] * 2)
|
||||
|
||||
@@ -690,7 +690,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
urow_in=z)
|
||||
|
||||
self.assertEqual(output['urow_out'].shape[0], 100)
|
||||
self.assertEqual(output['urow_out'].dtype, np.long)
|
||||
self.assertEqual(output['urow_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(100):
|
||||
self.assertEqual(output['urow_out'][i], x[i] * 2)
|
||||
@@ -710,7 +710,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
copy_all_inputs=True)
|
||||
|
||||
self.assertEqual(output['urow_out'].shape[0], 100)
|
||||
self.assertEqual(output['urow_out'].dtype, np.long)
|
||||
self.assertEqual(output['urow_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(100):
|
||||
self.assertEqual(output['urow_out'][i], x[i] * 2)
|
||||
@@ -923,7 +923,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
s_umatrix_in=z)
|
||||
|
||||
self.assertEqual(output['s_umatrix_out'].shape[0], 100)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(100):
|
||||
self.assertEqual(output['s_umatrix_out'][i, 0], x[i] * 2)
|
||||
@@ -943,7 +943,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
copy_all_inputs=True)
|
||||
|
||||
self.assertEqual(output['s_umatrix_out'].shape[0], 100)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.long)
|
||||
self.assertEqual(output['s_umatrix_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(100):
|
||||
self.assertEqual(output['s_umatrix_out'][i, 0], x[i] * 2)
|
||||
@@ -1003,7 +1003,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
ucol_in=z)
|
||||
|
||||
self.assertEqual(output['ucol_out'].shape[0], 100)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.long)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.dtype('intp'))
|
||||
for i in range(100):
|
||||
self.assertEqual(output['ucol_out'][i], x[i] * 2)
|
||||
|
||||
@@ -1022,7 +1022,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
copy_all_inputs=True)
|
||||
|
||||
self.assertEqual(output['ucol_out'].shape[0], 100)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.long)
|
||||
self.assertEqual(output['ucol_out'].dtype, np.dtype('intp'))
|
||||
for i in range(100):
|
||||
self.assertEqual(output['ucol_out'][i], x[i] * 2)
|
||||
|
||||
@@ -1081,7 +1081,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
urow_in=z)
|
||||
|
||||
self.assertEqual(output['urow_out'].shape[0], 100)
|
||||
self.assertEqual(output['urow_out'].dtype, np.long)
|
||||
self.assertEqual(output['urow_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(100):
|
||||
self.assertEqual(output['urow_out'][i], x[i] * 2)
|
||||
@@ -1101,7 +1101,7 @@ class TestPythonBinding(unittest.TestCase):
|
||||
copy_all_inputs=True)
|
||||
|
||||
self.assertEqual(output['urow_out'].shape[0], 101)
|
||||
self.assertEqual(output['urow_out'].dtype, np.long)
|
||||
self.assertEqual(output['urow_out'].dtype, np.dtype('intp'))
|
||||
|
||||
for i in range(101):
|
||||
self.assertEqual(output['urow_out'][i], x[0][i] * 2)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# Anything not in this list will not be compiled into mlpack.
|
||||
set(SOURCES
|
||||
arma_extend.hpp
|
||||
fn_inplace_reshape.hpp
|
||||
hdf5_misc.hpp
|
||||
SpMat_extra_bones.hpp
|
||||
SpMat_extra_meat.hpp
|
||||
Mat_extra_bones.hpp
|
||||
|
||||
@@ -36,11 +36,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Make sure that U64 and S64 support is enabled.
|
||||
#ifndef ARMA_USE_U64S64
|
||||
#define ARMA_USE_U64S64
|
||||
#endif
|
||||
|
||||
// Include everything we'll need for serialize().
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
@@ -48,13 +43,4 @@
|
||||
|
||||
#include <armadillo>
|
||||
|
||||
namespace arma {
|
||||
// u64/s64
|
||||
#include "hdf5_misc.hpp"
|
||||
|
||||
|
||||
// inplace_reshape()
|
||||
#include "fn_inplace_reshape.hpp"
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
//! \addtogroup fn_inplace_reshape
|
||||
//! @{
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This does not handle column vectors or row vectors entirely correctly. You
|
||||
* should be able to do multiplication or other basic operations with the
|
||||
* resulting matrix, but it may have other problems. So if you are using this
|
||||
* on vectors (arma::Col<> or arma::Row<>), be careful, and be warned that
|
||||
* bizarre behavior may occur.
|
||||
*/
|
||||
template<typename eT>
|
||||
inline
|
||||
Mat<eT>&
|
||||
inplace_reshape(Mat<eT>& X,
|
||||
const uword new_n_rows,
|
||||
const uword new_n_cols)
|
||||
{
|
||||
arma_extra_debug_sigprint();
|
||||
|
||||
arma_debug_check((new_n_rows * new_n_cols) != X.n_elem,
|
||||
"inplace_reshape(): cannot add or remove elements");
|
||||
|
||||
access::rw(X.n_rows) = new_n_rows;
|
||||
access::rw(X.n_cols) = new_n_cols;
|
||||
|
||||
return X;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright (C) 2012-2013 National ICT Australia (NICTA)
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// Written by Conrad Sanderson - http://conradsanderson.id.au
|
||||
// Written by Ryan Curtin
|
||||
// Written by Szabolcs Horvat
|
||||
|
||||
// To hack in u64/s64 support to Armadillo when it is not compiled with
|
||||
// ARMA_64BIT_WORD.
|
||||
namespace hdf5_misc {
|
||||
|
||||
#if defined(ARMA_USE_HDF5)
|
||||
#if !(defined(ARMA_64BIT_WORD) || defined(ARMA_USE_U64S64))
|
||||
#if defined(ULLONG_MAX)
|
||||
template<>
|
||||
inline
|
||||
hid_t
|
||||
get_hdf5_type< long long >()
|
||||
{
|
||||
return H5Tcopy(H5T_NATIVE_LLONG);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
hid_t
|
||||
get_hdf5_type< unsigned long long >()
|
||||
{
|
||||
return H5Tcopy(H5T_NATIVE_ULLONG);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} // namespace hdf5_misc
|
||||
@@ -10,6 +10,7 @@ set(SOURCES
|
||||
load_csv.hpp
|
||||
load_csv.cpp
|
||||
load.hpp
|
||||
load_image_impl.hpp
|
||||
load_model_impl.hpp
|
||||
load_vec_impl.hpp
|
||||
load_impl.hpp
|
||||
@@ -38,6 +39,7 @@ endforeach()
|
||||
# Add subdirectories.
|
||||
add_subdirectory(imputation_methods)
|
||||
add_subdirectory(map_policies)
|
||||
add_subdirectory(scaler_methods)
|
||||
|
||||
# Append sources (with directory name) to list of all mlpack sources (used at
|
||||
# parent scope).
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @file image_info.hpp
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* An image information holder.
|
||||
*
|
||||
* 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_HPP
|
||||
#define MLPACK_CORE_DATA_IMAGE_INFO_HPP
|
||||
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
#include "extension.hpp"
|
||||
|
||||
#ifdef HAS_STB // Compile this only if stb is present.
|
||||
|
||||
#define STB_IMAGE_STATIC
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
#define STB_IMAGE_WRITE_STATIC
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <stb_image_write.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
#ifdef HAS_STB // Compile this only if stb is present.
|
||||
|
||||
/**
|
||||
* Checks if the given image filename is supported.
|
||||
*
|
||||
* @param filename Name of the image file.
|
||||
* @return Boolean value indicating success if it is an image.
|
||||
*/
|
||||
inline bool ImageFormatSupported(const std::string& fileName,
|
||||
const bool save = false);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Implements meta-data of images required by data::Load and
|
||||
* data::Save for loading and saving images into arma::Mat.
|
||||
*/
|
||||
class ImageInfo
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Instantiate the ImageInfo object with the given image width, height,
|
||||
* number of channels and quality parameter.
|
||||
*
|
||||
* @param width Image width.
|
||||
* @param height Image height.
|
||||
* @param channels Number of channels in the image.
|
||||
* @param quality Compression of the image if saved as jpg (0 - 100).
|
||||
*/
|
||||
ImageInfo(const size_t width = 0,
|
||||
const size_t height = 0,
|
||||
const size_t channels = 3,
|
||||
const size_t quality = 90);
|
||||
|
||||
//! Get the image width.
|
||||
const size_t& Width() const { return width; }
|
||||
//! Modify the image width.
|
||||
size_t& Width() { return width; }
|
||||
//! Get the image height.
|
||||
|
||||
const size_t& Height() const { return height; }
|
||||
//! Modify the image height.
|
||||
size_t& Height() { return height; }
|
||||
|
||||
//! Get the image channels.
|
||||
const size_t& Channels() const { return channels; }
|
||||
//! Modify the image channels.
|
||||
size_t& Channels() { return channels; }
|
||||
|
||||
//! Get the image quality.
|
||||
const size_t& Quality() const { return quality; }
|
||||
//! Modify the image quality.
|
||||
size_t& Quality() { return quality; }
|
||||
|
||||
private:
|
||||
// To store the image width.
|
||||
size_t width;
|
||||
|
||||
// To store the image height.
|
||||
size_t height;
|
||||
|
||||
// To store the number of channels in the image.
|
||||
size_t channels;
|
||||
|
||||
// Compression of the image if saved as jpg (0 - 100).
|
||||
size_t quality;
|
||||
};
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation of Image.
|
||||
#include "image_info_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file 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
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "format.hpp"
|
||||
#include "dataset_mapper.hpp"
|
||||
#include "image_info.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data /** Functions to load and save matrices and models. */ {
|
||||
@@ -287,6 +288,47 @@ bool Load(const std::string& filename,
|
||||
const bool fatal = false,
|
||||
format f = format::autodetect);
|
||||
|
||||
/**
|
||||
* Image load/save interfaces.
|
||||
*/
|
||||
#ifdef HAS_STB
|
||||
|
||||
/**
|
||||
* Load the image file into the given matrix.
|
||||
*
|
||||
* @param filename Name of the image file.
|
||||
* @param matrix Matrix to load the image into.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Load(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true);
|
||||
|
||||
/**
|
||||
* Load the image file into the given matrix.
|
||||
*
|
||||
* @param files A vector consisting of filenames.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Load(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true);
|
||||
|
||||
#endif // HAS_STB.
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -294,5 +336,7 @@ bool Load(const std::string& filename,
|
||||
#include "load_model_impl.hpp"
|
||||
// Include implementation of Load() for vectors.
|
||||
#include "load_vec_impl.hpp"
|
||||
// Include implementation of Load() for images.
|
||||
#include "load_image_impl.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* @file 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 {
|
||||
|
||||
#ifdef HAS_STB // Compile this only if stb is present.
|
||||
|
||||
// Image loading API.
|
||||
template<typename eT>
|
||||
bool Load(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool /* fatal */,
|
||||
const bool transpose)
|
||||
{
|
||||
Timer::Start("loading_image");
|
||||
unsigned char* image;
|
||||
|
||||
if (!ImageFormatSupported(filename))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "File type " << Extension(filename) << " not supported.\n";
|
||||
oss << "Currently it supports ";
|
||||
for (auto extension : loadFileTypes)
|
||||
oss << " " << extension;
|
||||
oss << std::endl;
|
||||
throw std::runtime_error(oss.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
stbi_set_flip_vertically_on_load(transpose);
|
||||
|
||||
// Temporary variables needed as stb_image.h supports int parameters.
|
||||
int tempWidth, tempHeight, tempChannels;
|
||||
|
||||
// For grayscale images.
|
||||
if (info.Channels() == 1)
|
||||
{
|
||||
image = stbi_load(filename.c_str(), &tempWidth, &tempHeight, &tempChannels,
|
||||
STBI_grey);
|
||||
}
|
||||
else
|
||||
{
|
||||
image = stbi_load(filename.c_str(), &tempWidth, &tempHeight, &tempChannels,
|
||||
STBI_rgb);
|
||||
}
|
||||
|
||||
if (tempWidth <= 0 || tempHeight <= 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Image '" << filename << "' not found." << std::endl;
|
||||
free(image);
|
||||
throw std::runtime_error(oss.str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
info.Width() = tempWidth;
|
||||
info.Height() = tempHeight;
|
||||
info.Channels() = tempChannels;
|
||||
|
||||
// Copy image into armadillo Mat.
|
||||
matrix = arma::Mat<unsigned char>(image, info.Width() * info.Height() *
|
||||
info.Channels(), 1, true, true);
|
||||
|
||||
// Free the image pointer.
|
||||
free(image);
|
||||
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,
|
||||
const bool transpose)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Files vector is empty." << std::endl;
|
||||
|
||||
throw std::runtime_error(oss.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
arma::Mat<unsigned char> img;
|
||||
bool status = Load(files[0], img, info, fatal, transpose);
|
||||
|
||||
// Decide matrix dimension using the image height and width.
|
||||
matrix.set_size(info.Width() * info.Height() * info.Channels(), files.size());
|
||||
matrix.col(0) = img;
|
||||
|
||||
for (size_t i = 1; i < files.size() ; i++)
|
||||
{
|
||||
arma::Mat<unsigned char> colImg(matrix.colptr(i), matrix.n_rows, 1,
|
||||
false, true);
|
||||
status &= Load(files[i], colImg, info, fatal, transpose);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#else // No STB.
|
||||
template<typename eT>
|
||||
bool Load(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true)
|
||||
{
|
||||
throw std::runtime_error("Load(): HAS_STB is not defined, "
|
||||
"so STB is not available and images cannot be loaded!");
|
||||
}
|
||||
|
||||
template<typename eT>
|
||||
bool Load(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true)
|
||||
{
|
||||
throw std::runtime_error("Load(): HAS_STB is not defined, "
|
||||
"so STB is not available and images cannot be loaded!");
|
||||
}
|
||||
#endif // HAS_STB.
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "format.hpp"
|
||||
#include "image_info.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data /** Functions to load and save matrices. */ {
|
||||
@@ -90,6 +91,44 @@ bool Save(const std::string& filename,
|
||||
const bool fatal = false,
|
||||
format f = format::autodetect);
|
||||
|
||||
#ifdef HAS_STB
|
||||
|
||||
/**
|
||||
* Save the image file from the given matrix.
|
||||
*
|
||||
* @param filename Name of the image file.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true);
|
||||
|
||||
/**
|
||||
* Save the image file from the given matrix.
|
||||
*
|
||||
* @param files A vector consisting of filenames.
|
||||
* @param matrix Matrix to save the image from.
|
||||
* @param info An object of ImageInfo class.
|
||||
* @param fatal If an error should be reported as fatal (default false).
|
||||
* @param transpose If true, transpose the matrix after loading.
|
||||
* @return Boolean value indicating success or failure of load.
|
||||
*/
|
||||
template<typename eT>
|
||||
bool Save(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true);
|
||||
|
||||
#endif // HAS_STB.
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -283,6 +283,147 @@ bool Save(const std::string& filename,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAS_STB
|
||||
// Image saving API.
|
||||
template<typename eT>
|
||||
bool Save(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose)
|
||||
{
|
||||
Timer::Start("saving_image");
|
||||
// We transpose by default. So, un-transpose if necessary.
|
||||
if (!transpose)
|
||||
matrix = arma::trans(matrix);
|
||||
|
||||
int tempWidth, tempHeight, tempChannels, tempQuality;
|
||||
|
||||
tempWidth = info.Width();
|
||||
tempHeight = info.Height();
|
||||
tempChannels = info.Channels();
|
||||
tempQuality = info.Quality();
|
||||
|
||||
if (!ImageFormatSupported(filename, true))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "File type " << Extension(filename) << " not supported.\n";
|
||||
oss << "Currently it supports ";
|
||||
for (auto extension : saveFileTypes)
|
||||
oss << ", " << extension;
|
||||
oss << std::endl;
|
||||
throw std::runtime_error(oss.str());
|
||||
return false;
|
||||
}
|
||||
if (matrix.n_cols > 1)
|
||||
{
|
||||
std::cout << "Input Matrix contains more than 1 image." << std::endl;
|
||||
std::cout << "Only the firstimage will be saved!" << std::endl;
|
||||
}
|
||||
stbi_flip_vertically_on_write(transpose);
|
||||
|
||||
bool status = false;
|
||||
try
|
||||
{
|
||||
unsigned char* image = matrix.memptr();
|
||||
|
||||
if ("png" == Extension(filename))
|
||||
{
|
||||
status = stbi_write_png(filename.c_str(), tempWidth, tempHeight,
|
||||
tempChannels, image, tempWidth * tempChannels);
|
||||
}
|
||||
else if ("bmp" == Extension(filename))
|
||||
{
|
||||
status = stbi_write_bmp(filename.c_str(), tempWidth, tempHeight,
|
||||
tempChannels, image);
|
||||
}
|
||||
else if ("tga" == Extension(filename))
|
||||
{
|
||||
status = stbi_write_tga(filename.c_str(), tempWidth, tempHeight,
|
||||
tempChannels, image);
|
||||
}
|
||||
else if ("hdr" == Extension(filename))
|
||||
{
|
||||
status = stbi_write_hdr(filename.c_str(), tempWidth, tempHeight,
|
||||
tempChannels, reinterpret_cast<float*>(image));
|
||||
}
|
||||
else if ("jpg" == Extension(filename))
|
||||
{
|
||||
status = stbi_write_jpg(filename.c_str(), tempWidth, tempHeight,
|
||||
tempChannels, image, tempQuality);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
Timer::Stop("saving_image");
|
||||
if (fatal)
|
||||
Log::Fatal << e.what() << std::endl;
|
||||
Log::Warn << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
Timer::Stop("saving_image");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Image saving API for multiple files.
|
||||
template<typename eT>
|
||||
bool Save(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal,
|
||||
const bool transpose)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Files vector is empty." << std::endl;
|
||||
|
||||
throw std::runtime_error(oss.str());
|
||||
return false;
|
||||
}
|
||||
// We transpose by default. So, un-transpose if necessary.
|
||||
if (!transpose)
|
||||
matrix = arma::trans(matrix);
|
||||
|
||||
arma::Mat<unsigned char> img;
|
||||
bool status = Save(files[0], img, info, fatal, transpose);
|
||||
|
||||
// Decide matrix dimension using the image height and width.
|
||||
matrix.set_size(info.Width() * info.Height() * info.Channels(), files.size());
|
||||
matrix.col(0) = img;
|
||||
|
||||
for (size_t i = 1; i < files.size() ; i++)
|
||||
{
|
||||
arma::Mat<unsigned char> colImg(matrix.colptr(i), matrix.n_rows, 1,
|
||||
false, true);
|
||||
status &= Save(files[i], colImg, info, fatal, transpose);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#else
|
||||
template<typename eT>
|
||||
bool Save(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true)
|
||||
{
|
||||
throw std::runtime_error("Save(): HAS_STB is not defined, "
|
||||
"so STB is not available and images cannot be saved!");
|
||||
}
|
||||
|
||||
template<typename eT>
|
||||
bool Save(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal = false,
|
||||
const bool transpose = true)
|
||||
{
|
||||
throw std::runtime_error("Save(): HAS_STB is not defined, "
|
||||
"so STB is not available and images cannot be saved!");
|
||||
}
|
||||
#endif // HAS_STB.
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Define the files we need to compile
|
||||
# Anything not in this list will not be compiled into mlpack.
|
||||
set(SOURCES
|
||||
min_max_scaler.hpp
|
||||
max_abs_scaler.hpp
|
||||
standard_scaler.hpp
|
||||
mean_normalization.hpp
|
||||
pca_whitening.hpp
|
||||
zca_whitening.hpp
|
||||
)
|
||||
|
||||
# Add directory name to sources.
|
||||
set(DIR_SRCS)
|
||||
foreach(file ${SOURCES})
|
||||
set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
|
||||
endforeach()
|
||||
# Append sources (with directory name) to list of all mlpack sources (used at
|
||||
# the parent scope).
|
||||
set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE)
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @file max_abs_scaler.hpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* MaxAbsScaler class to scale features.
|
||||
*
|
||||
* 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_MAX_ABS_SCALE_HPP
|
||||
#define MLPACK_CORE_DATA_MAX_ABS_SCALE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* A simple MaxAbs Scaler class.
|
||||
*
|
||||
* Given an input dataset this class helps you to scale each
|
||||
* feature by its maximum absolute value.
|
||||
*
|
||||
* \[z = x / max(abs(x))\]
|
||||
*
|
||||
* where max(abs(x)) is maximum absolute value of feature.
|
||||
*
|
||||
* @code
|
||||
* arma::mat input;
|
||||
* Load("train.csv", input);
|
||||
* arma::mat output;
|
||||
*
|
||||
* // Fit the features.
|
||||
* MaxAbsScaler scale;
|
||||
* scale.Fit(input)
|
||||
*
|
||||
* // Scale the features.
|
||||
* scale.Transform(input, output);
|
||||
*
|
||||
* // Retransform the input.
|
||||
* scale.InverseTransform(output, input);
|
||||
* @endcode
|
||||
*/
|
||||
class MaxAbsScaler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Function to fit features, to find out the min max and scale.
|
||||
*
|
||||
* @param input Dataset to fit.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Fit(const MatType& input)
|
||||
{
|
||||
itemMin = arma::min(input, 1);
|
||||
itemMax = arma::max(input, 1);
|
||||
scale = arma::max(arma::abs(itemMin), arma::abs(itemMax));
|
||||
// Handling zeros in scale vector.
|
||||
scale.for_each([](arma::vec::elem_type& val) { val =
|
||||
(val == 0) ? 1 : val; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to scale features.
|
||||
*
|
||||
* @param input Dataset to scale features.
|
||||
* @param output Output matrix with scaled features.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Transform(const MatType& input, MatType& output)
|
||||
{
|
||||
if (scale.is_empty())
|
||||
{
|
||||
throw std::runtime_error("Call Fit() before Transform(), please"
|
||||
" refer to the documentation.");
|
||||
}
|
||||
output.copy_size(input);
|
||||
output = input.each_col() / scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to retrieve original dataset.
|
||||
*
|
||||
* @param input Scaled dataset.
|
||||
* @param output Output matrix with original Dataset.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void InverseTransform(const MatType& input, MatType& output)
|
||||
{
|
||||
output.copy_size(input);
|
||||
output = input.each_col() % scale;
|
||||
}
|
||||
|
||||
//! Get the Min row vector.
|
||||
const arma::vec& ItemMin() const { return itemMin; }
|
||||
//! Get the Max row vector.
|
||||
const arma::vec& ItemMax() const { return itemMax; }
|
||||
//! Get the Scale row vector.
|
||||
const arma::vec& Scale() const { return scale; }
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMin);
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMax);
|
||||
ar & BOOST_SERIALIZATION_NVP(scale);
|
||||
}
|
||||
private:
|
||||
// Vector which holds minimum of each feature.
|
||||
arma::vec itemMin;
|
||||
// Vector which holds maximum of each feature.
|
||||
arma::vec itemMax;
|
||||
// Vector which is used to scale up each feature.
|
||||
arma::vec scale;
|
||||
}; // class MaxAbsScaler
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* @file mean_normalization.hpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* MeanNormalization class to scale features.
|
||||
*
|
||||
* 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_MEAN_NORMALIZATION_HPP
|
||||
#define MLPACK_CORE_DATA_MEAN_NORMALIZATION_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* A simple Mean Normalization class
|
||||
*
|
||||
* Given an input dataset this class helps you to normalize each
|
||||
* feature.
|
||||
*
|
||||
* \[z = x - average(x) / (max(x) - min(x))\]
|
||||
*
|
||||
* where x is an original value,z is the normalized value.
|
||||
*
|
||||
* @code
|
||||
* arma::mat input;
|
||||
* Load("train.csv", input);
|
||||
* arma::mat output;
|
||||
*
|
||||
* // Fit the features.
|
||||
* MeanNormalization scale;
|
||||
* scale.Fit(input)
|
||||
*
|
||||
* // Scale the features.
|
||||
* scale.Transform(input, output);
|
||||
*
|
||||
* // Retransform the input.
|
||||
* scale.InverseTransform(output, input);
|
||||
* @endcode
|
||||
*/
|
||||
class MeanNormalization
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Function to fit features, to find out the min max and scale.
|
||||
*
|
||||
* @param input Dataset to fit.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Fit(const MatType& input)
|
||||
{
|
||||
itemMean = arma::mean(input, 1);
|
||||
itemMin = arma::min(input, 1);
|
||||
itemMax = arma::max(input, 1);
|
||||
scale = itemMax - itemMin;
|
||||
// Handling zeros in scale vector.
|
||||
scale.for_each([](arma::vec::elem_type& val) { val =
|
||||
(val == 0) ? 1 : val; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to scale features.
|
||||
*
|
||||
* @param input Dataset to scale features.
|
||||
* @param output Output matrix with scaled features.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Transform(const MatType& input, MatType& output)
|
||||
{
|
||||
if (itemMean.is_empty() || scale.is_empty())
|
||||
{
|
||||
throw std::runtime_error("Call Fit() before Transform(), please"
|
||||
" refer to the documentation.");
|
||||
}
|
||||
output.copy_size(input);
|
||||
output = (input.each_col() - itemMean).each_col() / scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to retrieve original dataset.
|
||||
*
|
||||
* @param input Scaled dataset.
|
||||
* @param output Output matrix with original Dataset.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void InverseTransform(const MatType& input, MatType& output)
|
||||
{
|
||||
output.copy_size(input);
|
||||
output = (input.each_col() % scale).each_col() + itemMean;
|
||||
}
|
||||
|
||||
//! Get the Mean row vector.
|
||||
const arma::vec& ItemMean() const { return itemMean; }
|
||||
//! Get the Min row vector.
|
||||
const arma::vec& ItemMin() const { return itemMin; }
|
||||
//! Get the Max row vector.
|
||||
const arma::vec& ItemMax() const { return itemMax; }
|
||||
//! Get the Scale row vector.
|
||||
const arma::vec& Scale() const { return scale; }
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMin);
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMax);
|
||||
ar & BOOST_SERIALIZATION_NVP(scale);
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMean);
|
||||
}
|
||||
|
||||
private:
|
||||
// Vector which holds mean of each feature.
|
||||
arma::vec itemMean;
|
||||
// Vector which holds minimum of each feature.
|
||||
arma::vec itemMin;
|
||||
// Vector which holds maximum of each feature.
|
||||
arma::vec itemMax;
|
||||
// Vector which is used to scale up each feature.
|
||||
arma::vec scale;
|
||||
}; // class MeanNormalization
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* @file min_max_scaler.hpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* MinMaxScaler class to scale features.
|
||||
*
|
||||
* 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_SCALE_HPP
|
||||
#define MLPACK_CORE_DATA_SCALE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* A simple MinMax Scaler class
|
||||
*
|
||||
* Given an input dataset this class helps you to scale each
|
||||
* feature to a given range.
|
||||
*
|
||||
* \[z = scale * x + scaleMin - min(x) * scale\]
|
||||
* \[scale = (scaleMax - scaleMin) / (max(x) - min(x))\]
|
||||
*
|
||||
* where scaleMin, scaleMax = feature_range and min(x), max(x)
|
||||
* are the minimum and maximum value of x respectively.
|
||||
*
|
||||
* @code
|
||||
* arma::mat input;
|
||||
* Load("train.csv", input);
|
||||
* arma::mat output;
|
||||
*
|
||||
* // Fit the features.
|
||||
* MinMaxScaler scale;
|
||||
* scale.Fit(input)
|
||||
*
|
||||
* // Scale the features.
|
||||
* scale.Transform(input, output);
|
||||
*
|
||||
* // Retransform the input.
|
||||
* scale.InverseTransform(output, input);
|
||||
* @endcode
|
||||
*/
|
||||
class MinMaxScaler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param min Lower range of scaling.
|
||||
* @param max Upper range of scaling.
|
||||
*/
|
||||
MinMaxScaler(const double min = 0, const double max = 1)
|
||||
{
|
||||
scaleMin = min;
|
||||
scaleMax = max;
|
||||
// Ensure scaleMin is smaller than scaleMax.
|
||||
if (scaleMin > scaleMax)
|
||||
{
|
||||
throw std::runtime_error("Range is not appropriate");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to fit features, to find out the min max and scale.
|
||||
*
|
||||
* @param input Dataset to fit.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Fit(const MatType& input)
|
||||
{
|
||||
itemMin = arma::min(input, 1);
|
||||
itemMax = arma::max(input, 1);
|
||||
scale = itemMax - itemMin;
|
||||
// Handle zeros in scale vector.
|
||||
scale.for_each([](arma::vec::elem_type& val) { val =
|
||||
(val == 0) ? 1 : val; });
|
||||
scale = (scaleMax - scaleMin) / scale;
|
||||
scalerowmin.copy_size(itemMin);
|
||||
scalerowmin.fill(scaleMin);
|
||||
scalerowmin = scalerowmin - itemMin % scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to scale features.
|
||||
*
|
||||
* @param input Dataset to scale features.
|
||||
* @param output Output matrix with scaled features.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Transform(const MatType& input, MatType& output)
|
||||
{
|
||||
if (scalerowmin.is_empty() || scale.is_empty())
|
||||
{
|
||||
throw std::runtime_error("Call Fit() before Transform(), please"
|
||||
" refer to the documentation.");
|
||||
}
|
||||
output.copy_size(input);
|
||||
output = (input.each_col() % scale).each_col() + scalerowmin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to retrieve original dataset.
|
||||
*
|
||||
* @param input Scaled dataset.
|
||||
* @param output Output matrix with original Dataset.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void InverseTransform(const MatType& input, MatType& output)
|
||||
{
|
||||
output.copy_size(input);
|
||||
output = (input.each_col() - scalerowmin).each_col() / scale;
|
||||
}
|
||||
|
||||
//! Get the Min row vector.
|
||||
const arma::vec& ItemMin() const { return itemMin; }
|
||||
//! Get the Max row vector.
|
||||
const arma::vec& ItemMax() const { return itemMax; }
|
||||
//! Get the Scale row vector.
|
||||
const arma::vec& Scale() const { return scale; }
|
||||
//! Get the upper range parameter.
|
||||
double ScaleMax() const { return scaleMax; }
|
||||
//! Get the lower range parameter.
|
||||
double ScaleMin() const { return scaleMin; }
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMin);
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMax);
|
||||
ar & BOOST_SERIALIZATION_NVP(scale);
|
||||
ar & BOOST_SERIALIZATION_NVP(scaleMin);
|
||||
ar & BOOST_SERIALIZATION_NVP(scaleMax);
|
||||
ar & BOOST_SERIALIZATION_NVP(scalerowmin);
|
||||
}
|
||||
|
||||
private:
|
||||
// Vector which holds minimum of each feature.
|
||||
arma::vec itemMin;
|
||||
// Vector which holds maximum of each feature.
|
||||
arma::vec itemMax;
|
||||
// Scale vector which is used to scale up each feature.
|
||||
arma::vec scale;
|
||||
// Lower value for range.
|
||||
double scaleMin;
|
||||
// Upper value for range.
|
||||
double scaleMax;
|
||||
// Column vector of scalemin
|
||||
arma::vec scalerowmin;
|
||||
}; // class MinMaxScaler
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @file pca_whitening.hpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* Whitening scaling to scale features, Using PCA Whitening.
|
||||
*
|
||||
* 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_PCA_WHITENING_SCALE_HPP
|
||||
#define MLPACK_CORE_DATA_PCA_WHITENING_SCALE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/math/lin_alg.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* A simple PCAWhitening class.
|
||||
*
|
||||
* Whitens a matrix using the eigendecomposition of the covariance matrix.
|
||||
* Whitening means the covariance matrix of the result is the identity matrix.
|
||||
*
|
||||
* For whitening related formula and more info, check the link below.
|
||||
* http://ufldl.stanford.edu/tutorial/unsupervised/PCAWhitening/
|
||||
*
|
||||
* @code
|
||||
* arma::mat input;
|
||||
* Load("train.csv", input);
|
||||
* arma::mat output;
|
||||
*
|
||||
* // Fit the features.
|
||||
* PCAWhitening scale;
|
||||
* scale.Fit(input)
|
||||
*
|
||||
* // Scale the features.
|
||||
* scale.Transform(input, output);
|
||||
*
|
||||
* // Retransform the input.
|
||||
* scale.InverseTransform(output, input);
|
||||
* @endcode
|
||||
*/
|
||||
class PCAWhitening
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A constructor to set the regularization parameter.
|
||||
*
|
||||
* @param eps Regularization parameter.
|
||||
*/
|
||||
PCAWhitening(double eps = 0.00005)
|
||||
{
|
||||
epsilon = eps;
|
||||
// Ensure scaleMin is smaller than scaleMax.
|
||||
if (epsilon < 0)
|
||||
{
|
||||
throw std::runtime_error("Regularization parameter is not correct");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to fit features, to find out the min max and scale.
|
||||
*
|
||||
* @param input Dataset to fit.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Fit(const MatType& input)
|
||||
{
|
||||
itemMean = arma::mean(input, 1);
|
||||
// Get eigenvectors and eigenvalues of covariance of input matrix.
|
||||
eig_sym(eigenValues, eigenVectors, mlpack::math::ColumnCovariance(
|
||||
input.each_col() - itemMean));
|
||||
eigenValues += epsilon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for PCA whitening.
|
||||
*
|
||||
* @param input Dataset to scale features.
|
||||
* @param output Output matrix with whitened features.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Transform(const MatType& input, MatType& output)
|
||||
{
|
||||
if (eigenValues.is_empty() || eigenVectors.is_empty())
|
||||
{
|
||||
throw std::runtime_error("Call Fit() before Transform(), please"
|
||||
" refer to the documentation.");
|
||||
}
|
||||
output.copy_size(input);
|
||||
output = (input.each_col() - itemMean);
|
||||
output = arma::diagmat(1.0 / (arma::sqrt(eigenValues))) * eigenVectors.t()
|
||||
* output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to retrieve original dataset.
|
||||
*
|
||||
* @param input Scaled dataset.
|
||||
* @param output Output matrix with original Dataset.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void InverseTransform(const MatType& input, MatType& output)
|
||||
{
|
||||
output = arma::diagmat(arma::sqrt(eigenValues)) * inv(eigenVectors.t())
|
||||
* input;
|
||||
output = (output.each_col() + itemMean);
|
||||
}
|
||||
|
||||
//! Get the mean row vector.
|
||||
const arma::vec& ItemMean() const { return itemMean; }
|
||||
//! Get the eigenvalues vector.
|
||||
const arma::vec& EigenValues() const { return eigenValues; }
|
||||
//! Get the eigenvector.
|
||||
const arma::mat& EigenVectors() const { return eigenVectors; }
|
||||
//! Get the regularization parameter.
|
||||
const double& Epsilon() const { return epsilon; }
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(eigenValues);
|
||||
ar & BOOST_SERIALIZATION_NVP(eigenVectors);
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMean);
|
||||
ar & BOOST_SERIALIZATION_NVP(epsilon);
|
||||
}
|
||||
|
||||
private:
|
||||
// Vector which holds mean of each feature.
|
||||
arma::vec itemMean;
|
||||
// Mat which hold the eigenvectors.
|
||||
arma::mat eigenVectors;
|
||||
// Regularization Paramter.
|
||||
double epsilon;
|
||||
// Vector which hold the eigenvalues.
|
||||
arma::vec eigenValues;
|
||||
}; // class PCAWhitening
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @file standard_scaler.hpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* StandardScaler class to scale features.
|
||||
*
|
||||
* 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_STANDARD_SCALE_HPP
|
||||
#define MLPACK_CORE_DATA_STANDARD_SCALE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* A simple Standard Scaler class
|
||||
*
|
||||
* Given an input dataset this class helps you to Standardize features
|
||||
* by removing the mean and scaling to unit variance.
|
||||
*
|
||||
* \[z = (x - u) / s\]
|
||||
*
|
||||
* where u is the mean of the training samples and s is the standard deviation
|
||||
* of the training samples.
|
||||
*
|
||||
* @code
|
||||
* arma::mat input;
|
||||
* Load("train.csv", input);
|
||||
* arma::mat output;
|
||||
*
|
||||
* // Fit the features.
|
||||
* StandardScaler scale;
|
||||
* scale.Fit(input)
|
||||
*
|
||||
* // Scale the features.
|
||||
* scale.Transform(input, output);
|
||||
*
|
||||
* // Retransform the input.
|
||||
* scale.InverseTransform(output, input);
|
||||
* @endcode
|
||||
*/
|
||||
class StandardScaler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Function to fit features, to find out the min max and scale.
|
||||
*
|
||||
* @param input Dataset to fit.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Fit(const MatType& input)
|
||||
{
|
||||
itemMean = arma::mean(input, 1);
|
||||
itemStdDev = arma::stddev(input, 1, 1);
|
||||
// Handle zeros in scale vector.
|
||||
itemStdDev.for_each([](arma::vec::elem_type& val) { val =
|
||||
(val == 0) ? 1 : val; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to scale features.
|
||||
*
|
||||
* @param input Dataset to scale features.
|
||||
* @param output Output matrix with scaled features.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Transform(const MatType& input, MatType& output)
|
||||
{
|
||||
if (itemMean.is_empty() || itemStdDev.is_empty())
|
||||
{
|
||||
throw std::runtime_error("Call Fit() before Transform(), please"
|
||||
" refer to the documentation.");
|
||||
}
|
||||
output.copy_size(input);
|
||||
output = (input.each_col() - itemMean).each_col() / itemStdDev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to retrieve original dataset.
|
||||
*
|
||||
* @param input Scaled dataset.
|
||||
* @param output Output matrix with original Dataset.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void InverseTransform(const MatType& input, MatType& output)
|
||||
{
|
||||
output.copy_size(input);
|
||||
output = (input.each_col() % itemStdDev).each_col() + itemMean;
|
||||
}
|
||||
|
||||
//! Get the mean row vector.
|
||||
const arma::vec& ItemMean() const { return itemMean; }
|
||||
//! Get the standard deviation row vector.
|
||||
const arma::vec& ItemStdDev() const { return itemStdDev; }
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(itemMean);
|
||||
ar & BOOST_SERIALIZATION_NVP(itemStdDev);
|
||||
}
|
||||
|
||||
private:
|
||||
// Vector which holds mean of each feature.
|
||||
arma::vec itemMean;
|
||||
// Vector which holds standard devation of each feature.
|
||||
arma::vec itemStdDev;
|
||||
}; // class StandardScaler
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @file zca_whitening.hpp
|
||||
* @author Jeffin Sam
|
||||
*
|
||||
* Whitening scaling to scale features, Using ZCA Whitening.
|
||||
*
|
||||
* 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_ZCA_WHITENING_SCALE_HPP
|
||||
#define MLPACK_CORE_DATA_ZCA_WHITENING_SCALE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/math/lin_alg.hpp>
|
||||
#include <mlpack/core/data/scaler_methods/pca_whitening.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
/**
|
||||
* A simple ZCAWhitening class.
|
||||
*
|
||||
* Whitens a matrix using the eigendecomposition of the covariance matrix.
|
||||
* Whitening means the covariance matrix of the result is the identity matrix.
|
||||
*
|
||||
* For whitening related formula and more info, check the link below.
|
||||
* http://ufldl.stanford.edu/tutorial/unsupervised/PCAWhitening/
|
||||
*
|
||||
* @code
|
||||
* arma::mat input;
|
||||
* Load("train.csv", input);
|
||||
* arma::mat output;
|
||||
*
|
||||
* // Fit the features.
|
||||
* ZCAWhitening scale;
|
||||
* scale.Fit(input)
|
||||
*
|
||||
* // Scale the features.
|
||||
* scale.Transform(input, output);
|
||||
*
|
||||
* // Retransform the input.
|
||||
* scale.InverseTransform(output, input);
|
||||
* @endcode
|
||||
*/
|
||||
class ZCAWhitening
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A constructor to set the regularization parameter.
|
||||
*
|
||||
* @param eps Regularization parameter.
|
||||
*/
|
||||
ZCAWhitening(double eps = 0.00005)
|
||||
{
|
||||
pca = new data::PCAWhitening(eps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to fit features, to find out the min max and scale.
|
||||
*
|
||||
* @param input Dataset to fit.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Fit(const MatType& input)
|
||||
{
|
||||
pca->Fit(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for ZCA whitening.
|
||||
*
|
||||
* @param input Dataset to scale features.
|
||||
* @param output Output matrix with whitened features.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void Transform(const MatType& input, MatType& output)
|
||||
{
|
||||
pca->Transform(input, output);
|
||||
output = pca->EigenVectors() * output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to retrieve original dataset.
|
||||
*
|
||||
* @param input Scaled dataset.
|
||||
* @param output Output matrix with original Dataset.
|
||||
*/
|
||||
template<typename MatType>
|
||||
void InverseTransform(const MatType& input, MatType& output)
|
||||
{
|
||||
output = inv(pca->EigenVectors()) * arma::diagmat(arma::sqrt(
|
||||
pca->EigenValues())) * inv(pca->EigenVectors().t()) * input;
|
||||
output = (output.each_col() + pca->ItemMean());
|
||||
}
|
||||
|
||||
//! Get the mean row vector.
|
||||
const arma::vec& ItemMean() const { return pca->ItemMean(); }
|
||||
//! Get the eigenvalues vector.
|
||||
const arma::vec& EigenValues() const { return pca->EigenValues(); }
|
||||
//! Get the eigenvector.
|
||||
const arma::mat& EigenVectors() const { return pca->EigenVectors(); }
|
||||
//! Get the regularization parameter.
|
||||
double Epsilon() const { return pca->Epsilon(); }
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(pca);
|
||||
}
|
||||
|
||||
private:
|
||||
// A pointer to PcaWhitening Class.
|
||||
PCAWhitening* pca;
|
||||
}; // class ZCAWhitening
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -168,6 +168,12 @@ class GaussianDistribution
|
||||
|
||||
void Covariance(arma::mat&& covariance);
|
||||
|
||||
//! Return the invCov.
|
||||
const arma::mat& InvCov() const { return invCov; }
|
||||
|
||||
//! Return the logDetCov.
|
||||
double LogDetCov() const { return logDetCov; }
|
||||
|
||||
/**
|
||||
* Serialize the distribution.
|
||||
*/
|
||||
|
||||
@@ -63,6 +63,13 @@ inline void FixedRandomSeed()
|
||||
srand((unsigned int) seed);
|
||||
arma::arma_rng::set_seed(seed);
|
||||
}
|
||||
|
||||
inline void CustomRandomSeed(const size_t seed)
|
||||
{
|
||||
randGen.seed((uint32_t) seed);
|
||||
srand((unsigned int) seed);
|
||||
arma::arma_rng::set_seed(seed);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,7 +61,7 @@ typename VecTypeA::elem_type LMetric<2, true>::Evaluate(
|
||||
const VecTypeA& a,
|
||||
const VecTypeB& b)
|
||||
{
|
||||
return sqrt(arma::accu(square(a - b)));
|
||||
return arma::norm(a - b, 2);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
||||
@@ -56,6 +56,18 @@ DualTreeTraverser<RuleType>::Traverse(
|
||||
// Store the current traversal info.
|
||||
traversalInfo = rule.TraversalInfo();
|
||||
|
||||
// If both nodes are root nodes, just score them.
|
||||
if (queryNode.Parent() == NULL && referenceNode.Parent() == NULL)
|
||||
{
|
||||
const double rootScore = rule.Score(queryNode, referenceNode);
|
||||
// If root score is DBL_MAX, don't recurse.
|
||||
if (rootScore == DBL_MAX)
|
||||
{
|
||||
++numPrunes;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If both are leaves, we must evaluate the base case.
|
||||
if (queryNode.IsLeaf() && referenceNode.IsLeaf())
|
||||
{
|
||||
|
||||
@@ -57,6 +57,18 @@ SingleTreeTraverser<RuleType>::Traverse(
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's the root node, just score it.
|
||||
if (referenceNode.Parent() == NULL)
|
||||
{
|
||||
const double rootScore = rule.Score(queryIndex, referenceNode);
|
||||
// If root score is DBL_MAX, don't recurse into that node.
|
||||
if (rootScore == DBL_MAX)
|
||||
{
|
||||
++numPrunes;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If either score is DBL_MAX, we do not recurse into that node.
|
||||
double leftScore = rule.Score(queryIndex, *referenceNode.Left());
|
||||
double rightScore = rule.Score(queryIndex, *referenceNode.Right());
|
||||
|
||||
@@ -238,6 +238,20 @@ class CoverTree
|
||||
*/
|
||||
CoverTree(CoverTree&& other);
|
||||
|
||||
/**
|
||||
* Copy the given Cover Tree.
|
||||
*
|
||||
* @param other The tree to be copied.
|
||||
*/
|
||||
CoverTree& operator=(const CoverTree& other);
|
||||
|
||||
/**
|
||||
* Take ownership of the given Cover Tree.
|
||||
*
|
||||
* @param other The tree to take ownership of.
|
||||
*/
|
||||
CoverTree& operator=(CoverTree&& other);
|
||||
|
||||
/**
|
||||
* Create a cover tree from a boost::serialization archive.
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,18 @@
|
||||
namespace mlpack {
|
||||
namespace tree {
|
||||
|
||||
// Build the statistics, bottom-up.
|
||||
template<typename TreeType, typename StatisticType>
|
||||
void BuildStatistics(TreeType* node)
|
||||
{
|
||||
// Recurse first.
|
||||
for (size_t i = 0; i < node->NumChildren(); ++i)
|
||||
BuildStatistics<TreeType, StatisticType>(&node->Child(i));
|
||||
|
||||
// Now build the statistic.
|
||||
node->Stat() = StatisticType(*node);
|
||||
}
|
||||
|
||||
// Create the cover tree.
|
||||
template<
|
||||
typename MetricType,
|
||||
@@ -88,9 +100,8 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
{
|
||||
children.push_back(&(old->Child(i)));
|
||||
|
||||
// Set its parent correctly, and rebuild the statistic.
|
||||
// Set its parent correctly.
|
||||
old->Child(i).Parent() = this;
|
||||
old->Child(i).Stat() = StatisticType(old->Child(i));
|
||||
}
|
||||
|
||||
// Remove all the children so they don't get erased.
|
||||
@@ -104,14 +115,19 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
// Use the furthest descendant distance to determine the scale of the root
|
||||
// node.
|
||||
if (furthestDescendantDistance == 0.0)
|
||||
// node. Note that if the root is a leaf, we can have scale INT_MIN, but if
|
||||
// it *isn't* a leaf, we need to mark the scale as one higher than INT_MIN, so
|
||||
// that the recursions don't fail.
|
||||
if (furthestDescendantDistance == 0.0 && dataset.n_cols == 1)
|
||||
scale = INT_MIN;
|
||||
else if (furthestDescendantDistance == 0.0)
|
||||
scale = INT_MIN + 1;
|
||||
else
|
||||
scale = (int) ceil(log(furthestDescendantDistance) / log(base));
|
||||
|
||||
// Initialize statistic.
|
||||
stat = StatisticType(*this);
|
||||
// Initialize statistics recursively after the entire tree construction is
|
||||
// complete.
|
||||
BuildStatistics<CoverTree, StatisticType>(this);
|
||||
|
||||
Log::Info << distanceComps << " distance computations during tree "
|
||||
<< "construction." << std::endl;
|
||||
@@ -181,8 +197,6 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
|
||||
// Set its parent correctly.
|
||||
old->Child(i).Parent() = this;
|
||||
// Rebuild the statistic.
|
||||
old->Child(i).Stat() = StatisticType(old->Child(i));
|
||||
}
|
||||
|
||||
// Remove all the children so they don't get erased.
|
||||
@@ -196,14 +210,19 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
// Use the furthest descendant distance to determine the scale of the root
|
||||
// node.
|
||||
if (furthestDescendantDistance == 0.0)
|
||||
// node. Note that if the root is a leaf, we can have scale INT_MIN, but if
|
||||
// it *isn't* a leaf, we need to mark the scale as one higher than INT_MIN, so
|
||||
// that the recursions don't fail.
|
||||
if (furthestDescendantDistance == 0.0 && dataset.n_cols == 1)
|
||||
scale = INT_MIN;
|
||||
else if (furthestDescendantDistance == 0.0)
|
||||
scale = INT_MIN + 1;
|
||||
else
|
||||
scale = (int) ceil(log(furthestDescendantDistance) / log(base));
|
||||
|
||||
// Initialize statistic.
|
||||
stat = StatisticType(*this);
|
||||
// Initialize statistics recursively after the entire tree construction is
|
||||
// complete.
|
||||
BuildStatistics<CoverTree, StatisticType>(this);
|
||||
|
||||
Log::Info << distanceComps << " distance computations during tree "
|
||||
<< "construction." << std::endl;
|
||||
@@ -272,9 +291,8 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
{
|
||||
children.push_back(&(old->Child(i)));
|
||||
|
||||
// Set its parent correctly, and rebuild the statistic.
|
||||
// Set its parent correctly.
|
||||
old->Child(i).Parent() = this;
|
||||
old->Child(i).Stat() = StatisticType(old->Child(i));
|
||||
}
|
||||
|
||||
// Remove all the children so they don't get erased.
|
||||
@@ -288,14 +306,19 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
// Use the furthest descendant distance to determine the scale of the root
|
||||
// node.
|
||||
if (furthestDescendantDistance == 0.0)
|
||||
// node. Note that if the root is a leaf, we can have scale INT_MIN, but if
|
||||
// it *isn't* a leaf, we need to mark the scale as one higher than INT_MIN, so
|
||||
// that the recursions don't fail.
|
||||
if (furthestDescendantDistance == 0.0 && dataset->n_cols == 1)
|
||||
scale = INT_MIN;
|
||||
else if (furthestDescendantDistance == 0.0)
|
||||
scale = INT_MIN + 1;
|
||||
else
|
||||
scale = (int) ceil(log(furthestDescendantDistance) / log(base));
|
||||
|
||||
// Initialize statistic.
|
||||
stat = StatisticType(*this);
|
||||
// Initialize statistics recursively after the entire tree construction is
|
||||
// complete.
|
||||
BuildStatistics<CoverTree, StatisticType>(this);
|
||||
|
||||
Log::Info << distanceComps << " distance computations during tree "
|
||||
<< "construction." << std::endl;
|
||||
@@ -363,9 +386,8 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
{
|
||||
children.push_back(&(old->Child(i)));
|
||||
|
||||
// Set its parent correctly, and rebuild the statistic.
|
||||
// Set its parent correctly.
|
||||
old->Child(i).Parent() = this;
|
||||
old->Child(i).Stat() = StatisticType(old->Child(i));
|
||||
}
|
||||
|
||||
// Remove all the children so they don't get erased.
|
||||
@@ -379,14 +401,19 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
// Use the furthest descendant distance to determine the scale of the root
|
||||
// node.
|
||||
if (furthestDescendantDistance == 0.0)
|
||||
// node. Note that if the root is a leaf, we can have scale INT_MIN, but if
|
||||
// it *isn't* a leaf, we need to mark the scale as one higher than INT_MIN, so
|
||||
// that the recursions don't fail.
|
||||
if (furthestDescendantDistance == 0.0 && dataset->n_cols == 1)
|
||||
scale = INT_MIN;
|
||||
else if (furthestDescendantDistance == 0.0)
|
||||
scale = INT_MIN + 1;
|
||||
else
|
||||
scale = (int) ceil(log(furthestDescendantDistance) / log(base));
|
||||
|
||||
// Initialize statistic.
|
||||
stat = StatisticType(*this);
|
||||
// Initialize statistics recursively after the entire tree construction is
|
||||
// complete.
|
||||
BuildStatistics<CoverTree, StatisticType>(this);
|
||||
|
||||
Log::Info << distanceComps << " distance computations during tree "
|
||||
<< "construction." << std::endl;
|
||||
@@ -429,15 +456,11 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
{
|
||||
this->scale = INT_MIN;
|
||||
numDescendants = 1;
|
||||
stat = StatisticType(*this);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, create the children.
|
||||
CreateChildren(indices, distances, nearSetSize, farSetSize, usedSetSize);
|
||||
|
||||
// Initialize statistic.
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
// Manually create a cover tree node.
|
||||
@@ -472,11 +495,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
// If necessary, create a local metric.
|
||||
if (localMetric)
|
||||
this->metric = new MetricType();
|
||||
|
||||
// Initialize the statistic.
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
// Copy Constructor.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename StatisticType,
|
||||
@@ -495,9 +516,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(other.parent),
|
||||
parentDistance(other.parentDistance),
|
||||
furthestDescendantDistance(other.furthestDescendantDistance),
|
||||
localMetric(false),
|
||||
localMetric(other.localMetric),
|
||||
localDataset(other.parent == NULL && other.localDataset),
|
||||
metric(other.metric),
|
||||
metric((other.localMetric ? new MetricType() : other.metric)),
|
||||
distanceComps(0)
|
||||
{
|
||||
// Copy each child by hand.
|
||||
@@ -527,6 +548,76 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
}
|
||||
|
||||
// Copy Assignment.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>&
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
operator=(const CoverTree& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
// Freeing memory that will not be used anymore.
|
||||
if (localDataset)
|
||||
delete dataset;
|
||||
|
||||
if (localMetric)
|
||||
delete metric;
|
||||
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
delete children[i];
|
||||
children.clear();
|
||||
|
||||
dataset = ((other.parent == NULL && other.localDataset) ?
|
||||
new MatType(*other.dataset) : other.dataset);
|
||||
point = other.point;
|
||||
scale = other.scale;
|
||||
base = other.base;
|
||||
stat = other.stat;
|
||||
numDescendants = other.numDescendants;
|
||||
parent = other.parent;
|
||||
parentDistance = other.parentDistance;
|
||||
furthestDescendantDistance = other.furthestDescendantDistance;
|
||||
localMetric = other.localMetric;
|
||||
localDataset = (other.parent == NULL && other.localDataset);
|
||||
metric = (other.localMetric ? new MetricType() : other.metric);
|
||||
distanceComps = 0;
|
||||
|
||||
// Copy each child by hand.
|
||||
for (size_t i = 0; i < other.NumChildren(); ++i)
|
||||
{
|
||||
children.push_back(new CoverTree(other.Child(i)));
|
||||
children[i]->Parent() = this;
|
||||
}
|
||||
|
||||
// Propagate matrix, but only if we are the root.
|
||||
if (parent == NULL && localDataset)
|
||||
{
|
||||
std::queue<CoverTree*> queue;
|
||||
|
||||
for (size_t i = 0; i < NumChildren(); ++i)
|
||||
queue.push(children[i]);
|
||||
|
||||
while (!queue.empty())
|
||||
{
|
||||
CoverTree* node = queue.front();
|
||||
queue.pop();
|
||||
|
||||
node->dataset = dataset;
|
||||
for (size_t i = 0; i < node->NumChildren(); ++i)
|
||||
queue.push(node->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move Constructor.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename StatisticType,
|
||||
@@ -567,6 +658,64 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
other.metric = NULL;
|
||||
}
|
||||
|
||||
// Move Assignment.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>&
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
operator=(CoverTree&& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
// Freeing memory that will not be used anymore.
|
||||
if (localDataset)
|
||||
delete dataset;
|
||||
|
||||
if (localMetric)
|
||||
delete metric;
|
||||
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
delete children[i];
|
||||
|
||||
dataset = other.dataset;
|
||||
point = other.point;
|
||||
children = std::move(other.children);
|
||||
scale = other.scale;
|
||||
base = other.base;
|
||||
stat = std::move(other.stat);
|
||||
numDescendants = other.numDescendants;
|
||||
parent = other.parent;
|
||||
parentDistance = other.parentDistance;
|
||||
furthestDescendantDistance = other.furthestDescendantDistance;
|
||||
localMetric = other.localMetric;
|
||||
localDataset = other.localDataset;
|
||||
metric = other.metric;
|
||||
distanceComps = other.distanceComps;
|
||||
|
||||
// Set proper parent pointer.
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
children[i]->Parent() = this;
|
||||
|
||||
other.dataset = NULL;
|
||||
other.point = 0;
|
||||
other.scale = INT_MIN;
|
||||
other.base = 0;
|
||||
other.numDescendants = 0;
|
||||
other.parent = NULL;
|
||||
other.parentDistance = 0;
|
||||
other.furthestDescendantDistance = 0;
|
||||
other.localMetric = false;
|
||||
other.localDataset = false;
|
||||
other.metric = NULL;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Construct from a boost::serialization archive.
|
||||
template<
|
||||
typename MetricType,
|
||||
@@ -907,8 +1056,8 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
other.Dataset().col(other.Point()));
|
||||
|
||||
math::RangeType<ElemType> result;
|
||||
result.Lo() = distance - furthestDescendantDistance -
|
||||
other.FurthestDescendantDistance();
|
||||
result.Lo() = std::max(distance - furthestDescendantDistance -
|
||||
other.FurthestDescendantDistance(), 0.0);
|
||||
result.Hi() = distance + furthestDescendantDistance +
|
||||
other.FurthestDescendantDistance();
|
||||
|
||||
@@ -930,8 +1079,8 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
const ElemType distance) const
|
||||
{
|
||||
math::RangeType<ElemType> result;
|
||||
result.Lo() = distance - furthestDescendantDistance -
|
||||
other.FurthestDescendantDistance();
|
||||
result.Lo() = std::max(distance - furthestDescendantDistance -
|
||||
other.FurthestDescendantDistance(), 0.0);
|
||||
result.Hi() = distance + furthestDescendantDistance +
|
||||
other.FurthestDescendantDistance();
|
||||
|
||||
@@ -952,8 +1101,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
{
|
||||
const ElemType distance = metric->Evaluate(dataset->col(point), other);
|
||||
|
||||
return math::RangeType<ElemType>(distance - furthestDescendantDistance,
|
||||
distance + furthestDescendantDistance);
|
||||
return math::RangeType<ElemType>(
|
||||
std::max(distance - furthestDescendantDistance, 0.0),
|
||||
distance + furthestDescendantDistance);
|
||||
}
|
||||
|
||||
//! Return the minimum and maximum distance to another point given that the
|
||||
@@ -970,8 +1120,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
RangeDistance(const arma::vec& /* other */,
|
||||
const ElemType distance) const
|
||||
{
|
||||
return math::RangeType<ElemType>(distance - furthestDescendantDistance,
|
||||
distance + furthestDescendantDistance);
|
||||
return math::RangeType<ElemType>(
|
||||
std::max(distance - furthestDescendantDistance, 0.0),
|
||||
distance + furthestDescendantDistance);
|
||||
}
|
||||
|
||||
//! For a newly initialized node, create children using the near and far set.
|
||||
@@ -1526,11 +1677,10 @@ inline void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
// Now take its child.
|
||||
children.push_back(&(old->Child(0)));
|
||||
|
||||
// Set its parent and parameters correctly, and rebuild the statistic.
|
||||
// Set its parent and parameters correctly.
|
||||
old->Child(0).Parent() = this;
|
||||
old->Child(0).ParentDistance() = old->ParentDistance();
|
||||
old->Child(0).DistanceComps() = old->DistanceComps();
|
||||
old->Child(0).Stat() = StatisticType(old->Child(0));
|
||||
|
||||
// Remove its child (so it doesn't delete it).
|
||||
old->Children().erase(old->Children().begin() + old->Children().size() - 1);
|
||||
|
||||
@@ -42,6 +42,18 @@ void Octree<MetricType, StatisticType, MatType>::DualTreeTraverser<RuleType>::
|
||||
// Store the current traversal info.
|
||||
traversalInfo = rule.TraversalInfo();
|
||||
|
||||
// If both nodes are root nodes, just score them.
|
||||
if (queryNode.Parent() == NULL && referenceNode.Parent() == NULL)
|
||||
{
|
||||
const double rootScore = rule.Score(queryNode, referenceNode);
|
||||
// If root score is DBL_MAX, don't recurse.
|
||||
if (rootScore == DBL_MAX)
|
||||
{
|
||||
++numPrunes;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (queryNode.IsLeaf() && referenceNode.IsLeaf())
|
||||
{
|
||||
const size_t begin = queryNode.Point(0);
|
||||
|
||||
@@ -22,7 +22,8 @@ template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename RuleType>
|
||||
Octree<MetricType, StatisticType, MatType>::SingleTreeTraverser<RuleType>::
|
||||
SingleTreeTraverser(RuleType& rule) :
|
||||
rule(rule)
|
||||
rule(rule),
|
||||
numPrunes(0)
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
@@ -42,6 +43,18 @@ void Octree<MetricType, StatisticType, MatType>::SingleTreeTraverser<RuleType>::
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's the root node, just score it.
|
||||
if (referenceNode.Parent() == NULL)
|
||||
{
|
||||
const double rootScore = rule.Score(queryIndex, referenceNode);
|
||||
// If root score is DBL_MAX, don't recurse into that node.
|
||||
if (rootScore == DBL_MAX)
|
||||
{
|
||||
++numPrunes;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Do a prioritized recursion, by scoring all candidates and then sorting
|
||||
// them.
|
||||
arma::vec scores(referenceNode.NumChildren());
|
||||
|
||||
@@ -181,10 +181,24 @@ class RectangleTree
|
||||
/**
|
||||
* Create a rectangle tree by moving the other tree.
|
||||
*
|
||||
* @param other The tree to be copied.
|
||||
* @param other The tree to be moved.
|
||||
*/
|
||||
RectangleTree(RectangleTree&& other);
|
||||
|
||||
/**
|
||||
* Copy the given rectangle tree.
|
||||
*
|
||||
* @param other The tree to be copied.
|
||||
*/
|
||||
RectangleTree& operator=(const RectangleTree& other);
|
||||
|
||||
/**
|
||||
* Take ownership of the given rectangle tree.
|
||||
*
|
||||
* @param other The tree to take ownership of.
|
||||
*/
|
||||
RectangleTree& operator=(RectangleTree&& other);
|
||||
|
||||
/**
|
||||
* Construct the tree from a boost::serialization archive.
|
||||
*/
|
||||
@@ -542,6 +556,13 @@ class RectangleTree
|
||||
*/
|
||||
void SplitNode(std::vector<bool>& relevels);
|
||||
|
||||
/**
|
||||
* Builds statistics for a node and all its descendants in a bottom-up way.
|
||||
*
|
||||
* @param node Node for which statistics will be built.
|
||||
*/
|
||||
void BuildStatistics(RectangleTree* node);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* A default constructor. This is meant to only be used with
|
||||
|
||||
@@ -21,6 +21,25 @@
|
||||
namespace mlpack {
|
||||
namespace tree {
|
||||
|
||||
// Build the statistics, bottom-up.
|
||||
template<typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
BuildStatistics(RectangleTree* node)
|
||||
{
|
||||
// Recurse first.
|
||||
for (size_t i = 0; i < node->NumChildren(); ++i)
|
||||
BuildStatistics(&node->Child(i));
|
||||
|
||||
// Now build the statistic.
|
||||
node->Stat() = StatisticType(*node);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
@@ -52,13 +71,14 @@ RectangleTree(const MatType& data,
|
||||
points(maxLeafSize + 1), // Add one to make splitting the node simpler.
|
||||
auxiliaryInfo(this)
|
||||
{
|
||||
stat = StatisticType(*this);
|
||||
|
||||
// For now, just insert the points in order.
|
||||
RectangleTree* root = this;
|
||||
|
||||
for (size_t i = firstDataIndex; i < data.n_cols; i++)
|
||||
root->InsertPoint(i);
|
||||
|
||||
// Initialize statistic recursively after tree construction is complete.
|
||||
BuildStatistics(this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
@@ -92,13 +112,14 @@ RectangleTree(MatType&& data,
|
||||
points(maxLeafSize + 1), // Add one to make splitting the node simpler.
|
||||
auxiliaryInfo(this)
|
||||
{
|
||||
stat = StatisticType(*this);
|
||||
|
||||
// For now, just insert the points in order.
|
||||
RectangleTree* root = this;
|
||||
|
||||
for (size_t i = firstDataIndex; i < dataset->n_cols; i++)
|
||||
root->InsertPoint(i);
|
||||
|
||||
// Initialize statistic recursively after tree construction is complete.
|
||||
BuildStatistics(this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
@@ -131,7 +152,8 @@ RectangleTree(
|
||||
points(maxLeafSize + 1), // Add one to make splitting the node simpler.
|
||||
auxiliaryInfo(this)
|
||||
{
|
||||
stat = StatisticType(*this);
|
||||
// Initialize statistic.
|
||||
BuildStatistics(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,6 +256,96 @@ RectangleTree(RectangleTree&& other) :
|
||||
other.ownsDataset = false;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>&
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
operator=(const RectangleTree& other)
|
||||
{
|
||||
// Return if it's the same tree.
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
for (size_t i = 0; i < numChildren; i++)
|
||||
delete children[i];
|
||||
|
||||
if (ownsDataset)
|
||||
delete dataset;
|
||||
|
||||
maxNumChildren = other.MaxNumChildren();
|
||||
minNumChildren = other.MinNumChildren();
|
||||
numChildren = other.NumChildren();
|
||||
children.resize(maxNumChildren + 1, NULL);
|
||||
parent = NULL;
|
||||
begin = other.Begin();
|
||||
count = other.Count();
|
||||
numDescendants = other.numDescendants;
|
||||
maxLeafSize = other.MaxLeafSize();
|
||||
minLeafSize = other.MinLeafSize();
|
||||
bound = other.bound;
|
||||
parentDistance = other.ParentDistance();
|
||||
dataset = new MatType(*other.dataset);
|
||||
ownsDataset = true;
|
||||
points = other.points;
|
||||
auxiliaryInfo = AuxiliaryInfoType(other.auxiliaryInfo, this, true);
|
||||
|
||||
if (numChildren > 0)
|
||||
{
|
||||
for (size_t i = 0; i < numChildren; i++)
|
||||
children[i] = new RectangleTree(other.Child(i), true, this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>&
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
operator=(RectangleTree&& other)
|
||||
{
|
||||
// Return if it's the same tree.
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
for (size_t i = 0; i < numChildren; i++)
|
||||
delete children[i];
|
||||
|
||||
if (ownsDataset)
|
||||
delete dataset;
|
||||
|
||||
maxNumChildren = other.MaxNumChildren();
|
||||
minNumChildren = other.MinNumChildren();
|
||||
numChildren = other.NumChildren();
|
||||
children = std::move(other.children);
|
||||
parent = other.Parent();
|
||||
begin = other.Begin();
|
||||
count = other.Count();
|
||||
numDescendants = other.numDescendants;
|
||||
maxLeafSize = other.MaxLeafSize();
|
||||
minLeafSize = other.MinLeafSize();
|
||||
bound = std::move(other.bound);
|
||||
parentDistance = other.ParentDistance();
|
||||
dataset = other.dataset;
|
||||
ownsDataset = other.ownsDataset;
|
||||
points = std::move(other.points);
|
||||
auxiliaryInfo = std::move(other.auxiliaryInfo);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the tree from a boost::serialization archive.
|
||||
*/
|
||||
|
||||
@@ -209,6 +209,20 @@ class SpillTree
|
||||
*/
|
||||
SpillTree(SpillTree&& other);
|
||||
|
||||
/**
|
||||
* Copy the given Spill Tree.
|
||||
*
|
||||
* @param other The tree to be copied.
|
||||
*/
|
||||
SpillTree& operator=(const SpillTree& other);
|
||||
|
||||
/**
|
||||
* Take ownership of the given Spill Tree.
|
||||
*
|
||||
* @param other The tree to take ownership of.
|
||||
*/
|
||||
SpillTree& operator=(SpillTree&& other);
|
||||
|
||||
/**
|
||||
* Initialize the tree from a boost::serialization archive.
|
||||
*
|
||||
|
||||
@@ -192,6 +192,88 @@ SpillTree(const SpillTree& other) :
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy Assignment.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
operator=(const SpillTree& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
// Freeing memory that will not be used anymore.
|
||||
if (localDataset)
|
||||
delete dataset;
|
||||
|
||||
delete pointsIndex;
|
||||
delete left;
|
||||
delete right;
|
||||
|
||||
left = NULL;
|
||||
right = NULL;
|
||||
parent = other.parent;
|
||||
count = other.count;
|
||||
pointsIndex = NULL;
|
||||
overlappingNode = other.overlappingNode;
|
||||
hyperplane = other.hyperplane;
|
||||
bound = other.bound;
|
||||
stat = other.stat;
|
||||
parentDistance = other.parentDistance;
|
||||
furthestDescendantDistance = other.furthestDescendantDistance;
|
||||
|
||||
// Copy matrix, but only if we are the root and the other tree has its own
|
||||
// copy of the dataset.
|
||||
dataset = (other.parent == NULL && other.localDataset) ?
|
||||
new MatType(*other.dataset) : other.dataset;
|
||||
localDataset = other.parent == NULL && other.localDataset;
|
||||
|
||||
// Create left and right children (if any).
|
||||
if (other.Left())
|
||||
{
|
||||
left = new SpillTree(*other.Left());
|
||||
left->Parent() = this; // Set parent to this, not other tree.
|
||||
}
|
||||
|
||||
if (other.Right())
|
||||
{
|
||||
right = new SpillTree(*other.Right());
|
||||
right->Parent() = this; // Set parent to this, not other tree.
|
||||
}
|
||||
|
||||
// If vector of indexes, copy it.
|
||||
if (other.pointsIndex)
|
||||
pointsIndex = new arma::Col<size_t>(*other.pointsIndex);
|
||||
|
||||
// Propagate matrix, but only if we are the root.
|
||||
if (parent == NULL && localDataset)
|
||||
{
|
||||
std::queue<SpillTree*> queue;
|
||||
if (left)
|
||||
queue.push(left);
|
||||
if (right)
|
||||
queue.push(right);
|
||||
while (!queue.empty())
|
||||
{
|
||||
SpillTree* node = queue.front();
|
||||
queue.pop();
|
||||
|
||||
node->dataset = dataset;
|
||||
if (node->left)
|
||||
queue.push(node->left);
|
||||
if (node->right)
|
||||
queue.push(node->right);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move constructor.
|
||||
*/
|
||||
@@ -237,6 +319,66 @@ SpillTree(SpillTree&& other) :
|
||||
right->parent = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move Assignment.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
operator=(SpillTree&& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
// Freeing memory that will not be used anymore.
|
||||
if (localDataset)
|
||||
delete dataset;
|
||||
|
||||
delete pointsIndex;
|
||||
delete left;
|
||||
delete right;
|
||||
|
||||
left = other.left;
|
||||
right = other.right;
|
||||
parent = other.parent;
|
||||
count = other.count;
|
||||
pointsIndex = other.pointsIndex;
|
||||
overlappingNode = other.overlappingNode;
|
||||
hyperplane = other.hyperplane;
|
||||
bound = std::move(other.bound);
|
||||
stat = std::move(other.stat);
|
||||
parentDistance = other.parentDistance;
|
||||
furthestDescendantDistance = other.furthestDescendantDistance;
|
||||
minimumBoundDistance = other.minimumBoundDistance;
|
||||
dataset = other.dataset;
|
||||
localDataset = other.localDataset;
|
||||
|
||||
// Now we are a clone of the other tree. But we must also clear the other
|
||||
// tree's contents, so it doesn't delete anything when it is destructed.
|
||||
other.left = NULL;
|
||||
other.right = NULL;
|
||||
other.count = 0;
|
||||
other.pointsIndex = NULL;
|
||||
other.parentDistance = 0.0;
|
||||
other.furthestDescendantDistance = 0.0;
|
||||
other.minimumBoundDistance = 0.0;
|
||||
other.dataset = NULL;
|
||||
other.localDataset = false;
|
||||
|
||||
// Set new parent.
|
||||
if (left)
|
||||
left->parent = this;
|
||||
if (right)
|
||||
right->parent = this;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tree from an archive.
|
||||
*/
|
||||
|
||||
@@ -36,28 +36,22 @@ ARMA_64BIT_WORD disabled."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check if OpenMP was enabled when mlpack was built. This only matters for
|
||||
// Armadillo 8.300.1 and newer.
|
||||
#if (ARMA_VERSION_MAJOR > 8) || \
|
||||
((ARMA_VERSION_MAJOR == 8) && (ARMA_VERSION_MINOR > 300)) || \
|
||||
((ARMA_VERSION_MAJOR == 8) && (ARMA_VERSION_MINOR == 300) && \
|
||||
(ARMA_VERSION_PATCH >= 1))
|
||||
#ifdef ARMA_USE_OPENMP
|
||||
#ifdef MLPACK_ARMA_DONT_USE_OPENMP
|
||||
#pragma message "mlpack was compiled without OpenMP support, but you are \
|
||||
// Check if OpenMP was enabled when mlpack was built.
|
||||
#ifdef ARMA_USE_OPENMP
|
||||
#ifdef MLPACK_ARMA_DONT_USE_OPENMP
|
||||
#pragma message "mlpack was compiled without OpenMP support, but you are \
|
||||
compiling with OpenMP support (either -fopenmp or another option). This will \
|
||||
almost certainly cause irreparable disaster. Either compile your application \
|
||||
*without* OpenMP support (i.e. remove -fopenmp or another flag), or, recompile \
|
||||
mlpack with OpenMP support."
|
||||
#endif
|
||||
#else
|
||||
#ifdef MLPACK_ARMA_USE_OPENMP
|
||||
#pragma message "mlpack was compiled with OpenMP support, but you are \
|
||||
#endif
|
||||
#else
|
||||
#ifdef MLPACK_ARMA_USE_OPENMP
|
||||
#pragma message "mlpack was compiled with OpenMP support, but you are \
|
||||
compiling without OpenMP support. This will almost certainly cause \
|
||||
irreparable disaster. Either enable OpenMP support in your application (e.g., \
|
||||
add -fopenmp to your compiler command line), or, recompile mlpack *without* \
|
||||
OpenMP support."
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,11 +37,43 @@
|
||||
#include <mlpack/bindings/cli/cli_option.hpp>
|
||||
#include <mlpack/bindings/cli/print_doc_functions.hpp>
|
||||
|
||||
/**
|
||||
* PRINT_PARAM_STRING() returns a string that contains the correct
|
||||
* language-specific representation of a parameter's name.
|
||||
*/
|
||||
#define PRINT_PARAM_STRING mlpack::bindings::cli::ParamString
|
||||
|
||||
/**
|
||||
* PRINT_PARAM_VALUE() returns a string that contains a correct
|
||||
* language-specific representation of a parameter's value.
|
||||
*/
|
||||
#define PRINT_PARAM_VALUE mlpack::bindings::cli::PrintValue
|
||||
|
||||
/**
|
||||
* PRINT_CALL() returns a string that contains the full language-specific
|
||||
* representation of a call to an mlpack binding. The first argument should be
|
||||
* the name of the binding, and all other arguments should be names of
|
||||
* parameters followed by values (in the case where the preceding parameter is
|
||||
* not a flag).
|
||||
*/
|
||||
#define PRINT_CALL mlpack::bindings::cli::ProgramCall
|
||||
|
||||
/**
|
||||
* PRINT_DATASET() returns a string that contains a correct language-specific
|
||||
* representation of a dataset name.
|
||||
*/
|
||||
#define PRINT_DATASET mlpack::bindings::cli::PrintDataset
|
||||
|
||||
/**
|
||||
* PRINT_MODEL() returns a string that contains a correct language-specific
|
||||
* representation of an mlpack model name.
|
||||
*/
|
||||
#define PRINT_MODEL mlpack::bindings::cli::PrintModel
|
||||
|
||||
/**
|
||||
* BINDING_IGNORE_CHECK() is an internally-used macro to determine whether or
|
||||
* not a specific parameter check should be ignored.
|
||||
*/
|
||||
#define BINDING_IGNORE_CHECK mlpack::bindings::cli::IgnoreCheck
|
||||
|
||||
namespace mlpack {
|
||||
@@ -91,7 +123,20 @@ int main(int argc, char** argv)
|
||||
#define PRINT_PARAM_VALUE(A, B) std::string(" ")
|
||||
#define PRINT_DATASET(A) std::string(" ")
|
||||
#define PRINT_MODEL(A) std::string(" ")
|
||||
|
||||
/**
|
||||
* PRINT_CALL() returns a string that contains the full language-specific
|
||||
* representation of a call to an mlpack binding. The first argument should be
|
||||
* the name of the binding, and all other arguments should be names of
|
||||
* parameters followed by values (in the case where the preceding parameter is
|
||||
* not a flag).
|
||||
*/
|
||||
#define PRINT_CALL(...) std::string(" ")
|
||||
|
||||
/**
|
||||
* BINDING_IGNORE_CHECK() is an internally-used macro to determine whether or
|
||||
* not a specific parameter check should be ignored.
|
||||
*/
|
||||
#define BINDING_IGNORE_CHECK mlpack::bindings::tests::IgnoreCheck
|
||||
|
||||
namespace mlpack {
|
||||
@@ -120,11 +165,43 @@ using Option = mlpack::bindings::tests::TestOption<T>;
|
||||
#include <mlpack/bindings/python/py_option.hpp>
|
||||
#include <mlpack/bindings/python/print_doc_functions.hpp>
|
||||
|
||||
/**
|
||||
* PRINT_PARAM_STRING() returns a string that contains the correct
|
||||
* language-specific representation of a parameter's name.
|
||||
*/
|
||||
#define PRINT_PARAM_STRING mlpack::bindings::python::ParamString
|
||||
|
||||
/**
|
||||
* PRINT_PARAM_VALUE() returns a string that contains a correct
|
||||
* language-specific representation of a parameter's value.
|
||||
*/
|
||||
#define PRINT_PARAM_VALUE mlpack::bindings::python::PrintValue
|
||||
|
||||
/**
|
||||
* PRINT_DATASET() returns a string that contains a correct language-specific
|
||||
* representation of a dataset name.
|
||||
*/
|
||||
#define PRINT_DATASET mlpack::bindings::python::PrintDataset
|
||||
|
||||
/**
|
||||
* PRINT_MODEL() returns a string that contains a correct language-specific
|
||||
* representation of an mlpack model name.
|
||||
*/
|
||||
#define PRINT_MODEL mlpack::bindings::python::PrintModel
|
||||
|
||||
/**
|
||||
* PRINT_CALL() returns a string that contains the full language-specific
|
||||
* representation of a call to an mlpack binding. The first argument should be
|
||||
* the name of the binding, and all other arguments should be names of
|
||||
* parameters followed by values (in the case where the preceding parameter is
|
||||
* not a flag).
|
||||
*/
|
||||
#define PRINT_CALL mlpack::bindings::python::ProgramCall
|
||||
|
||||
/**
|
||||
* BINDING_IGNORE_CHECK() is an internally-used macro to determine whether or
|
||||
* not a specific parameter check should be ignored.
|
||||
*/
|
||||
#define BINDING_IGNORE_CHECK mlpack::bindings::python::IgnoreCheck
|
||||
|
||||
namespace mlpack {
|
||||
@@ -217,11 +294,43 @@ PARAM_FLAG("verbose", "Display informational messages and the full list of "
|
||||
#include <mlpack/bindings/markdown/md_option.hpp>
|
||||
#include <mlpack/bindings/markdown/print_doc_functions.hpp>
|
||||
|
||||
/**
|
||||
* PRINT_PARAM_STRING() returns a string that contains the correct
|
||||
* language-specific representation of a parameter's name.
|
||||
*/
|
||||
#define PRINT_PARAM_STRING mlpack::bindings::markdown::ParamString
|
||||
|
||||
/**
|
||||
* PRINT_PARAM_VALUE() returns a string that contains a correct
|
||||
* language-specific representation of a parameter's value.
|
||||
*/
|
||||
#define PRINT_PARAM_VALUE mlpack::bindings::markdown::PrintValue
|
||||
|
||||
/**
|
||||
* PRINT_DATASET() returns a string that contains a correct language-specific
|
||||
* representation of a dataset name.
|
||||
*/
|
||||
#define PRINT_DATASET mlpack::bindings::markdown::PrintDataset
|
||||
|
||||
/**
|
||||
* PRINT_MODEL() returns a string that contains a correct language-specific
|
||||
* representation of an mlpack model name.
|
||||
*/
|
||||
#define PRINT_MODEL mlpack::bindings::markdown::PrintModel
|
||||
|
||||
/**
|
||||
* PRINT_CALL() returns a string that contains the full language-specific
|
||||
* representation of a call to an mlpack binding. The first argument should be
|
||||
* the name of the binding, and all other arguments should be names of
|
||||
* parameters followed by values (in the case where the preceding parameter is
|
||||
* not a flag).
|
||||
*/
|
||||
#define PRINT_CALL mlpack::bindings::markdown::ProgramCall
|
||||
|
||||
/**
|
||||
* BINDING_IGNORE_CHECK() is an internally-used macro to determine whether or
|
||||
* not a specific parameter check should be ignored.
|
||||
*/
|
||||
#define BINDING_IGNORE_CHECK mlpack::bindings::markdown::IgnoreCheck
|
||||
|
||||
// This doesn't actually matter for this binding type.
|
||||
|
||||
+108
-36
@@ -77,7 +77,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* Define a flag parameter.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
@@ -100,7 +102,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* --ID=value.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
* @param DEF Default value of the parameter.
|
||||
*
|
||||
@@ -131,7 +135,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* will be issued.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
*
|
||||
@@ -153,7 +159,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* --ID=value.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
* @param DEF Default value of the parameter.
|
||||
*
|
||||
@@ -183,7 +191,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* will be issued.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
*
|
||||
@@ -206,7 +216,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* PROGRAM_INFO() macro), the parameter can be specified with just --ID=value.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
* @param DEF Default value of the parameter.
|
||||
*
|
||||
@@ -236,7 +248,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
@@ -264,7 +278,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -290,7 +306,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -321,7 +339,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* types.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -348,7 +368,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -376,7 +398,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -409,7 +433,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* types.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -435,7 +461,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -462,7 +490,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -494,7 +524,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* types.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -521,7 +553,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -547,7 +581,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -573,7 +609,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -599,7 +637,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -626,7 +666,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -657,7 +699,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* types.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -688,7 +732,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* types.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -719,7 +765,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* types.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -750,7 +798,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* types.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @bug
|
||||
@@ -771,7 +821,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* --ID=value1,value2,value3.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
* @param DEF Default value of the parameter.
|
||||
*
|
||||
@@ -802,7 +854,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* will be issued.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
*
|
||||
@@ -838,7 +892,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* @endcode
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS One-character string representing the alias of the parameter.
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
@@ -881,7 +937,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
*
|
||||
* @param TYPE Type of the model to be loaded.
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter.
|
||||
* @param DESC Description of the parameter. Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*/
|
||||
#define PARAM_MODEL_IN(TYPE, ID, DESC, ALIAS) \
|
||||
@@ -913,7 +971,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
*
|
||||
* @param TYPE Type of the model to be loaded.
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter.
|
||||
* @param DESC Description of the parameter. Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*/
|
||||
#define PARAM_MODEL_IN_REQ(TYPE, ID, DESC, ALIAS) \
|
||||
@@ -936,7 +996,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
*
|
||||
* @param TYPE Type of the model to be saved.
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter.
|
||||
* @param DESC Description of the parameter. Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*/
|
||||
#define PARAM_MODEL_OUT(TYPE, ID, DESC, ALIAS) \
|
||||
@@ -948,7 +1010,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* The parameter must then be specified on the command line with --ID=value.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
@@ -970,7 +1034,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* The parameter must then be specified on the command line with --ID=value.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
@@ -992,7 +1058,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* The parameter must then be specified on the command line with --ID=value.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
@@ -1015,7 +1083,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
* --ID=value1,value2,value3.
|
||||
*
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Quick description of the parameter (1-2 sentences).
|
||||
* @param DESC Quick description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS An alias for the parameter (one letter).
|
||||
*
|
||||
* @see mlpack::CLI, PROGRAM_INFO()
|
||||
@@ -1052,7 +1122,9 @@ using DatasetInfo = DatasetMapper<IncrementPolicy, std::string>;
|
||||
*
|
||||
* @param T Type of the parameter.
|
||||
* @param ID Name of the parameter.
|
||||
* @param DESC Description of the parameter (1-2 sentences).
|
||||
* @param DESC Description of the parameter (1-2 sentences). Don't use
|
||||
* printing macros like PRINT_PARAM_STRING() or PRINT_DATASET() or others
|
||||
* here---it will cause problems.
|
||||
* @param ALIAS Alias for this parameter (one letter).
|
||||
* @param DEF Default value of the parameter.
|
||||
* @param REQ Whether or not parameter is required (boolean value).
|
||||
|
||||
@@ -220,7 +220,7 @@ struct NAME \
|
||||
#define SINGLE_ARG(...) __VA_ARGS__
|
||||
|
||||
/**
|
||||
* HAS_METHOD_FORM generates a template that allows to check at compile time
|
||||
* HAS_METHOD_FORM generates a template that allows a compile time check for
|
||||
* whether a given class has a method of the requested form. For example, for
|
||||
* the following class
|
||||
*
|
||||
@@ -254,8 +254,8 @@ struct NAME \
|
||||
HAS_METHOD_FORM_BASE(SINGLE_ARG(METHOD), SINGLE_ARG(NAME), 7)
|
||||
|
||||
/**
|
||||
* HAS_EXACT_METHOD_FORM generates a template that allows to check at compile
|
||||
* time whether a given class has a method of the requested form. For example,
|
||||
* HAS_EXACT_METHOD_FORM generates a template that allows a compile time check
|
||||
* whether a given class has a method of the requested form. For example,
|
||||
* for the following class
|
||||
*
|
||||
* class A
|
||||
@@ -291,7 +291,7 @@ struct NAME \
|
||||
* A version of HAS_METHOD_FORM() where the maximum number of extra arguments is
|
||||
* set to the default of 7.
|
||||
*
|
||||
* HAS_METHOD_FORM generates a template that allows to check at compile time
|
||||
* HAS_METHOD_FORM generates a template that allows a compile time check as to
|
||||
* whether a given class has a method of the requested form. For example, for
|
||||
* the following class
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// The version of mlpack. If this is a git repository, this will be a version
|
||||
// with higher number than the most recent release.
|
||||
#define MLPACK_VERSION_MAJOR 3
|
||||
#define MLPACK_VERSION_MINOR 1
|
||||
#define MLPACK_VERSION_MINOR 2
|
||||
#define MLPACK_VERSION_PATCH 2
|
||||
|
||||
// The name of the version (for use by --version).
|
||||
|
||||
@@ -7,6 +7,7 @@ set(SOURCES
|
||||
rnn_impl.hpp
|
||||
brnn.hpp
|
||||
brnn_impl.hpp
|
||||
layer_names.hpp
|
||||
)
|
||||
|
||||
add_subdirectory(visitor)
|
||||
@@ -18,6 +19,7 @@ add_subdirectory(convolution_rules)
|
||||
add_subdirectory(gan)
|
||||
add_subdirectory(rbm)
|
||||
add_subdirectory(augmented)
|
||||
add_subdirectory(regularizer)
|
||||
|
||||
# Add directory name to sources.
|
||||
set(DIR_SRCS)
|
||||
|
||||
@@ -94,15 +94,19 @@ class FFN
|
||||
* object, be sure to use std::move to avoid unnecessary copy.
|
||||
*
|
||||
* @tparam OptimizerType Type of optimizer to use to train the model.
|
||||
* @tparam CallbackTypes Types of Callback Functions.
|
||||
* @param predictors Input training variables.
|
||||
* @param responses Outputs results from input training variables.
|
||||
* @param optimizer Instantiated optimizer used to train the model.
|
||||
* @param callbacks Callback function for ensmallen optimizer `OptimizerType`.
|
||||
* See https://www.ensmallen.org/docs.html#callback-documentation.
|
||||
* @return The final objective of the trained model (NaN or Inf on error).
|
||||
*/
|
||||
template<typename OptimizerType>
|
||||
template<typename OptimizerType, typename... CallbackTypes>
|
||||
double Train(arma::mat predictors,
|
||||
arma::mat responses,
|
||||
OptimizerType& optimizer);
|
||||
OptimizerType& optimizer,
|
||||
CallbackTypes&&... callbacks);
|
||||
|
||||
/**
|
||||
* Train the feedforward network on the given input data. By default, the
|
||||
@@ -118,11 +122,16 @@ class FFN
|
||||
*
|
||||
* @tparam OptimizerType Type of optimizer to use to train the model.
|
||||
* @param predictors Input training variables.
|
||||
* @tparam CallbackTypes Types of Callback Functions.
|
||||
* @param responses Outputs results from input training variables.
|
||||
* @param callbacks Callback function for ensmallen optimizer `OptimizerType`.
|
||||
* See https://www.ensmallen.org/docs.html#callback-documentation.
|
||||
* @return The final objective of the trained model (NaN or Inf on error).
|
||||
*/
|
||||
template<typename OptimizerType = ens::RMSProp>
|
||||
double Train(arma::mat predictors, arma::mat responses);
|
||||
template<typename OptimizerType = ens::RMSProp, typename... CallbackTypes>
|
||||
double Train(arma::mat predictors,
|
||||
arma::mat responses,
|
||||
CallbackTypes&&... callbacks);
|
||||
|
||||
/**
|
||||
* Predict the responses to a given set of predictors. The responses will
|
||||
@@ -257,6 +266,14 @@ class FFN
|
||||
*/
|
||||
void Add(LayerTypes<CustomLayers...> layer) { network.push_back(layer); }
|
||||
|
||||
//! Get the network model.
|
||||
const std::vector<LayerTypes<CustomLayers...> >& Model() const
|
||||
{
|
||||
return network;
|
||||
}
|
||||
//! Modify the network model.
|
||||
std::vector<LayerTypes<CustomLayers...> >& Model() { return network; }
|
||||
|
||||
//! Return the number of separable functions (the number of predictor points).
|
||||
size_t NumFunctions() const { return numFunctions; }
|
||||
|
||||
|
||||
@@ -69,17 +69,18 @@ void FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::ResetData(
|
||||
|
||||
template<typename OutputLayerType, typename InitializationRuleType,
|
||||
typename... CustomLayers>
|
||||
template<typename OptimizerType>
|
||||
template<typename OptimizerType, typename... CallbackTypes>
|
||||
double FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Train(
|
||||
arma::mat predictors,
|
||||
arma::mat responses,
|
||||
OptimizerType& optimizer)
|
||||
OptimizerType& optimizer,
|
||||
CallbackTypes&&... callbacks)
|
||||
{
|
||||
ResetData(std::move(predictors), std::move(responses));
|
||||
|
||||
// Train the model.
|
||||
Timer::Start("ffn_optimization");
|
||||
const double out = optimizer.Optimize(*this, parameter);
|
||||
const double out = optimizer.Optimize(*this, parameter, callbacks...);
|
||||
Timer::Stop("ffn_optimization");
|
||||
|
||||
Log::Info << "FFN::FFN(): final objective of trained model is " << out
|
||||
@@ -89,9 +90,11 @@ double FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Train(
|
||||
|
||||
template<typename OutputLayerType, typename InitializationRuleType,
|
||||
typename... CustomLayers>
|
||||
template<typename OptimizerType>
|
||||
template<typename OptimizerType, typename... CallbackTypes>
|
||||
double FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Train(
|
||||
arma::mat predictors, arma::mat responses)
|
||||
arma::mat predictors,
|
||||
arma::mat responses,
|
||||
CallbackTypes&&... callbacks)
|
||||
{
|
||||
ResetData(std::move(predictors), std::move(responses));
|
||||
|
||||
@@ -99,7 +102,7 @@ double FFN<OutputLayerType, InitializationRuleType, CustomLayers...>::Train(
|
||||
|
||||
// Train the model.
|
||||
Timer::Start("ffn_optimization");
|
||||
const double out = optimizer.Optimize(*this, parameter);
|
||||
const double out = optimizer.Optimize(*this, parameter, callbacks...);
|
||||
Timer::Stop("ffn_optimization");
|
||||
|
||||
Log::Info << "FFN::FFN(): final objective of trained model is " << out
|
||||
|
||||
@@ -8,6 +8,8 @@ set(SOURCES
|
||||
wgangp_impl.hpp
|
||||
)
|
||||
|
||||
add_subdirectory(metrics)
|
||||
|
||||
# Add directory name to sources.
|
||||
set(DIR_SRCS)
|
||||
foreach(file ${SOURCES})
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <mlpack/methods/ann/visitor/reset_visitor.hpp>
|
||||
#include <mlpack/methods/ann/visitor/weight_size_visitor.hpp>
|
||||
#include <mlpack/methods/ann/visitor/weight_set_visitor.hpp>
|
||||
#include "metrics/inception_score.hpp"
|
||||
|
||||
|
||||
namespace mlpack {
|
||||
@@ -65,9 +66,12 @@ class GAN
|
||||
/**
|
||||
* Constructor for GAN class.
|
||||
*
|
||||
* @param trainData The real data.
|
||||
* @param generator Generator network.
|
||||
* @param discriminator Discriminator network.
|
||||
* @param initializeRule Initialization rule to use for initializing
|
||||
* parameters.
|
||||
* @param noiseFunction Function to be used for generating noise.
|
||||
* @param noiseDim Dimension of noise vector to be created.
|
||||
* @param batchSize Batch size to be used for training.
|
||||
* @param generatorUpdateStep Number of steps to train Discriminator
|
||||
* before updating Generator.
|
||||
@@ -76,8 +80,7 @@ class GAN
|
||||
* @param clippingParameter Weight range for enforcing Lipschitz constraint.
|
||||
* @param lambda Parameter for setting the gradient penalty.
|
||||
*/
|
||||
GAN(arma::mat& trainData,
|
||||
Model generator,
|
||||
GAN(Model generator,
|
||||
Model discriminator,
|
||||
InitializationRuleType& initializeRule,
|
||||
Noise& noiseFunction,
|
||||
@@ -95,16 +98,32 @@ class GAN
|
||||
//! Move constructor.
|
||||
GAN(GAN&&);
|
||||
|
||||
/**
|
||||
* Initialize the generator, discriminator and weights of the model for
|
||||
* training. This function won't actually trigger training process.
|
||||
*
|
||||
* @param trainData The data points of real distribution.
|
||||
*/
|
||||
void ResetData(arma::mat trainData);
|
||||
|
||||
// Reset function.
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Train function.
|
||||
*
|
||||
*
|
||||
* @tparam OptimizerType Type of optimizer to use to train the model.
|
||||
* @tparam CallbackTypes Types of Callback functions.
|
||||
* @param trainData The data points of real distribution.
|
||||
* @param optimizer Instantiated optimizer used to train the model.
|
||||
* @param callbacks Callback function for ensmallen optimizer `OptimizerType`.
|
||||
* See https://www.ensmallen.org/docs.html#callback-documentation.
|
||||
* @return The final objective of the trained model (NaN or Inf on error).
|
||||
*/
|
||||
template<typename OptimizerType>
|
||||
double Train(OptimizerType& Optimizer);
|
||||
template<typename OptimizerType, typename... CallbackTypes>
|
||||
double Train(arma::mat trainData,
|
||||
OptimizerType& Optimizer,
|
||||
CallbackTypes&&... callbacks);
|
||||
|
||||
/**
|
||||
* Evaluate function for the Standard GAN and DCGAN.
|
||||
@@ -275,11 +294,10 @@ class GAN
|
||||
/**
|
||||
* This function predicts the output of the network on the given input.
|
||||
*
|
||||
* @param input The input the Discriminator network.
|
||||
* @param input The input of the Generator network.
|
||||
* @param output Result of the Discriminator network.
|
||||
*/
|
||||
void Predict(arma::mat&& input,
|
||||
arma::mat& output);
|
||||
void Predict(arma::mat input, arma::mat& output);
|
||||
|
||||
//! Return the parameters of the network.
|
||||
const arma::mat& Parameters() const { return parameter; }
|
||||
@@ -313,6 +331,12 @@ class GAN
|
||||
void serialize(Archive& ar, const unsigned int /* version */);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Reset the module status by setting the current deterministic parameter
|
||||
* for the discriminator and generator networks and their respective layers.
|
||||
*/
|
||||
void ResetDeterministic();
|
||||
|
||||
//! Locally stored parameter for training data + noise data.
|
||||
arma::mat predictors;
|
||||
//! Locally stored parameters of the network.
|
||||
@@ -331,8 +355,6 @@ class GAN
|
||||
size_t numFunctions;
|
||||
//! Locally stored batch size parameter.
|
||||
size_t batchSize;
|
||||
//! Locally stored number of iterations that have been completed.
|
||||
size_t counter;
|
||||
//! Locally stored batch number which is being processed.
|
||||
size_t currentBatch;
|
||||
//! Locally stored number of training step before Generator is trained.
|
||||
@@ -373,8 +395,12 @@ class GAN
|
||||
arma::mat noise;
|
||||
//! Locally stored gradient for Generator.
|
||||
arma::mat gradientGenerator;
|
||||
//! Locally stored output of the Generator network.
|
||||
arma::mat ganOutput;
|
||||
//! The current evaluation mode (training or testing).
|
||||
bool deterministic;
|
||||
//! To keep track of number of generator weights in total weights.
|
||||
size_t genWeights;
|
||||
//! To keep track of number of discriminator weights in total weights.
|
||||
size_t discWeights;
|
||||
};
|
||||
|
||||
} // namespace ann
|
||||
|
||||
@@ -30,7 +30,6 @@ template<
|
||||
typename PolicyType
|
||||
>
|
||||
GAN<Model, InitializationRuleType, Noise, PolicyType>::GAN(
|
||||
arma::mat& predictors,
|
||||
Model generator,
|
||||
Model discriminator,
|
||||
InitializationRuleType& initializeRule,
|
||||
@@ -47,41 +46,23 @@ GAN<Model, InitializationRuleType, Noise, PolicyType>::GAN(
|
||||
initializeRule(initializeRule),
|
||||
noiseFunction(noiseFunction),
|
||||
noiseDim(noiseDim),
|
||||
numFunctions(0),
|
||||
batchSize(batchSize),
|
||||
currentBatch(0),
|
||||
generatorUpdateStep(generatorUpdateStep),
|
||||
preTrainSize(preTrainSize),
|
||||
multiplier(multiplier),
|
||||
clippingParameter(clippingParameter),
|
||||
lambda(lambda),
|
||||
reset(false)
|
||||
reset(false),
|
||||
deterministic(false),
|
||||
genWeights(0),
|
||||
discWeights(0)
|
||||
{
|
||||
// Insert IdentityLayer for joining the Generator and Discriminator.
|
||||
this->discriminator.network.insert(
|
||||
this->discriminator.network.begin(),
|
||||
new IdentityLayer<>());
|
||||
|
||||
counter = 0;
|
||||
currentBatch = 0;
|
||||
|
||||
this->discriminator.deterministic = this->generator.deterministic = true;
|
||||
|
||||
this->predictors.set_size(predictors.n_rows, predictors.n_cols + batchSize);
|
||||
this->predictors.cols(0, predictors.n_cols - 1) = predictors;
|
||||
this->discriminator.predictors = arma::mat(this->predictors.memptr(),
|
||||
this->predictors.n_rows, this->predictors.n_cols, false, false);
|
||||
|
||||
responses.ones(1, predictors.n_cols + batchSize);
|
||||
responses.cols(predictors.n_cols,
|
||||
predictors.n_cols + batchSize - 1) = arma::zeros(1, batchSize);
|
||||
this->discriminator.responses = arma::mat(this->responses.memptr(),
|
||||
this->responses.n_rows, this->responses.n_cols, false, false);
|
||||
|
||||
numFunctions = predictors.n_cols;
|
||||
|
||||
noise.set_size(noiseDim, batchSize);
|
||||
|
||||
this->generator.predictors.set_size(noiseDim, batchSize);
|
||||
this->generator.responses.set_size(predictors.n_rows, batchSize);
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -106,11 +87,13 @@ GAN<Model, InitializationRuleType, Noise, PolicyType>::GAN(
|
||||
clippingParameter(network.clippingParameter),
|
||||
lambda(network.lambda),
|
||||
reset(network.reset),
|
||||
counter(network.counter),
|
||||
currentBatch(network.currentBatch),
|
||||
parameter(network.parameter),
|
||||
numFunctions(network.numFunctions),
|
||||
noise(network.noise)
|
||||
noise(network.noise),
|
||||
deterministic(network.deterministic),
|
||||
genWeights(network.genWeights),
|
||||
discWeights(network.discWeights)
|
||||
{
|
||||
/* Nothing to do here */
|
||||
}
|
||||
@@ -137,15 +120,59 @@ GAN<Model, InitializationRuleType, Noise, PolicyType>::GAN(
|
||||
clippingParameter(network.clippingParameter),
|
||||
lambda(network.lambda),
|
||||
reset(network.reset),
|
||||
counter(network.counter),
|
||||
currentBatch(network.currentBatch),
|
||||
parameter(std::move(network.parameter)),
|
||||
numFunctions(network.numFunctions),
|
||||
noise(std::move(network.noise))
|
||||
noise(std::move(network.noise)),
|
||||
deterministic(network.deterministic),
|
||||
genWeights(network.genWeights),
|
||||
discWeights(network.discWeights)
|
||||
{
|
||||
/* Nothing to do here */
|
||||
}
|
||||
|
||||
template<
|
||||
typename Model,
|
||||
typename InitializationRuleType,
|
||||
typename Noise,
|
||||
typename PolicyType
|
||||
>
|
||||
void GAN<Model, InitializationRuleType, Noise, PolicyType>::ResetData(
|
||||
arma::mat trainData)
|
||||
{
|
||||
currentBatch = 0;
|
||||
|
||||
numFunctions = trainData.n_cols;
|
||||
noise.set_size(noiseDim, batchSize);
|
||||
|
||||
deterministic = true;
|
||||
ResetDeterministic();
|
||||
|
||||
/**
|
||||
* These predictors are shared by the discriminator network. The additional
|
||||
* batch size predictors are taken from the generator network while training.
|
||||
* For more details please look in EvaluateWithGradient() function.
|
||||
*/
|
||||
this->predictors.set_size(trainData.n_rows, numFunctions + batchSize);
|
||||
this->predictors.cols(0, numFunctions - 1) = std::move(trainData);
|
||||
this->discriminator.predictors = arma::mat(this->predictors.memptr(),
|
||||
this->predictors.n_rows, this->predictors.n_cols, false, false);
|
||||
|
||||
responses.ones(1, numFunctions + batchSize);
|
||||
responses.cols(numFunctions, numFunctions + batchSize - 1) =
|
||||
arma::zeros(1, batchSize);
|
||||
this->discriminator.responses = arma::mat(this->responses.memptr(),
|
||||
this->responses.n_rows, this->responses.n_cols, false, false);
|
||||
|
||||
this->generator.predictors.set_size(noiseDim, batchSize);
|
||||
this->generator.responses.set_size(predictors.n_rows, batchSize);
|
||||
|
||||
if (!reset)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
template<
|
||||
typename Model,
|
||||
typename InitializationRuleType,
|
||||
@@ -154,8 +181,8 @@ template<
|
||||
>
|
||||
void GAN<Model, InitializationRuleType, Noise, PolicyType>::Reset()
|
||||
{
|
||||
size_t genWeights = 0;
|
||||
size_t discWeights = 0;
|
||||
genWeights = 0;
|
||||
discWeights = 0;
|
||||
|
||||
NetworkInitialization<InitializationRuleType> networkInit(initializeRule);
|
||||
|
||||
@@ -190,13 +217,15 @@ template<
|
||||
typename Noise,
|
||||
typename PolicyType
|
||||
>
|
||||
template<typename OptimizerType>
|
||||
template<typename OptimizerType, typename... CallbackTypes>
|
||||
double GAN<Model, InitializationRuleType, Noise, PolicyType>::Train(
|
||||
OptimizerType& Optimizer)
|
||||
arma::mat trainData,
|
||||
OptimizerType& Optimizer,
|
||||
CallbackTypes&&... callbacks)
|
||||
{
|
||||
if (!reset)
|
||||
Reset();
|
||||
return Optimizer.Optimize(*this, parameter);
|
||||
ResetData(std::move(trainData));
|
||||
|
||||
return Optimizer.Optimize(*this, parameter, callbacks...);
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -213,8 +242,16 @@ GAN<Model, InitializationRuleType, Noise, PolicyType>::Evaluate(
|
||||
const size_t i,
|
||||
const size_t /* batchSize */)
|
||||
{
|
||||
if (!reset)
|
||||
if (parameter.is_empty())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (!deterministic)
|
||||
{
|
||||
deterministic = true;
|
||||
ResetDeterministic();
|
||||
}
|
||||
|
||||
currentInput = arma::mat(predictors.memptr() + (i * predictors.n_rows),
|
||||
predictors.n_rows, batchSize, false, false);
|
||||
@@ -262,8 +299,10 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
GradType& gradient,
|
||||
const size_t /* batchSize */)
|
||||
{
|
||||
if (!reset)
|
||||
if (parameter.is_empty())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (gradient.is_empty())
|
||||
{
|
||||
@@ -274,6 +313,12 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
else
|
||||
gradient.zeros();
|
||||
|
||||
if (this->deterministic)
|
||||
{
|
||||
this->deterministic = false;
|
||||
ResetDeterministic();
|
||||
}
|
||||
|
||||
if (noiseGradientDiscriminator.is_empty())
|
||||
{
|
||||
noiseGradientDiscriminator = arma::zeros<arma::mat>(
|
||||
@@ -325,14 +370,8 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
gradientGenerator *= multiplier;
|
||||
}
|
||||
|
||||
counter++;
|
||||
currentBatch++;
|
||||
|
||||
// Revert the counter to zero, if the total dataset get's covered.
|
||||
if (counter * batchSize >= numFunctions)
|
||||
{
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
if (preTrainSize > 0)
|
||||
{
|
||||
@@ -382,12 +421,13 @@ template<
|
||||
void GAN<Model, InitializationRuleType, Noise, PolicyType>::Forward(
|
||||
arma::mat&& input)
|
||||
{
|
||||
if (!reset)
|
||||
if (parameter.is_empty())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
generator.Forward(std::move(input));
|
||||
ganOutput = boost::apply_visitor(
|
||||
outputParameterVisitor,
|
||||
arma::mat ganOutput = boost::apply_visitor(outputParameterVisitor,
|
||||
generator.network.back());
|
||||
|
||||
discriminator.Forward(std::move(ganOutput));
|
||||
@@ -400,10 +440,18 @@ template<
|
||||
typename PolicyType
|
||||
>
|
||||
void GAN<Model, InitializationRuleType, Noise, PolicyType>::
|
||||
Predict(arma::mat&& input, arma::mat& output)
|
||||
Predict(arma::mat input, arma::mat& output)
|
||||
{
|
||||
if (!reset)
|
||||
if (parameter.is_empty())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (!deterministic)
|
||||
{
|
||||
deterministic = true;
|
||||
ResetDeterministic();
|
||||
}
|
||||
|
||||
Forward(std::move(input));
|
||||
|
||||
@@ -411,6 +459,21 @@ Predict(arma::mat&& input, arma::mat& output)
|
||||
discriminator.network.back());
|
||||
}
|
||||
|
||||
template<
|
||||
typename Model,
|
||||
typename InitializationRuleType,
|
||||
typename Noise,
|
||||
typename PolicyType
|
||||
>
|
||||
void GAN<Model, InitializationRuleType, Noise, PolicyType>::
|
||||
ResetDeterministic()
|
||||
{
|
||||
this->discriminator.deterministic = deterministic;
|
||||
this->generator.deterministic = deterministic;
|
||||
this->discriminator.ResetDeterministic();
|
||||
this->generator.ResetDeterministic();
|
||||
}
|
||||
|
||||
template<
|
||||
typename Model,
|
||||
typename InitializationRuleType,
|
||||
@@ -424,7 +487,39 @@ serialize(Archive& ar, const unsigned int /* version */)
|
||||
ar & BOOST_SERIALIZATION_NVP(parameter);
|
||||
ar & BOOST_SERIALIZATION_NVP(generator);
|
||||
ar & BOOST_SERIALIZATION_NVP(discriminator);
|
||||
ar & BOOST_SERIALIZATION_NVP(noiseFunction);
|
||||
ar & BOOST_SERIALIZATION_NVP(reset);
|
||||
ar & BOOST_SERIALIZATION_NVP(genWeights);
|
||||
ar & BOOST_SERIALIZATION_NVP(discWeights);
|
||||
|
||||
if (Archive::is_loading::value)
|
||||
{
|
||||
// Share the parameters between the network.
|
||||
generator.Parameters() = arma::mat(parameter.memptr(), genWeights, 1, false,
|
||||
false);
|
||||
discriminator.Parameters() = arma::mat(parameter.memptr() + genWeights,
|
||||
discWeights, 1, false, false);
|
||||
|
||||
size_t offset = 0;
|
||||
for (size_t i = 0; i < generator.network.size(); ++i)
|
||||
{
|
||||
offset += boost::apply_visitor(WeightSetVisitor(std::move(
|
||||
generator.parameter), offset), generator.network[i]);
|
||||
|
||||
boost::apply_visitor(resetVisitor, generator.network[i]);
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
for (size_t i = 0; i < discriminator.network.size(); ++i)
|
||||
{
|
||||
offset += boost::apply_visitor(WeightSetVisitor(std::move(
|
||||
discriminator.parameter), offset), discriminator.network[i]);
|
||||
|
||||
boost::apply_visitor(resetVisitor, discriminator.network[i]);
|
||||
}
|
||||
|
||||
deterministic = true;
|
||||
ResetDeterministic();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# Define the files we need to compile.
|
||||
# Anything not in this list will not be compiled into mlpack.
|
||||
set(SOURCES
|
||||
inception_score
|
||||
inception_score_impl
|
||||
)
|
||||
|
||||
# Add directory name to sources.
|
||||
set(DIR_SRCS)
|
||||
foreach(file ${SOURCES})
|
||||
set(DIR_SRCS ${DIR_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
|
||||
endforeach()
|
||||
# Append sources (with directory name) to list of all mlpack sources (used at
|
||||
# the parent scope).
|
||||
set(MLPACK_SRCS ${MLPACK_SRCS} ${DIR_SRCS} PARENT_SCOPE)
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file inception_score.hpp
|
||||
* @author Saksham Bansal
|
||||
*
|
||||
* Definition of Inception Score for Generative Adversarial Networks.
|
||||
*
|
||||
* 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_METRICS_INCEPTION_SCORE_HPP
|
||||
#define MLPACK_METHODS_METRICS_INCEPTION_SCORE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /* Artificial Neural Network */ {
|
||||
|
||||
/**
|
||||
* Function that computes Inception Score for a set of images produced by a GAN.
|
||||
* For more information, see the following.
|
||||
*
|
||||
* @code
|
||||
* @article{Goodfellow2016,
|
||||
* author = {Tim Salimans, Ian Goodfellow, Wojciech Zaremba, Vicki Cheung,
|
||||
* Alec Radford, Xi Chen},
|
||||
* title = {Improved Techniques for Training GANs},
|
||||
* year = {2016},
|
||||
* url = {https://arxiv.org/abs/1606.03498},
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param Model Model for evaluating the quality of images.
|
||||
* @param images Images generated by GAN.
|
||||
*/
|
||||
template<typename ModelType>
|
||||
double InceptionScore(ModelType Model,
|
||||
arma::mat images,
|
||||
size_t splits = 1);
|
||||
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#include "inception_score_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @file inception_score_impl.hpp
|
||||
* @author Saksham Bansal
|
||||
*
|
||||
* Definition of Inception Score for Generative Adversarial Networks.
|
||||
*
|
||||
* 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_METRICS_INCEPTION_SCORE_IMPL_HPP
|
||||
#define MLPACK_METHODS_METRICS_INCEPTION_SCORE_IMPL_HPP
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
#include "inception_score.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /* Artificial Neural Network */ {
|
||||
|
||||
template <typename ModelType>
|
||||
double InceptionScore(ModelType model,
|
||||
arma::mat images,
|
||||
size_t splits)
|
||||
{
|
||||
size_t samples = images.n_cols;
|
||||
size_t splitSize = samples / splits;
|
||||
size_t remainder = samples % splits;
|
||||
arma::mat preds;
|
||||
model.Predict(images, preds);
|
||||
|
||||
size_t index = 0;
|
||||
arma::vec scores = arma::vec(splits);
|
||||
|
||||
for (int i = 0; i < splits; i++)
|
||||
{
|
||||
size_t curSize = splitSize;
|
||||
if (remainder)
|
||||
{
|
||||
curSize++;
|
||||
remainder--;
|
||||
}
|
||||
arma::mat curPreds =
|
||||
arma::mat(preds.colptr(index), preds.n_rows, curSize, false, true);
|
||||
arma::colvec c = arma::log(arma::mean(curPreds, 1));
|
||||
arma::mat temp = arma::log(curPreds);
|
||||
temp.each_col() -= c;
|
||||
curPreds %= temp;
|
||||
scores(i) = exp(arma::as_scalar(arma::mean(arma::sum(curPreds, 0))));
|
||||
index += curSize;
|
||||
}
|
||||
|
||||
return arma::mean(scores);
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -34,8 +34,16 @@ GAN<Model, InitializationRuleType, Noise, PolicyType>::Evaluate(
|
||||
const size_t i,
|
||||
const size_t /* batchSize */)
|
||||
{
|
||||
if (!reset)
|
||||
if (parameter.is_empty())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (!deterministic)
|
||||
{
|
||||
deterministic = true;
|
||||
ResetDeterministic();
|
||||
}
|
||||
|
||||
currentInput = arma::mat(predictors.memptr() + (i * predictors.n_rows),
|
||||
predictors.n_rows, batchSize, false, false);
|
||||
@@ -82,8 +90,10 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
GradType& gradient,
|
||||
const size_t /* batchSize */)
|
||||
{
|
||||
if (!reset)
|
||||
if (parameter.is_empty())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (gradient.is_empty())
|
||||
{
|
||||
@@ -94,6 +104,12 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
else
|
||||
gradient.zeros();
|
||||
|
||||
if (this->deterministic)
|
||||
{
|
||||
this->deterministic = false;
|
||||
ResetDeterministic();
|
||||
}
|
||||
|
||||
if (noiseGradientDiscriminator.is_empty())
|
||||
{
|
||||
noiseGradientDiscriminator = arma::zeros<arma::mat>(
|
||||
@@ -147,15 +163,8 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
gradientGenerator *= multiplier;
|
||||
}
|
||||
|
||||
counter++;
|
||||
currentBatch++;
|
||||
|
||||
// Revert the counter to zero, if the total dataset get's covered.
|
||||
if (counter * batchSize >= numFunctions)
|
||||
{
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
if (preTrainSize > 0)
|
||||
{
|
||||
preTrainSize--;
|
||||
|
||||
@@ -35,8 +35,16 @@ GAN<Model, InitializationRuleType, Noise, PolicyType>::Evaluate(
|
||||
const size_t i,
|
||||
const size_t /* batchSize */)
|
||||
{
|
||||
if (!reset)
|
||||
if ((parameter.is_empty()))
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (!deterministic)
|
||||
{
|
||||
deterministic = true;
|
||||
ResetDeterministic();
|
||||
}
|
||||
|
||||
currentInput = arma::mat(predictors.memptr() + (i * predictors.n_rows),
|
||||
predictors.n_rows, batchSize, false, false);
|
||||
@@ -96,8 +104,10 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
GradType& gradient,
|
||||
const size_t /* batchSize */)
|
||||
{
|
||||
if (!reset)
|
||||
if (parameter.is_empty())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
if (gradient.is_empty())
|
||||
{
|
||||
@@ -108,6 +118,12 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
else
|
||||
gradient.zeros();
|
||||
|
||||
if (this->deterministic)
|
||||
{
|
||||
this->deterministic = false;
|
||||
ResetDeterministic();
|
||||
}
|
||||
|
||||
if (noiseGradientDiscriminator.is_empty())
|
||||
{
|
||||
noiseGradientDiscriminator = arma::zeros<arma::mat>(
|
||||
@@ -171,15 +187,8 @@ EvaluateWithGradient(const arma::mat& /* parameters */,
|
||||
gradientGenerator *= multiplier;
|
||||
}
|
||||
|
||||
counter++;
|
||||
currentBatch++;
|
||||
|
||||
// Revert the counter to zero, if the total dataset get's covered.
|
||||
if (counter * batchSize >= numFunctions)
|
||||
{
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
if (preTrainSize > 0)
|
||||
{
|
||||
preTrainSize--;
|
||||
|
||||
@@ -40,6 +40,8 @@ set(SOURCES
|
||||
gru_impl.hpp
|
||||
hard_tanh.hpp
|
||||
hard_tanh_impl.hpp
|
||||
highway.hpp
|
||||
highway_impl.hpp
|
||||
join.hpp
|
||||
join_impl.hpp
|
||||
layer.hpp
|
||||
@@ -63,6 +65,8 @@ set(SOURCES
|
||||
max_pooling_impl.hpp
|
||||
mean_pooling.hpp
|
||||
mean_pooling_impl.hpp
|
||||
minibatch_discrimination.hpp
|
||||
minibatch_discrimination_impl.hpp
|
||||
multiply_constant.hpp
|
||||
multiply_constant_impl.hpp
|
||||
multiply_merge.hpp
|
||||
@@ -88,6 +92,8 @@ set(SOURCES
|
||||
vr_class_reward_impl.hpp
|
||||
c_relu.hpp
|
||||
c_relu_impl.hpp
|
||||
weight_norm.hpp
|
||||
weight_norm_impl.hpp
|
||||
)
|
||||
|
||||
# Add directory name to sources.
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace ann /** Artificial Neural Network. */ {
|
||||
* journal = {Advances in Neural Information Processing Systems},
|
||||
* year = {2017}
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @tparam InputDataType Type of the input data (arma::colvec, arma::mat,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <mlpack/methods/ann/convolution_rules/svd_convolution.hpp>
|
||||
|
||||
#include "layer_types.hpp"
|
||||
#include "padding.hpp"
|
||||
|
||||
namespace mlpack{
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
@@ -70,6 +71,7 @@ class AtrousConvolution
|
||||
* @param inputHeight The height of the input data.
|
||||
* @param dilationW The space between the cells of filters in x direction.
|
||||
* @param dilationH The space between the cells of filters in y direction.
|
||||
* @param paddingType The type of padding (Valid or Same). Defaults to None.
|
||||
*/
|
||||
AtrousConvolution(const size_t inSize,
|
||||
const size_t outSize,
|
||||
@@ -82,7 +84,45 @@ class AtrousConvolution
|
||||
const size_t inputWidth = 0,
|
||||
const size_t inputHeight = 0,
|
||||
const size_t dilationW = 1,
|
||||
const size_t dilationH = 1);
|
||||
const size_t dilationH = 1,
|
||||
const std::string paddingType = "None");
|
||||
|
||||
/**
|
||||
* Create the AtrousConvolution object using the specified number of
|
||||
* input maps, output maps, filter size, stride, dilation and
|
||||
* padding parameter.
|
||||
*
|
||||
* @param inSize The number of input maps.
|
||||
* @param outSize The number of output maps.
|
||||
* @param kW Width of the filter/kernel.
|
||||
* @param kH Height of the filter/kernel.
|
||||
* @param dW Stride of filter application in the x direction.
|
||||
* @param dH Stride of filter application in the y direction.
|
||||
* @param padW A two-value tuple indicating padding widths of the input.
|
||||
* First value is padding at left side. Second value is padding on
|
||||
* right side.
|
||||
* @param padH A two-value tuple indicating padding heights of the input.
|
||||
* First value is padding at top. Second value is padding on
|
||||
* bottom.
|
||||
* @param inputWidth The widht of the input data.
|
||||
* @param inputHeight The height of the input data.
|
||||
* @param dilationW The space between the cells of filters in x direction.
|
||||
* @param dilationH The space between the cells of filters in y direction.
|
||||
* @param paddingType The type of padding (Valid or Same). Defaults to None.
|
||||
*/
|
||||
AtrousConvolution(const size_t inSize,
|
||||
const size_t outSize,
|
||||
const size_t kW,
|
||||
const size_t kH,
|
||||
const size_t dW,
|
||||
const size_t dH,
|
||||
const std::tuple<size_t, size_t> padW,
|
||||
const std::tuple<size_t, size_t> padH,
|
||||
const size_t inputWidth = 0,
|
||||
const size_t inputHeight = 0,
|
||||
const size_t dilationW = 1,
|
||||
const size_t dilationH = 1,
|
||||
const std::string paddingType = "None");
|
||||
|
||||
/*
|
||||
* Set the weight and bias term.
|
||||
@@ -165,6 +205,9 @@ class AtrousConvolution
|
||||
//! Modify the output height.
|
||||
size_t& OutputHeight() { return outputHeight; }
|
||||
|
||||
//! Modify the bias weights of the layer.
|
||||
arma::mat& Bias() { return bias; }
|
||||
|
||||
/**
|
||||
* Serialize the layer
|
||||
*/
|
||||
@@ -178,19 +221,26 @@ class AtrousConvolution
|
||||
* @param size The size of the input (row or column).
|
||||
* @param k The size of the filter (width or height).
|
||||
* @param s The stride size (x or y direction).
|
||||
* @param p The size of the padding (width or height).
|
||||
* @param pSideOne The size of the padding (width or height) on one side.
|
||||
* @param pSideTwo The size of the padding (width or height) on another side.
|
||||
* @param d The dilation size.
|
||||
* @return The convolution output size.
|
||||
*/
|
||||
size_t ConvOutSize(const size_t size,
|
||||
const size_t k,
|
||||
const size_t s,
|
||||
const size_t p,
|
||||
const size_t d)
|
||||
const size_t k,
|
||||
const size_t s,
|
||||
const size_t pSideOne,
|
||||
const size_t pSideTwo,
|
||||
const size_t d)
|
||||
{
|
||||
return std::floor(size + p * 2 - d * (k - 1) - 1) / s + 1;
|
||||
return std::floor(size + pSideOne + pSideTwo - d * (k - 1) - 1) / s + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to assign padding such that output size is same as input size.
|
||||
*/
|
||||
void InitializeSamePadding();
|
||||
|
||||
/*
|
||||
* Rotates a 3rd-order tensor counterclockwise by 180 degrees.
|
||||
*
|
||||
@@ -220,53 +270,6 @@ class AtrousConvolution
|
||||
output = arma::fliplr(arma::flipud(input));
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad the given input data.
|
||||
*
|
||||
* @param input The input to be padded.
|
||||
* @param wPad Padding width of the input.
|
||||
* @param hPad Padding height of the input.
|
||||
* @param output The padded output data.
|
||||
*/
|
||||
template<typename eT>
|
||||
void Pad(const arma::Mat<eT>& input,
|
||||
size_t wPad,
|
||||
size_t hPad,
|
||||
arma::Mat<eT>& output)
|
||||
{
|
||||
if (output.n_rows != input.n_rows + wPad * 2 ||
|
||||
output.n_cols != input.n_cols + hPad * 2)
|
||||
{
|
||||
output = arma::zeros(input.n_rows + wPad * 2, input.n_cols + hPad * 2);
|
||||
}
|
||||
|
||||
output.submat(wPad, hPad, wPad + input.n_rows - 1,
|
||||
hPad + input.n_cols - 1) = input;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad the given input data.
|
||||
*
|
||||
* @param input The input to be padded.
|
||||
* @param wPad Padding width of the input.
|
||||
* @param hPad Padding height of the input.
|
||||
* @param output The padded output data.
|
||||
*/
|
||||
template<typename eT>
|
||||
void Pad(const arma::Cube<eT>& input,
|
||||
size_t wPad,
|
||||
size_t hPad,
|
||||
arma::Cube<eT>& output)
|
||||
{
|
||||
output = arma::zeros(input.n_rows + wPad * 2,
|
||||
input.n_cols + hPad * 2, input.n_slices);
|
||||
|
||||
for (size_t i = 0; i < input.n_slices; ++i)
|
||||
{
|
||||
Pad<double>(input.slice(i), wPad, hPad, output.slice(i));
|
||||
}
|
||||
}
|
||||
|
||||
//! Locally-stored number of input channels.
|
||||
size_t inSize;
|
||||
|
||||
@@ -288,11 +291,17 @@ class AtrousConvolution
|
||||
//! Locally-stored stride of the filter in y-direction.
|
||||
size_t dH;
|
||||
|
||||
//! Locally-stored padding width.
|
||||
size_t padW;
|
||||
//! Locally-stored left-side padding width.
|
||||
size_t padWLeft;
|
||||
|
||||
//! Locally-stored padding height.
|
||||
size_t padH;
|
||||
//! Locally-stored right-side padding width.
|
||||
size_t padWRight;
|
||||
|
||||
//! Locally-stored bottom padding height.
|
||||
size_t padHBottom;
|
||||
|
||||
//! Locally-stored top padding height.
|
||||
size_t padHTop;
|
||||
|
||||
//! Locally-stored weight object.
|
||||
OutputDataType weights;
|
||||
@@ -336,6 +345,9 @@ class AtrousConvolution
|
||||
//! Locally-stored transformed gradient parameter.
|
||||
arma::cube gradientTemp;
|
||||
|
||||
//! Locally-stored padding layer.
|
||||
Padding<>* padding;
|
||||
|
||||
//! Locally-stored delta object.
|
||||
OutputDataType delta;
|
||||
|
||||
@@ -349,6 +361,28 @@ class AtrousConvolution
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
//! Set the serialization version of the AtrousConvolution class.
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
template<
|
||||
typename ForwardConvolutionRule,
|
||||
typename BackwardConvolutionRule,
|
||||
typename GradientConvolutionRule,
|
||||
typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
struct version<
|
||||
mlpack::ann::AtrousConvolution<ForwardConvolutionRule,
|
||||
BackwardConvolutionRule, GradientConvolutionRule, InputDataType,
|
||||
OutputDataType> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 1);
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
|
||||
// Include implementation
|
||||
#include "atrous_convolution_impl.hpp"
|
||||
|
||||
|
||||
@@ -62,15 +62,18 @@ AtrousConvolution<
|
||||
const size_t inputWidth,
|
||||
const size_t inputHeight,
|
||||
const size_t dilationW,
|
||||
const size_t dilationH) :
|
||||
const size_t dilationH,
|
||||
const std::string paddingType) :
|
||||
inSize(inSize),
|
||||
outSize(outSize),
|
||||
kW(kW),
|
||||
kH(kH),
|
||||
dW(dW),
|
||||
dH(dH),
|
||||
padW(padW),
|
||||
padH(padH),
|
||||
padWLeft(padW),
|
||||
padWRight(padW),
|
||||
padHBottom(padH),
|
||||
padHTop(padH),
|
||||
inputWidth(inputWidth),
|
||||
inputHeight(inputHeight),
|
||||
outputWidth(0),
|
||||
@@ -79,6 +82,91 @@ AtrousConvolution<
|
||||
dilationH(dilationH)
|
||||
{
|
||||
weights.set_size((outSize * inSize * kW * kH) + outSize, 1);
|
||||
|
||||
// Transform paddingType to lowercase.
|
||||
std::string paddingTypeLow = paddingType;
|
||||
std::transform(paddingType.begin(), paddingType.end(), paddingTypeLow.begin(),
|
||||
[](unsigned char c){ return std::tolower(c); });
|
||||
|
||||
if (paddingTypeLow == "valid")
|
||||
{
|
||||
padWLeft = 0;
|
||||
padWRight = 0;
|
||||
padHTop = 0;
|
||||
padHBottom = 0;
|
||||
}
|
||||
else if (paddingTypeLow == "same")
|
||||
{
|
||||
InitializeSamePadding();
|
||||
}
|
||||
|
||||
padding = new Padding<>(padWLeft, padWRight, padHTop, padHBottom);
|
||||
}
|
||||
|
||||
template<
|
||||
typename ForwardConvolutionRule,
|
||||
typename BackwardConvolutionRule,
|
||||
typename GradientConvolutionRule,
|
||||
typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
AtrousConvolution<
|
||||
ForwardConvolutionRule,
|
||||
BackwardConvolutionRule,
|
||||
GradientConvolutionRule,
|
||||
InputDataType,
|
||||
OutputDataType
|
||||
>::AtrousConvolution(
|
||||
const size_t inSize,
|
||||
const size_t outSize,
|
||||
const size_t kW,
|
||||
const size_t kH,
|
||||
const size_t dW,
|
||||
const size_t dH,
|
||||
const std::tuple<size_t, size_t> padW,
|
||||
const std::tuple<size_t, size_t> padH,
|
||||
const size_t inputWidth,
|
||||
const size_t inputHeight,
|
||||
const size_t dilationW,
|
||||
const size_t dilationH,
|
||||
const std::string paddingType) :
|
||||
inSize(inSize),
|
||||
outSize(outSize),
|
||||
kW(kW),
|
||||
kH(kH),
|
||||
dW(dW),
|
||||
dH(dH),
|
||||
padWLeft(std::get<0>(padW)),
|
||||
padWRight(std::get<1>(padW)),
|
||||
padHBottom(std::get<1>(padH)),
|
||||
padHTop(std::get<0>(padH)),
|
||||
inputWidth(inputWidth),
|
||||
inputHeight(inputHeight),
|
||||
outputWidth(0),
|
||||
outputHeight(0),
|
||||
dilationW(dilationW),
|
||||
dilationH(dilationH)
|
||||
{
|
||||
weights.set_size((outSize * inSize * kW * kH) + outSize, 1);
|
||||
|
||||
// Transform paddingType to lowercase.
|
||||
std::string paddingTypeLow = paddingType;
|
||||
std::transform(paddingType.begin(), paddingType.end(), paddingTypeLow.begin(),
|
||||
[](unsigned char c){ return std::tolower(c); });
|
||||
|
||||
if (paddingTypeLow == "valid")
|
||||
{
|
||||
padWLeft = 0;
|
||||
padWRight = 0;
|
||||
padHTop = 0;
|
||||
padHBottom = 0;
|
||||
}
|
||||
else if (paddingTypeLow == "same")
|
||||
{
|
||||
InitializeSamePadding();
|
||||
}
|
||||
|
||||
padding = new Padding<>(padWLeft, padWRight, padHTop, padHBottom);
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -122,13 +210,22 @@ void AtrousConvolution<
|
||||
inputTemp = arma::cube(const_cast<arma::Mat<eT>&&>(input).memptr(),
|
||||
inputWidth, inputHeight, inSize * batchSize, false, false);
|
||||
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
Pad(inputTemp, padW, padH, inputPaddedTemp);
|
||||
inputPaddedTemp.set_size(inputTemp.n_rows + padWLeft + padWRight,
|
||||
inputTemp.n_cols + padHTop + padHBottom, inputTemp.n_slices);
|
||||
|
||||
for (size_t i = 0; i < inputTemp.n_slices; ++i)
|
||||
{
|
||||
padding->Forward(std::move(inputTemp.slice(i)),
|
||||
std::move(inputPaddedTemp.slice(i)));
|
||||
}
|
||||
}
|
||||
|
||||
size_t wConv = ConvOutSize(inputWidth, kW, dW, padW, dilationW);
|
||||
size_t hConv = ConvOutSize(inputHeight, kH, dH, padH, dilationH);
|
||||
size_t wConv = ConvOutSize(inputWidth, kW, dW, padWLeft, padWRight,
|
||||
dilationW);
|
||||
size_t hConv = ConvOutSize(inputHeight, kH, dH, padHTop, padHBottom,
|
||||
dilationH);
|
||||
|
||||
output.set_size(wConv * hConv * outSize, batchSize);
|
||||
outputTemp = arma::Cube<eT>(output.memptr(), wConv, hConv,
|
||||
@@ -148,7 +245,7 @@ void AtrousConvolution<
|
||||
{
|
||||
arma::Mat<eT> convOutput;
|
||||
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
ForwardConvolutionRule::Convolution(inputPaddedTemp.slice(inMap +
|
||||
batchCount * inSize), weight.slice(outMapIdx), convOutput, dW, dH,
|
||||
@@ -213,11 +310,10 @@ void AtrousConvolution<
|
||||
BackwardConvolutionRule::Convolution(mappedError.slice(outMap),
|
||||
rotatedFilter, output, dW, dH, dilationW, dilationH);
|
||||
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
gTemp.slice(inMap + batchCount * inSize) += output.submat(padW, padH,
|
||||
padW + gTemp.n_rows - 1,
|
||||
padH + gTemp.n_cols - 1);
|
||||
gTemp.slice(inMap + batchCount * inSize) += output.submat(padWLeft,
|
||||
padHTop, padWLeft + gTemp.n_rows - 1, padHTop + gTemp.n_cols - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -266,7 +362,7 @@ void AtrousConvolution<
|
||||
for (size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
|
||||
{
|
||||
arma::Mat<eT> inputSlice;
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
inputSlice = inputPaddedTemp.slice(inMap + batchCount * inSize);
|
||||
}
|
||||
@@ -331,8 +427,7 @@ void AtrousConvolution<
|
||||
GradientConvolutionRule,
|
||||
InputDataType,
|
||||
OutputDataType
|
||||
>::serialize(
|
||||
Archive& ar, const unsigned int /* version */)
|
||||
>::serialize(Archive& ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(inSize);
|
||||
ar & BOOST_SERIALIZATION_NVP(outSize);
|
||||
@@ -341,8 +436,10 @@ void AtrousConvolution<
|
||||
ar & BOOST_SERIALIZATION_NVP(kH);
|
||||
ar & BOOST_SERIALIZATION_NVP(dW);
|
||||
ar & BOOST_SERIALIZATION_NVP(dH);
|
||||
ar & BOOST_SERIALIZATION_NVP(padW);
|
||||
ar & BOOST_SERIALIZATION_NVP(padH);
|
||||
ar & BOOST_SERIALIZATION_NVP(padWLeft);
|
||||
ar & BOOST_SERIALIZATION_NVP(padWRight);
|
||||
ar & BOOST_SERIALIZATION_NVP(padHBottom);
|
||||
ar & BOOST_SERIALIZATION_NVP(padHTop);
|
||||
ar & BOOST_SERIALIZATION_NVP(inputWidth);
|
||||
ar & BOOST_SERIALIZATION_NVP(inputHeight);
|
||||
ar & BOOST_SERIALIZATION_NVP(outputWidth);
|
||||
@@ -350,10 +447,42 @@ void AtrousConvolution<
|
||||
ar & BOOST_SERIALIZATION_NVP(dilationW);
|
||||
ar & BOOST_SERIALIZATION_NVP(dilationH);
|
||||
|
||||
if (version > 0)
|
||||
ar & BOOST_SERIALIZATION_NVP(padding);
|
||||
|
||||
if (Archive::is_loading::value)
|
||||
weights.set_size((outSize * inSize * kW * kH) + outSize, 1);
|
||||
}
|
||||
|
||||
template<
|
||||
typename ForwardConvolutionRule,
|
||||
typename BackwardConvolutionRule,
|
||||
typename GradientConvolutionRule,
|
||||
typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
void AtrousConvolution<
|
||||
ForwardConvolutionRule,
|
||||
BackwardConvolutionRule,
|
||||
GradientConvolutionRule,
|
||||
InputDataType,
|
||||
OutputDataType
|
||||
>::InitializeSamePadding()
|
||||
{
|
||||
/*
|
||||
* Using O = (W - F + 2P) / s + 1;
|
||||
*/
|
||||
size_t totalVerticalPadding = (dW - 1) * inputWidth + kW - dW + (dilationW -
|
||||
1) * (kW - 1);
|
||||
size_t totalHorizontalPadding = (dH - 1) * inputHeight + kH - dH + (dilationH
|
||||
- 1) * (kH - 1);
|
||||
|
||||
padWLeft = totalVerticalPadding / 2;
|
||||
padWRight = totalVerticalPadding - totalVerticalPadding / 2;
|
||||
padHTop = totalHorizontalPadding / 2;
|
||||
padHBottom = totalHorizontalPadding - totalHorizontalPadding / 2;
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ class BatchNorm
|
||||
//! Locally-stored epsilon value.
|
||||
double eps;
|
||||
|
||||
//! Whether we are in loading or saving mode.
|
||||
//! Variable to keep track of whether we are in loading or saving mode.
|
||||
bool loading;
|
||||
|
||||
//! Locally-stored scale parameter.
|
||||
|
||||
@@ -110,7 +110,7 @@ void BatchNorm<InputDataType, OutputDataType>::Backward(
|
||||
{
|
||||
const arma::mat stdInv = 1.0 / arma::sqrt(variance + eps);
|
||||
|
||||
// Step 1: dl / dxhat
|
||||
// Step 1: dl / dxhat.
|
||||
const arma::mat norm = gy.each_col() % gamma;
|
||||
|
||||
// Step 2: sum dl / dxhat * (x - mu) * -0.5 * stdInv^3.
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <mlpack/methods/ann/convolution_rules/svd_convolution.hpp>
|
||||
|
||||
#include "layer_types.hpp"
|
||||
#include "padding.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
@@ -63,6 +64,7 @@ class Convolution
|
||||
* @param padH Padding height of the input.
|
||||
* @param inputWidth The width of the input data.
|
||||
* @param inputHeight The height of the input data.
|
||||
* @param paddingType The type of padding (Valid or Same). Defaults to None.
|
||||
*/
|
||||
Convolution(const size_t inSize,
|
||||
const size_t outSize,
|
||||
@@ -73,7 +75,40 @@ class Convolution
|
||||
const size_t padW = 0,
|
||||
const size_t padH = 0,
|
||||
const size_t inputWidth = 0,
|
||||
const size_t inputHeight = 0);
|
||||
const size_t inputHeight = 0,
|
||||
const std::string paddingType = "None");
|
||||
|
||||
/**
|
||||
* Create the Convolution object using the specified number of input maps,
|
||||
* output maps, filter size, stride and padding parameter.
|
||||
*
|
||||
* @param inSize The number of input maps.
|
||||
* @param outSize The number of output maps.
|
||||
* @param kW Width of the filter/kernel.
|
||||
* @param kH Height of the filter/kernel.
|
||||
* @param dW Stride of filter application in the x direction.
|
||||
* @param dH Stride of filter application in the y direction.
|
||||
* @param padW A two-value tuple indicating padding widths of the input.
|
||||
* First value is padding at left side. Second value is padding on
|
||||
* right side.
|
||||
* @param padH A two-value tuple indicating padding heights of the input.
|
||||
* First value is padding at top. Second value is padding on
|
||||
* bottom.
|
||||
* @param inputWidth The width of the input data.
|
||||
* @param inputHeight The height of the input data.
|
||||
* @param paddingType The type of padding (Valid or Same). Defaults to None.
|
||||
*/
|
||||
Convolution(const size_t inSize,
|
||||
const size_t outSize,
|
||||
const size_t kW,
|
||||
const size_t kH,
|
||||
const size_t dW,
|
||||
const size_t dH,
|
||||
const std::tuple<size_t, size_t> padW,
|
||||
const std::tuple<size_t, size_t> padH,
|
||||
const size_t inputWidth = 0,
|
||||
const size_t inputHeight = 0,
|
||||
const std::string paddingType = "None");
|
||||
|
||||
/*
|
||||
* Set the weight and bias term.
|
||||
@@ -161,6 +196,9 @@ class Convolution
|
||||
//! Modify the output height.
|
||||
size_t& OutputHeight() { return outputHeight; }
|
||||
|
||||
//! Modify the bias weights of the layer.
|
||||
arma::mat& Bias() { return bias; }
|
||||
|
||||
/**
|
||||
* Serialize the layer
|
||||
*/
|
||||
@@ -174,17 +212,24 @@ class Convolution
|
||||
* @param size The size of the input (row or column).
|
||||
* @param k The size of the filter (width or height).
|
||||
* @param s The stride size (x or y direction).
|
||||
* @param p The size of the padding (width or height).
|
||||
* @param pSideOne The size of the padding (width or height) on one side.
|
||||
* @param pSideTwo The size of the padding (width or height) on another side.
|
||||
* @return The convolution output size.
|
||||
*/
|
||||
size_t ConvOutSize(const size_t size,
|
||||
const size_t k,
|
||||
const size_t s,
|
||||
const size_t p)
|
||||
const size_t pSideOne,
|
||||
const size_t pSideTwo)
|
||||
{
|
||||
return std::floor(size + p * 2 - k) / s + 1;
|
||||
return std::floor(size + pSideOne + pSideTwo - k) / s + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to assign padding such that output size is same as input size.
|
||||
*/
|
||||
void InitializeSamePadding();
|
||||
|
||||
/*
|
||||
* Rotates a 3rd-order tensor counterclockwise by 180 degrees.
|
||||
*
|
||||
@@ -214,53 +259,6 @@ class Convolution
|
||||
output = arma::fliplr(arma::flipud(input));
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad the given input data.
|
||||
*
|
||||
* @param input The input to be padded.
|
||||
* @param wPad Padding width of the input.
|
||||
* @param hPad Padding height of the input.
|
||||
* @param output The padded output data.
|
||||
*/
|
||||
template<typename eT>
|
||||
void Pad(const arma::Mat<eT>& input,
|
||||
size_t wPad,
|
||||
size_t hPad,
|
||||
arma::Mat<eT>& output)
|
||||
{
|
||||
if (output.n_rows != input.n_rows + wPad * 2 ||
|
||||
output.n_cols != input.n_cols + hPad * 2)
|
||||
{
|
||||
output = arma::zeros(input.n_rows + wPad * 2, input.n_cols + hPad * 2);
|
||||
}
|
||||
|
||||
output.submat(wPad, hPad, wPad + input.n_rows - 1,
|
||||
hPad + input.n_cols - 1) = input;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad the given input data.
|
||||
*
|
||||
* @param input The input to be padded.
|
||||
* @param wPad Padding width of the input.
|
||||
* @param hPad Padding height of the input.
|
||||
* @param output The padded output data.
|
||||
*/
|
||||
template<typename eT>
|
||||
void Pad(const arma::Cube<eT>& input,
|
||||
size_t wPad,
|
||||
size_t hPad,
|
||||
arma::Cube<eT>& output)
|
||||
{
|
||||
output = arma::zeros(input.n_rows + wPad * 2,
|
||||
input.n_cols + hPad * 2, input.n_slices);
|
||||
|
||||
for (size_t i = 0; i < input.n_slices; ++i)
|
||||
{
|
||||
Pad<eT>(input.slice(i), wPad, hPad, output.slice(i));
|
||||
}
|
||||
}
|
||||
|
||||
//! Locally-stored number of input channels.
|
||||
size_t inSize;
|
||||
|
||||
@@ -282,11 +280,17 @@ class Convolution
|
||||
//! Locally-stored stride of the filter in y-direction.
|
||||
size_t dH;
|
||||
|
||||
//! Locally-stored padding width.
|
||||
size_t padW;
|
||||
//! Locally-stored left-side padding width.
|
||||
size_t padWLeft;
|
||||
|
||||
//! Locally-stored padding height.
|
||||
size_t padH;
|
||||
//! Locally-stored right-side padding width.
|
||||
size_t padWRight;
|
||||
|
||||
//! Locally-stored bottom padding height.
|
||||
size_t padHBottom;
|
||||
|
||||
//! Locally-stored top padding height.
|
||||
size_t padHTop;
|
||||
|
||||
//! Locally-stored weight object.
|
||||
OutputDataType weights;
|
||||
@@ -324,6 +328,9 @@ class Convolution
|
||||
//! Locally-stored transformed gradient parameter.
|
||||
arma::cube gradientTemp;
|
||||
|
||||
//! Locally-stored padding layer.
|
||||
Padding<>* padding;
|
||||
|
||||
//! Locally-stored delta object.
|
||||
OutputDataType delta;
|
||||
|
||||
@@ -340,6 +347,27 @@ class Convolution
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
//! Set the serialization version of the Convolution class.
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
template<
|
||||
typename ForwardConvolutionRule,
|
||||
typename BackwardConvolutionRule,
|
||||
typename GradientConvolutionRule,
|
||||
typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
struct version<
|
||||
mlpack::ann::Convolution<ForwardConvolutionRule, BackwardConvolutionRule,
|
||||
GradientConvolutionRule, InputDataType, OutputDataType> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(int, value = 1);
|
||||
};
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
|
||||
// Include implementation.
|
||||
#include "convolution_impl.hpp"
|
||||
|
||||
|
||||
@@ -59,21 +59,105 @@ Convolution<
|
||||
const size_t padW,
|
||||
const size_t padH,
|
||||
const size_t inputWidth,
|
||||
const size_t inputHeight) :
|
||||
const size_t inputHeight,
|
||||
const std::string paddingType) :
|
||||
inSize(inSize),
|
||||
outSize(outSize),
|
||||
kW(kW),
|
||||
kH(kH),
|
||||
dW(dW),
|
||||
dH(dH),
|
||||
padW(padW),
|
||||
padH(padH),
|
||||
padWLeft(padW),
|
||||
padWRight(padW),
|
||||
padHBottom(padH),
|
||||
padHTop(padH),
|
||||
inputWidth(inputWidth),
|
||||
inputHeight(inputHeight),
|
||||
outputWidth(0),
|
||||
outputHeight(0)
|
||||
{
|
||||
weights.set_size((outSize * inSize * kW * kH) + outSize, 1);
|
||||
|
||||
// Transform paddingType to lowercase.
|
||||
std::string paddingTypeLow = paddingType;
|
||||
std::transform(paddingType.begin(), paddingType.end(), paddingTypeLow.begin(),
|
||||
[](unsigned char c){ return std::tolower(c); });
|
||||
|
||||
if (paddingTypeLow == "valid")
|
||||
{
|
||||
padWLeft = 0;
|
||||
padWRight = 0;
|
||||
padHTop = 0;
|
||||
padHBottom = 0;
|
||||
}
|
||||
else if (paddingTypeLow == "same")
|
||||
{
|
||||
InitializeSamePadding();
|
||||
}
|
||||
|
||||
padding = new Padding<>(padWLeft, padWRight, padHTop, padHBottom);
|
||||
}
|
||||
|
||||
template<
|
||||
typename ForwardConvolutionRule,
|
||||
typename BackwardConvolutionRule,
|
||||
typename GradientConvolutionRule,
|
||||
typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
Convolution<
|
||||
ForwardConvolutionRule,
|
||||
BackwardConvolutionRule,
|
||||
GradientConvolutionRule,
|
||||
InputDataType,
|
||||
OutputDataType
|
||||
>::Convolution(
|
||||
const size_t inSize,
|
||||
const size_t outSize,
|
||||
const size_t kW,
|
||||
const size_t kH,
|
||||
const size_t dW,
|
||||
const size_t dH,
|
||||
const std::tuple<size_t, size_t> padW,
|
||||
const std::tuple<size_t, size_t> padH,
|
||||
const size_t inputWidth,
|
||||
const size_t inputHeight,
|
||||
const std::string paddingType) :
|
||||
inSize(inSize),
|
||||
outSize(outSize),
|
||||
kW(kW),
|
||||
kH(kH),
|
||||
dW(dW),
|
||||
dH(dH),
|
||||
padWLeft(std::get<0>(padW)),
|
||||
padWRight(std::get<1>(padW)),
|
||||
padHBottom(std::get<1>(padH)),
|
||||
padHTop(std::get<0>(padH)),
|
||||
inputWidth(inputWidth),
|
||||
inputHeight(inputHeight),
|
||||
outputWidth(0),
|
||||
outputHeight(0)
|
||||
{
|
||||
weights.set_size((outSize * inSize * kW * kH) + outSize, 1);
|
||||
|
||||
// Transform paddingType to lowercase.
|
||||
std::string paddingTypeLow = paddingType;
|
||||
std::transform(paddingType.begin(), paddingType.end(), paddingTypeLow.begin(),
|
||||
[](unsigned char c){ return std::tolower(c); });
|
||||
|
||||
if (paddingTypeLow == "valid")
|
||||
{
|
||||
padWLeft = 0;
|
||||
padWRight = 0;
|
||||
padHTop = 0;
|
||||
padHBottom = 0;
|
||||
}
|
||||
else if (paddingTypeLow == "same")
|
||||
{
|
||||
InitializeSamePadding();
|
||||
}
|
||||
|
||||
padding = new Padding<>(padWLeft, padWRight, padHTop, padHBottom);
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -117,13 +201,20 @@ void Convolution<
|
||||
inputTemp = arma::cube(const_cast<arma::Mat<eT>&&>(input).memptr(),
|
||||
inputWidth, inputHeight, inSize * batchSize, false, false);
|
||||
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
Pad(inputTemp, padW, padH, inputPaddedTemp);
|
||||
inputPaddedTemp.set_size(inputTemp.n_rows + padWLeft + padWRight,
|
||||
inputTemp.n_cols + padHTop + padHBottom, inputTemp.n_slices);
|
||||
|
||||
for (size_t i = 0; i < inputTemp.n_slices; ++i)
|
||||
{
|
||||
padding->Forward(std::move(inputTemp.slice(i)),
|
||||
std::move(inputPaddedTemp.slice(i)));
|
||||
}
|
||||
}
|
||||
|
||||
size_t wConv = ConvOutSize(inputWidth, kW, dW, padW);
|
||||
size_t hConv = ConvOutSize(inputHeight, kH, dH, padH);
|
||||
size_t wConv = ConvOutSize(inputWidth, kW, dW, padWLeft, padWRight);
|
||||
size_t hConv = ConvOutSize(inputHeight, kH, dH, padHTop, padHBottom);
|
||||
|
||||
output.set_size(wConv * hConv * outSize, batchSize);
|
||||
outputTemp = arma::Cube<eT>(output.memptr(), wConv, hConv,
|
||||
@@ -143,7 +234,7 @@ void Convolution<
|
||||
{
|
||||
arma::Mat<eT> convOutput;
|
||||
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
ForwardConvolutionRule::Convolution(inputPaddedTemp.slice(inMap +
|
||||
batchCount * inSize), weight.slice(outMapIdx), convOutput, dW, dH);
|
||||
@@ -206,11 +297,10 @@ void Convolution<
|
||||
BackwardConvolutionRule::Convolution(mappedError.slice(outMap),
|
||||
rotatedFilter, output, dW, dH);
|
||||
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
gTemp.slice(inMap + batchCount * inSize) += output.submat(padW, padH,
|
||||
padW + gTemp.n_rows - 1,
|
||||
padH + gTemp.n_cols - 1);
|
||||
gTemp.slice(inMap + batchCount * inSize) += output.submat(padWLeft,
|
||||
padHTop, padWLeft + gTemp.n_rows - 1, padHTop + gTemp.n_cols - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -259,7 +349,7 @@ void Convolution<
|
||||
for (size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
|
||||
{
|
||||
arma::Mat<eT> inputSlice;
|
||||
if (padW != 0 || padH != 0)
|
||||
if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
|
||||
{
|
||||
inputSlice = inputPaddedTemp.slice(inMap + batchCount * inSize);
|
||||
}
|
||||
@@ -311,8 +401,7 @@ void Convolution<
|
||||
GradientConvolutionRule,
|
||||
InputDataType,
|
||||
OutputDataType
|
||||
>::serialize(
|
||||
Archive& ar, const unsigned int /* version */)
|
||||
>::serialize(Archive& ar, const unsigned int version)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(inSize);
|
||||
ar & BOOST_SERIALIZATION_NVP(outSize);
|
||||
@@ -321,17 +410,49 @@ void Convolution<
|
||||
ar & BOOST_SERIALIZATION_NVP(kH);
|
||||
ar & BOOST_SERIALIZATION_NVP(dW);
|
||||
ar & BOOST_SERIALIZATION_NVP(dH);
|
||||
ar & BOOST_SERIALIZATION_NVP(padW);
|
||||
ar & BOOST_SERIALIZATION_NVP(padH);
|
||||
ar & BOOST_SERIALIZATION_NVP(padWLeft);
|
||||
ar & BOOST_SERIALIZATION_NVP(padWRight);
|
||||
ar & BOOST_SERIALIZATION_NVP(padHBottom);
|
||||
ar & BOOST_SERIALIZATION_NVP(padHTop);
|
||||
ar & BOOST_SERIALIZATION_NVP(inputWidth);
|
||||
ar & BOOST_SERIALIZATION_NVP(inputHeight);
|
||||
ar & BOOST_SERIALIZATION_NVP(outputWidth);
|
||||
ar & BOOST_SERIALIZATION_NVP(outputHeight);
|
||||
|
||||
if (version > 0)
|
||||
ar & BOOST_SERIALIZATION_NVP(padding);
|
||||
|
||||
if (Archive::is_loading::value)
|
||||
weights.set_size((outSize * inSize * kW * kH) + outSize, 1);
|
||||
}
|
||||
|
||||
template<
|
||||
typename ForwardConvolutionRule,
|
||||
typename BackwardConvolutionRule,
|
||||
typename GradientConvolutionRule,
|
||||
typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
void Convolution<
|
||||
ForwardConvolutionRule,
|
||||
BackwardConvolutionRule,
|
||||
GradientConvolutionRule,
|
||||
InputDataType,
|
||||
OutputDataType
|
||||
>::InitializeSamePadding()
|
||||
{
|
||||
/*
|
||||
* Using O = (W - F + 2P) / s + 1;
|
||||
*/
|
||||
size_t totalVerticalPadding = (dW - 1) * inputWidth + kW - dW;
|
||||
size_t totalHorizontalPadding = (dH - 1) * inputHeight + kH - dH;
|
||||
|
||||
padWLeft = totalVerticalPadding / 2;
|
||||
padWRight = totalVerticalPadding - totalVerticalPadding / 2;
|
||||
padHTop = totalHorizontalPadding / 2;
|
||||
padHBottom = totalHorizontalPadding - totalHorizontalPadding / 2;
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ namespace ann /** Artificial Neural Network. */ {
|
||||
* Note that FastLSTM network layer does not use peephole connections between
|
||||
* the cell and gates.
|
||||
*
|
||||
* Note also that if a FastLSTM layer is desired as the first layer of a neural
|
||||
* network, an IdentityLayer should be added to the network as the first layer,
|
||||
* and then the FastLSTM layer should be added.
|
||||
*
|
||||
* For more information, see the following.
|
||||
*
|
||||
* @code
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* @file highway.hpp
|
||||
* @author Konstantin Sidorov
|
||||
* @author Saksham Bansal
|
||||
*
|
||||
* Definition of the Highway layer.
|
||||
*
|
||||
* 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_LAYER_HIGHWAY_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_HIGHWAY_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
#include "../visitor/delete_visitor.hpp"
|
||||
#include "../visitor/delta_visitor.hpp"
|
||||
#include "../visitor/output_height_visitor.hpp"
|
||||
#include "../visitor/output_parameter_visitor.hpp"
|
||||
#include "../visitor/output_width_visitor.hpp"
|
||||
|
||||
#include "layer_types.hpp"
|
||||
#include "add_merge.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
/**
|
||||
* Implementation of the Highway layer. The Highway class can vary its behavior
|
||||
* between that of feed-forward fully connected network container and that
|
||||
* of a layer which simply passes its inputs through depending on the transform
|
||||
* gate. Note that the size of the input and output matrices of this class
|
||||
* should be equal.
|
||||
*
|
||||
* For more information, refer the following paper.
|
||||
*
|
||||
* @code
|
||||
* @article{Srivastava2015,
|
||||
* author = {Rupesh Kumar Srivastava, Klaus Greff, Jurgen Schmidhuber},
|
||||
* title = {Training Very Deep Networks},
|
||||
* journal = {Advances in Neural Information Processing Systems},
|
||||
* year = {2015},
|
||||
* url = {https://arxiv.org/abs/1507.06228},
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @tparam InputDataType Type of the input data (arma::colvec, arma::mat,
|
||||
* arma::sp_mat or arma::cube).
|
||||
* @tparam OutputDataType Type of the output data (arma::colvec, arma::mat,
|
||||
* arma::sp_mat or arma::cube).
|
||||
*/
|
||||
template <
|
||||
typename InputDataType = arma::mat,
|
||||
typename OutputDataType = arma::mat,
|
||||
typename... CustomLayers>
|
||||
class Highway
|
||||
{
|
||||
public:
|
||||
//! Create the Highway object.
|
||||
Highway();
|
||||
|
||||
/**
|
||||
* Create the Highway object.
|
||||
*
|
||||
* @param inSize The number of input units.
|
||||
* @param model Expose all the network modules.
|
||||
*/
|
||||
Highway(const size_t inSize, const bool model = true);
|
||||
|
||||
//! Destroy the Highway object.
|
||||
~Highway();
|
||||
|
||||
/**
|
||||
* Destroy all the modules added to the Highway object.
|
||||
*/
|
||||
void DeleteModules();
|
||||
|
||||
/**
|
||||
* Reset the layer parameter.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Ordinary feed-forward pass of a neural network, evaluating the function
|
||||
* f(x) by propagating the activity forward through f.
|
||||
*
|
||||
* @param input Input data used for evaluating the specified function.
|
||||
* @param output Resulting output activation.
|
||||
*/
|
||||
template<typename eT>
|
||||
void Forward(arma::Mat<eT>&& input, arma::Mat<eT>&& output);
|
||||
|
||||
/**
|
||||
* Ordinary feed-backward pass of a neural network, calculating the function
|
||||
* f(x) by propagating x backwards through f. Using the results from the
|
||||
* feed-forward pass.
|
||||
*
|
||||
* @param input The propagated input activation.
|
||||
* @param gy The backpropagated error.
|
||||
* @param g The calculated gradient.
|
||||
*/
|
||||
template<typename eT>
|
||||
void Backward(const arma::Mat<eT>&& /* input */,
|
||||
arma::Mat<eT>&& gy,
|
||||
arma::Mat<eT>&& g);
|
||||
|
||||
/**
|
||||
* Calculate the gradient using the output delta and the input activation.
|
||||
*
|
||||
* @param input The input parameter used for calculating the gradient.
|
||||
* @param error The calculated error.
|
||||
* @param gradient The calculated gradient.
|
||||
*/
|
||||
template<typename eT>
|
||||
void Gradient(arma::Mat<eT>&& input,
|
||||
arma::Mat<eT>&& error,
|
||||
arma::Mat<eT>&& gradient);
|
||||
|
||||
/**
|
||||
* Add a new module to the model.
|
||||
*
|
||||
* @param args The layer parameter.
|
||||
*/
|
||||
template <class LayerType, class... Args>
|
||||
void Add(Args... args) { network.push_back(new LayerType(args...)); }
|
||||
|
||||
/**
|
||||
* Add a new module to the model.
|
||||
*
|
||||
* @param layer The Layer to be added to the model.
|
||||
*/
|
||||
void Add(LayerTypes<CustomLayers...> layer) { network.push_back(layer); }
|
||||
|
||||
//! Return the modules of the model.
|
||||
std::vector<LayerTypes<CustomLayers...> >& Model()
|
||||
{
|
||||
if (model)
|
||||
{
|
||||
return network;
|
||||
}
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
//! Get the parameters.
|
||||
OutputDataType const& Parameters() const { return weights; }
|
||||
//! Modify the parameters.
|
||||
OutputDataType& Parameters() { return weights; }
|
||||
|
||||
//! Get the input parameter.
|
||||
InputDataType const& InputParameter() const { return inputParameter; }
|
||||
//! Modify the input parameter.
|
||||
InputDataType& InputParameter() { return inputParameter; }
|
||||
|
||||
//! Get the output parameter.
|
||||
OutputDataType const& OutputParameter() const { return outputParameter; }
|
||||
//! Modify the output parameter.
|
||||
OutputDataType& OutputParameter() { return outputParameter; }
|
||||
|
||||
//! Get the delta.
|
||||
OutputDataType const& Delta() const { return delta; }
|
||||
//! Modify the delta.
|
||||
OutputDataType& Delta() { return delta; }
|
||||
|
||||
//! Get the gradient.
|
||||
OutputDataType const& Gradient() const { return gradient; }
|
||||
//! Modify the gradient.
|
||||
OutputDataType& Gradient() { return gradient; }
|
||||
|
||||
/**
|
||||
* Serialize the layer.
|
||||
*/
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int /* version */);
|
||||
|
||||
private:
|
||||
//! Locally-stored number of input units.
|
||||
size_t inSize;
|
||||
|
||||
//! Parameter which indicates if the modules should be exposed.
|
||||
bool model;
|
||||
|
||||
//! Indicator if we already initialized the model.
|
||||
bool reset;
|
||||
|
||||
//! Locally-stored network modules.
|
||||
std::vector<LayerTypes<CustomLayers...> > network;
|
||||
|
||||
//! Locally-stored empty list of modules.
|
||||
std::vector<LayerTypes<CustomLayers...> > empty;
|
||||
|
||||
//! Locally-stored weight object.
|
||||
OutputDataType weights;
|
||||
|
||||
//! Locally-stored delta object.
|
||||
OutputDataType delta;
|
||||
|
||||
//! Locally-stored gradient object.
|
||||
OutputDataType gradient;
|
||||
|
||||
//! Weights for transformation of output.
|
||||
OutputDataType transformWeight;
|
||||
|
||||
//! Bias for transformation of output.
|
||||
OutputDataType transformBias;
|
||||
|
||||
//! Locally-stored transform gate parameters.
|
||||
OutputDataType transformGate;
|
||||
|
||||
//! Locally-stored transform gate activation.
|
||||
OutputDataType transformGateActivation;
|
||||
|
||||
//! Locally-stored transform gate error.
|
||||
OutputDataType transformGateError;
|
||||
|
||||
//! Locally-stored input parameter object.
|
||||
InputDataType inputParameter;
|
||||
|
||||
//! Locally-stored output parameter object.
|
||||
OutputDataType outputParameter;
|
||||
|
||||
//! The input width.
|
||||
size_t width;
|
||||
|
||||
//! The input height.
|
||||
size_t height;
|
||||
|
||||
//! The normal output without highway network.
|
||||
OutputDataType networkOutput;
|
||||
|
||||
//! Locally-stored delta visitor.
|
||||
DeltaVisitor deltaVisitor;
|
||||
|
||||
//! Locally-stored output parameter visitor.
|
||||
OutputParameterVisitor outputParameterVisitor;
|
||||
|
||||
//! Locally-stored delete visitor.
|
||||
DeleteVisitor deleteVisitor;
|
||||
|
||||
//! Locally-stored output width visitor.
|
||||
OutputWidthVisitor outputWidthVisitor;
|
||||
|
||||
//! Locally-stored output height visitor.
|
||||
OutputHeightVisitor outputHeightVisitor;
|
||||
}; // class Highway
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation.
|
||||
#include "highway_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,249 @@
|
||||
/**
|
||||
* @file highway_impl.hpp
|
||||
* @author Konstantin Sidorov
|
||||
* @author Saksham Bansal
|
||||
*
|
||||
* Implementation of Highway layer.
|
||||
*
|
||||
* 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_LAYER_HIGHWAY_IMPL_HPP
|
||||
#define MLPACK_METHODS_ANN_LAYER_HIGHWAY_IMPL_HPP
|
||||
|
||||
// In case it hasn't yet been included.
|
||||
#include "highway.hpp"
|
||||
|
||||
#include "../visitor/forward_visitor.hpp"
|
||||
#include "../visitor/backward_visitor.hpp"
|
||||
#include "../visitor/gradient_visitor.hpp"
|
||||
#include "../visitor/set_input_height_visitor.hpp"
|
||||
#include "../visitor/set_input_width_visitor.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
Highway<InputDataType, OutputDataType, CustomLayers...>::Highway() :
|
||||
inSize(0),
|
||||
model(true),
|
||||
reset(false),
|
||||
width(0),
|
||||
height(0)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputDataType, typename OutputDataType, typename... CustomLayers>
|
||||
Highway<InputDataType, OutputDataType, CustomLayers...>::Highway(
|
||||
const size_t inSize,
|
||||
const bool model) :
|
||||
inSize(inSize),
|
||||
model(model),
|
||||
reset(false),
|
||||
width(0),
|
||||
height(0)
|
||||
{
|
||||
weights.set_size(inSize * inSize + inSize, 1);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
Highway<InputDataType, OutputDataType, CustomLayers...>::~Highway()
|
||||
{
|
||||
if (!model)
|
||||
{
|
||||
for (LayerTypes<CustomLayers...>& layer : network)
|
||||
{
|
||||
boost::apply_visitor(deleteVisitor, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
void Highway<
|
||||
InputDataType, OutputDataType, CustomLayers...>::DeleteModules()
|
||||
{
|
||||
if (model)
|
||||
{
|
||||
for (LayerTypes<CustomLayers...>& layer : network)
|
||||
{
|
||||
boost::apply_visitor(deleteVisitor, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
void Highway<InputDataType, OutputDataType, CustomLayers...>::Reset()
|
||||
{
|
||||
transformWeight = arma::mat(weights.memptr(), inSize, inSize, false, false);
|
||||
transformBias = arma::mat(weights.memptr() + transformWeight.n_elem,
|
||||
inSize, 1, false, false);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
template<typename eT>
|
||||
void Highway<InputDataType, OutputDataType, CustomLayers...>::Forward(
|
||||
arma::Mat<eT>&& input, arma::Mat<eT>&& output)
|
||||
{
|
||||
boost::apply_visitor(ForwardVisitor(std::move(input), std::move(
|
||||
boost::apply_visitor(outputParameterVisitor, network.front()))),
|
||||
network.front());
|
||||
|
||||
if (!reset)
|
||||
{
|
||||
if (boost::apply_visitor(outputWidthVisitor, network.front()) != 0)
|
||||
{
|
||||
width = boost::apply_visitor(outputWidthVisitor, network.front());
|
||||
}
|
||||
|
||||
if (boost::apply_visitor(outputHeightVisitor, network.front()) != 0)
|
||||
{
|
||||
height = boost::apply_visitor(outputHeightVisitor, network.front());
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < network.size(); ++i)
|
||||
{
|
||||
if (!reset)
|
||||
{
|
||||
// Set the input width.
|
||||
boost::apply_visitor(SetInputWidthVisitor(width), network[i]);
|
||||
|
||||
// Set the input height.
|
||||
boost::apply_visitor(SetInputHeightVisitor(height), network[i]);
|
||||
}
|
||||
|
||||
boost::apply_visitor(ForwardVisitor(std::move(boost::apply_visitor(
|
||||
outputParameterVisitor, network[i - 1])), std::move(
|
||||
boost::apply_visitor(outputParameterVisitor, network[i]))),
|
||||
network[i]);
|
||||
|
||||
if (!reset)
|
||||
{
|
||||
// Get the output width.
|
||||
if (boost::apply_visitor(outputWidthVisitor, network[i]) != 0)
|
||||
{
|
||||
width = boost::apply_visitor(outputWidthVisitor, network[i]);
|
||||
}
|
||||
|
||||
// Get the output height.
|
||||
if (boost::apply_visitor(outputHeightVisitor, network[i]) != 0)
|
||||
{
|
||||
height = boost::apply_visitor(outputHeightVisitor, network[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!reset)
|
||||
{
|
||||
reset = true;
|
||||
}
|
||||
|
||||
output = boost::apply_visitor(outputParameterVisitor, network.back());
|
||||
|
||||
if (arma::size(output) != arma::size(input))
|
||||
{
|
||||
Log::Fatal << "The sizes of the output and input matrices of the Highway"
|
||||
<< " network should be equal. Please examine the network layers.";
|
||||
}
|
||||
|
||||
transformGate = transformWeight * input;
|
||||
transformGate.each_col() += transformBias;
|
||||
transformGateActivation = 1.0 /(1 + arma::exp(-transformGate));
|
||||
inputParameter = input;
|
||||
networkOutput = output;
|
||||
output = (output % transformGateActivation) +
|
||||
(input % (1 - transformGateActivation));
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
template<typename eT>
|
||||
void Highway<InputDataType, OutputDataType, CustomLayers...>::Backward(
|
||||
const arma::Mat<eT>&& /* input */,
|
||||
arma::Mat<eT>&& gy,
|
||||
arma::Mat<eT>&& g)
|
||||
{
|
||||
boost::apply_visitor(BackwardVisitor(std::move(boost::apply_visitor(
|
||||
outputParameterVisitor, network.back())),
|
||||
std::move(gy % transformGateActivation),
|
||||
std::move(boost::apply_visitor(deltaVisitor, network.back()))),
|
||||
network.back());
|
||||
|
||||
for (size_t i = 2; i < network.size() + 1; ++i)
|
||||
{
|
||||
boost::apply_visitor(BackwardVisitor(std::move(boost::apply_visitor(
|
||||
outputParameterVisitor, network[network.size() - i])), std::move(
|
||||
boost::apply_visitor(deltaVisitor, network[network.size() - i + 1])),
|
||||
std::move(boost::apply_visitor(deltaVisitor,
|
||||
network[network.size() - i]))), network[network.size() - i]);
|
||||
}
|
||||
|
||||
g = boost::apply_visitor(deltaVisitor, network.front());
|
||||
|
||||
transformGateError = gy % (networkOutput - inputParameter) %
|
||||
transformGateActivation % (1.0 - transformGateActivation);
|
||||
g += transformWeight.t() * transformGateError;
|
||||
g += gy % (1 - transformGateActivation);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
template<typename eT>
|
||||
void Highway<InputDataType, OutputDataType, CustomLayers...>::Gradient(
|
||||
arma::Mat<eT>&& input,
|
||||
arma::Mat<eT>&& error,
|
||||
arma::Mat<eT>&& gradient)
|
||||
{
|
||||
boost::apply_visitor(GradientVisitor(std::move(boost::apply_visitor(
|
||||
outputParameterVisitor, network[network.size() - 2])),
|
||||
std::move(error % transformGateActivation)), network.back());
|
||||
|
||||
for (size_t i = 2; i < network.size(); ++i)
|
||||
{
|
||||
boost::apply_visitor(GradientVisitor(std::move(boost::apply_visitor(
|
||||
outputParameterVisitor, network[network.size() - i - 1])), std::move(
|
||||
boost::apply_visitor(deltaVisitor, network[network.size() - i + 1]))),
|
||||
network[network.size() - i]);
|
||||
}
|
||||
|
||||
boost::apply_visitor(GradientVisitor(std::move(input), std::move(
|
||||
boost::apply_visitor(deltaVisitor, network[1]))), network.front());
|
||||
|
||||
gradient.submat(0, 0, transformWeight.n_elem - 1, 0) = arma::vectorise(
|
||||
transformGateError * input.t());
|
||||
gradient.submat(transformWeight.n_elem, 0, gradient.n_elem - 1, 0) =
|
||||
arma::sum(transformGateError, 1);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename... CustomLayers>
|
||||
template<typename Archive>
|
||||
void Highway<InputDataType, OutputDataType, CustomLayers...>::serialize(
|
||||
Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
// If loading, delete the old layers and set size for weights.
|
||||
if (Archive::is_loading::value)
|
||||
{
|
||||
for (LayerTypes<CustomLayers...>& layer : network)
|
||||
{
|
||||
boost::apply_visitor(deleteVisitor, layer);
|
||||
}
|
||||
weights.set_size(inSize * inSize + inSize, 1);
|
||||
}
|
||||
|
||||
ar & BOOST_SERIALIZATION_NVP(model);
|
||||
ar & BOOST_SERIALIZATION_NVP(network);
|
||||
}
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -19,12 +19,15 @@
|
||||
#include "convolution.hpp"
|
||||
#include "dropconnect.hpp"
|
||||
#include "glimpse.hpp"
|
||||
#include "highway.hpp"
|
||||
#include "layer_norm.hpp"
|
||||
#include "layer_types.hpp"
|
||||
#include "linear.hpp"
|
||||
#include "linear_no_bias.hpp"
|
||||
#include "lstm.hpp"
|
||||
#include "minibatch_discrimination.hpp"
|
||||
#include "multiply_merge.hpp"
|
||||
#include "padding.hpp"
|
||||
#include "gru.hpp"
|
||||
#include "fast_lstm.hpp"
|
||||
#include "recurrent.hpp"
|
||||
@@ -35,5 +38,6 @@
|
||||
#include "concat.hpp"
|
||||
#include "vr_class_reward.hpp"
|
||||
#include "transposed_convolution.hpp"
|
||||
#include "weight_norm.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -155,7 +155,7 @@ class LayerNorm
|
||||
//! Locally-stored epsilon value.
|
||||
double eps;
|
||||
|
||||
//! Whether we are in loading or saving mode.
|
||||
//! Variable to keep track of whether we are in loading or saving mode.
|
||||
bool loading;
|
||||
|
||||
//! Locally-stored scale parameter.
|
||||
|
||||
@@ -82,7 +82,7 @@ void LayerNorm<InputDataType, OutputDataType>::Backward(
|
||||
{
|
||||
const arma::mat stdInv = 1.0 / arma::sqrt(variance + eps);
|
||||
|
||||
// dl / dxhat
|
||||
// dl / dxhat.
|
||||
const arma::mat norm = gy.each_col() % gamma;
|
||||
|
||||
// sum dl / dxhat * (x - mu) * -0.5 * stdInv^3.
|
||||
|
||||
@@ -112,6 +112,10 @@ HAS_MEM_FUNC(Loss, HasLoss);
|
||||
// can use with SFINAE to catch when a type has a Run() function.
|
||||
HAS_MEM_FUNC(Run, HasRunCheck);
|
||||
|
||||
// This gives us a HasBiasCheck<T, U> type (where U is a function pointer) we
|
||||
// can use with SFINAE to catch when a type has a Bias() function.
|
||||
HAS_MEM_FUNC(Bias, HasBiasCheck);
|
||||
|
||||
} // namespace ann
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -40,12 +40,16 @@
|
||||
#include <mlpack/methods/ann/layer/reparametrization.hpp>
|
||||
#include <mlpack/methods/ann/layer/select.hpp>
|
||||
#include <mlpack/methods/ann/layer/subview.hpp>
|
||||
#include <mlpack/methods/ann/layer/virtual_batch_norm.hpp>
|
||||
|
||||
// Convolution modules.
|
||||
#include <mlpack/methods/ann/convolution_rules/border_modes.hpp>
|
||||
#include <mlpack/methods/ann/convolution_rules/naive_convolution.hpp>
|
||||
#include <mlpack/methods/ann/convolution_rules/fft_convolution.hpp>
|
||||
|
||||
// Regularizers.
|
||||
#include <mlpack/methods/ann/regularizer/no_regularizer.hpp>
|
||||
|
||||
// Loss function modules.
|
||||
#include <mlpack/methods/ann/loss_functions/negative_log_likelihood.hpp>
|
||||
|
||||
@@ -56,13 +60,32 @@ template<typename InputDataType, typename OutputDataType> class BatchNorm;
|
||||
template<typename InputDataType, typename OutputDataType> class DropConnect;
|
||||
template<typename InputDataType, typename OutputDataType> class Glimpse;
|
||||
template<typename InputDataType, typename OutputDataType> class LayerNorm;
|
||||
template<typename InputDataType, typename OutputDataType> class Linear;
|
||||
template<typename InputDataType, typename OutputDataType> class LinearNoBias;
|
||||
template<typename InputDataType, typename OutputDataType> class LSTM;
|
||||
template<typename InputDataType, typename OutputDataType> class GRU;
|
||||
template<typename InputDataType, typename OutputDataType> class FastLSTM;
|
||||
template<typename InputDataType, typename OutputDataType> class VRClassReward;
|
||||
template<typename InputDataType, typename OutputDataType> class Concatenate;
|
||||
template<typename InputDataType, typename OutputDataType> class Padding;
|
||||
|
||||
template<typename InputDataType,
|
||||
typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
class Linear;
|
||||
|
||||
template<typename InputDataType,
|
||||
typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
class LinearNoBias;
|
||||
|
||||
template<typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
class VirtualBatchNorm;
|
||||
|
||||
template<typename InputDataType,
|
||||
typename OutputDataType
|
||||
>
|
||||
class MiniBatchDiscrimination;
|
||||
|
||||
template<typename InputDataType,
|
||||
typename OutputDataType
|
||||
@@ -82,6 +105,12 @@ template<typename InputDataType,
|
||||
>
|
||||
class Sequential;
|
||||
|
||||
template<typename InputDataType,
|
||||
typename OutputDataType,
|
||||
typename... CustomLayers
|
||||
>
|
||||
class Highway;
|
||||
|
||||
template<typename InputDataType,
|
||||
typename OutputDataType,
|
||||
typename... CustomLayers
|
||||
@@ -140,6 +169,25 @@ template<typename InputDataType,
|
||||
>
|
||||
class MultiplyMerge;
|
||||
|
||||
template <typename InputDataType,
|
||||
typename OutputDataType,
|
||||
typename... CustomLayers
|
||||
>
|
||||
class WeightNorm;
|
||||
|
||||
using MoreTypes = boost::variant<
|
||||
Recurrent<arma::mat, arma::mat>*,
|
||||
RecurrentAttention<arma::mat, arma::mat>*,
|
||||
ReinforceNormal<arma::mat, arma::mat>*,
|
||||
Reparametrization<arma::mat, arma::mat>*,
|
||||
Select<arma::mat, arma::mat>*,
|
||||
Sequential<arma::mat, arma::mat, false>*,
|
||||
Sequential<arma::mat, arma::mat, true>*,
|
||||
Subview<arma::mat, arma::mat>*,
|
||||
VRClassReward<arma::mat, arma::mat>*,
|
||||
VirtualBatchNorm<arma::mat, arma::mat>*
|
||||
>;
|
||||
|
||||
template <typename... CustomLayers>
|
||||
using LayerTypes = boost::variant<
|
||||
Add<arma::mat, arma::mat>*,
|
||||
@@ -164,7 +212,7 @@ using LayerTypes = boost::variant<
|
||||
NaiveConvolution<FullConvolution>,
|
||||
NaiveConvolution<ValidConvolution>, arma::mat, arma::mat>*,
|
||||
TransposedConvolution<NaiveConvolution<ValidConvolution>,
|
||||
NaiveConvolution<FullConvolution>,
|
||||
NaiveConvolution<ValidConvolution>,
|
||||
NaiveConvolution<ValidConvolution>, arma::mat, arma::mat>*,
|
||||
DropConnect<arma::mat, arma::mat>*,
|
||||
Dropout<arma::mat, arma::mat>*,
|
||||
@@ -173,12 +221,13 @@ using LayerTypes = boost::variant<
|
||||
FlexibleReLU<arma::mat, arma::mat>*,
|
||||
Glimpse<arma::mat, arma::mat>*,
|
||||
HardTanH<arma::mat, arma::mat>*,
|
||||
Highway<arma::mat, arma::mat>*,
|
||||
Join<arma::mat, arma::mat>*,
|
||||
LayerNorm<arma::mat, arma::mat>*,
|
||||
LeakyReLU<arma::mat, arma::mat>*,
|
||||
CReLU<arma::mat, arma::mat>*,
|
||||
Linear<arma::mat, arma::mat>*,
|
||||
LinearNoBias<arma::mat, arma::mat>*,
|
||||
Linear<arma::mat, arma::mat, NoRegularizer>*,
|
||||
LinearNoBias<arma::mat, arma::mat, NoRegularizer>*,
|
||||
LogSoftMax<arma::mat, arma::mat>*,
|
||||
Lookup<arma::mat, arma::mat>*,
|
||||
LSTM<arma::mat, arma::mat>*,
|
||||
@@ -186,19 +235,14 @@ using LayerTypes = boost::variant<
|
||||
FastLSTM<arma::mat, arma::mat>*,
|
||||
MaxPooling<arma::mat, arma::mat>*,
|
||||
MeanPooling<arma::mat, arma::mat>*,
|
||||
MiniBatchDiscrimination<arma::mat, arma::mat>*,
|
||||
MultiplyConstant<arma::mat, arma::mat>*,
|
||||
MultiplyMerge<arma::mat, arma::mat>*,
|
||||
NegativeLogLikelihood<arma::mat, arma::mat>*,
|
||||
Padding<arma::mat, arma::mat>*,
|
||||
PReLU<arma::mat, arma::mat>*,
|
||||
Recurrent<arma::mat, arma::mat>*,
|
||||
RecurrentAttention<arma::mat, arma::mat>*,
|
||||
ReinforceNormal<arma::mat, arma::mat>*,
|
||||
Reparametrization<arma::mat, arma::mat>*,
|
||||
Select<arma::mat, arma::mat>*,
|
||||
Sequential<arma::mat, arma::mat, false>*,
|
||||
Sequential<arma::mat, arma::mat, true>*,
|
||||
Subview<arma::mat, arma::mat>*,
|
||||
VRClassReward<arma::mat, arma::mat>*,
|
||||
WeightNorm<arma::mat, arma::mat>*,
|
||||
MoreTypes,
|
||||
CustomLayers*...
|
||||
>;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define MLPACK_METHODS_ANN_LAYER_LINEAR_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/methods/ann/regularizer/no_regularizer.hpp>
|
||||
|
||||
#include "layer_types.hpp"
|
||||
|
||||
@@ -31,7 +32,8 @@ namespace ann /** Artificial Neural Network. */ {
|
||||
*/
|
||||
template <
|
||||
typename InputDataType = arma::mat,
|
||||
typename OutputDataType = arma::mat
|
||||
typename OutputDataType = arma::mat,
|
||||
typename RegularizerType = NoRegularizer
|
||||
>
|
||||
class Linear
|
||||
{
|
||||
@@ -45,7 +47,9 @@ class Linear
|
||||
* @param inSize The number of input units.
|
||||
* @param outSize The number of output units.
|
||||
*/
|
||||
Linear(const size_t inSize, const size_t outSize);
|
||||
Linear(const size_t inSize,
|
||||
const size_t outSize,
|
||||
RegularizerType regularizer = RegularizerType());
|
||||
|
||||
/*
|
||||
* Reset the layer parameter.
|
||||
@@ -113,6 +117,9 @@ class Linear
|
||||
//! Modify the gradient.
|
||||
OutputDataType& Gradient() { return gradient; }
|
||||
|
||||
//! Modify the bias weights of the layer.
|
||||
arma::mat& Bias() { return bias; }
|
||||
|
||||
/**
|
||||
* Serialize the layer
|
||||
*/
|
||||
@@ -146,6 +153,9 @@ class Linear
|
||||
|
||||
//! Locally-stored output parameter object.
|
||||
OutputDataType outputParameter;
|
||||
|
||||
//! Locally-stored regularizer object.
|
||||
RegularizerType regularizer;
|
||||
}; // class Linear
|
||||
|
||||
} // namespace ann
|
||||
|
||||
@@ -19,50 +19,60 @@
|
||||
namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
Linear<InputDataType, OutputDataType>::Linear()
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
Linear<InputDataType, OutputDataType, RegularizerType>::Linear() :
|
||||
inSize(0),
|
||||
outSize(0)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template <typename InputDataType, typename OutputDataType>
|
||||
Linear<InputDataType, OutputDataType>::Linear(
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
Linear<InputDataType, OutputDataType, RegularizerType>::Linear(
|
||||
const size_t inSize,
|
||||
const size_t outSize) :
|
||||
const size_t outSize,
|
||||
RegularizerType regularizer) :
|
||||
inSize(inSize),
|
||||
outSize(outSize)
|
||||
outSize(outSize),
|
||||
regularizer(regularizer)
|
||||
{
|
||||
weights.set_size(outSize * inSize + outSize, 1);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
void Linear<InputDataType, OutputDataType>::Reset()
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
void Linear<InputDataType, OutputDataType, RegularizerType>::Reset()
|
||||
{
|
||||
weight = arma::mat(weights.memptr(), outSize, inSize, false, false);
|
||||
bias = arma::mat(weights.memptr() + weight.n_elem,
|
||||
outSize, 1, false, false);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
template<typename eT>
|
||||
void Linear<InputDataType, OutputDataType>::Forward(
|
||||
void Linear<InputDataType, OutputDataType, RegularizerType>::Forward(
|
||||
const arma::Mat<eT>&& input, arma::Mat<eT>&& output)
|
||||
{
|
||||
output = weight * input;
|
||||
output.each_col() += bias;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
template<typename eT>
|
||||
void Linear<InputDataType, OutputDataType>::Backward(
|
||||
void Linear<InputDataType, OutputDataType, RegularizerType>::Backward(
|
||||
const arma::Mat<eT>&& /* input */, arma::Mat<eT>&& gy, arma::Mat<eT>&& g)
|
||||
{
|
||||
g = weight.t() * gy;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
template<typename eT>
|
||||
void Linear<InputDataType, OutputDataType>::Gradient(
|
||||
void Linear<InputDataType, OutputDataType, RegularizerType>::Gradient(
|
||||
const arma::Mat<eT>&& input,
|
||||
arma::Mat<eT>&& error,
|
||||
arma::Mat<eT>&& gradient)
|
||||
@@ -71,11 +81,13 @@ void Linear<InputDataType, OutputDataType>::Gradient(
|
||||
error * input.t());
|
||||
gradient.submat(weight.n_elem, 0, gradient.n_elem - 1, 0) =
|
||||
arma::sum(error, 1);
|
||||
regularizer.Evaluate(weights, gradient);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
template<typename Archive>
|
||||
void Linear<InputDataType, OutputDataType>::serialize(
|
||||
void Linear<InputDataType, OutputDataType, RegularizerType>::serialize(
|
||||
Archive& ar, const unsigned int /* version */)
|
||||
{
|
||||
ar & BOOST_SERIALIZATION_NVP(inSize);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define MLPACK_METHODS_ANN_LAYER_LINEAR_NO_BIAS_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/methods/ann/regularizer/no_regularizer.hpp>
|
||||
|
||||
#include "layer_types.hpp"
|
||||
|
||||
@@ -31,7 +32,8 @@ namespace ann /** Artificial Neural Network. */ {
|
||||
*/
|
||||
template <
|
||||
typename InputDataType = arma::mat,
|
||||
typename OutputDataType = arma::mat
|
||||
typename OutputDataType = arma::mat,
|
||||
typename RegularizerType = NoRegularizer
|
||||
>
|
||||
class LinearNoBias
|
||||
{
|
||||
@@ -44,7 +46,9 @@ class LinearNoBias
|
||||
* @param inSize The number of input units.
|
||||
* @param outSize The number of output units.
|
||||
*/
|
||||
LinearNoBias(const size_t inSize, const size_t outSize);
|
||||
LinearNoBias(const size_t inSize,
|
||||
const size_t outSize,
|
||||
RegularizerType regularizer = RegularizerType());
|
||||
|
||||
/*
|
||||
* Reset the layer parameter.
|
||||
@@ -142,6 +146,9 @@ class LinearNoBias
|
||||
|
||||
//! Locally-stored output parameter object.
|
||||
OutputDataType outputParameter;
|
||||
|
||||
//! Locally-stored regularizer object.
|
||||
RegularizerType regularizer;
|
||||
}; // class LinearNoBias
|
||||
|
||||
} // namespace ann
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user