Skip to content
Snippets Groups Projects
Commit 3b3eba96 authored by Jakhes's avatar Jakhes
Browse files

Finishing lcc tests

parent 2c6c97a5
Branches
No related tags found
No related merge requests found
...@@ -15,11 +15,6 @@ using namespace mlpack; ...@@ -15,11 +15,6 @@ using namespace mlpack;
using namespace std; using namespace std;
using namespace mlpack::lcc; using namespace mlpack::lcc;
// Global Variable of the LocalCoordinateCoding object so it can be accessed from all functions
LocalCoordinateCoding lccGlobObj;
bool normalizeData = false;
// input: const arma::mat & data, // input: const arma::mat & data,
// const size_t atoms, // const size_t atoms,
...@@ -27,179 +22,40 @@ bool normalizeData = false; ...@@ -27,179 +22,40 @@ bool normalizeData = false;
// const size_t maxIterations = 0, // const size_t maxIterations = 0,
// const double tolerance = 0.01, // const double tolerance = 0.01,
// const DictionaryInitializer & initializer = DictionaryInitializer() // const DictionaryInitializer & initializer = DictionaryInitializer()
// output: // const arma::mat & toEncodedata,
// description:
// Initializes the model and trains it so encode/6 can be called after
//
void initModelWithTrain(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum,
SP_integer normalize, SP_integer atoms, double lambda, SP_integer maxIterations, double tolerance)
{
normalizeData = normalize == 1;
// convert the Prolog array to arma::mat
mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
if (normalizeData)
{
Log::Info << "Normalizing data before coding..." << endl;
for (size_t i = 0; i < data.n_cols; ++i)
data.col(i) /= arma::norm(data.col(i), 2);
}
try
{
lccGlobObj = LocalCoordinateCoding(data, atoms, lambda, maxIterations, tolerance);lccGlobObj = LocalCoordinateCoding(atoms, lambda, maxIterations, tolerance);
}
catch(const std::exception& e)
{
raisePrologSystemExeption(e.what());
}
}
// input: const size_t atoms = 0,
// const double lambda = 0.0,
// const size_t maxIterations = 0,
// const double tolerance = 0.01
// output:
// description:
// Initializes the model but doesnt train it so train/4 has to be called befor encode/6 can be used.
//
void initModelNoTrain(SP_integer normalize, SP_integer atoms, double lambda, SP_integer maxIterations, double tolerance)
{
normalizeData = normalize == 1;
try
{
lccGlobObj = LocalCoordinateCoding(atoms, lambda, maxIterations, tolerance);
}
catch(const std::exception& e)
{
raisePrologSystemExeption(e.what());
}
}
// input: const arma::mat & data,
// arma::mat & codes <- // arma::mat & codes <-
// output: // output:
// description: // description:
// Code each point via distance-weighted LARS. // Initializes the model, trains it and encodes each point of the given data via distance-weighted LARS.
// //
void encode(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, void lcc(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum,
SP_integer normalize, SP_integer atoms, double lambda, SP_integer maxIterations, double tolerance,
float *toEncodeDataMatArr, SP_integer toEncodeDataMatSize, SP_integer toEncodeDataMatRowNum,
float **codesMatArr, SP_integer *codesMatColNum, SP_integer *codesMatRowNum) float **codesMatArr, SP_integer *codesMatColNum, SP_integer *codesMatRowNum)
{ {
// convert the Prolog array to arma::mat // convert the Prolog array to arma::mat
mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
mat toEncodeData = convertArrayToMat(toEncodeDataMatArr, toEncodeDataMatSize, toEncodeDataMatRowNum);
// create the ReturnMat // create the ReturnMat
mat codesReturnMat; mat codesReturnMat;
// Normalize each point if the user asked for it. if (normalize == 1)
if (IO::HasParam("normalize"))
{ {
Log::Info << "Normalizing test data before coding..." << endl; Log::Info << "Normalizing data before coding..." << endl;
for (size_t i = 0; i < data.n_cols; ++i)
data.col(i) /= arma::norm(data.col(i), 2);
}
try
{
lccGlobObj.Encode(data, codesReturnMat);
}
catch(const std::exception& e)
{
raisePrologSystemExeption(e.what());
}
// return the Matrix
returnMatrixInformation(codesReturnMat, codesMatArr, codesMatColNum, codesMatRowNum);
}
// TODO: wrong inputs
// input: const arma::mat & data,
// const arma::mat & codes,
// const arma::uvec & adjacencies
// output:
// description:
// Compute objective function given the list of adjacencies.
//
void objective(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum,
float **codesMatArr, SP_integer *codesMatColNum, SP_integer *codesMatRowNum,
float **adjacenciesArr, SP_integer *adjacenciesArrSize)
{
// convert the Prolog arrays to arma::mat
mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
// create the ReturnMat
mat codesReturnMat;
// create the ReturnVector
uvec adjacenciesReturnVector;
// Normalize each point if the user asked for it.
if (IO::HasParam("normalize"))
{
Log::Info << "Normalizing test data before coding..." << endl;
for (size_t i = 0; i < data.n_cols; ++i) for (size_t i = 0; i < data.n_cols; ++i)
data.col(i) /= arma::norm(data.col(i), 2); data.col(i) /= arma::norm(data.col(i), 2);
}
try
{
lccGlobObj.Objective(data, codesReturnMat, adjacenciesReturnVector);
}
catch(const std::exception& e)
{
raisePrologSystemExeption(e.what());
}
// return the Matrix
returnMatrixInformation(codesReturnMat, codesMatArr, codesMatColNum, codesMatRowNum);
// return the Vector
returnVectorInformation(arma::conv_to<vec>::from(adjacenciesReturnVector), adjacenciesArr, adjacenciesArrSize);
}
// TODO: wrong inputs
// input: const arma::mat & data,
// const arma::mat & codes,
// const arma::uvec & adjacencies
// output:
// description:
// Learn dictionary by solving linear system.
//
void optimizeDictionary(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum,
float **codesMatArr, SP_integer *codesMatColNum, SP_integer *codesMatRowNum,
float **adjacenciesArr, SP_integer *adjacenciesArrSize)
{
// convert the Prolog arrays to arma::mat
mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
// create the ReturnMat
mat codesReturnMat;
// create the ReturnVector
uvec adjacenciesReturnVector;
// Normalize each point if the user asked for it.
if (IO::HasParam("normalize"))
{
Log::Info << "Normalizing test data before coding..." << endl; Log::Info << "Normalizing test data before coding..." << endl;
for (size_t i = 0; i < data.n_cols; ++i) for (size_t i = 0; i < toEncodeData.n_cols; ++i)
data.col(i) /= arma::norm(data.col(i), 2); toEncodeData.col(i) /= arma::norm(toEncodeData.col(i), 2);
} }
try try
{ {
lccGlobObj.OptimizeDictionary(data, codesReturnMat, adjacenciesReturnVector); LocalCoordinateCoding(data, atoms, lambda, maxIterations, tolerance)
.Encode(toEncodeData, codesReturnMat);
} }
catch(const std::exception& e) catch(const std::exception& e)
{ {
...@@ -209,37 +65,4 @@ void optimizeDictionary(float *dataMatArr, SP_integer dataMatSize, SP_integer da ...@@ -209,37 +65,4 @@ void optimizeDictionary(float *dataMatArr, SP_integer dataMatSize, SP_integer da
// return the Matrix // return the Matrix
returnMatrixInformation(codesReturnMat, codesMatArr, codesMatColNum, codesMatRowNum); returnMatrixInformation(codesReturnMat, codesMatArr, codesMatColNum, codesMatRowNum);
// return the Vector
returnVectorInformation(arma::conv_to<vec>::from(adjacenciesReturnVector), adjacenciesArr, adjacenciesArrSize);
}
// input: const arma::mat & data,
// const DictionaryInitializer & initializer = DictionaryInitializer()
// output: double final objective value
// description:
// Run local coordinate coding and train the model.
//
double train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum)
{
// convert the Prolog arrays to arma::mat
mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum);
if (normalizeData)
{
Log::Info << "Normalizing data before coding..." << endl;
for (size_t i = 0; i < data.n_cols; ++i)
data.col(i) /= arma::norm(data.col(i), 2);
}
try
{
return lccGlobObj.Train(data);
}
catch(const std::exception& e)
{
raisePrologSystemExeption(e.what());
}
} }
\ No newline at end of file
:- module(local_coordinate_coding, [ lcc_initModelWithTrain/7, :- module(local_coordinate_coding, [lcc/11]).
lcc_initModelNoTrain/5,
lcc_encode/4,
lcc_objective/5,
lcc_optimizeDictionary/5,
lcc_train/3]).
%% requirements of library(struct) %% requirements of library(struct)
:- load_files(library(str_decl), :- load_files(library(str_decl),
...@@ -29,123 +24,33 @@ ...@@ -29,123 +24,33 @@
%% float32 lambda => 0.0, %% float32 lambda => 0.0,
%% int maxIterations => 0, %% int maxIterations => 0,
%% float32 tolerance => 0.01 %% float32 tolerance => 0.01
%% mat data
%% %%
%% --Output-- %% --Output--
%% mat codes
%% %%
%% --Description-- %% --Description--
%% Initializes the model and trains it so encode/6 can be called after %% Initializes the model and trains it so encode/6 can be called after
%% %%
lcc_initModelWithTrain(DataList, DataRows, Normalize, Atoms, Lambda, MaxIterations, Tolerance) :- lcc(DataList, DataRows, Normalize, Atoms, Lambda, MaxIterations, Tolerance, TestDataList, TestDataRows, CodesList, ZRows) :-
Atoms > 0,
Lambda >= 0,
MaxIterations >= 0,
Tolerance > 0,
convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrownum, X)), convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrownum, X)),
initModelWithTrainI(X, Xsize, Xrownum, Normalize, Atoms, Lambda, MaxIterations, Tolerance). Atoms < (Xsize / Xrownum),
convert_list_to_float_array(TestDataList, TestDataRows, array(Ysize, Yrownum, Y)),
lccI(X, Xsize, Xrownum, Normalize, Atoms, Lambda, MaxIterations, Tolerance, Y, Ysize, Yrownum, Z, ZCols, ZRows),
convert_float_array_to_2d_list(Z, ZCols, ZRows, CodesList).
foreign(initModelWithTrain, c, initModelWithTrainI( +pointer(float_array), +integer, +integer, foreign(lcc, c, lccI( +pointer(float_array), +integer, +integer,
+integer, +integer,
+integer, +float32, +integer, +float32)). +integer, +float32, +integer, +float32,
+pointer(float_array), +integer, +integer,
%% --Input--
%% bool normalize => (1)true / (0)false => false,
%% int atoms => 0,
%% float32 lambda => 0.0,
%% int maxIterations => 0,
%% float32 tolerance => 0.01
%%
%% --Output--
%%
%% --Description--
%% Initializes the model but doesnt train it so train/4 has to be called befor encode/6 can be used.
%%
lcc_initModelNoTrain(Normalize, Atoms, Lambda, MaxIterations, Tolerance) :-
initModelNoTrainI(Normalize, Atoms, Lambda, MaxIterations, Tolerance).
foreign(initModelNoTrain, c, initModelNoTrainI( +integer,
+integer, +float32, +integer, +float32)).
%% --Input--
%% mat data
%%
%% --Output--
%% mat codes
%%
%% --Description--
%% Code each point via distance-weighted LARS.
%%
lcc_encode(DataList, DataRows, CodesList, YCols) :-
convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrows, X)),
encodeI(X, Xsize, Xrows, Y, YCols, YRows),
convert_float_array_to_2d_list(Y, YCols, YRows, CodesList).
foreign(encode, c, encodeI( +pointer(float_array), +integer, +integer,
-pointer(float_array), -integer, -integer)). -pointer(float_array), -integer, -integer)).
%% --Input--
%% mat data
%%
%% --Output--
%% mat codes,
%% vec adjacencies
%%
%% --Description--
%% Compute objective function given the list of adjacencies.
%%
lcc_objective(DataList, DataRows, CodesList, YCols, AdjacenciesList) :-
convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrows, X)),
objectiveI(X, Xsize, Xrows, Y, YCols, YRows, Z, Zsize),
convert_float_array_to_2d_list(Y, YCols, YRows, CodesList),
convert_float_array_to_list(Z, Zsize, AdjacenciesList).
foreign(objective, c, objectiveI( +pointer(float_array), +integer, +integer,
-pointer(float_array), -integer, -integer,
-pointer(float_array), -integer)).
%% --Input--
%% mat data
%%
%% --Output--
%% mat codes,
%% vec adjacencies
%%
%% --Description--
%% Learn dictionary by solving linear system.
%%
lcc_optimizeDictionary(DataList, DataRows, CodesList, YCols, AdjacenciesList) :-
convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrows, X)),
optimizeDictionaryI(X, Xsize, Xrows, Y, YCols, YRows, Z, Zsize),
convert_float_array_to_2d_list(Y, YCols, YRows, CodesList),
convert_float_array_to_list(Z, Zsize, AdjacenciesList).
foreign(optimizeDictionary, c, optimizeDictionaryI( +pointer(float_array), +integer, +integer,
-pointer(float_array), -integer, -integer,
-pointer(float_array), -integer)).
%% --Input--
%% mat data
%%
%% --Output--
%% float32 final objective value
%%
%% --Description--
%% Run local coordinate coding and train the model.
%%
lcc_train(DataList, DataRows, ReturnValue) :-
convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrows, X)),
trainI(X, Xsize, Xrows, ReturnValue).
foreign(train, c, trainI( +pointer(float_array), +integer, +integer,
[-float32])).
%% Defines the functions that get connected from main.cpp %% Defines the functions that get connected from main.cpp
foreign_resource(local_coordinate_coding, [ initModelWithTrain, foreign_resource(local_coordinate_coding, [lcc]).
initModelNoTrain,
encode,
objective,
optimizeDictionary,
train]).
:- load_foreign_resource(local_coordinate_coding). :- load_foreign_resource(local_coordinate_coding).
...@@ -6,38 +6,46 @@ ...@@ -6,38 +6,46 @@
:- use_module(local_coordinate_coding). :- use_module(local_coordinate_coding).
:- use_module('../../helper_files/helper.pl'). :- use_module('../../helper_files/helper.pl').
reset_Model :-
lcc_initModel(1,0,50,0.0001).
%% %%
%% TESTING predicate predicate/10 %% TESTING predicate lcc/11
%% %%
:- begin_tests(predicate). :- begin_tests(lcc).
%% Failure Tests %% Failure Tests
test(testDescription, [error(domain_error('expectation' , culprit), _)]) :- test(lcc_Bad_Atom_Input, fail) :-
reset_Model_No_Train(perceptron), lcc([5.1,3.5,1.4, 4.9,3.0,1.4, 4.7,3.2,1.3, 4.6,3.1,1.5], 3, 0, -2, 0.0, 0, 0.01, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, _, _),
train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,0,0,0], 2, culprit, 50, 0.0001, _). lcc([5.1,3.5,1.4, 4.9,3.0,1.4, 4.7,3.2,1.3, 4.6,3.1,1.5], 3, 0, 4, 0.0, 0, 0.01, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, _, _).
test(testDescription2, [error(_,system_error('The values of the Label have to start at 0 and be >= 0 and < the given numClass!'))]) :- test(lcc_Negative_Lambda, fail) :-
reset_Model_No_Train(perceptron), lcc([5.1,3.5,1.4, 4.9,3.0,1.4, 4.7,3.2,1.3, 4.6,3.1,1.5], 3, 0, 2, -1.0, 0, 0.01, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, _, _).
train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,2], 2, perceptron, 50, 0.0001, _).
test(lcc_Negative_MaxIterations, fail) :-
lcc([5.1,3.5,1.4, 4.9,3.0,1.4, 4.7,3.2,1.3, 4.6,3.1,1.5], 3, 0, 2, 0.0, -1, 0.01, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, _, _).
test(lcc_Negative_Tolerance, fail) :-
lcc([5.1,3.5,1.4, 4.9,3.0,1.4, 4.7,3.2,1.3, 4.6,3.1,1.5], 3, 0, 2, 0.0, 0, -0.01, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, _, _).
test(lcc_Different_Dims, [error(_,system_error('matrix multiplication: incompatible matrix dimensions: 2x4 and 3x4'))]) :-
lcc([5.1,3.5,1.4, 4.9,3.0,1.4, 4.7,3.2,1.3, 4.6,3.1,1.5], 4, 0, 2, 0.0, 0, 0.01, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, _, _).
%% Successful Tests %% Successful Tests
test(testDescription3, [true(Error =:= 1)]) :- test(lcc_Normal_Use) :-
reset_Model_No_Train(perceptron), lcc([5.1,3.5,1.4, 4.9,3.0,1.4, 4.7,3.2,1.3, 4.6,3.1,1.5], 3, 0, 2, 0.0, 0, 0.01, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, CodesList, _),
train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,0,0,0], 2, perceptron, 50, 0.0001, Error). print('\nCodes: '),
print(CodesList).
test(testDescription4, [true(Error =:= 0.9797958971132711)]) :- test(lcc_CSV_Input) :-
reset_Model_No_Train(perceptron),
open('src/data_csv/iris2.csv', read, File), open('src/data_csv/iris2.csv', read, File),
take_csv_row(File, skipFirstRow,10, Data), take_csv_row(File, skipFirstRow,10, Data),
train(Data, 4, [0,1,0,1,1,0,1,1,1,0], 2, perceptron, 50, 0.0001, Error). lcc(Data, 4, 1, 5, 1.5, 50, 0.042, [5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 4, CodesList, _),
print('\nCodes: '),
print(CodesList).
:- end_tests(predicate). :- end_tests(lcc).
run_local_coordinate_coding_tests :- run_local_coordinate_coding_tests :-
run_tests. run_tests.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment