Merge branch 'master' of https://github.com/mlpack/mlpack into iss2071
This commit is contained in:
@@ -71,7 +71,6 @@ build_script:
|
||||
-DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY%
|
||||
-DCEREAL_INCLUDE_DIR="C:/projects/mlpack/unofficial-flayan-cereal.1.2.2/build/native/include"
|
||||
-DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE%
|
||||
-DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack/boost_libs"
|
||||
-DDEBUG=OFF
|
||||
-DPROFILE=OFF
|
||||
-DBUILD_PYTHON_BINDINGS=OFF
|
||||
|
||||
-19
@@ -59,25 +59,6 @@ jobs:
|
||||
steps:
|
||||
- template: macos-steps.yaml
|
||||
|
||||
# - job: WindowsVS15
|
||||
# timeoutInMinutes: 360
|
||||
# displayName: Windows VS15
|
||||
# pool:
|
||||
# vmImage: vs2017-win2016
|
||||
# strategy:
|
||||
# matrix:
|
||||
# Plain:
|
||||
# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
# python.version: '2.7'
|
||||
# CMakeGenerator: '-G "Visual Studio 15 2017 Win64"'
|
||||
# MSBuildVersion: '15.0'
|
||||
# ArchiveNoLibs: 'mlpack-windows-vs15-no-libs.zip'
|
||||
# ArchiveLibs: 'mlpack-windows-vs15.zip'
|
||||
# ArchiveTests: 'mlpack_test-vs15.xml'
|
||||
|
||||
# steps:
|
||||
# - template: windows-steps.yaml
|
||||
|
||||
- job: WindowsVS16
|
||||
timeoutInMinutes: 360
|
||||
displayName: Windows VS16
|
||||
|
||||
@@ -116,6 +116,56 @@ steps:
|
||||
replaceExistingArchive: true
|
||||
displayName: 'Build artifacts'
|
||||
|
||||
# Build MSI installer.
|
||||
- powershell: |
|
||||
# Pull the documentation for the installer.
|
||||
try {
|
||||
$url = "http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip"
|
||||
(new-object net.webclient).DownloadFile($url, 'dist\win-installer\jenkinsdoc.zip')
|
||||
}
|
||||
catch {
|
||||
Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!"
|
||||
}
|
||||
try {
|
||||
(Add-Type -AssemblyName System.IO.Compression.FileSystem);
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\mlpack-win-installer\Sources\doc')
|
||||
}
|
||||
catch{Write-Output "Unable to add doc to installer, skipping!"}
|
||||
# Preparing installer staging.
|
||||
mkdir dist\win-installer\mlpack-win-installer\Sources\lib
|
||||
cp build\Release\*.lib dist\win-installer\mlpack-win-installer\Sources\lib\
|
||||
cp build\Release\*.exp dist\win-installer\mlpack-win-installer\Sources\lib\
|
||||
cp build\Release\*.dll dist\win-installer\mlpack-win-installer\Sources\
|
||||
cp build\Release\*.exe dist\win-installer\mlpack-win-installer\Sources\
|
||||
cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\mlpack-win-installer\Sources\
|
||||
cp build\include\mlpack dist\win-installer\mlpack-win-installer\Sources -recurse
|
||||
cp doc\examples dist\win-installer\mlpack-win-installer\Sources -recurse
|
||||
cp src\mlpack\tests\data\german.csv dist\win-installer\mlpack-win-installer\Sources\examples\sample-ml-app\sample-ml-app\data\
|
||||
# Check current git version or mlpack version.
|
||||
$ver = (Get-Content "src\mlpack\core\util\version.hpp" | where {$_ -like "*MLPACK_VERSION*"});
|
||||
$env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.';
|
||||
$env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.';
|
||||
$env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1);
|
||||
|
||||
if (Test-Path "src/mlpack/core/util/gitversion.hpp")
|
||||
{
|
||||
$ver = (Get-Content "src/mlpack/core/util/gitversion.hpp");
|
||||
$env:INSTALL_VERSION = $ver.Split('"')[1].Split(' ')[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$env:INSTALL_VERSION = $env:MLPACK_VERSION;
|
||||
}
|
||||
|
||||
# Build the MSI installer.
|
||||
cd dist\win-installer\mlpack-win-installer
|
||||
& 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' `
|
||||
-t:rebuild `
|
||||
-p:Configuration=Release `
|
||||
-p:TreatWarningsAsErrors=True `
|
||||
mlpack-win-installer.wixproj
|
||||
displayName: 'Build MSI Windows installer'
|
||||
|
||||
# Publish artifacts to Azure Pipelines
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
@@ -132,6 +182,11 @@ steps:
|
||||
pathtoPublish: 'build/Testing/'
|
||||
artifactName: 'Tests'
|
||||
displayName: 'Publish artifacts test results'
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\Release\mlpack-windows.msi'
|
||||
artifactName: mlpack-windows-installer
|
||||
displayName: 'Publish Windows MSI installer'
|
||||
|
||||
# Publish test results to Azure Pipelines
|
||||
- task: PublishTestResults@2
|
||||
|
||||
+3
-24
@@ -289,7 +289,6 @@ endif()
|
||||
# ARMADILLO_INCLUDE_DIRS - directories necessary for Armadillo includes
|
||||
# BOOST_ROOT - root of Boost installation
|
||||
# BOOST_INCLUDEDIR - include directory for Boost
|
||||
# BOOST_LIBRARYDIR - library directory for Boost
|
||||
# ENSMALLEN_INCLUDE_DIR - include directory for ensmallen
|
||||
# STB_IMAGE_INCLUDE_DIR - include directory for STB image library
|
||||
# MATHJAX_ROOT - root of MathJax installation
|
||||
@@ -443,31 +442,11 @@ set(Boost_ADDITIONAL_VERSIONS
|
||||
# TODO for the brave: transition all mlpack's CMake to 'target-based modern
|
||||
# CMake'. Good luck! You'll need it.
|
||||
set(Boost_NO_BOOST_CMAKE 1)
|
||||
find_package(Boost "${BOOST_VERSION}"
|
||||
COMPONENTS
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
|
||||
# In Visual Studio, automatic linking is performed, so we don't need to worry
|
||||
# about it. Clear the list of libraries to link against and let Visual Studio
|
||||
# handle it.
|
||||
if (MSVC)
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
set(CMAKE_MSVCIDE_RUN_PATH ${CMAKE_MSVCIDE_RUN_PATH} ${Boost_LIBRARY_DIRS})
|
||||
message("boost lib dirs ${Boost_LIBRARY_DIRS}")
|
||||
set(Boost_LIBRARIES "")
|
||||
endif ()
|
||||
find_package(Boost "${BOOST_VERSION}")
|
||||
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
|
||||
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${Boost_LIBRARIES})
|
||||
set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
|
||||
|
||||
# For Boost testing framework (will have no effect on non-testing executables).
|
||||
# This specifies to Boost that we are dynamically linking to the Boost test
|
||||
# library.
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES})
|
||||
set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS})
|
||||
|
||||
# Detect OpenMP support in a compiler. If the compiler supports OpenMP, flags
|
||||
# to compile with OpenMP are returned and added and the HAS_OPENMP definition
|
||||
|
||||
@@ -136,6 +136,8 @@ Copyright:
|
||||
Copyright 2020, Aakash Kaushik <kaushikaakash7539@gmail.com>
|
||||
Copyright 2020, Anush Kini <anushkini@gmail.com>
|
||||
Copyright 2020, Nippun Sharma <inbox.nippun@gmail.com>
|
||||
Copyright 2020, Rishabh Garg <rishabhgarg108@gmail.com>
|
||||
Copyright 2020, Sudhakar Brar <dxhrmhall1449@tutanota.com>
|
||||
|
||||
License: BSD-3-clause
|
||||
All rights reserved.
|
||||
|
||||
+30
-39
@@ -2,47 +2,38 @@
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<!-- 1) DO NOT CHANGE the product GUID! It is forever -->
|
||||
<!-- 2) %MLPACK_VERSION env var is set by .appveyor.yml -->
|
||||
<Product Id="02A00C77-197D-4E91-B7D9-5836220E92E9"
|
||||
UpgradeCode="6C2D7EC0-6F10-40CB-9703-1DC160A62662"
|
||||
Name="mlpack"
|
||||
Language="1033"
|
||||
Version="$(env.MLPACK_VERSION)"
|
||||
Manufacturer="mlpack">
|
||||
|
||||
<Package InstallerVersion="200"
|
||||
Description="mlpack Windows Installer"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine"
|
||||
Platform="x64"/>
|
||||
<Product Id="02A00C77-197D-4E91-B7D9-5836220E92E9"
|
||||
UpgradeCode="6C2D7EC0-6F10-40CB-9703-1DC160A62662"
|
||||
Name="mlpack"
|
||||
Language="1033"
|
||||
Version="$(env.MLPACK_VERSION)"
|
||||
Manufacturer="mlpack">
|
||||
<Package InstallerVersion="200"
|
||||
Description="mlpack Windows Installer"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine"
|
||||
Platform="x64"/>
|
||||
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
|
||||
<MediaTemplate EmbedCab="yes"/>
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
<MediaTemplate EmbedCab="yes"/>
|
||||
|
||||
<Feature Id="ProductFeature" Title="mlpackWindows" Level="1">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
</Feature>
|
||||
<Property Id="MLPACK_VERSION">$(env.MLPACK_VERSION)</Property>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
<WixVariable Id="WixUILicenseRtf" Value="..\staging\license.rtf"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="..\res\banner.jpg"/>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="..\res\dialog_white.jpg"/>
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
</Product>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="ProgramFilesFolder" Name="PFiles">
|
||||
<Directory Id="INSTALLDIR" Name="mlpack">
|
||||
<Directory Id="Sources" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="ProgramFiles64Folder">
|
||||
<Directory Id="INSTALLFOLDER" Name="mlpack" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
||||
<!-- This references the list of mlpack files automatically generated using Heat (see .wixproj BeforeBuild Target) -->
|
||||
<ComponentGroupRef Id="HeatGenerated"/>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
<Feature Id="ProductFeature" Title="mlpackWindows" ConfigurableDirectory="INSTALLDIR" Level="1">
|
||||
<ComponentGroupRef Id="Sources" />
|
||||
</Feature>
|
||||
|
||||
<Property Id="MLPACK_VERSION">$(env.MLPACK_VERSION)</Property>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
|
||||
<WixVariable Id="WixUILicenseRtf" Value="..\staging\license.rtf"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="..\res\banner.jpg"/>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="..\res\dialog_white.jpg"/>
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
</Product>
|
||||
</Wix>
|
||||
|
||||
@@ -9,33 +9,36 @@
|
||||
<OutputName>mlpack-windows</OutputName>
|
||||
<OutputType>Package</OutputType>
|
||||
<Name>mlpack-win-installer</Name>
|
||||
<DefineSolutionProperties>false</DefineSolutionProperties>
|
||||
<DefineConstants>SourceDir=.\Sources</DefineConstants>
|
||||
<WixTargetsPath Condition=" '$(WixTargetsPath' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug</DefineConstants>
|
||||
<DefineConstants>Debug;$(DefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DefineConstants>Debug</DefineConstants>
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug;$(DefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<DefineConstants>HarvestPath=..\staging</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Product.wxs" />
|
||||
<Compile Include="HeatGeneratedFileList.wxs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<HarvestDirectory Include=".\Sources">
|
||||
<DirectoryRefId>Sources</DirectoryRefId>
|
||||
<ComponentGroupName>Sources</ComponentGroupName>
|
||||
<PreprocessorVariable>var.SourceDir</PreprocessorVariable>
|
||||
<SuppressRegistry>true</SuppressRegistry>
|
||||
</HarvestDirectory>
|
||||
<WixExtension Include="WixUIExtension">
|
||||
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||
<Name>WixUIExtension</Name>
|
||||
@@ -46,14 +49,4 @@
|
||||
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
|
||||
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
|
||||
</Target>
|
||||
<!--
|
||||
To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Wix.targets.-->
|
||||
<Target Name="BeforeBuild">
|
||||
<HeatDirectory Directory="..\staging" PreprocessorVariable="var.HarvestPath" OutputFile="HeatGeneratedFileList.wxs" ComponentGroupName="HeatGenerated" DirectoryRefId="INSTALLFOLDER" AutogenerateGuids="true" ToolPath="$(WixToolPath)" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" />
|
||||
</Target>
|
||||
<!--
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
+12
-12
@@ -2,10 +2,10 @@
|
||||
|
||||
@section build_buildintro Introduction
|
||||
|
||||
This document discusses how to build mlpack from source. These build directions
|
||||
This document discusses how to build mlpack from source. These build directions
|
||||
will work for any Linux-like shell environment (for example Ubuntu, macOS,
|
||||
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
|
||||
and so it may be easier to use the package manager for your system. For example,
|
||||
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
|
||||
and so it may be easier to use the package manager for your system. For example,
|
||||
on Ubuntu, you can install mlpack with the following command:
|
||||
|
||||
@code
|
||||
@@ -25,7 +25,7 @@ mlpack uses CMake as a build system and allows several flexible build
|
||||
configuration options. One can consult any of numerous CMake tutorials for
|
||||
further documentation, but this tutorial should be enough to get mlpack built
|
||||
and installed on most Linux and UNIX-like systems (including OS X). If you want
|
||||
to build mlpack on Windows, see \ref build_windows (alternatively, you can read
|
||||
to build mlpack on Windows, see \ref build_windows (alternatively, you can read
|
||||
<a href="https://keon.io/mlpack-on-windows/">Keon's excellent tutorial</a> which
|
||||
is based on older versions).
|
||||
|
||||
@@ -78,7 +78,7 @@ mlpack depends on the following libraries, which need to be installed on the
|
||||
system and have headers present:
|
||||
|
||||
- Armadillo >= 8.400.0 (with LAPACK support)
|
||||
- Boost (math_c99, unit_test_framework, heap, spirit) >= 1.58
|
||||
- Boost (math_c99, spirit) >= 1.58
|
||||
- cereal >= 1.1.2
|
||||
- ensmallen >= 2.10.0 (will be downloaded if not found)
|
||||
|
||||
@@ -95,11 +95,11 @@ For Python bindings, the following packages are required:
|
||||
- pandas >= 0.15.0
|
||||
- pytest-runner
|
||||
|
||||
In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be
|
||||
In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be
|
||||
installed through apt:
|
||||
|
||||
@code
|
||||
# apt-get install libboost-math-dev libboost-test-dev libcereal-dev
|
||||
# apt-get install libboost-math-dev libcereal-dev
|
||||
libarmadillo-dev binutils-dev python3-pandas python3-numpy cython3
|
||||
python3-setuptools
|
||||
@endcode
|
||||
@@ -112,18 +112,18 @@ packages:
|
||||
# apt-get install libensmallen-dev libstb-dev
|
||||
@endcode
|
||||
|
||||
@note For older versions of Ubuntu and Debian, Armadillo needs to be built from
|
||||
source as apt installs an older version. So you need to omit
|
||||
@note For older versions of Ubuntu and Debian, Armadillo needs to be built from
|
||||
source as apt installs an older version. So you need to omit
|
||||
\c libarmadillo-dev from the code snippet above and instead use
|
||||
<a href="http://arma.sourceforge.net/download.html">this link</a>
|
||||
to download the required file. Extract this file and follow the README in the
|
||||
to download the required file. Extract this file and follow the README in the
|
||||
uncompressed folder to build and install Armadillo.
|
||||
|
||||
On Fedora, Red Hat, or CentOS, these same dependencies can be obtained via dnf:
|
||||
|
||||
@code
|
||||
# dnf install boost-devel boost-test boost-math armadillo-devel binutils-devel
|
||||
python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel
|
||||
# dnf install boost-devel boost-math armadillo-devel binutils-devel
|
||||
python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel
|
||||
stbi-devel cereal-devel
|
||||
@endcode
|
||||
|
||||
|
||||
+115
-10
@@ -9,8 +9,13 @@
|
||||
|
||||
@section build_windows_intro Introduction
|
||||
|
||||
This tutorial will show you how to build mlpack for Windows from source, so you can
|
||||
later create your own C++ applications. Before you try building mlpack, you may
|
||||
This tutorial will show you how to build mlpack for Windows from source, so
|
||||
you can later create your own C++ applications, using two different ways:
|
||||
|
||||
- Using CMake to generate an intermeditate Visual Studio solution (`.sln`).
|
||||
- @ref build_visual_studio_cmake_integration "Use Visual Studio's CMake integration to directly build from the `CMakeLists`."
|
||||
|
||||
Before you try building mlpack, you may
|
||||
want to install mlpack using vcpkg for Windows. If you don't want to install
|
||||
using vcpkg, skip this section and continue with the build tutorial.
|
||||
|
||||
@@ -78,6 +83,23 @@ system environment variables or manually set the PATH before running CMake)
|
||||
- Click on OpenBlas and check the mlpack project, then click Install
|
||||
- Once it has finished installing, close Visual Studio
|
||||
|
||||
<b> Building OpenBLAS from Source </b>
|
||||
|
||||
Unfortunately, the support for building `LAPACK` and `BLAS` on Windows is quite poor, due to the need for Fortran
|
||||
compiler and libraries. The easiest method to get the necessary `BLAS/LAPACK` libraries built on Windows is to
|
||||
compile OpenBLAS with LLVM's `clang-cl` and `flang` to produce the required static library (`.lib`) files
|
||||
compatible with the MSVC compiler. A comprehensive guide on the
|
||||
<a href="https://github.com/xianyi/OpenBLAS/wiki/How-to-use-OpenBLAS-in-Microsoft-Visual-Studio">compilation
|
||||
of OpenBLAS for Windows can be found here</a>.
|
||||
|
||||
One could always download prebuilt `LAPACK` and `BLAS` libraries for Windows. However, there are few official
|
||||
sources, and some of those libraries may require further `dll`s at runtime which may not be available in your
|
||||
system.
|
||||
|
||||
It you choose to build `OpenBLAS` from source, make sure that `LAPACK` functions are also built. Finally, make
|
||||
sure that the `openblas.lib` library is linked in your `Armadillo` build (see below), as well as the library
|
||||
path used for the CMake options `BLAS_LIBRARIES` and `LAPACK_LIBRARIES` in the mlpack CMake project.
|
||||
|
||||
<b> Boost Dependency </b>
|
||||
|
||||
You can either get Boost via NuGet or you can download the prebuilt Windows binaries separately.
|
||||
@@ -110,7 +132,7 @@ compiler version, check if the Visual Studio compiler and Windows SDK are instal
|
||||
- Build > Build Solution
|
||||
- Once it has successfully finished, close Visual Studio
|
||||
|
||||
@section build_windows_mlpack Building mlpack
|
||||
@section build_windows_mlpack Building mlpack with CMake-Generated Solution
|
||||
|
||||
- Create a "build" directory into "C:\mlpack\mlpack\"
|
||||
- You can generate the project using either cmake via command line or GUI. If you prefer to use GUI, refer to the \ref build_windows_appendix "appendix"
|
||||
@@ -129,6 +151,96 @@ cmake -G "Visual Studio 16 2019" -A x64 -DBLAS_LIBRARIES:FILEPATH="C:/mlpack/mlp
|
||||
|
||||
You are ready to create your first application, take a look at the @ref sample_ml_app "Sample C++ ML App"
|
||||
|
||||
@section build_visual_studio_cmake_integration Building mlpack with Visual Studio's CMake Integration
|
||||
|
||||
This project can be directly built from the `CMakeLists.txt` with the latest version of MS Visual Studio,
|
||||
given you have CMake integration via the
|
||||
<a href="https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-160">C++
|
||||
CMake tools for Windows</a>. To open the CMake project with Visual Studio, select File->Open->CMake
|
||||
in the top menu, followed by selecting the root `CMakeLists.txt` located in mlpack's root directory.
|
||||
|
||||
In order to allow Visual Studio to configure the CMake project, the CMake configuration json will have
|
||||
to be edited to provide the <a href="https://github.com/mlpack/mlpack#3-dependencies">relevant options
|
||||
shown in the `README`</a> needed to find all the dependencies. The options that you
|
||||
must provide to Visual Studio's CMake are:
|
||||
|
||||
- `ARMADILLO_INCLUDE_DIR`
|
||||
- `ARMADILLO_LIBRARY`
|
||||
- `BOOST_ROOT`
|
||||
- `CEREAL_INCLUDE_DIR`
|
||||
- `BLAS_LIBRARIES`
|
||||
- `LAPACK_LIBRARIES`
|
||||
|
||||
The CMake configuration json can be editted in Visual Studio by right clicking the root `CMakeLists.txt`
|
||||
in the project view, selecting <b>CMake settings for mlpack</b> and finally clicking on <b>edit JSON</b>.
|
||||
Adding a new CMake option can be done by adding object fields with the following format to the variables
|
||||
array in the `CMakeSettings.json`:
|
||||
|
||||
@code
|
||||
{
|
||||
"name": "options_name_string",
|
||||
"value": "options_value_string",
|
||||
"type" : "{BOOL|FILEPATH|PATH|STRING}"
|
||||
}
|
||||
@endcode
|
||||
|
||||
Here is a full example of the `CMakeSettings.json`file:
|
||||
|
||||
@code
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x64-Debug (default)",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"variables": [
|
||||
{
|
||||
"name": "ARMADILLO_INCLUDE_DIR",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/include",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "ARMADILLO_LIBBRARY",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/lib/armadillo.lib",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "CEREAL_INCLUDE_DIR",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/cereal-1.3.0/include",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "BUILD_ROOT",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "BOOST_INCLUDEDIR",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "BLAS_LIBRARIES",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "LAPACK_LIBRARIES",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib",
|
||||
"type": "PATH"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section build_windows_appendix Appendix
|
||||
|
||||
If you prefer to use cmake GUI, follow these instructions:
|
||||
@@ -147,13 +259,6 @@ If you prefer to use cmake GUI, follow these instructions:
|
||||
following variables and reconfigure:
|
||||
- Name: `BOOST_INCLUDEDIR`; type `PATH`; value `C:/boost/`
|
||||
- Name: `BOOST_LIBRARYDIR`; type `PATH`; value `C:/boost/lib64-msvc-14.2`
|
||||
- If Boost is still not found, try adding the following variables and
|
||||
reconfigure:
|
||||
- Name: `Boost_INCLUDE_DIR`; type `PATH`; value `C:/boost/`
|
||||
- Name: `Boost_SERIALIZATION_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-gd-x64-1_71.lib`
|
||||
- Name: `Boost_SERIALIZATION_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-x64-1_71.lib`
|
||||
- Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-gd-x64-1_71.lib`
|
||||
- Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-x64-1_71.lib`
|
||||
- Once CMake has configured successfully, hit "Generate" to create the `.sln` file.
|
||||
|
||||
@section build_windows_additional_information Additional Information
|
||||
|
||||
@@ -34,7 +34,6 @@ mlpack and dependencies in Release Mode).
|
||||
- Under Linker > Input > Additional Dependencies add:
|
||||
@code
|
||||
- C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.lib
|
||||
- C:\boost\boost_1_71_0\lib64-msvc-14.2\libboost_serialization-vc142-mt-gd-x64-1_71.lib
|
||||
@endcode
|
||||
- Under Build Events > Post-Build Event > Command Line add:
|
||||
@code
|
||||
|
||||
@@ -53,7 +53,6 @@ if (BUILD_CLI_EXECUTABLES)
|
||||
target_link_libraries(mlpack_${name}
|
||||
mlpack
|
||||
${ARMADILLO_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${COMPILER_SUPPORT_LIBRARIES}
|
||||
)
|
||||
# Make sure that we set BINDING_TYPE to cli so the command-line program is
|
||||
|
||||
@@ -18,7 +18,6 @@ macro (post_python_bindings)
|
||||
-D GENERATE_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/setup.py.in
|
||||
-D GENERATE_CPP_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py
|
||||
-D PACKAGE_VERSION="${PACKAGE_VERSION}"
|
||||
-D Boost_LIBRARY_DIRS="${Boost_LIBRARY_DIRS}"
|
||||
-D ARMADILLO_LIBRARIES="${ARMADILLO_LIBRARIES}"
|
||||
-D MLPACK_LIBRARY=$<TARGET_LINKER_FILE:mlpack>
|
||||
-D MLPACK_LIBDIR=$<TARGET_LINKER_FILE_DIR:mlpack>
|
||||
@@ -240,14 +239,6 @@ if (WIN32)
|
||||
foreach (dll ${DLL_COPY_LIBS})
|
||||
file(COPY ${dll} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
|
||||
endforeach ()
|
||||
|
||||
# We also need to copy the boost DLLs over.
|
||||
file(GLOB boost_ser_dll_files "${Boost_LIBRARY_DIRS}/*serialization*.dll")
|
||||
file(COPY ${boost_ser_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
|
||||
file(GLOB boost_po_dll_files "${Boost_LIBRARY_DIRS}/*program*options*.dll")
|
||||
file(COPY ${boost_po_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
|
||||
file(GLOB boost_utf_dll_files "${Boost_LIBRARY_DIRS}/*unit*test*framework*.dll")
|
||||
file(COPY ${boost_utf_dll_files} DESTINATION ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/)
|
||||
endif ()
|
||||
|
||||
# Add a macro to build a python binding.
|
||||
|
||||
@@ -34,8 +34,7 @@ else:
|
||||
# directories with a (valid) space in the name will be given to us as '\ '; so,
|
||||
# in order to split these right, we first convert all spaces to ';', then
|
||||
# convert '\;' back to ' ', then split on ';'.
|
||||
library_dirs = list(filter(None, ['${MLPACK_LIBDIR}'] +
|
||||
'${Boost_LIBRARY_DIRS}'.replace(' ', ';').replace('\;', ' ').split(' ')))
|
||||
library_dirs = ['${MLPACK_LIBDIR}']
|
||||
|
||||
# We'll link with the exact paths to each library using extra_objects, instead
|
||||
# of linking with 'libraries' and 'library_dirs', because of differences in
|
||||
|
||||
@@ -1,77 +1,77 @@
|
||||
/**
|
||||
/**
|
||||
* @file core/data/image_info_impl.hpp
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* An image information holder implementation.
|
||||
*
|
||||
* mlpack is free software; you may redistribute it and/or modify it under the
|
||||
* terms of the 3-clause BSD license. You should have received a copy of the
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
|
||||
#ifndef MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
|
||||
#define MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
|
||||
|
||||
#ifdef HAS_STB // Compile this only if stb is present.
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
#include "image_info.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
static const std::vector<std::string> loadFileTypes({"jpg", "png", "tga",
|
||||
"bmp", "psd", "gif", "hdr", "pic", "pnm", "jpeg"});
|
||||
|
||||
static const std::vector<std::string> saveFileTypes({"jpg", "png", "tga",
|
||||
"bmp", "hdr"});
|
||||
|
||||
inline bool ImageFormatSupported(const std::string& fileName, const bool save)
|
||||
{
|
||||
if (save)
|
||||
{
|
||||
// Iterate over all supported file types that can be saved.
|
||||
for (auto extension : saveFileTypes)
|
||||
{
|
||||
if (extension == Extension(fileName))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Iterate over all supported file types that can be loaded.
|
||||
for (auto extension : loadFileTypes)
|
||||
{
|
||||
if (extension == Extension(fileName))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif // HAS_STB.
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
inline ImageInfo::ImageInfo(const size_t width,
|
||||
const size_t height,
|
||||
const size_t channels,
|
||||
const size_t quality) :
|
||||
width(width),
|
||||
height(height),
|
||||
channels(channels),
|
||||
quality(quality)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* An image information holder implementation.
|
||||
*
|
||||
* mlpack is free software; you may redistribute it and/or modify it under the
|
||||
* terms of the 3-clause BSD license. You should have received a copy of the
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
|
||||
#ifndef MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
|
||||
#define MLPACK_CORE_DATA_IMAGE_INFO_IMPL_HPP
|
||||
|
||||
#ifdef HAS_STB // Compile this only if stb is present.
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
#include "image_info.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
static const std::vector<std::string> loadFileTypes({"jpg", "png", "tga",
|
||||
"bmp", "psd", "gif", "hdr", "pic", "pnm", "jpeg"});
|
||||
|
||||
static const std::vector<std::string> saveFileTypes({"jpg", "png", "tga",
|
||||
"bmp", "hdr"});
|
||||
|
||||
inline bool ImageFormatSupported(const std::string& fileName, const bool save)
|
||||
{
|
||||
if (save)
|
||||
{
|
||||
// Iterate over all supported file types that can be saved.
|
||||
for (auto extension : saveFileTypes)
|
||||
{
|
||||
if (extension == Extension(fileName))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Iterate over all supported file types that can be loaded.
|
||||
for (auto extension : loadFileTypes)
|
||||
{
|
||||
if (extension == Extension(fileName))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif // HAS_STB.
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
inline ImageInfo::ImageInfo(const size_t width,
|
||||
const size_t height,
|
||||
const size_t channels,
|
||||
const size_t quality) :
|
||||
width(width),
|
||||
height(height),
|
||||
channels(channels),
|
||||
quality(quality)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,96 +1,96 @@
|
||||
/**
|
||||
/**
|
||||
* @file core/data/load_image_impl.hpp
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* An image loading utility implementation.
|
||||
*
|
||||
* mlpack is free software; you may redistribute it and/or modify it under the
|
||||
* terms of the 3-clause BSD license. You should have received a copy of the
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
|
||||
#ifndef MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP
|
||||
#define MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
#include "load.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
// Image loading API.
|
||||
template<typename eT>
|
||||
bool Load(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
Timer::Start("loading_image");
|
||||
|
||||
// STB loads into unsigned char matrices, so we may have to convert once
|
||||
// loaded.
|
||||
arma::Mat<unsigned char> tempMatrix;
|
||||
const bool result = LoadImage(filename, tempMatrix, info, fatal);
|
||||
|
||||
// If fatal is true, then the program will have already thrown an exception.
|
||||
if (!result)
|
||||
{
|
||||
Timer::Stop("loading_image");
|
||||
return false;
|
||||
}
|
||||
|
||||
matrix = arma::conv_to<arma::Mat<eT>>::from(tempMatrix);
|
||||
Timer::Stop("loading_image");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Image loading API for multiple files.
|
||||
template<typename eT>
|
||||
bool Load(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Load(): vector of image files is empty." << std::endl;
|
||||
|
||||
if (fatal)
|
||||
Log::Fatal << oss.str();
|
||||
else
|
||||
Log::Warn << oss.str();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
arma::Mat<unsigned char> img;
|
||||
bool status = LoadImage(files[0], img, info, fatal);
|
||||
|
||||
if (!status)
|
||||
return false;
|
||||
|
||||
// Decide matrix dimension using the image height and width.
|
||||
arma::Mat<unsigned char> tmpMatrix(
|
||||
info.Width() * info.Height() * info.Channels(), files.size());
|
||||
tmpMatrix.col(0) = img;
|
||||
|
||||
for (size_t i = 1; i < files.size() ; ++i)
|
||||
{
|
||||
arma::Mat<unsigned char> colImg(tmpMatrix.colptr(i), tmpMatrix.n_rows, 1,
|
||||
false, true);
|
||||
status = LoadImage(files[i], colImg, info, fatal);
|
||||
|
||||
if (!status)
|
||||
return false;
|
||||
}
|
||||
|
||||
matrix = arma::conv_to<arma::Mat<eT>>::from(tmpMatrix);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
* @author Mehul Kumar Nirala
|
||||
*
|
||||
* An image loading utility implementation.
|
||||
*
|
||||
* mlpack is free software; you may redistribute it and/or modify it under the
|
||||
* terms of the 3-clause BSD license. You should have received a copy of the
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
|
||||
#ifndef MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP
|
||||
#define MLPACK_CORE_DATA_LOAD_IMAGE_IMPL_HPP
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
#include "load.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace data {
|
||||
|
||||
// Image loading API.
|
||||
template<typename eT>
|
||||
bool Load(const std::string& filename,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
Timer::Start("loading_image");
|
||||
|
||||
// STB loads into unsigned char matrices, so we may have to convert once
|
||||
// loaded.
|
||||
arma::Mat<unsigned char> tempMatrix;
|
||||
const bool result = LoadImage(filename, tempMatrix, info, fatal);
|
||||
|
||||
// If fatal is true, then the program will have already thrown an exception.
|
||||
if (!result)
|
||||
{
|
||||
Timer::Stop("loading_image");
|
||||
return false;
|
||||
}
|
||||
|
||||
matrix = arma::conv_to<arma::Mat<eT>>::from(tempMatrix);
|
||||
Timer::Stop("loading_image");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Image loading API for multiple files.
|
||||
template<typename eT>
|
||||
bool Load(const std::vector<std::string>& files,
|
||||
arma::Mat<eT>& matrix,
|
||||
ImageInfo& info,
|
||||
const bool fatal)
|
||||
{
|
||||
if (files.size() == 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Load(): vector of image files is empty." << std::endl;
|
||||
|
||||
if (fatal)
|
||||
Log::Fatal << oss.str();
|
||||
else
|
||||
Log::Warn << oss.str();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
arma::Mat<unsigned char> img;
|
||||
bool status = LoadImage(files[0], img, info, fatal);
|
||||
|
||||
if (!status)
|
||||
return false;
|
||||
|
||||
// Decide matrix dimension using the image height and width.
|
||||
arma::Mat<unsigned char> tmpMatrix(
|
||||
info.Width() * info.Height() * info.Channels(), files.size());
|
||||
tmpMatrix.col(0) = img;
|
||||
|
||||
for (size_t i = 1; i < files.size() ; ++i)
|
||||
{
|
||||
arma::Mat<unsigned char> colImg(tmpMatrix.colptr(i), tmpMatrix.n_rows, 1,
|
||||
false, true);
|
||||
status = LoadImage(files[i], colImg, info, fatal);
|
||||
|
||||
if (!status)
|
||||
return false;
|
||||
}
|
||||
|
||||
matrix = arma::conv_to<arma::Mat<eT>>::from(tmpMatrix);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,6 +41,18 @@ class Concatenate
|
||||
*/
|
||||
Concatenate();
|
||||
|
||||
//! Copy constructor.
|
||||
Concatenate(const Concatenate& layer);
|
||||
|
||||
//! Move constructor.
|
||||
Concatenate(Concatenate&& layer);
|
||||
|
||||
//! Operator= copy constructor.
|
||||
Concatenate& operator=(const Concatenate& layer);
|
||||
|
||||
//! Operator= move constructor.
|
||||
Concatenate& operator=(Concatenate&& layer);
|
||||
|
||||
/**
|
||||
* Ordinary feed forward pass of a neural network, evaluating the function
|
||||
* f(x) by propagating the activity forward through f.
|
||||
@@ -82,7 +94,7 @@ class Concatenate
|
||||
|
||||
//! Get the concat matrix.
|
||||
OutputDataType const& Concat() const { return concat; }
|
||||
//! Modify the delta.
|
||||
//! Modify the concat.
|
||||
OutputDataType& Concat() { return concat; }
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,11 +20,63 @@ namespace mlpack {
|
||||
namespace ann /** Artificial Neural Network. */ {
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
Concatenate<InputDataType, OutputDataType>::Concatenate()
|
||||
Concatenate<InputDataType, OutputDataType>::Concatenate() :
|
||||
inRows(0)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
Concatenate<InputDataType, OutputDataType>::Concatenate(const Concatenate& layer) :
|
||||
inRows(layer.inRows),
|
||||
weights(layer.weights),
|
||||
delta(layer.delta),
|
||||
concat(layer.concat)
|
||||
{
|
||||
// Nothing to to here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
Concatenate<InputDataType, OutputDataType>::Concatenate(Concatenate&& layer) :
|
||||
inRows(layer.inRows),
|
||||
weights(std::move(layer.weights)),
|
||||
delta(std::move(layer.delta)),
|
||||
concat(std::move(layer.concat))
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
Concatenate<InputDataType, OutputDataType>&
|
||||
Concatenate<InputDataType, OutputDataType>::
|
||||
operator=(const Concatenate& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inRows = layer.inRows;
|
||||
weights = layer.weights;
|
||||
delta = layer.delta;
|
||||
concat = layer.concat;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
Concatenate<InputDataType, OutputDataType>&
|
||||
Concatenate<InputDataType, OutputDataType>::
|
||||
operator=(Concatenate&& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inRows = layer.inRows;
|
||||
weights = std::move(layer.weights);
|
||||
delta = std::move(layer.delta);
|
||||
concat = std::move(layer.concat);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename eT>
|
||||
void Concatenate<InputDataType, OutputDataType>::Forward(
|
||||
|
||||
@@ -73,6 +73,18 @@ class FastLSTM
|
||||
//! Create the Fast LSTM object.
|
||||
FastLSTM();
|
||||
|
||||
//! Copy Constructor
|
||||
FastLSTM(const FastLSTM& layer);
|
||||
|
||||
//! Move Constructor
|
||||
FastLSTM(FastLSTM&& layer);
|
||||
|
||||
//! Copy assignment operator
|
||||
FastLSTM& operator=(const FastLSTM& layer);
|
||||
|
||||
//! Move assignment operator
|
||||
FastLSTM& operator=(FastLSTM&& layer);
|
||||
|
||||
/**
|
||||
* Create the Fast LSTM layer object using the specified parameters.
|
||||
*
|
||||
|
||||
@@ -45,6 +45,90 @@ FastLSTM<InputDataType, OutputDataType>::FastLSTM(
|
||||
weights.set_size(WeightSize(), 1);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
FastLSTM<InputDataType, OutputDataType>::FastLSTM(const FastLSTM& layer) :
|
||||
inSize(layer.inSize),
|
||||
outSize(layer.outSize),
|
||||
rho(layer.rho),
|
||||
forwardStep(layer.forwardStep),
|
||||
backwardStep(layer.backwardStep),
|
||||
gradientStep(layer.gradientStep),
|
||||
weights(layer.weights),
|
||||
batchSize(layer.batchSize),
|
||||
batchStep(layer.batchStep),
|
||||
gradientStepIdx(layer.gradientStepIdx),
|
||||
grad(layer.grad),
|
||||
rhoSize(layer.rho),
|
||||
bpttSteps(layer.bpttSteps)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
FastLSTM<InputDataType, OutputDataType>::FastLSTM(FastLSTM&& layer) :
|
||||
inSize(std::move(layer.inSize)),
|
||||
outSize(std::move(layer.outSize)),
|
||||
rho(std::move(layer.rho)),
|
||||
forwardStep(std::move(layer.forwardStep)),
|
||||
backwardStep(std::move(layer.backwardStep)),
|
||||
gradientStep(std::move(layer.gradientStep)),
|
||||
weights(std::move(layer.weights)),
|
||||
batchSize(std::move(layer.batchSize)),
|
||||
batchStep(std::move(layer.batchStep)),
|
||||
gradientStepIdx(std::move(layer.gradientStepIdx)),
|
||||
grad(std::move(layer.grad)),
|
||||
rhoSize(std::move(layer.rho)),
|
||||
bpttSteps(std::move(layer.bpttSteps))
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
FastLSTM<InputDataType, OutputDataType>&
|
||||
FastLSTM<InputDataType, OutputDataType>::operator=(const FastLSTM& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inSize = layer.inSize;
|
||||
outSize = layer.outSize;
|
||||
rho = layer.rho;
|
||||
forwardStep = layer.forwardStep;
|
||||
backwardStep = layer.backwardStep;
|
||||
gradientStep = layer.gradientStep;
|
||||
weights = layer.weights;
|
||||
batchSize = layer.batchSize;
|
||||
batchStep = layer.batchStep;
|
||||
gradientStepIdx = layer.gradientStepIdx;
|
||||
grad = layer.grad;
|
||||
rhoSize = layer.rho;
|
||||
bpttSteps = layer.bpttSteps;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
FastLSTM<InputDataType, OutputDataType>&
|
||||
FastLSTM<InputDataType, OutputDataType>::operator=(FastLSTM&& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inSize = std::move(layer.inSize);
|
||||
outSize = std::move(layer.outSize);
|
||||
rho = std::move(layer.rho);
|
||||
forwardStep = std::move(layer.forwardStep);
|
||||
backwardStep = std::move(layer.backwardStep);
|
||||
gradientStep = std::move(layer.gradientStep);
|
||||
weights = std::move(layer.weights);
|
||||
batchSize = std::move(layer.batchSize);
|
||||
batchStep = std::move(layer.batchStep);
|
||||
gradientStepIdx = std::move(layer.gradientStepIdx);
|
||||
grad = std::move(layer.grad);
|
||||
rhoSize = std::move(layer.rho);
|
||||
bpttSteps = std::move(layer.bpttSteps);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
void FastLSTM<InputDataType, OutputDataType>::Reset()
|
||||
{
|
||||
|
||||
@@ -54,6 +54,18 @@ class Linear3D
|
||||
const size_t outSize,
|
||||
RegularizerType regularizer = RegularizerType());
|
||||
|
||||
//! Copy constructor.
|
||||
Linear3D(const Linear3D& layer);
|
||||
|
||||
//! Move constructor.
|
||||
Linear3D(Linear3D&&);
|
||||
|
||||
//! Copy assignment operator.
|
||||
Linear3D& operator=(const Linear3D& layer);
|
||||
|
||||
//! Move assignment operator.
|
||||
Linear3D& operator=(Linear3D&& layer);
|
||||
|
||||
/*
|
||||
* Reset the layer parameter.
|
||||
*/
|
||||
|
||||
@@ -40,6 +40,62 @@ Linear3D<InputDataType, OutputDataType, RegularizerType>::Linear3D(
|
||||
weights.set_size(outSize * inSize + outSize, 1);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
Linear3D<InputDataType, OutputDataType, RegularizerType>::Linear3D(
|
||||
const Linear3D& layer) :
|
||||
inSize(layer.inSize),
|
||||
outSize(layer.outSize),
|
||||
weights(layer.weights),
|
||||
regularizer(layer.regularizer)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
Linear3D<InputDataType, OutputDataType, RegularizerType>::Linear3D(
|
||||
Linear3D&& layer) :
|
||||
inSize(0),
|
||||
outSize(0),
|
||||
weights(std::move(layer.weights)),
|
||||
regularizer(std::move(layer.regularizer))
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
Linear3D<InputDataType, OutputDataType, RegularizerType>&
|
||||
Linear3D<InputDataType, OutputDataType, RegularizerType>::
|
||||
operator=(const Linear3D& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inSize = layer.inSize;
|
||||
outSize = layer.outSize;
|
||||
weights = layer.weights;
|
||||
regularizer = layer.regularizer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
Linear3D<InputDataType, OutputDataType, RegularizerType>&
|
||||
Linear3D<InputDataType, OutputDataType, RegularizerType>::
|
||||
operator=(Linear3D&& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inSize = 0;
|
||||
outSize = 0;
|
||||
weights = std::move(layer.weights);
|
||||
regularizer = std::move(layer.regularizer);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType,
|
||||
typename RegularizerType>
|
||||
void Linear3D<InputDataType, OutputDataType, RegularizerType>::Reset()
|
||||
|
||||
@@ -48,6 +48,15 @@ class NoisyLinear
|
||||
//! Copy constructor.
|
||||
NoisyLinear(const NoisyLinear&);
|
||||
|
||||
//! Move constructor.
|
||||
NoisyLinear(NoisyLinear&&);
|
||||
|
||||
//! Operator= copy constructor.
|
||||
NoisyLinear& operator=(const NoisyLinear& layer);
|
||||
|
||||
//! Operator= move constructor.
|
||||
NoisyLinear& operator=(NoisyLinear&& layer);
|
||||
|
||||
/*
|
||||
* Reset the layer parameter.
|
||||
*/
|
||||
|
||||
@@ -48,6 +48,50 @@ NoisyLinear<InputDataType, OutputDataType>::NoisyLinear(
|
||||
biasEpsilon.set_size(outSize, 1);
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
NoisyLinear<InputDataType, OutputDataType>::NoisyLinear(
|
||||
NoisyLinear&& layer) :
|
||||
inSize(std::move(layer.inSize)),
|
||||
outSize(std::move(layer.outSize)),
|
||||
weights(std::move(layer.weights))
|
||||
{
|
||||
layer.inSize = 0;
|
||||
layer.outSize = 0;
|
||||
layer.weights = nullptr;
|
||||
Reset();
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
NoisyLinear<InputDataType, OutputDataType>&
|
||||
NoisyLinear<InputDataType, OutputDataType>::operator=(const NoisyLinear& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inSize = layer.inSize;
|
||||
outSize = layer.outSize;
|
||||
weights = layer.weights;
|
||||
Reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
NoisyLinear<InputDataType, OutputDataType>&
|
||||
NoisyLinear<InputDataType, OutputDataType>::operator=(NoisyLinear&& layer)
|
||||
{
|
||||
if (this != &layer)
|
||||
{
|
||||
inSize = std::move(layer.inSize);
|
||||
layer.inSize = 0;
|
||||
outSize = std::move(layer.outSize);
|
||||
layer.outSize = 0;
|
||||
weights = std::move(layer.weights);
|
||||
layer.weights = nullptr;
|
||||
Reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
void NoisyLinear<InputDataType, OutputDataType>::Reset()
|
||||
{
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* @file methods/ann/layer/recurrent.hpp
|
||||
* @author Marcus Edel
|
||||
*
|
||||
* Definition of the LinearLayer class also known as fully-connected layer or
|
||||
* affine transformation.
|
||||
* Definition of the Recurrent class.
|
||||
*
|
||||
* mlpack is free software; you may redistribute it and/or modify it under the
|
||||
* terms of the 3-clause BSD license. You should have received a copy of the
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* @file methods/ann/layer/recurrent_impl.hpp
|
||||
* @author Marcus Edel
|
||||
*
|
||||
* Implementation of the LinearLayer class also known as fully-connected layer
|
||||
* or affine transformation.
|
||||
* Implementation of the Recurrent class.
|
||||
*
|
||||
* mlpack is free software; you may redistribute it and/or modify it under the
|
||||
* terms of the 3-clause BSD license. You should have received a copy of the
|
||||
|
||||
@@ -51,6 +51,9 @@ template<typename eT>
|
||||
void SpatialDropout<InputDataType, OutputDataType>::Forward(
|
||||
const arma::Mat<eT>& input, arma::Mat<eT>& output)
|
||||
{
|
||||
Log::Assert(input.n_rows % size == 0, "Input features must be divisible \
|
||||
by feature maps.");
|
||||
|
||||
if (!reset)
|
||||
{
|
||||
batchSize = input.n_cols;
|
||||
|
||||
@@ -67,6 +67,9 @@ template<typename eT>
|
||||
void VirtualBatchNorm<InputDataType, OutputDataType>::Forward(
|
||||
const arma::Mat<eT>& input, arma::Mat<eT>& output)
|
||||
{
|
||||
Log::Assert(input.n_rows % size == 0, "Input features must be divisible \
|
||||
by feature maps.");
|
||||
|
||||
inputParameter = input;
|
||||
arma::mat inputMean = arma::mean(input, 1);
|
||||
arma::mat inputMeanSquared = arma::mean(arma::square(input), 1);
|
||||
|
||||
@@ -42,24 +42,26 @@ class MeanSquaredError
|
||||
/**
|
||||
* Computes the mean squared error function.
|
||||
*
|
||||
* @param input Input data used for evaluating the specified function.
|
||||
* @param prediction Predictions used for evaluating the specified loss
|
||||
* function.
|
||||
* @param target The target vector.
|
||||
*/
|
||||
template<typename InputType, typename TargetType>
|
||||
typename InputType::elem_type Forward(const InputType& input,
|
||||
const TargetType& target);
|
||||
template<typename PredictionType, typename TargetType>
|
||||
typename PredictionType::elem_type Forward(const PredictionType& prediction,
|
||||
const TargetType& target);
|
||||
|
||||
/**
|
||||
* Ordinary feed backward pass of a neural network.
|
||||
*
|
||||
* @param input The propagated input activation.
|
||||
* @param prediction Predictions used for evaluating the specified loss
|
||||
* function
|
||||
* @param target The target vector.
|
||||
* @param output The calculated error.
|
||||
* @param loss The calculated error.
|
||||
*/
|
||||
template<typename InputType, typename TargetType, typename OutputType>
|
||||
void Backward(const InputType& input,
|
||||
template<typename PredictionType, typename TargetType, typename LossType>
|
||||
void Backward(const PredictionType& prediction,
|
||||
const TargetType& target,
|
||||
OutputType& output);
|
||||
LossType& loss);
|
||||
|
||||
//! Get the output parameter.
|
||||
OutputDataType& OutputParameter() const { return outputParameter; }
|
||||
|
||||
@@ -25,23 +25,23 @@ MeanSquaredError<InputDataType, OutputDataType>::MeanSquaredError()
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputType, typename TargetType>
|
||||
typename InputType::elem_type
|
||||
template<typename PredictionType, typename TargetType>
|
||||
typename PredictionType::elem_type
|
||||
MeanSquaredError<InputDataType, OutputDataType>::Forward(
|
||||
const InputType& input,
|
||||
const PredictionType& prediction,
|
||||
const TargetType& target)
|
||||
{
|
||||
return arma::accu(arma::square(input - target)) / target.n_cols;
|
||||
return arma::accu(arma::square(prediction - target)) / target.n_cols;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
template<typename InputType, typename TargetType, typename OutputType>
|
||||
template<typename PredictionType, typename TargetType, typename LossType>
|
||||
void MeanSquaredError<InputDataType, OutputDataType>::Backward(
|
||||
const InputType& input,
|
||||
const PredictionType& prediction,
|
||||
const TargetType& target,
|
||||
OutputType& output)
|
||||
LossType& loss)
|
||||
{
|
||||
output = 2 * (input - target) / target.n_cols;
|
||||
loss = 2 * (prediction - target) / target.n_cols;
|
||||
}
|
||||
|
||||
template<typename InputDataType, typename OutputDataType>
|
||||
|
||||
@@ -70,6 +70,18 @@ class RNN
|
||||
OutputLayerType outputLayer = OutputLayerType(),
|
||||
InitializationRuleType initializeRule = InitializationRuleType());
|
||||
|
||||
//! Copy constructor.
|
||||
RNN(const RNN&);
|
||||
|
||||
//! Move constructor.
|
||||
RNN(RNN&&);
|
||||
|
||||
//! Copy assignment operator.
|
||||
RNN& operator=(const RNN&);
|
||||
|
||||
//! Move assignment operator
|
||||
RNN& operator=(RNN&&);
|
||||
|
||||
//! Destructor to release allocated memory.
|
||||
~RNN();
|
||||
|
||||
@@ -412,6 +424,9 @@ class RNN
|
||||
//! Locally-stored weight size visitor.
|
||||
WeightSizeVisitor weightSizeVisitor;
|
||||
|
||||
//! Locally-stored copy visitor
|
||||
CopyVisitor<CustomLayers...> copyVisitor;
|
||||
|
||||
//! Locally-stored reset visitor.
|
||||
ResetVisitor resetVisitor;
|
||||
|
||||
|
||||
@@ -51,6 +51,50 @@ RNN<OutputLayerType, InitializationRuleType, CustomLayers...>::RNN(
|
||||
/* Nothing to do here */
|
||||
}
|
||||
|
||||
template<typename OutputLayerType, typename InitializationRuleType,
|
||||
typename... CustomLayers>
|
||||
RNN<OutputLayerType, InitializationRuleType, CustomLayers...>::RNN(
|
||||
const RNN& network) :
|
||||
rho(network.rho),
|
||||
outputLayer(network.outputLayer),
|
||||
initializeRule(network.initializeRule),
|
||||
inputSize(network.inputSize),
|
||||
outputSize(network.outputSize),
|
||||
targetSize(network.targetSize),
|
||||
reset(network.reset),
|
||||
single(network.single),
|
||||
parameter(network.parameter),
|
||||
numFunctions(network.numFunctions),
|
||||
deterministic(network.deterministic)
|
||||
{
|
||||
for (size_t i = 0; i < network.network.size(); ++i)
|
||||
{
|
||||
this->network.push_back(boost::apply_visitor(copyVisitor,
|
||||
network.network[i]));
|
||||
boost::apply_visitor(resetVisitor, this->network.back());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OutputLayerType, typename InitializationRuleType,
|
||||
typename... CustomLayers>
|
||||
RNN<OutputLayerType, InitializationRuleType, CustomLayers...>::RNN(
|
||||
RNN&& network) :
|
||||
rho(std::move(network.rho)),
|
||||
outputLayer(std::move(network.outputLayer)),
|
||||
initializeRule(std::move(network.initializeRule)),
|
||||
inputSize(std::move(network.inputSize)),
|
||||
outputSize(std::move(network.outputSize)),
|
||||
targetSize(std::move(network.targetSize)),
|
||||
reset(std::move(network.reset)),
|
||||
single(std::move(network.single)),
|
||||
parameter(std::move(network.parameter)),
|
||||
numFunctions(std::move(network.numFunctions)),
|
||||
deterministic(std::move(network.deterministic)),
|
||||
network(std::move(network.network))
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
template<typename OutputLayerType, typename InitializationRuleType,
|
||||
typename... CustomLayers>
|
||||
RNN<OutputLayerType, InitializationRuleType, CustomLayers...>::~RNN()
|
||||
|
||||
@@ -179,7 +179,6 @@ add_executable(mlpack_test
|
||||
target_link_libraries(mlpack_test
|
||||
mlpack
|
||||
${ARMADILLO_LIBRARIES}
|
||||
${BOOST_LIBRARIES}
|
||||
${COMPILER_SUPPORT_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
@@ -31,6 +31,52 @@
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
// network1 should be allocated with `new`, and trained on some data.
|
||||
template<typename MatType = arma::cube, typename ModelType>
|
||||
void CheckRNNCopyFunction(ModelType* network1,
|
||||
MatType& trainData,
|
||||
MatType& trainLabels,
|
||||
const size_t maxEpochs)
|
||||
{
|
||||
arma::cube predictions1;
|
||||
arma::cube predictions2;
|
||||
ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_slices, -100, false);
|
||||
|
||||
network1->Train(trainData, trainLabels, opt);
|
||||
network1->Predict(trainData, predictions1);
|
||||
|
||||
RNN<> network2 = *network1;
|
||||
delete network1;
|
||||
|
||||
// Deallocating all of network1's memory, so that network2 does not use any
|
||||
// of that memory.
|
||||
network2.Predict(trainData, predictions2);
|
||||
CheckMatrices(predictions1, predictions2);
|
||||
}
|
||||
|
||||
// network1 should be allocated with `new`, and trained on some data.
|
||||
template<typename MatType = arma::cube, typename ModelType>
|
||||
void CheckRNNMoveFunction(ModelType* network1,
|
||||
MatType& trainData,
|
||||
MatType& trainLabels,
|
||||
const size_t maxEpochs)
|
||||
{
|
||||
arma::cube predictions1;
|
||||
arma::cube predictions2;
|
||||
ens::StandardSGD opt(0.1, 1, maxEpochs * trainData.n_slices, -100, false);
|
||||
|
||||
network1->Train(trainData, trainLabels, opt);
|
||||
network1->Predict(trainData, predictions1);
|
||||
|
||||
RNN<> network2(std::move(*network1));
|
||||
delete network1;
|
||||
|
||||
// Deallocating all of network1's memory, so that network2 does not use any
|
||||
// of that memory.
|
||||
network2.Predict(trainData, predictions2);
|
||||
CheckMatrices(predictions1, predictions2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple add module test.
|
||||
*/
|
||||
@@ -1183,6 +1229,40 @@ TEST_CASE("FastLSTMLayerParametersTest", "[ANNLayerTest]")
|
||||
REQUIRE(layer1.Rho() == layer2.Rho());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether copying and moving network with FastLSTM is working or not.
|
||||
*/
|
||||
TEST_CASE("CheckCopyMoveFastLSTMTest", "[ANNLayerTest]")
|
||||
{
|
||||
arma::cube input = arma::randu(1, 1, 5);
|
||||
arma::cube target = arma::ones(1, 1, 5);
|
||||
const size_t rho = 5;
|
||||
|
||||
RNN<NegativeLogLikelihood<> > *model1 =
|
||||
new RNN<NegativeLogLikelihood<> >(rho);
|
||||
model1->Predictors() = input;
|
||||
model1->Responses() = target;
|
||||
model1->Add<IdentityLayer<> >();
|
||||
model1->Add<Linear<> >(1, 10);
|
||||
model1->Add<FastLSTM<> >(10, 3, rho);
|
||||
model1->Add<LogSoftMax<> >();
|
||||
|
||||
RNN<NegativeLogLikelihood<> > *model2 =
|
||||
new RNN<NegativeLogLikelihood<> >(rho);
|
||||
model2->Predictors() = input;
|
||||
model2->Responses() = target;
|
||||
model2->Add<IdentityLayer<> >();
|
||||
model2->Add<Linear<> >(1, 10);
|
||||
model2->Add<FastLSTM<> >(10, 3, rho);
|
||||
model2->Add<LogSoftMax<> >();
|
||||
|
||||
// Check whether copy constructor is working or not.
|
||||
CheckRNNCopyFunction<>(model1, input, target, 1);
|
||||
|
||||
// Check whether move constructor is working or not.
|
||||
CheckRNNMoveFunction<>(model2, input, target, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing the overloaded Forward() of the LSTM layer, for retrieving the cell
|
||||
* state. Besides output, the overloaded function provides read access to cell
|
||||
|
||||
@@ -42,9 +42,9 @@ TEST_CASE("FFNCallbackTest", "[CallbackTest]")
|
||||
arma::mat data;
|
||||
arma::mat labels;
|
||||
|
||||
if (!data::Load("lab1.csv", data, true))
|
||||
if (!data::Load("lab1.csv", data))
|
||||
FAIL("Cannot load test dataset lab1.csv!");
|
||||
if (!data::Load("lab3.csv", labels, true))
|
||||
if (!data::Load("lab3.csv", labels))
|
||||
FAIL("Cannot load test dataset lab3.csv!");
|
||||
|
||||
FFN<MeanSquaredError<>, RandomInitialization> model;
|
||||
@@ -68,9 +68,9 @@ TEST_CASE("FFNWithOptimizerCallbackTest", "[CallbackTest]")
|
||||
arma::mat data;
|
||||
arma::mat labels;
|
||||
|
||||
if (!data::Load("lab1.csv", data, true))
|
||||
if (!data::Load("lab1.csv", data))
|
||||
FAIL("Cannot load test dataset lab1.csv!");
|
||||
if (!data::Load("lab3.csv", labels, true))
|
||||
if (!data::Load("lab3.csv", labels))
|
||||
FAIL("Cannot load test dataset lab3.csv!");
|
||||
|
||||
FFN<MeanSquaredError<>, RandomInitialization> model;
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
3
|
||||
2
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
3
|
||||
2
|
||||
4
|
||||
2
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
4
|
||||
4
|
||||
1
|
||||
3
|
||||
0
|
||||
2
|
||||
0
|
||||
0
|
||||
2
|
||||
0
|
||||
1
|
||||
3
|
||||
3
|
||||
2
|
||||
2
|
||||
2
|
||||
3
|
||||
3
|
||||
3
|
||||
3
|
||||
3
|
||||
0
|
||||
0
|
||||
4
|
||||
3
|
||||
3
|
||||
0
|
||||
3
|
||||
2
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
3
|
||||
2
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
3
|
||||
2
|
||||
4
|
||||
2
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
4
|
||||
4
|
||||
1
|
||||
3
|
||||
0
|
||||
2
|
||||
0
|
||||
0
|
||||
2
|
||||
0
|
||||
1
|
||||
3
|
||||
3
|
||||
2
|
||||
2
|
||||
2
|
||||
3
|
||||
3
|
||||
3
|
||||
3
|
||||
3
|
||||
0
|
||||
0
|
||||
4
|
||||
3
|
||||
3
|
||||
0
|
||||
3
|
||||
2
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
|
||||
|
@@ -1,200 +1,200 @@
|
||||
1
|
||||
4
|
||||
2
|
||||
2
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
0
|
||||
4
|
||||
0
|
||||
4
|
||||
3
|
||||
4
|
||||
3
|
||||
2
|
||||
4
|
||||
2
|
||||
2
|
||||
2
|
||||
4
|
||||
1
|
||||
2
|
||||
1
|
||||
3
|
||||
0
|
||||
4
|
||||
1
|
||||
4
|
||||
4
|
||||
4
|
||||
0
|
||||
3
|
||||
4
|
||||
3
|
||||
1
|
||||
3
|
||||
2
|
||||
3
|
||||
0
|
||||
4
|
||||
1
|
||||
4
|
||||
1
|
||||
4
|
||||
2
|
||||
1
|
||||
4
|
||||
2
|
||||
1
|
||||
2
|
||||
0
|
||||
2
|
||||
2
|
||||
4
|
||||
2
|
||||
0
|
||||
2
|
||||
0
|
||||
3
|
||||
3
|
||||
3
|
||||
0
|
||||
2
|
||||
1
|
||||
4
|
||||
3
|
||||
1
|
||||
2
|
||||
2
|
||||
4
|
||||
0
|
||||
1
|
||||
3
|
||||
4
|
||||
4
|
||||
4
|
||||
2
|
||||
4
|
||||
2
|
||||
3
|
||||
4
|
||||
4
|
||||
3
|
||||
2
|
||||
3
|
||||
3
|
||||
4
|
||||
3
|
||||
4
|
||||
2
|
||||
4
|
||||
0
|
||||
3
|
||||
3
|
||||
1
|
||||
3
|
||||
4
|
||||
2
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
3
|
||||
3
|
||||
0
|
||||
4
|
||||
0
|
||||
0
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
2
|
||||
2
|
||||
4
|
||||
2
|
||||
3
|
||||
1
|
||||
4
|
||||
4
|
||||
2
|
||||
3
|
||||
4
|
||||
0
|
||||
2
|
||||
2
|
||||
0
|
||||
4
|
||||
0
|
||||
3
|
||||
1
|
||||
4
|
||||
4
|
||||
2
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
3
|
||||
4
|
||||
3
|
||||
2
|
||||
0
|
||||
4
|
||||
3
|
||||
3
|
||||
4
|
||||
0
|
||||
3
|
||||
1
|
||||
3
|
||||
4
|
||||
3
|
||||
2
|
||||
2
|
||||
4
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
4
|
||||
0
|
||||
3
|
||||
4
|
||||
3
|
||||
1
|
||||
4
|
||||
0
|
||||
1
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
3
|
||||
2
|
||||
4
|
||||
3
|
||||
2
|
||||
0
|
||||
1
|
||||
4
|
||||
2
|
||||
0
|
||||
2
|
||||
3
|
||||
0
|
||||
0
|
||||
2
|
||||
1
|
||||
3
|
||||
1
|
||||
1
|
||||
4
|
||||
2
|
||||
2
|
||||
1
|
||||
0
|
||||
1
|
||||
0
|
||||
0
|
||||
4
|
||||
0
|
||||
4
|
||||
3
|
||||
4
|
||||
3
|
||||
2
|
||||
4
|
||||
2
|
||||
2
|
||||
2
|
||||
4
|
||||
1
|
||||
2
|
||||
1
|
||||
3
|
||||
0
|
||||
4
|
||||
1
|
||||
4
|
||||
4
|
||||
4
|
||||
0
|
||||
3
|
||||
4
|
||||
3
|
||||
1
|
||||
3
|
||||
2
|
||||
3
|
||||
0
|
||||
4
|
||||
1
|
||||
4
|
||||
1
|
||||
4
|
||||
2
|
||||
1
|
||||
4
|
||||
2
|
||||
1
|
||||
2
|
||||
0
|
||||
2
|
||||
2
|
||||
4
|
||||
2
|
||||
0
|
||||
2
|
||||
0
|
||||
3
|
||||
3
|
||||
3
|
||||
0
|
||||
2
|
||||
1
|
||||
4
|
||||
3
|
||||
1
|
||||
2
|
||||
2
|
||||
4
|
||||
0
|
||||
1
|
||||
3
|
||||
4
|
||||
4
|
||||
4
|
||||
2
|
||||
4
|
||||
2
|
||||
3
|
||||
4
|
||||
4
|
||||
3
|
||||
2
|
||||
3
|
||||
3
|
||||
4
|
||||
3
|
||||
4
|
||||
2
|
||||
4
|
||||
0
|
||||
3
|
||||
3
|
||||
1
|
||||
3
|
||||
4
|
||||
2
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
3
|
||||
3
|
||||
0
|
||||
4
|
||||
0
|
||||
0
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
2
|
||||
2
|
||||
4
|
||||
2
|
||||
3
|
||||
1
|
||||
4
|
||||
4
|
||||
2
|
||||
3
|
||||
4
|
||||
0
|
||||
2
|
||||
2
|
||||
0
|
||||
4
|
||||
0
|
||||
3
|
||||
1
|
||||
4
|
||||
4
|
||||
2
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
3
|
||||
4
|
||||
3
|
||||
2
|
||||
0
|
||||
4
|
||||
3
|
||||
3
|
||||
4
|
||||
0
|
||||
3
|
||||
1
|
||||
3
|
||||
4
|
||||
3
|
||||
2
|
||||
2
|
||||
4
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
4
|
||||
0
|
||||
3
|
||||
4
|
||||
3
|
||||
1
|
||||
4
|
||||
0
|
||||
1
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
3
|
||||
2
|
||||
4
|
||||
3
|
||||
2
|
||||
0
|
||||
1
|
||||
4
|
||||
2
|
||||
0
|
||||
2
|
||||
3
|
||||
0
|
||||
0
|
||||
2
|
||||
1
|
||||
3
|
||||
1
|
||||
|
||||
|
@@ -71,8 +71,8 @@ void CheckCopyFunction(ModelType* network1,
|
||||
network2 = *network1;
|
||||
delete network1;
|
||||
|
||||
// Deallocating all of network1's memory, so that
|
||||
// if network2 is trying to use any of that memory.
|
||||
// Deallocating all of network1's memory, so that network2 does not use any
|
||||
// of that memory.
|
||||
arma::mat predictions2;
|
||||
network2.Predict(trainData, predictions2);
|
||||
CheckMatrices(predictions1, predictions2);
|
||||
@@ -93,8 +93,8 @@ void CheckMoveFunction(ModelType* network1,
|
||||
FFN<> network2(std::move(*network1));
|
||||
delete network1;
|
||||
|
||||
// Deallocating all of network1's memory, so that
|
||||
// if network2 is trying to use any of that memory.
|
||||
// Deallocating all of network1's memory, so that network2 does not use any
|
||||
// of that memory.
|
||||
arma::mat predictions2;
|
||||
network2.Predict(trainData, predictions2);
|
||||
CheckMatrices(predictions1, predictions2);
|
||||
@@ -154,7 +154,145 @@ TEST_CASE("CheckCopyMovingVanillaNetworkTest", "[FeedForwardNetworkTest]")
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether copying and moving network with dropout is working or not.
|
||||
* Check whether copying and moving network with linear3d is working or not.
|
||||
*/
|
||||
TEST_CASE("CheckCopyMovingLinear3DNetworkTest", "[FeedForwardNetworkTest]")
|
||||
{
|
||||
// Load the dataset.
|
||||
arma::mat trainData;
|
||||
data::Load("thyroid_train.csv", trainData, true);
|
||||
|
||||
arma::mat trainLabels = trainData.row(trainData.n_rows - 1);
|
||||
trainData.shed_row(trainData.n_rows - 1);
|
||||
|
||||
/*
|
||||
* Construct a feed forward network with trainData.n_rows input nodes,
|
||||
* hiddenLayerSize hidden nodes and trainLabels.n_rows output nodes. The
|
||||
* network structure looks like:
|
||||
*
|
||||
* Input Hidden Output
|
||||
* Layer Layer Layer
|
||||
* +-----+ +-----+ +-----+
|
||||
* | | | | | |
|
||||
* | +------>| +------>| |
|
||||
* | | +>| | +>| |
|
||||
* +-----+ | +--+--+ | +-----+
|
||||
* | |
|
||||
* Bias | Bias |
|
||||
* Layer | Layer |
|
||||
* +-----+ | +-----+ |
|
||||
* | | | | | |
|
||||
* | +-----+ | +-----+
|
||||
* | | | |
|
||||
* +-----+ +-----+
|
||||
*/
|
||||
|
||||
FFN<NegativeLogLikelihood<> > *model = new FFN<NegativeLogLikelihood<> >;
|
||||
model->Add<Linear<> >(trainData.n_rows, 8);
|
||||
model->Add<SigmoidLayer<> >();
|
||||
model->Add<Linear3D<> >(8, 3);
|
||||
model->Add<LogSoftMax<> >();
|
||||
|
||||
FFN<NegativeLogLikelihood<> > *model1 = new FFN<NegativeLogLikelihood<> >;
|
||||
model1->Add<Linear<> >(trainData.n_rows, 8);
|
||||
model1->Add<SigmoidLayer<> >();
|
||||
model1->Add<Linear3D<> >(8, 3);
|
||||
model1->Add<LogSoftMax<> >();
|
||||
|
||||
// Check whether copy constructor is working or not.
|
||||
CheckCopyFunction<>(model, trainData, trainLabels, 1);
|
||||
|
||||
// Check whether move constructor is working or not.
|
||||
CheckMoveFunction<>(model1, trainData, trainLabels, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether copying and moving of Noisy Linear layer is working or not.
|
||||
*/
|
||||
TEST_CASE("CheckCopyMovingNoisyLinearTest", "[FeedForwardNetworkTest]")
|
||||
{
|
||||
// Create training input by 5x5 matrix.
|
||||
arma::mat input = arma::randu(10,1);
|
||||
// Create training output by 1 matrix.
|
||||
arma::mat output = arma::mat("1");
|
||||
|
||||
// Check copying constructor.
|
||||
FFN<NegativeLogLikelihood<>> *model1 = new FFN<NegativeLogLikelihood<>>();
|
||||
model1->Predictors() = input;
|
||||
model1->Responses() = output;
|
||||
model1->Add<IdentityLayer<>>();
|
||||
model1->Add<NoisyLinear<>>(10, 5);
|
||||
model1->Add<Linear<> >(5, 1);
|
||||
model1->Add<LogSoftMax<>>();
|
||||
|
||||
// Check whether copy constructor is working or not.
|
||||
CheckCopyFunction<>(model1, input, output, 1);
|
||||
|
||||
// Check moving constructor.
|
||||
FFN<NegativeLogLikelihood<>> *model2 = new FFN<NegativeLogLikelihood<>>();
|
||||
model2->Predictors() = input;
|
||||
model2->Responses() = output;
|
||||
model2->Add<IdentityLayer<>>();
|
||||
model2->Add<NoisyLinear<>>(10, 5);
|
||||
model2->Add<Linear<> >(5, 1);
|
||||
model2->Add<LogSoftMax<>>();
|
||||
|
||||
// Check whether move constructor is working or not.
|
||||
CheckMoveFunction<>(model2, input, output, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether copying and moving of concatenate layer is working or not.
|
||||
*/
|
||||
TEST_CASE("CheckCopyMovingConcatenateTest", "[FeedForwardNetworkTest]")
|
||||
{
|
||||
// Create training input by 5x5 matrix.
|
||||
arma::mat input = arma::randu(10,1);
|
||||
// Create training output by 1 matrix.
|
||||
arma::mat output = arma::mat("1");
|
||||
|
||||
// Check copying constructor.
|
||||
FFN<NegativeLogLikelihood<>> *model1 = new FFN<NegativeLogLikelihood<>>();
|
||||
model1->Predictors() = input;
|
||||
model1->Responses() = output;
|
||||
model1->Add<IdentityLayer<>>();
|
||||
model1->Add<Linear<>>(10, 5);
|
||||
|
||||
// Create concatenate layer.
|
||||
arma::mat concatMatrix = arma::ones(5, 1);
|
||||
Concatenate<>* concatLayer = new Concatenate<>();
|
||||
concatLayer->Concat() = concatMatrix;
|
||||
|
||||
// Add concatenate layer to the current network.
|
||||
model1->Add(concatLayer);
|
||||
model1->Add<Linear<> >(10, 5);
|
||||
model1->Add<LogSoftMax<>>();
|
||||
|
||||
// Check whether copy constructor is working or not.
|
||||
CheckCopyFunction<>(model1, input, output, 1);
|
||||
|
||||
// Check moving constructor.
|
||||
FFN<NegativeLogLikelihood<>> *model2 = new FFN<NegativeLogLikelihood<>>();
|
||||
model2->Predictors() = input;
|
||||
model2->Responses() = output;
|
||||
model2->Add<IdentityLayer<>>();
|
||||
model2->Add<Linear<>>(10, 5);
|
||||
|
||||
// Create new concat layer.
|
||||
Concatenate<>* concatLayer2 = new Concatenate<>();
|
||||
concatLayer2->Concat() = concatMatrix;
|
||||
|
||||
// Add concatenate layer to the current network.
|
||||
model2->Add(concatLayer2);
|
||||
model2->Add<Linear<> >(10, 5);
|
||||
model2->Add<LogSoftMax<>>();
|
||||
|
||||
// Check whether move constructor is working or not.
|
||||
CheckMoveFunction<>(model2, input, output, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether copying and moving of Dropout network is working or not.
|
||||
*/
|
||||
TEST_CASE("CheckCopyMovingDropoutNetworkTest", "[FeedForwardNetworkTest]")
|
||||
{
|
||||
|
||||
@@ -70,7 +70,8 @@ class SpecificRandomInitialization
|
||||
TEST_CASE("SVDBatchMomentumTest", "[SVDBatchTest]")
|
||||
{
|
||||
mat dataset;
|
||||
data::Load("GroupLensSmall.csv", dataset);
|
||||
if (!data::Load("GroupLensSmall.csv", dataset))
|
||||
FAIL("Cannot load dataset GroupLensSmall.csv!");
|
||||
|
||||
// Generate list of locations for batch insert constructor for sparse
|
||||
// matrices.
|
||||
@@ -117,7 +118,8 @@ TEST_CASE("SVDBatchMomentumTest", "[SVDBatchTest]")
|
||||
TEST_CASE("SVDBatchRegularizationTest", "[SVDBatchTest]")
|
||||
{
|
||||
mat dataset;
|
||||
data::Load("GroupLensSmall.csv", dataset);
|
||||
if (!data::Load("GroupLensSmall.csv", dataset))
|
||||
FAIL("Cannot load dataset GroupLensSmall.csv!");
|
||||
|
||||
// Generate list of locations for batch insert constructor for sparse
|
||||
// matrices.
|
||||
|
||||
Reference in New Issue
Block a user