Ann.cpp
#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <unistd.h>
#include <stdio.h>
#include <sstream>
#include <unistd.h>
#include <pthread.h>
using std :: cout;
using std :: endl;
using std :: cin;
using std :: string;
using std :: stringstream;
//int const static LIMIT = 19;
template <typename T>
class Ann
{
public:
Ann(int input , int argc , int * detailed , int output);
virtual ~Ann();
void load(string filename);
void save();
void print_weight();
void train(T ** set , int number , int times , double rate , double lambda , double limit , double probality , double decay , int addition , int extract);
bool adjust_output(double * target);
bool adjust_hidden();
void calculator(bool flag = false);
int get_argc_input();
int get_argc_output();
void set_input(double * argc);
bool get_result(int goal);
void write_file(string filename);
private:
double * input , ** level , * output , *** weight , ***best_weight, * target , * err , ** offset , ** best_offset;
bool ** dropout;
T ** set , ** temp;
double rate , lambda , limit , probality , backup;
int argc_input , argc_level , argc_output , * info;
double ** list , ** medium , ** origin;
double *** record;
int point , max , temp_point;
stringstream stream;
void init(int input , int argc , int * detailed , int end);
void init_level();
double sigmod(double value);
void free(double * array);
void free(int argc , double ** matrix);
void free(int argc , int * argv , double *** matrix);
void free(int * array);
void copy(int * info , int * detailed , int argc);
double sum(int level , int input , int output);
double get_random();
void print_output();
void print_input();
void print_level();
double get_err(int i);
void pre_process(T ** set , int value);
double offset_sum(int target);
double get_regular();
double softmax(T ** set , int const point , int const max , int const argc_output , int const value , bool flag = false);
void compute_gradient(int point , int max);
void copy_level(int i);
void copy_input(int i);
void copy_list(int i);
double gaussrand();
void test();
bool check(T ** set , T ** check, int train , int confirm);
int best_train , best_confirm;
string itos(int data);
void deal_for_svm(T ** set , int value);
void reset();
void segmentation(T ** set , int * count , int value , double rate , int addition , int extract);
void generate_svm(T ** set , string filename , int number , int size);
};
template<typename T>
void Ann<T> :: generate_svm(T ** set , string filename , int number , int size)
{
std::ofstream out;
out.open(filename.c_str());
if(out.is_open())
{
for(int i = 0 ; i < number ; i++)
{
out << set[i][size] << " ";
for(int j = 0 ; j < size ; j++)
{
out << j+1 << ":" << set[i][j] << " " ;
}
out << "\n";
}
}
cout << "generate over . " << endl;
}
template <typename T>
void Ann<T> :: reset()
{
for (int i = 0; i < argc_level; ++i)
{
for (int j = 0; j < info[i]; ++j)
{
dropout[i][j] = get_random() > probality ? true : false;
}
}
}
template <typename T>
string Ann<T> :: itos(int data)
{
stream << data;
string result = stream.str();
stream.clear();
stream.str("");
return result;
}
template <typename T>
bool Ann<T> :: check(T ** set , T ** check , int train , int size)
{
int err_train = 0 , err_confirm = 0;
bool flag = false;
for (int i = 0; i < train; ++i)
{
set_input(set[i]);
calculator(true);
if(!get_result(set[i][argc_input]))
{
err_train ++;
}
if(flag)
{
cout << "check for input : " << set[i][argc_input] << endl;
int max = 0;
for (int j = 1; j < argc_output; ++j)
{
if(output[j] > output[max]) max = j;
}
cout << "check for calculator : " << max << endl << endl << endl;
}
}
if(flag) cout << "--------------------" << endl;
for (int i = 0; i < size; ++i)
{
set_input(check[i]);
calculator(true);
if(!get_result(check[i][argc_input]))
{
err_confirm ++;
}
if(flag)
{
cout << "check for input : " << check[i][argc_input] << endl;
int max = 0;
for (int j = 1; j < argc_output; ++j)
{
if(output[j] > output[max]) max = j;
}
cout << "check for calculator : " << max << endl << endl << endl;
}
}
cout << "Error in train for : " << err_train << endl;
cout << "Number for : " << train << endl;
cout << "Rate for : " << 1 - (double)err_train / train << endl;
cout << "Error in check for : " << err_confirm << endl;
cout << "Number for : " << size << endl;
cout << "Rate for : " << 1 - (double)err_confirm / size << endl;
if(err_train * 0.2 + err_confirm * 0.8 < best_train * 0.2 + best_confirm * 0.8)
{
best_train = err_train;
best_confirm = err_confirm;
save();
return true;
}
return false;
}
template <typename T>
double Ann<T> :: gaussrand()
{
{
static double V1, V2, S;
static int phase = 0;
double X;
if ( phase == 0 )
{
do
{
double U1 = (double)rand() / RAND_MAX;
double U2 = (double)rand() / RAND_MAX;
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
}
while(S >= 1 || S == 0);
X = V1 * sqrt(-2 * log(S) / S);
}
else
{
X = V2 * sqrt(-2 * log(S) / S);
}
phase = 1 - phase;
return X;
}
}
template <typename T>
void Ann<T> :: test()
{
for (int i = 0; i < point; ++i)
{
for (int j = 0; j < argc_input; ++j)
{
if(origin[i][j] != origin[i][j])
{
cout << "origin failed ." << endl;
exit(1);
}
}
for (int j = 0; j < argc_output; ++j)
{
if(list[i][j] != list[i][j])
{
cout << "list failed ." << endl;
exit(1);
}
}
for (int j = 0; j < argc_level; ++j)
{
for (int k = 0; k < info[j]; ++k)
{
if(record[i][j][k] != record[i][j][k])
{
cout << "record failed " << endl;
exit(1);
}
}
}
}
}
template <typename T>
void Ann<T> :: copy_level(int position)
{
for (int i = 0; i < argc_level; ++i)
{
for (int j = 0 ; j < info[i]; ++j)
{
record[position][i][j] = level[i][j];
}
}
}
template <typename T>
void Ann<T> :: copy_input(int position)
{
for (int i = 0; i < argc_input; ++i)
{
origin[position][i] = input[i];
}
}
template <typename T>
void Ann<T> :: copy_list(int position)
{
for (int i = 0; i < argc_output; ++i)
{
list[position][i] = output[i];
}
}
template <typename T>
void Ann<T> :: compute_gradient(int point , int max)
{
double list_back[point][max];
for (int i = argc_level - 1 ; i >= 0; --i)
{
if(i == argc_level - 1)
{
{
int m = info[i] , n = point , p = argc_output;
for (int j = 0; j < m; ++j)
{
for (int k = 0; k < p; ++k)
{
double sum = 0;
for (int h = 0; h < n; ++h)
{
sum += record[h][i][j] * list[h][k];
}
medium[j][k] = sum;
}
}
}
for (int j = 0; j < argc_output; ++j)
{
offset[i+1][j] += -rate * offset_sum(j);
}
{
int m = point , n = argc_output , p = info[i];
for (int j = 0; j < m; ++j)
{
for (int k = 0; k < p; ++k)
{
double sum = 0;
for (int h = 0; h < n; ++h)
{
sum += list[j][h] * weight[i+1][k][h];
}
list_back[j][k] = record[j][i][k] <= 0 ? 0 : sum;
}
}
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < p; ++j)
{
list[i][j] = list_back[i][j];
}
}
}
for (int j = 0; j < info[argc_level-1]; ++j)
{
if(dropout[i][j])
{
for (int k = 0; k < argc_outp