Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
adaline_learning.cpp File Reference

Adaptive Linear Neuron (ADALINE) implementation More...

#include <cassert>
#include <climits>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <numeric>
#include <vector>
Include dependency graph for adaline_learning.cpp:

Classes

class  machine_learning::adaline
 

Namespaces

 machine_learning
 Machine learning algorithms.
 

Macros

#define MAX_ITER   500
 

Functions

void test1 (double eta=0.01)
 
void test2 (double eta=0.01)
 
void test3 (double eta=0.01)
 
int main (int argc, char **argv)
 

Detailed Description

Adaptive Linear Neuron (ADALINE) implementation

Author
Krishna Vedala

Structure of an ADALINE network. Source: Wikipedia

ADALINE is one of the first and simplest single layer artificial neural network. The algorithm essentially implements a linear function

\[ f\left(x_0,x_1,x_2,\ldots\right) = \sum_j x_jw_j+\theta \]

where \(x_j\) are the input features of a sample, \(w_j\) are the coefficients of the linear function and \(\theta\) is a constant. If we know the \(w_j\), then for any given set of features, \(y\) can be computed. Computing the \(w_j\) is a supervised learning algorithm wherein a set of features and their corresponding outputs are given and weights are computed using stochastic gradient descent method.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Main function

333  {
334  std::srand(std::time(nullptr)); // initialize random number generator
335 
336  double eta = 0.1; // default value of eta
337  if (argc == 2) // read eta value from commandline argument if present
338  eta = strtof(argv[1], nullptr);
339 
340  test1(eta);
341 
342  std::cout << "Press ENTER to continue..." << std::endl;
343  std::cin.get();
344 
345  test2(eta);
346 
347  std::cout << "Press ENTER to continue..." << std::endl;
348  std::cin.get();
349 
350  test3(eta);
351 
352  return 0;
353 }
Here is the call graph for this function:

◆ test1()

void test1 ( double  eta = 0.01)

test function to predict points in a 2D coordinate system above the line \(x=y\) as +1 and others as -1. Note that each point is defined by 2 values or 2 features.

Parameters
[in]etalearning rate (optional, default=0.01)
204  {
205  adaline ada(2, eta); // 2 features
206 
207  const int N = 10; // number of sample points
208 
209  std::vector<double> X[N] = {{0, 1}, {1, -2}, {2, 3}, {3, -1},
210  {4, 1}, {6, -5}, {-7, -3}, {-8, 5},
211  {-9, 2}, {-10, -15}};
212  int y[] = {1, -1, 1, -1, -1, -1, 1, 1, 1, -1}; // corresponding y-values
213 
214  std::cout << "------- Test 1 -------" << std::endl;
215  std::cout << "Model before fit: " << ada << std::endl;
216 
217  ada.fit(X, y);
218  std::cout << "Model after fit: " << ada << std::endl;
219 
220  int predict = ada.predict({5, -3});
221  std::cout << "Predict for x=(5,-3): " << predict;
222  assert(predict == -1);
223  std::cout << " ...passed" << std::endl;
224 
225  predict = ada.predict({5, 8});
226  std::cout << "Predict for x=(5,8): " << predict;
227  assert(predict == 1);
228  std::cout << " ...passed" << std::endl;
229 }
Here is the call graph for this function:

◆ test2()

void test2 ( double  eta = 0.01)

test function to predict points in a 2D coordinate system above the line \(x+3y=-1\) as +1 and others as -1. Note that each point is defined by 2 values or 2 features. The function will create random sample points for training and test purposes.

