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

📄 layer.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.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
//To contact the author send an email to panthomakos@users.sourceforge.net

#include "nn-utility.h"

using namespace nn_utility;

template<class T> void layer<T>:: define( int rows, int cols ){
	set_defaults();
	row = rows; col = cols;
	for ( int clear = 0; clear < cols; clear++ )
		weight[clear] = 0;
};
template<class T> 
void layer<T>:: definei( int row_, int col_, T value, ... ){
	set_defaults();
	row = row_; col = col_;
	for ( int clear = 0; clear < col_; clear++ )
		weight[clear] = 0;

	va_list argument_ptr;
	matrix[0][0] = value;
	va_start(argument_ptr, value);
	for ( int i = 0; i < row; i++ ){
		//the insert if statement determines whether that value has already been placed, since the
		//first value is read outside the loop
		for ( int e = ( i == 0 ? 1 : 0 ); e < col; e++ ){
			matrix[i][e] = (T)va_arg(argument_ptr, int);
		}
	}
	va_end(argument_ptr);
}

template<class T> 
void layer<T>:: definef( int row_, int col_, T value, ... ){
	set_defaults();
	row = row_; col = col_;
	for ( int clear = 0; clear < col_; clear++ )
		weight[clear] = 0;

	va_list argument_ptr;
	matrix[0][0] = value;
	va_start(argument_ptr, value);
	for ( int i = 0; i < row; i++ ){
		//the insert if statement determines whether that value has already been placed, since the
		//first value is read outside the loop
		for ( int e = ( i == 0 ? 1 : 0 ); e < col; e++ ){
			matrix[i][e] = (T)va_arg(argument_ptr, double);
		}
	}
	va_end(argument_ptr);
}
template<class T> 
void layer<T>:: define( char *filename, int index ){
	binary_fire = false;
	fstream infile( filename, ios::in );
	char buffer[256];
	for ( int i = 0; i < index; i++ ){
		infile >> buffer;
		infile >> buffer;
		while ( buffer[0] != ':' && buffer != NULL )
			infile >> buffer;
	}
	if ( buffer[0] != ':' ){
		infile >> buffer;}
	if ( buffer[0] == ':' ){
		do{
		infile >> buffer;
		if ( buffer[0] == 's' ){
			Next = NULL;
			Previous = NULL;
			infile >> row >> col;
		}
		else if ( buffer[0] == 'b' ){
			for ( int i = 0; i < col; i++ )
				infile >> weight[i];
		}
		else if ( buffer[0] == 'w' ){
			for ( int i = 0; i < row; i++ ){
				for ( int e = 0; e < col; e++ ){
					infile >> matrix[i][e];}
			}
		}
		else if ( buffer[0] == 'f' ){
			binary_fire = true;
			for ( int i = 0; i < col; i++ ){
				for ( int e = 0; e < row; e++ ){
					infile >> binary_number[i][e];
				}
			}
		}
		}while( buffer[0] != ':' && buffer[0] != '\0' );
	}
	infile.close();
}
template<class T> 
void layer<T>:: define( char *filename, int index, layer<T> **PREV ){
	binary_fire = false;
	fstream infile( filename, ios::in );
	char buffer[256];
	for ( int i = 0; i < index; i++ ){
		infile >> buffer;
		infile >> buffer;
		while ( buffer[0] != ':' && buffer != NULL )
			infile >> buffer;
	}
	if ( buffer[0] != ':' ){
		infile >> buffer;}
	if ( buffer[0] == ':' ){
		do{
		infile >> buffer;
		if ( buffer[0] == 's' ){
			Next = NULL;
			Previous = NULL;
			infile >> row >> col;
		}
		else if ( buffer[0] == 'b' ){
			for ( int i = 0; i < col; i++ )
				infile >> weight[i];
		}
		else if ( buffer[0] == 'w' ){
			for ( int i = 0; i < row; i++ ){
				for ( int e = 0; e < col; e++ ){
					infile >> matrix[i][e];}
			}
		}
		else if ( buffer[0] == 'f' ){
			for ( int i = 0; i < col; i++ )
				for ( int e = 0; e < row; e++ ){
					infile >> binary_number[i][e];
				}
		}
		}while( buffer[0] != ':' && buffer[0] != '\0' );
	}
	infile.close();

	if ( (*PREV) ){
		(*PREV)->Next = this;
		Previous = (*PREV);
	}			
}
template<class T> 
void layer<T>:: set_defaults( ){
	Previous = NULL;
	Next = NULL;
	binary_fire = false;
	length = 0;
	network_recurrent = false;
	annealing_on = false;
};
template<class T> 
void layer<T>:: FeedForward( VECTOR in, VECTOR &final ){			
	for ( int e = 0; e < col; e++ ){
		VECTOR vector;
		CreateVector( vector, e );

		VECTOR fire;
		int counter = row;
		if ( binary_fire ){
			counter = 0;
			for ( int r = 0; r < row; r++ )
				if ( binary_number[e][r] )
					fire[counter++] = in[r];
		}
		else{ CopyVector( fire, in, row ); }
		
		result[e] = function( fire, vector, weight[e], counter, ( !(Next) ? true : false ) );
	}

	if ( !(Next) ){ CopyVector( final, result, col ); }
	else{ Next->FeedForward( result, final ); }
}
template<class T> 	
void layer<T>:: BackPropagate( VECTOR input, VECTOR target, T learning_rate, int length ){
	VECTOR NewTarget;
	ClearVector( NewTarget, row );
	if ( !(Previous) ){
		UpdateLayer( target, NewTarget, length, learning_rate, input, result, ( Next ? 0 : 1 ) ); }
	else{
		UpdateLayer( target, NewTarget, length, learning_rate, Previous->result, result, ( !(Next) ? 1 : 0 ) ); }
	
	if ( Previous ){ Previous->BackPropagate( input, NewTarget, learning_rate, length ); }
}
template<class T> 			
void layer<T>:: CreateVector( VECTOR &vector, int column ){
	for ( int j = 0; j < row; j++ ){ vector[j] = matrix[j][column]; }  }

