⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 array.cpp

📁 神经网络vc源代码神经网络的VC++代码呀
💻 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 + -