Parameters
[in]etalearning rate (optional, default=0.01)
238  {
239  adaline ada(2, eta); // 2 features
240 
241  const int N = 50; // number of sample points
242 
243  std::vector<double> X[N];
244  int Y[N]; // corresponding y-values
245 
246  // generate sample points in the interval
247  // [-range2/100 , (range2-1)/100]
248  int range = 500; // sample points full-range
249  int range2 = range >> 1; // sample points half-range
250  for (int i = 0; i < N; i++) {
251  double x0 = ((std::rand() % range) - range2) / 100.f;
252  double x1 = ((std::rand() % range) - range2) / 100.f;
253  X[i] = {x0, x1};
254  Y[i] = (x0 + 3. * x1) > -1 ? 1 : -1;
255  }
256 
257  std::cout << "------- Test 2 -------" << std::endl;
258  std::cout << "Model before fit: " << ada << std::endl;
259 
260  ada.fit(X, Y);
261  std::cout << "Model after fit: " << ada << std::endl;
262 
263  int N_test_cases = 5;
264  for (int i = 0; i < N_test_cases; i++) {
265  double x0 = ((std::rand() % range) - range2) / 100.f;
266  double x1 = ((std::rand() % range) - range2) / 100.f;
267 
268  int predict = ada.predict({x0, x1});
269 
270  std::cout << "Predict for x=(" << x0 << "," << x1 << "): " << predict;
271 
272  int expected_val = (x0 + 3. * x1) > -1 ? 1 : -1;
273  assert(predict == expected_val);
274  std::cout << " ...passed" << std::endl;
275  }
276 }
Here is the call graph for this function:

◆ test3()

void test3 ( double  eta = 0.01)

test function to predict points in a 3D coordinate system lying within the sphere of radius 1 and centre at origin as +1 and others as -1. Note that each point is defined by 3 values but we use 6 features. The function will create random sample points for training and test purposes. The sphere centred at origin and radius 1 is defined as: \(x^2+y^2+z^2=r^2=1\) and if the \(r^2<1\), point lies within the sphere else, outside.

Parameters
[in]etalearning rate (optional, default=0.01)
289  {
290  adaline ada(6, eta); // 2 features
291 
292  const int N = 100; // number of sample points
293 
294  std::vector<double> X[N];
295  int Y[N]; // corresponding y-values
296 
297  // generate sample points in the interval
298  // [-range2/100 , (range2-1)/100]
299  int range = 200; // sample points full-range
300  int range2 = range >> 1; // sample points half-range
301  for (int i = 0; i < N; i++) {
302  double x0 = ((std::rand() % range) - range2) / 100.f;
303  double x1 = ((std::rand() % range) - range2) / 100.f;
304  double x2 = ((std::rand() % range) - range2) / 100.f;
305  X[i] = {x0, x1, x2, x0 * x0, x1 * x1, x2 * x2};
306  Y[i] = ((x0 * x0) + (x1 * x1) + (x2 * x2)) <= 1.f ? 1 : -1;
307  }
308 
309  std::cout << "------- Test 3 -------" << std::endl;
310  std::cout << "Model before fit: " << ada << std::endl;
311 
312  ada.fit(X, Y);
313  std::cout << "Model after fit: " << ada << std::endl;
314 
315  int N_test_cases = 5;
316  for (int i = 0; i < N_test_cases; i++) {
317  double x0 = ((std::rand() % range) - range2) / 100.f;
318  double x1 = ((std::rand() % range) - range2) / 100.f;
319  double x2 = ((std::rand() % range) - range2) / 100.f;
320 
321  int predict = ada.predict({x0, x1, x2, x0 * x0, x1 * x1, x2 * x2});
322 
323  std::cout << "Predict for x=(" << x0 << "," << x1 << "," << x2
324  << "): " << predict;
325 
326  int expected_val = ((x0 * x0) + (x1 * x1) + (x2 * x2)) <= 1.f ? 1 : -1;
327  assert(predict == expected_val);
328  std::cout << " ...passed" << std::endl;
329  }
330 }
Here is the call graph for this function:
std::srand
T srand(T... args)
std::vector< double >
test1
void test1(double eta=0.01)
Definition: adaline_learning.cpp:204
std::cout
std::rand
T rand(T... args)
std::endl
T endl(T... args)
std::strtof
T strtof(T... args)
std::time
T time(T... args)
std::cin
test2
void test2(double eta=0.01)
Definition: adaline_learning.cpp:238
test3
void test3(double eta=0.01)
Definition: adaline_learning.cpp:289
machine_learning::adaline
Definition: adaline_learning.cpp:44