template<class T> 
void layer<T>:: Seti( T value, ... ){
	va_list argument_ptr; matrix[0][0] = value;
	va_start(argument_ptr, value);
	for ( int i = 0; i < row; i++ ){
		//the insert if statement determines whether that value has already been placed, since the
		//first value is read outside the loop
		for ( int e = ( i == 0 ? 1 : 0 ); e < col; e++ ){
			matrix[i][e] = (T)va_arg(argument_ptr, int);
		}
	}
	va_end(argument_ptr);
}

template<class T> 
void layer<T>:: Setf( T value, ... ){
	va_list argument_ptr; matrix[0][0] = value;
	va_start(argument_ptr, value);
	for ( int i = 0; i < row; i++ ){
		//the insert if statement determines whether that value has already been placed, since the
		//first value is read outside the loop
		for ( int e = ( i == 0 ? 1 : 0 ); e < col; e++ ){
			matrix[i][e] = (T)va_arg(argument_ptr, double);
		}
	}
	va_end(argument_ptr);
}
template<class T> void layer<T>:: SetBinary( int value, ... ){
	binary_fire = true;
	va_list argument_ptr;
	binary_number[0][0] = (T) value;
	va_start(argument_ptr, value);
	for ( int i = 0; i < col; i++ ){
		//the insert if statement determines whether that value has already been placed, since the
		//first value is read outside the loop
		for ( int e = ( i == 0 ? 1 : 0 ); e < row; e++ ){
			binary_number[i][e] = (T)va_arg(argument_ptr, int);
		}
	}
	va_end(argument_ptr);
}
			
template<class T> void layer<T>:: SetColumn( int index, VECTOR to_load ){
	for ( int i = 0; i < row; i++ )
		matrix[i][index] = to_load[i];  }
			
template<class T> void layer<T>:: Print(){
	cout << "\n[\t";
	int i;
	for ( i = 0; i < col; i++ )
		cout << "w:" << weight[i] << "\t";
	cout << "]";
	for ( i = 0; i < row; i++ ){
		for ( int e = 0; e < col; e++ ){
			 if ( e == 0 )
				 cout << "\n[\t";
				 cout << setprecision(2) << matrix[i][e] << "\t";
			 if ( e == col-1 )
				 cout << "]";
		}
	}	
}
			
template<class T> void layer<T>:: SetConstant( T n ){
	for ( int i = 0; i < row; i++ )
		for ( int e = 0; e < col; e++ )
			matrix[i][e] = n; }
			
template<class T> void layer<T>:: annealing( VECTOR input, int len, VECTOR output, int length ){
	annealing_length = len;
	int one = 0, two = 0;
	for ( int i = 0; i < length; i++ ){
		one += (int) output[i];
		two += (int) annealing_result[i];}
	annealing_energy = (T) (float)(two-one);
	annealing_probability = (T)exp(-1*annealing_energy/annealing_temperature);	
	if ( annealing_energy < 0 || ((rand() % 2)+1)/rand() < annealing_probability ){
		CopyVector( annealing_input, input, len );
		int flip = rand() % len;
		annealing_input[flip] = !(annealing_input[flip]);		
		annealing_update++;
	}
	if ( annealing_update >= annealing_M ){
		annealing_update = 0;
		annealing_temperature *= annealing_alpha;
	}
}

template<class T> void layer<T>:: set_annealing( VECTOR initial, int len, T temperature, T alpha, int M ){
	annealing_on = true;
	CopyVector( annealing_input, initial, len );
	annealing_temperature = temperature;
	annealing_alpha = alpha;
	annealing_M = M;
}

template<class T> void layer<T>:: write( ostream &output ){
	output << '\n' << row << " " << col << '\n';
	int i;
	for ( i = 0; i < col; i++ )
		output << setw(8) << weight[i];
	for ( i = 0; i < row; i++ ){
		for ( int e = 0; e < col; e++ ){
			 if ( e == 0 )
				 output << "\n";
			 output << setw(8) << setprecision(2) << matrix[i][e];
		}
	}
}

template<class T> void layer<T>:: read( istream &input ){
	input >> row >> col;
	set_defaults();
	define( row, col );
	int i;
	for ( i = 0; i < col; i++ )
		input >> weight[i];
	for ( i = 0; i < row; i++ ){
		for ( int e = 0; e < col; e++ ){
			input >> matrix[i][e];}
	}
}

template<class T> void layer<T>:: define_recurrent(){
	ClearVector( NULL_VECTOR, NN_UTIL_SIZE-1, 0 );
	network_recurrent = true;
	length = 0;
}
template<class T> void layer<T>:: add( layer<T> **ADD ){ layers[length] = (*ADD); length++; }
	
template<class T> void layer<T>::FeedForward( MATRIX input, MATRIX &final, int inputs ){ FeedForward_recurrent( input, final, inputs ); }

template<class T> int layer<T>::THETA( int x ){ return ( x >= 1 ? 1 : 0 ); }

template<class T> int layer<T>::F( int x, int e, int l ){ return x-(abs(x-e)*THETA(x-e))-(abs(x-l)*THETA(x-l)); }

template<class T> void layer<T>:: FeedForward_recurrent( MATRIX input, MATRIX &final, int inputs ){
	int interations = length+inputs-1;
	int e = ( inputs <= length ? inputs : length );
	int l = ( length >= inputs ? length : inputs );

	for ( int t = 1; t <= interations; t++ ){
		int w = ( t-inputs > 0 ? t-inputs : 0 );
		for ( int a = w; a <= w+F(t, e, l)-1; a++ ){
			VECTOR shoot;
	
			Merge( shoot,
			       ( t-a == 0 ? NULL_VECTOR : history[a][t-a-1] ), layers[a]->col,
			       ( a == 0 ? input[t-1] : history[a-1][t-a] ), layers[a]->row-layers[a]->col );
			layers[a]->FeedForward( shoot, history[a][t-a] );
			if ( a == length-1 ){ CopyVector( final[t-length], history[a][t-a], layers[a]->col ); }
		}
	}
}

template<class T> void layer<T>:: BackPropagate_recurrent( MATRIX input, MATRIX target, T learning_rate, int inputs ){
	int interations = length+inputs-1;
	int e = ( inputs <= length ? inputs : length );
	int l = ( length >= inputs ? length : inputs );

	for ( int t = interations; t >= 1; t-- ){
		int w = ( t-inputs > 0 ? t-inputs : 0 );
		for ( int a = w+F(t, e, l)-1; a >= w; a-- ){
			VECTOR shoot;
					
			Merge( shoot,
			       ( t-a == 0 ? NULL_VECTOR : history[a][t-a-1] ), layers[a]->col,
			       ( a == 0 ? input[t-1] : history[a-1][t-a] ), layers[a]->row-layers[a]->col );
						
			layers[a]->UpdateLayer( ( a == length-1 ? target[t-length] : history[a+1][t-a] ),
						history[a][t-a], layers[a]->col, learning_rate,
					        shoot, history[a][t-a], ( a == length-1 ? true : false ) );
		}
	}
}
//			void layer<T>:: Train( int interations, float learning_rate );
template<class T> void layer<T>:: Merge( VECTOR &destination, VECTOR first, int len1, VECTOR second, int len2 ){
	CopyVector( destination, first, len1 );
	for ( int i = 0; i < len2; i++ ){ destination[i+len1] = second[i]; } }
template<class T> void layer<T>:: SetConstant_recurrent( T n ){
	for ( int i = 0; i < length; i++ )
		layers[i]->SetConstant( n ); }
template<class T> void layer<T>:: SetConstant_recurrent( int index, T n ){
	layers[index]->SetConstant( n ); }
			
/*User defined feed forward sweep function*/
template<class T> T layer<T>::function( VECTOR in, VECTOR weight, T bias, int length, bool output){ return 0; };
/*User defined functino to update a layer in a back propagation sweep*/
template<class T> void layer<T>:: UpdateLayer( VECTOR target, VECTOR &new_target, int length,
		T learning_rate, VECTOR input, VECTOR result, bool output ){};

template nn_utility::layer<double>;
template nn_utility::layer<float>;
template nn_utility::layer<int>;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -