map.cpp
/*This program declares a 5 x 5 two-dimensional array
called 'map' which is used to represent numerals. The
representation is achieved by entering the value 1 in
the appropriate location in the array to form the shape
of the numeral. For example, the numeral '7' is represented
in the following way (for the sake of clarity '1' has been
replaced by '*' in the diagram below):
00000
0***0
00*00
0*000
00000.
The map array is a much simplified simulation of the way in
which computer screen images are represented in pixellated form.
In reality, the representation of even a low resolution image
would require a 320 x 240 two-dimensional array. In the map array,
'0' is chosen to represent a white pixel and '1' a black pixel.
WHAT THE PROGRAM DOES
The program initialises the map array to the empty screen
where all the pixels are white:
00000
00000
00000
00000
00000.
The empty screen is displayed and the program then searches
the array locations to check whether the shape of the numeral
'1' has been entered (this numeral has been chosen for the sake
of simplicity). The program displays confirmation that the
representation of the numeral '1' has not been entered.
The program then enters the value 1 in the appropriate map
array locations to form the shape of the numeral '1':
00000
00100
00100
00100
00000.
The screen representing the numeral '1' is displayed and the
program then searches the array locations to check whether
the shape of the numeral '1' has been entered. It displays
confirmation that the representation of the numeral '1' has
been entered.*/
//map.cpp
#include <iostream.h>
void main()
{
int a, i, j;
// two-dimensional array representing numeral
shapes
int map [5] [5];
// enter 0 in all array positions and display
map
for (i=0; i<5; i++)
{
for (j=0; j<5; j++)
{
map [i]
[j] = 0;
cout <<
map [i] [j];
}
cout << endl;
}
cout << endl;
// check relevant array positions for shape of
numeral '1'
a = 0;
i=2;
for (j=1; j<=3; j++)
{
if(map[j] [i] == 1)
{
a++;
}
}
// display result
if(a==3)
cout << "This numeral
is 1";
else
cout << "This numeral
is not 1";
cout << endl << endl;
// enter 1 in relevant array positions to form
shape of
// numeral '1' and display map.
i = 2;
for (j=1; j<=3; j++)
{
map [j] [i] = 1;
}
for (i=0; i<5; i++)
{
for (j=0; j<5; j++)
{
cout <<
map [i] [j];
}
cout << endl;
}
cout << endl;
// check relevant array positions for shape of
numeral '1'
a = 0;
i=2;
for (j=1; j<=3; j++)
{
if(map[j] [i] == 1)
{
a++;
}
}
// display result
if(a==3)
cout << "This numeral
is 1";
else
cout << "This numeral
is not 1";
}
UNIT 2
logicgts
perceptron
//logicgts.cpp
//program for demonstrating "supervised learning"
#include <iomanip.h>
#include <iostream.h>
#include <string.h>
#include <conio.h>
//declaration of functions for OR, AND, XOR logic gates
int or_func(int inputs[]);
int and_func(int inputs[]);
int xor_func(int inputs[]);
void main()
{
//initial weights for neuron with two binary inputs
int weight_a = 0, weight_b = 0;
//input variables for neuron with two binary inputs
int input_a, input_b;
//variables for correct output and actual output of
neuron
int correct_output, actual_output;
//display intial value of weights
cout << "initial value of weights: " <<
endl;
cout << "weight_a = " << weight_a <<
endl;
cout << "weight_b = " << weight_b <<
endl << endl;
//allow user to enter training data (two binary inputs)
for (int i = 0; i<20; i++)
{
cout << "enter two inputs separated
by a space: ";
cin >> input_a >> input_b;
//enter the training data in an AND
gate
int input[]={input_a, input_b};
and_func(input);
//define correct output as output
of AND gate
correct_output = and_func(input);
//activation function (threshold
value: > 1)
if ((weight_a * input_a) + (weight_b
* input_b) > 1)
actual_output = 1;
else
actual_output = 0;
//display actual output and correct
output
cout << "actual output: " <<
actual_output << endl;
cout << "correct output: "
<< correct_output << endl;
//adjust weights if actual output
incorrect
if (actual_output != correct_output)
{
weight_a = weight_a
+ (1 * input_a *(correct_output - actual_output));
weight_b = weight_b
+ (1 * input_b*(correct_output - actual_output));
}
//display adjusted weights
cout << "weight_a: " <<
weight_a << endl;
cout << "weight_b: " <<
weight_b << endl << endl;
}
}
// function definitions of OR, AND, XOR logic gates
// OR function (takes 2 inputs)
int or_func(int inputs[])
{
if(inputs[0] || inputs[1])
return 1;
else
return 0;
}
// AND function (takes 2 inputs)
int and_func(int inputs[])
{
if(inputs[0] && inputs[1])
return 1;
else
return 0;
}
// XOR (exclusive OR) function (takes 2 inputs)
int xor_func(int inputs[])
{
if (!(inputs[0] && inputs[1])
&&
((inputs[0] ||
inputs[1]) || (inputs[1] || inputs[0])))
return 1;
else
return 0;
}
function.hpp
function.cpp
percept.hpp
percept.cpp
Copy the code for the Perceptron program. Separate the individual files
and save them as function.hpp, function.cpp, percept.hpp and percept.cpp
in the directory you normally use for C++ programs. Create a project called
'perceptron_1' in your C++ compiler and make the function.cpp and percept.cpp
files the nodes of that project.
WHAT THE PROGRAM DOES
The following edited details are taken
from the description of the Perceptron program given in http://www-cse.uta.edu/~holder/courses/ai2cpp/code/mydean/05.Learning/C++Code/Perceptron/.
This program demonstrates the perceptron learning algorithm with a
very simple perceptron network, a logic threshold unit. This code was written
by Jon Monsarrat, [email protected].
The program is described in the following four sections:
1. The problem
2. Compiling the program
3. Running the program
4. The solution and how to read the source code
1. The problem
We have some function (let's pretend it's unknown or takes a long
time to compute). We want a perceptron network to simulate the function.
Unfortunately, a perceptron network must be configured with a bunch of weights
that tell the network how to work. This program solves the
problem by learning the weights.
2. Compiling the program
The source code in this directory is complete and uses standard libraries
which should come with any C++ compiler.
3. Running the program
Once you have created the 'perceptron_1' project in your C++ compiler,
run the program and choose the function you want the network to learn. The
network has been programmed to learn the following logic functions: 'OR',
'AND' and 'XOR' (i.e. 'exclusive or'). The program regards these functions
as having two inputs which can be either 1 or 0.
The OR, AND and XOR functions come with the perceptron program, but
you are welcome to create additional functions and add extra inputs. You'll
need to write extra code to do this.
4. The solution - and how to read the source code
The 'functions' in the program are real C++ functions. To get all
combinations of inputs, they must be generated. The perceptron program does
this. It is not possible to have a partially defined
function which does not return values for some inputs.
The classes in the program are:
perceptron: this holds the entire perceptron, and runs
the learning algorithm;
function: this holds a single
function, which is a pointer to a real C++ function.
There are four files in this directory:
the function class:
1. function.hpp
2. function.cpp
the perceptron class:
3. percept.hpp
4. percept.cpp.
function.cpp
/* function.cpp
*
* A function is a mapping from inputs to a boolean output. We read
* this is from a file. Note the weird syntax "int (*function)(int
input[])"
* refers to a pointer to a C++ function that takes an array of inputs
* and returns a boolean. This function pointer is called "function"
* and can be executed by calling "int x = (*function)(inputs);".
*/
/*
* Copyright 1994, Brown University, Providence, RI
* See end of file for full copyright information
*/
#include "function.hpp"
// Construct a function, given a pointer to a real C++ function and
// the number of inputs it will take
Function::Function(int _num_inputs, int (* _function)(int input[]))
{
num_inputs = _num_inputs;
function = _function;
}
// Destroy the function
Function::~Function()
{
}
// Execute the function, by calling the real C++ function
int Function::execute(int input[])
{
return (*function)(input);
}
// Get the number of boolean inputs for the function
int Function::get_num_inputs()
{
return num_inputs;
}
percept.hpp
/* percept.hpp
*
* This class encapsulates the entire perceptron program.
*/
/*
* Copyright 1994, Brown University, Providence, RI
* See end of file for full copyright information
*/
const int MAX_INPUTS = 100;
const int MAX_ADJUSTMENTS = 3000; // Should be higher for several
bit functions
class Function;
class Perceptron {
Function *function; // The function to
be learned
int *weights;
// The weights of the perceptron network
int num_inputs; // the
number of inputs to the function
int *inputs;
// An array of inputs to be given to the function
int ltu(int input[]); // output of logic threshold
unit with current weights
int success();
public:
void test(Function *function, int *weights); // Learn
the given function
};
/* percept.cpp
*
* This class encapsulates the entire perceptron program.
*/
/*
* Copyright 1994, Brown University, Providence, RI
* See end of file for full copyright information
*/
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <time.h>
#include "percept.hpp"
#include "function.hpp"
// A function that takes 2 inputs.
int or_func(int inputs[])
{
if(inputs[0] || inputs[1])
return 1;
else
return 0;
}
// A function that takes 2 inputs.
int and_func(int inputs[])
{
if(inputs[0] && inputs[1])
return 1;
else
return 0;
}
// A function that takes 2 inputs.
int xor_func(int inputs[])
{
if(inputs[0] ^ inputs[1])
return 1;
else
return 0;
}
// The main() function is the first function called in this program.
// You are welcome to add more functions
// yourself, with inputs of more than just 2 bits. However, you'll
// have to compile them in. There is no example file to read.
int main()
{
// Initialize random number generator.
#ifndef DEBUG
srand((unsigned int) time(0));
#endif
Perceptron perceptron;
Function *function;
// choose which function to test
int choice;
cout << "1. 'or' function" << endl;
cout << "2. 'and' function" << endl;
cout << "3. 'x-or' function" << endl <<
endl;
cout << "Enter function to test: ";
cin >> choice;
cout << endl;
switch(choice) {
case 1:
function = new
Function(2, or_func);
break;
case 2:
function = new
Function(2, and_func);
break;
case 3:
function = new
Function(2, xor_func);
break;
}
int weights[MAX_INPUTS];
// Initialize all weights to zero
for(int x = 0; x < function->get_num_inputs();
x++)
weights[x] = 0;
perceptron.test(function, weights);
// Try to learn the function
delete function;
return 0;
}
// Try to learn the function, given the initial weights, by iterating.
// After each iteration, test to see if we have successfully learned the
// function.
void Perceptron::test(Function *_function, int *_weights)
{
function = _function;
weights = _weights;
num_inputs = function->get_num_inputs();
inputs = new int[num_inputs];
int result;
int x;
// Try to adjust the network until successful, or until
too many adjustments
for(int adjustments = 0; !success() && adjustments
< MAX_ADJUSTMENTS;
adjustments++) {
// Choose a training example by
generating inputs randomly
cout << "Training example:";
for(x = 0; x < num_inputs; x++)
{ // Try a random input
inputs[x] = rand()
% 2;
cout <<
" " << inputs[x];
}
cout << endl;
result = ltu(inputs); // Put
training example into the network. Correct?
// Now, adjust the weights
if(result != function->execute(inputs))
{
if(result ==
0)
for(x = 0; x < num_inputs; x++)
weights[x] += inputs[x];
else
for(x = 0; x < num_inputs; x++)
weights[x] -= inputs[x];
}
cout << "Adjusted weights:";
for(x = 0; x < num_inputs; x++)
// Print out the weights
cout <<
" " << weights[x];
cout << endl;
}
delete [] inputs;
if(adjustments < MAX_ADJUSTMENTS)
cout << "Number of adjustments:
" << adjustments << endl;
else
cout << "Could not learn function
in "
<<
MAX_ADJUSTMENTS << " adjustments." << endl;
}
// test the network against the function for all combinations of
// inputs. For a 2-bit input function, this is no big deal, but
of
// course you couldn't do this for a 50-bit function. It would take
too
// long to generate all the inputs. So you'd probably just take
a
// random sample. This program doesn't do random sampling.
int Perceptron::success()
{
for(int x = 0; x < num_inputs; x++)
inputs[x] = 0;
// This loop generates all combinations of inputs.
// The logic threshold unit is tested for each input
combination.
x = 0;
while(x >= 0) {
if(ltu(inputs) != function->execute(inputs))
// test network
return 0;
for(x = num_inputs - 1; x >=
0; x--) { // generate next input combo
inputs[x] = !inputs[x];
if(inputs[x]
== 1)
break;
}
}
return 1;
}
// Here is a straight-through logic threshold unit with a fixed
// threshold of one for any length of input and weight vectors.
// Return the output given the current weights and current input
int Perceptron::ltu(int input[])
{
int sum = 0;
for(int x = 0; x < num_inputs; x++)
sum += inputs[x] * weights[x];
if(sum > 1)
return 1;
else
return 0;
}
/*
* Copyright 1994, Brown University, Providence, RI
*
* Permission to use and modify this software and its documentation
for
* any purpose other than its incorporation into a commercial
product is
* hereby granted without fee. Permission to copy and
distribute this
* software and its documentation only for non-commercial use
is also
* granted without fee, provided, however, that the above copyright
notice
* appear in all copies, that both that copyright notice and
this permission
* notice appear in supporting documentation, that the name
of Brown
* University not be used in advertising or publicity pertaining
to
* distribution of the software without specific, written prior
permission,
* and that the person doing the distribution notify Brown University
of
* such distributions outside of his or her organization. Brown
University
* makes no representations about the suitability of this software
for
* any purpose. It is provided "as is" without express
or implied warranty.
* Brown University requests notification of any modifications
to this
* software or its documentation.
*
* Send the following redistribution information:
*
* Name:
* Organization:
* Address (postal and/or electronic):
*
* To:
* Software Librarian
* Computer Science Department, Box 1910
* Brown University
* Providence, RI 02912
*
* or
*
* [email protected]
*
* We will acknowledge all electronic notifications.
*/