📄 array.cpp
字号:
/*
nn-utility (Provides neural networking utilities for c++ programmers)
Copyright (C) 2003 Panayiotis Thomakos
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
*/
//To contact the author send an email to panthomakos@users.sourceforge.net
/*The purpose of this example is to illustrate the identification of numbers 0-9
* that are 10x10 bitmaps stored in the numbers.txt file. The program then outputs
* classification of numbers to verify network learning, as well as classification
* of noisy patterns. The user is asked if they want to view the noisy patterns or
* not, as well as load a bitmap they may have created in the numbers_yours.txt file.*/
#include <nn-utility.h>
using namespace nn_utility;
#define BITMAP_SIZE 100 //size of the bitmaps
#define OUTPUT_SIZE 20 //size of the ouput of the network
BITMAP<float> *bit = new BITMAP<float>( "numbers.txt" );//create a bitmap object of the "numbers.txt" file
nn_utility_functions<float>::VECTOR numbers[10]; //create an array of vectors to store the numbers
//create a new class of nn_utility_functions of type float, with a GetInput functoin and a
//counter variable, "id", for the different patterns in numbers
class array_example : public nn_utility_functions<float>{
public:
typedef float VECTOR[NN_UTIL_SIZE];
array_example(){ id = 0; };
int id; //counter
void GetInput( int interation, VECTOR &send, VECTOR &target );
}derived;
void array_example::GetInput( int interation, VECTOR &send, VECTOR &target ){
CopyVector( send, numbers[ id ], BITMAP_SIZE ); //send the number referenced by id
ClearVector( target, OUTPUT_SIZE, 0.1 ); //clear the target to 0.1 and
target[ id ] = 0.9; //set the [id] in target to 0.9
//for example, number 2 output would
//look like this:
//01, 0.1, 0.9, 0.1, 0.1 .... 0.1
id = ( ++id > 9 ? 0 : id ); //if id has reached 10, start from 0 again
}
//userdefined function to set random weights in a network
void SetRandomWeights( layer<float> **in, int row, int col ){
for ( int i = 0; i < col; i++ ){
float it2 = rand() % 10;
(*in)->weight[i] = it2/10*( (rand() % 2) == 0 ? -1 : 1 );
for ( int e = 0; e < row; e++ ){
float it = rand() % 10;
(*in)->matrix[e][i] = (float) it/10*( (rand() % 2) == 0 ? -1 : 1 );
}
}
}
//used to classify patterns (how close they are to the actualy number)
void classifypattern( nn_utility_functions<float>::VECTOR &output ){
int max = 0;
for ( int i = 1; i < 10; i++ ){
if ( output[i] > output[max] )
max = i; }
//this is based on a sigmoid scale, 0 through 1 values.
if ( output[max] < 0.1 ) cout << "Guessed to be: " << max << '\n';
else if ( output[max] < 0.2 ) cout << "Iffy Educated guess to be: " << max << '\n';
else if ( output[max] < 0.3 ) cout << "Educated guess to be: " << max << '\n';
else if ( output[max] < 0.4 ) cout << "Number thought to be: " << max << '\n';
else if ( output[max] < 0.5 ) cout << "Number suggested to be: " << max << '\n';
else if ( output[max] < 0.6 ) cout << "Number known to be: " << max << '\n';
else if ( output[max] < 0.7 ) cout << "Pretty sure it\'s: " << max << '\n';
else cout << "Positive of a: " << max << '\n';
}
int main(){
//create a parrent class that will handle the classification
SIGMOID *parent = new SIGMOID();
parent->define( BITMAP_SIZE, OUTPUT_SIZE );
//use a for loop to load the numbers from numbers.txt into the numbers array
for ( int i = 0; i < 10; i++ ){
bit->readbitmap( numbers[i], i );
parent->sigmoid( numbers[i], BITMAP_SIZE ); }
//create a buffer for "parent'
layer<float> *ppParent = parent;
//set random weights, for some weird reason this had to be done twice
SetRandomWeights( &ppParent, BITMAP_SIZE,OUTPUT_SIZE );
SetRandomWeights( &ppParent, BITMAP_SIZE,OUTPUT_SIZE );
//declare a resulting array and clear it
nn_utility_functions<float>::VECTOR FINAL;
derived.ClearVector( FINAL, 10 );
//train the network for 150 epochs at a 0.9 learning rate (high learning rate)
derived.train( &ppParent, 150, 0.9, true );
//check the training by looping through the numbers and presenting the network
//with them. Also add noise to the bitmaps and re-evaluate the output
for ( int q = 0; q < 10; q++ ){
cout << "NUMBER: " << q << ": ";
//feed number to network
parent->FeedForward( numbers[ q ], FINAL );
//classify clear pattern
classifypattern( FINAL );
//add noise
bit->noise( numbers[q], BITMAP_SIZE, 1, 3 );
//feed noisy number to network
parent->FeedForward( numbers[ q ], FINAL );
//classify noisy pattern
cout << "And noisy: ";
classifypattern( FINAL );
//ask if the user wants to see the noisy pattern
int choice;
cout << "See noisy pattern? (1)yes (0)no ";
cin >> choice;
if ( choice == 1 )
bit->Print( numbers[q], 10, 100 );
}
//ask the user if he wants to load a pattern into the network and check it
int choice;
cout << "Classify first pattern in numbers_yours.txt? (1)yes (0)no ";
cin >> choice;
if ( choice == 1 ){
BITMAP<float> *users = new BITMAP<float>( "numbers_yours.txt" );
users->readbitmap( numbers[0], 0 );
parent->sigmoid( numbers[0], BITMAP_SIZE );
parent->FeedForward( numbers[0], FINAL );
classifypattern( FINAL );
}
cout << '\n';
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -