Skip to content

Instantly share code, notes, and snippets.

@ollewelin
Last active July 27, 2017 21:09
Show Gist options
  • Save ollewelin/be13f1c70a3f990803e6ef0ea94b1a22 to your computer and use it in GitHub Desktop.
Save ollewelin/be13f1c70a3f990803e6ef0ea94b1a22 to your computer and use it in GitHub Desktop.
Convolution Neural Network CNN2. 3-layer Autoencoder. Convolution and Max Pooling. Fully connected not attached yet
#include <stdio.h>
#include <stdlib.h>// exit(0);
float abs_value(float signed_value)
{
float abs_v;
abs_v = signed_value;
if(abs_v < 0)
{
abs_v = -abs_v;
}
return abs_v;
}
int get_CIFAR_file_size(void)
{
int file_size=0;
FILE *fp2;
fp2 = fopen("data_batch_1.bin", "r");
if (fp2 == NULL)
{
puts("Error while opening file data_batch_1.bin");
exit(0);
}
fseek(fp2, 0L, SEEK_END);
file_size = ftell(fp2);
printf("file_size %d\n", file_size);
rewind(fp2);
fclose(fp2);
return file_size;
}
#ifndef C_FUNC_H_INCLUDED
#define C_FUNC_H_INCLUDED
#include <math.h>
#include "c_func.c"
float abs_value(float signed_value);
int get_CIFAR_file_size(void);
#endif // C_FUNC_H_INCLUDED
#ifndef CPP_FUNC_HPP_INCLUDED
#define CPP_FUNC_HPP_INCLUDED
#include <opencv2/highgui/highgui.hpp> // OpenCV window I/O
#include <opencv2/imgproc/imgproc.hpp> // Gaussian Blur
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
//#include "cpp_func.cpp"
using namespace cv;
Mat gray_local_normalizing(Mat gray)
{
//#define BLUR_FLT_NUMERATOR 2
//#define BLUR_FLT_DENOMINATOR 20
#define BLUR_FLT_NUMERATOR 2
#define BLUR_FLT_DENOMINATOR 20
Mat float_gray, blur, num, den, store_gray;
store_gray = gray;//Initialize size
// convert to floating-point image
gray.convertTo(float_gray, CV_32F, 1.0/255.0);
// numerator = img - gauss_blur(img)
cv::GaussianBlur(float_gray, blur, Size(0,0), BLUR_FLT_NUMERATOR, BLUR_FLT_NUMERATOR);
num = float_gray - blur;
// denominator = sqrt(gauss_blur(img^2))
cv::GaussianBlur(num.mul(num), blur, Size(0,0), BLUR_FLT_DENOMINATOR, BLUR_FLT_DENOMINATOR);
cv::pow(blur, 0.5, den);
// output = numerator / denominator
gray = num / den;
// normalize output into [0,1]
cv::normalize(gray, gray, 0.0, 1.0, NORM_MINMAX, -1);
// Display
//namedWindow("demo", CV_WINDOW_AUTOSIZE );
gray.convertTo(store_gray, CV_8U, 255);
return store_gray;
//imshow("demo", gray);
}
Mat CV_32FC3_local_normalizing(Mat input_colour)
{
//#define BLUR_FLT_NUMERATOR 2
//#define BLUR_FLT_DENOMINATOR 20
#define BLUR_FLT_NUMERATOR 2
#define BLUR_FLT_DENOMINATOR 20
Mat float_gray, blur, num, den, colour;
colour = input_colour.clone();
// convert to floating-point image
// numerator = img - gauss_blur(img)
cv::GaussianBlur(colour, blur, Size(0,0), BLUR_FLT_NUMERATOR, BLUR_FLT_NUMERATOR);
num = colour - blur;
// denominator = sqrt(gauss_blur(img^2))
cv::GaussianBlur(num.mul(num), blur, Size(0,0), BLUR_FLT_DENOMINATOR, BLUR_FLT_DENOMINATOR);
cv::pow(blur, 0.5, den);
// output = numerator / denominator
colour = num / den;
// normalize output into [0,1]
cv::normalize(colour, colour, 0.0, 1.0, NORM_MINMAX, -1);
// Display
//namedWindow("demo", CV_WINDOW_AUTOSIZE );
return colour;
//imshow("demo", gray);
}
/*
Mat testCV32FC3;
testCV32FC3.create(10,10,CV_32FC3);
float *zero_ptr_testCV32FC3 = testCV32FC3.ptr<float>(0);
float *index_ptr_testCV32FC3 = testCV32FC3.ptr<float>(0);
for(int i=0;i<100*3;i++)
{
if(i%3 == 0)
{
*index_ptr_testCV32FC3 = 0.0f;///BLUE
}
if(i%3 == 1)
{
*index_ptr_testCV32FC3 = 1.0f;///GREEN
}
if(i%3 == 2)
{
*index_ptr_testCV32FC3 = 0.0f;///RED
}
index_ptr_testCV32FC3++;
}
imshow("testCV32FC3", testCV32FC3);
cout << "testCV32FC3 = " << endl << " " << testCV32FC3 << endl << endl;
printf("testCV32FC3.cols = %d\n", testCV32FC3.cols);
*/
/*
void attach_weight_2_RGBmat(float* ptr_M_matrix, int i, Mat src, int sqr_of_H_nod_plus1, int Hidden_nodes, int Height, int Width)
{
char *start_corner_offset = src.ptr<char>(0);
int start_offset=0;
char *src_zero_ptr = src.ptr<char>(0);
char *src_ptr = src.ptr<char>(0);
for(int j=0; j<Hidden_nodes ; j++)
{
start_offset = (j/sqr_of_H_nod_plus1)*Height*src.cols + (j%sqr_of_H_nod_plus1)*Width;
start_corner_offset = start_offset + src_zero_ptr;
src_ptr = start_corner_offset + (i/Width)*src.cols + (i%Width);
*src_ptr = *ptr_M_matrix;
ptr_M_matrix++;
}
}
*/
///Måste byta frpn GRAY2RGB
//attach_weight_2_mat(ptr_M_matrix, i, visual_all_feature, sqr_of_H_nod_plus1, Hidden_nodes, Height, Width);
void attach_weight_2_mat(float* ptr_M_matrix, int i, Mat src, int sqr_of_H_nod_plus1, int conv_depth, int Height, int Width)
{
float *start_corner_offset = src.ptr<float>(0);
int start_offset=0;
float *src_zero_ptr = src.ptr<float>(0);
float *src_ptr = src.ptr<float>(0);
for(int j=0; j<conv_depth ; j++)
{
start_offset = (j/sqr_of_H_nod_plus1)*Height*src.cols*src.channels() + (j%sqr_of_H_nod_plus1)*(Width*src.channels());
start_corner_offset = start_offset + src_zero_ptr;
src_ptr = start_corner_offset + (i/(Width*src.channels()))*src.cols*src.channels() + (i%(Width*src.channels()));
*src_ptr = *ptr_M_matrix;
ptr_M_matrix++;
}
}
void attach_in2hid_w_2_mat(float* ptr_bias_weights, Mat src, int sqr_of_H_nod_plus1, int Hidden_nodes, int Height, int Width)
{
float *start_corner_offset = src.ptr<float>(0);
int start_offset=0;
float *src_zero_ptr = src.ptr<float>(0);
float *src_ptr = src.ptr<float>(0);
int j=Hidden_nodes;///Hidden_nodes+0 is the patch position where in2hid weight should be visualized
start_offset = (j/sqr_of_H_nod_plus1)*Height*src.cols + (j%sqr_of_H_nod_plus1)*Width;
start_corner_offset = start_offset + src_zero_ptr;
for(int i=0; i<Hidden_nodes; i++)
{
if(i>(Height*Width-1))
{
break;///The hidden nodes may be larger then one visualize patches then break so it not point out in neverland
}
src_ptr = start_corner_offset + (i/Width)*src.cols + (i%Width);
*src_ptr = *ptr_bias_weights;
ptr_bias_weights++;
}
}
void attach_hid2out_w_2_mat(float* ptr_bias_weights, Mat src, int sqr_of_H_nod_plus1, int Hidden_nodes, int Height, int Width)
{
float *start_corner_offset = src.ptr<float>(0);
int start_offset=0;
float *src_zero_ptr = src.ptr<float>(0);
float *src_ptr = src.ptr<float>(0);
int j=Hidden_nodes+1;///Hidden_nodes+1 is the patch position where hid2out weight should be visualized
start_offset = (j/sqr_of_H_nod_plus1)*Height*src.cols + (j%sqr_of_H_nod_plus1)*Width;
start_corner_offset = start_offset + src_zero_ptr;
for(int i=0; i<(Height*Width); i++)
{
src_ptr = start_corner_offset + (i/Width)*src.cols + (i%Width);
*src_ptr = *ptr_bias_weights;
ptr_bias_weights++;
}
}
class Lx_attach_weight2mat
{
/// L2_sqr_of_H_nod_plus1 = sqrt(L2_conv_depth);
/// L2_sqr_of_IN_depth = sqrt(FL2_depth);///FL2_depth = L1_conv_depth
/// L2_sqr_of_H_nod_plus1 += 1;///+1 becasue sqrt() result will be round up downwards to an integer and that may result in to small square then
/// L2_sqr_of_IN_depth += 1;///+1 becasue sqrt() result will be round up downwards to an integer and that may result in to small square then
/// L2_visual_all_feature.create(FL2_srt_size * L2_sqr_of_IN_depth * L2_sqr_of_H_nod_plus1, FL2_srt_size * L2_sqr_of_IN_depth * L2_sqr_of_H_nod_plus1,CV_32FC1);///This is gray because the depth is larger then "BGR"
/// L2_attach_weight_2_mat(L2_ptr_M_matrix, i, j, L2_visual_all_feature, L2_sqr_of_H_nod_plus1, L2_conv_depth, FL2_srt_size, FL2_srt_size);///
public:
Lx_attach_weight2mat();
~Lx_attach_weight2mat();
void Xattach_weight2mat(void);
float* Lx_ptr_M_matrix;///Must point to the Lx_weight_matrix_M[i*j][0] address
int FLx_i_location_area;///Index
int FLx_j_location_depth;///Index
Mat Lx_src;///Visual image pointer
int Lx_Hidden_nodes;///Lx_conv_depth. put in a constant
int FL_Height;///Feature height. put in a constant
int FL_Width;///Feature width. put in a constant
/// int FL_depth;///Feature depth. put in a constant
private:
protected:
};
Lx_attach_weight2mat::Lx_attach_weight2mat()
{
printf("Lx_attach_weight2mat contructor\n");
}
void Lx_attach_weight2mat::Xattach_weight2mat(void)
{
float* zero_ptr = Lx_src.ptr<float>(0);
float* index_ptr = Lx_src.ptr<float>(0);
for(int k=0;k<Lx_Hidden_nodes;k++)///Go throue the output depth of L2 features. One line of small squares patches with size FL_Height*FL_Width and nr of boxes length = FL_depth will belong to one output node
{
///Fill only in one pixel per line (k nr of boxes line)
index_ptr = zero_ptr + k*Lx_src.cols*FL_Height + Lx_src.cols* (FLx_i_location_area/FL_Width) + FL_Width*FLx_j_location_depth + FLx_i_location_area%FL_Width;
*index_ptr = *Lx_ptr_M_matrix;
Lx_ptr_M_matrix++;///Increas output depth Lx_weight_matrix_M[i*j][k]
}
}
Lx_attach_weight2mat::~Lx_attach_weight2mat()
{
printf("Lx_attach_weight2mat destructor\n");
}
#endif // CPP_FUNC_HPP_INCLUDED
#include "cpp_func2.hpp"
#include <stdio.h>
#include <cstdlib>/// rand()
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int cpp_func2::kbhit(void)
{
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}
return 0;
}
cpp_func2::cpp_func2()
{
//ctor
}
void cpp_func2::init(void)
{
noise_pos = new int [nr_of_positions];
L2_noise_pos = new int [L2_nr_of_positions];
}
void cpp_func2::rand_input_data_pos(void)
{
nr_of_noise_rand_ittr=0;
noise_p_counter=0;
noise_ratio=0.0f;
rand_pix_pos=0;
for(int n=0; n<nr_of_positions; n++)
{
noise_pos[n] = 0;
}
while(noise_ratio < (noise_percent*0.01f))
{
rand_pix_pos = (int) (rand() % nr_of_positions);
if(noise_pos[rand_pix_pos] == 0)
{
noise_p_counter++;
}
noise_pos[rand_pix_pos] = 1;
noise_ratio = ((float)noise_p_counter) / ((float)nr_of_positions);
nr_of_noise_rand_ittr++;
if(nr_of_noise_rand_ittr > 2*nr_of_positions)
{
printf("give up fill random up noise this turn\n");
printf("noise_ratio %f\n", noise_ratio);
break;
}
}
}
void cpp_func2::L2_rand_input_data_pos(void)
{
nr_of_noise_rand_ittr=0;
noise_p_counter=0;
noise_ratio=0.0f;
rand_pix_pos=0;
for(int n=0; n<L2_nr_of_positions; n++)
{
L2_noise_pos[n] = 0;
}
while(noise_ratio < (L2_noise_percent*0.01f))
{
rand_pix_pos = (int) (rand() % L2_nr_of_positions);
if(L2_noise_pos[rand_pix_pos] == 0)
{
noise_p_counter++;
}
L2_noise_pos[rand_pix_pos] = 1;
noise_ratio = ((float)noise_p_counter) / ((float)L2_nr_of_positions);
nr_of_noise_rand_ittr++;
if(nr_of_noise_rand_ittr > 2*L2_nr_of_positions)
{
printf("give up fill random up L2 noise this turn\n");
printf("L2 noise_ratio %f\n", noise_ratio);
break;
}
}
}
void cpp_func2::L3_rand_input_data_pos(void)
{
nr_of_noise_rand_ittr=0;
noise_p_counter=0;
noise_ratio=0.0f;
rand_pix_pos=0;
for(int n=0; n<L3_nr_of_positions; n++)
{
L3_noise_pos[n] = 0;
}
while(noise_ratio < (L3_noise_percent*0.01f))
{
rand_pix_pos = (int) (rand() % L3_nr_of_positions);
if(L3_noise_pos[rand_pix_pos] == 0)
{
noise_p_counter++;
}
L3_noise_pos[rand_pix_pos] = 1;
noise_ratio = ((float)noise_p_counter) / ((float)L3_nr_of_positions);
nr_of_noise_rand_ittr++;
if(nr_of_noise_rand_ittr > 2*L3_nr_of_positions)
{
printf("give up fill random up L3 noise this turn\n");
printf("L3 noise_ratio %f\n", noise_ratio);
break;
}
}
}
void cpp_func2::print_help(void)
{
printf("Hit <?> or <Space> show HELP menu\n");
printf("Hit <Space> TOGGLE start training or stop and delay for show\n");
printf("Hit <A> to save all weights to weight_matrix_M.dat file\n");
printf("Hit <B> TOGGLE Autoencoder L1 ON/OFF\n");
printf("Hit <C> TOGGLE Autoencoder L2 ON/OFF\n");
printf("Hit <D> TOGGLE Convolution L1 ON/OFF\n");
printf("Hit <E> TOGGLE Convolution L2 ON/OFF\n");
printf("Hit <F> TOGGLE Autoencoder L3 ON/OFF\n");
printf("Hit <G> TOGGLE Convolution L3 ON/OFF\n");
printf("Hit <H> \n");
printf("Hit <I> \n");
printf("Hit <J> \n");
printf("Hit <K> \n");
printf("Hit <L> \n");
printf("Hit <M> \n");
printf("Hit <N> \n");
}
void cpp_func2::keyboard_event(void)
{
char keyboard;
if(kbhit())
{
keyboard = getchar();
if(keyboard== ' ')
{
print_help();
if(started == 1)
{
started = 0;
printf("Stop training\n");
printf("Training stop now only feed forward\n");
}
else
{
started = 1;
printf("Start training\n");
}
}
if(keyboard== '?')
{
print_help();
started = 0;
printf("Stop training\n");
printf("Training stop now only feed forward\n");
}
if(keyboard== 'A' || keyboard== 'a')
{
save_L1_weights=1;
}
if(keyboard== 'B' || keyboard== 'b')
{
if(L1_autoencoder_ON==0)
{
L1_autoencoder_ON=1;
}
else
{
L1_autoencoder_ON=0;
}
printf("L1_autoencoder_ON=%d\n", L1_autoencoder_ON);
}
if(keyboard== 'C' || keyboard== 'c')
{
if(L2_autoencoder_ON==0)
{
L2_autoencoder_ON=1;
}
else
{
L2_autoencoder_ON=0;
}
printf("L2_autoencoder_ON=%d\n", L2_autoencoder_ON);
}
if(keyboard== 'D' || keyboard== 'd')
{
if(L1_convolution_ON==0)
{
L1_convolution_ON=1;
}
else
{
L1_convolution_ON=0;
}
printf("L1_convolution_ON=%d\n", L1_convolution_ON);
}
if(keyboard== 'E' || keyboard== 'e')
{
if(L2_convolution_ON==0)
{
L2_convolution_ON=1;
}
else
{
L2_convolution_ON=0;
}
printf("L2_convolution_ON=%d\n", L2_convolution_ON);
}
if(keyboard== 'F' || keyboard== 'f')
{
if(L3_autoencoder_ON==0)
{
L3_autoencoder_ON=1;
}
else
{
L3_autoencoder_ON=0;
}
printf("L3_autoencoder_ON=%d\n", L3_autoencoder_ON);
}
if(keyboard== 'G' || keyboard== 'g')
{
if(L3_convolution_ON==0)
{
L3_convolution_ON=1;
}
else
{
L3_convolution_ON=0;
}
printf("L3_convolution_ON=%d\n", L3_convolution_ON);
}
}
}
cpp_func2::~cpp_func2()
{
//dtor
if(noise_pos)
delete[] noise_pos;
}
#ifndef CPP_FUNC2_HPP
#define CPP_FUNC2_HPP
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
class cpp_func2
{
public:
cpp_func2();
void init(void);///Setting up a new 1D array noise_pos[nr_of_positions]
void rand_input_data_pos(void);
void L2_rand_input_data_pos(void);
void L3_rand_input_data_pos(void);
float noise_percent;
float L2_noise_percent;
float L3_noise_percent;
int nr_of_positions;
int L2_nr_of_positions;
int L3_nr_of_positions;
int *noise_pos;///Pointer to make a new 1D array noise_pos[nr_of_positions]
int *L2_noise_pos;///Pointer to make a new 1D array noise_pos[nr_of_positions]
int *L3_noise_pos;///Pointer to make a new 1D array noise_pos[nr_of_positions]
void print_help(void);
void keyboard_event(void);
int kbhit(void);
int started;
int save_L1_weights=0;
int L1_autoencoder_ON=0;
int L2_autoencoder_ON=0;
int L3_autoencoder_ON=0;
int L1_convolution_ON=0;
int L2_convolution_ON=0;
int L3_convolution_ON=0;
virtual ~cpp_func2();
protected:
private:
int nr_of_noise_rand_ittr;
int noise_p_counter;
float noise_ratio;
int rand_pix_pos;
struct termios oldt, newt;
int ch;
int oldf;
};
#endif // CPP_FUNC2_HPP
#include <opencv2/highgui/highgui.hpp> // OpenCV window I/O
#include <opencv2/imgproc/imgproc.hpp> // Gaussian Blur
#include <stdio.h>
#include <raspicam/raspicam_cv.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
#include <cstdlib>
#include <ctime>
#include <math.h> // exp
#include <stdlib.h>// exit(0);
#include <iostream>
using namespace std;
using namespace cv;
#include "c_func.h"
#include "cpp_func.hpp"
#include "cpp_func2.hpp"
///#define USE_BGR_NORMALIZER
#define USE_PATCH_NOISE
FILE *fp1;//Parameter file
float start_weight_noise_range = 0.15f;//+/- Weight startnoise range
float L1_autoencoder_noise_ratio = 25.0f;///25.0f
float L2_autoencoder_noise_ratio = 5.0f;///
float L3_autoencoder_noise_ratio = 5.0f;///
int nr_of_autoenc_ittr_1_image=20;///Nr of autoencoder training of a patch with ranomized location on eact input image
int L2_nr_of_autoenc_ittr_1_image=5;///
int L3_nr_of_autoenc_ittr_1_image=5;///
float noise_amplitude = 1.0f;///1.0f
float noise_offset = 0.0f;///-0.5..+0.5
float Relu_neg_gain = 0.1f;
const float C_LearningRate =0.0002f;///0.0015
const float C_Momentum = 0.9f;///0.0f
float LearningRate = C_LearningRate;///
float Momentum = C_Momentum;///
float L2_LearningRate = 0.0002f;///
float L2_Momentum = 0.9f;///
float L3_LearningRate = 0.0002f;///
float L3_Momentum = 0.1f;///0.9
int show_patch_noise = 0;
///float run_autoencoder_ratio = 1.0f;
char filename[100];
///char filename2[100];
///char filename_dst[100];
int main()
{
FILE *fp2;
/// FILE *fp3;
/// FILE *fp4;
srand (static_cast <unsigned> (time(0)));//Seed the randomizer
float Rando=0.0f;
int autoencoder_mode = 1;///0=No autoencoder training. 1=L1 autoencoder training. 2=L2 autoencoder training.
int stride = 1;
int pooling = 4;///maxpooling from 4->1 node. This value is the pooling area
int pool_sqr = sqrt(pooling);
int nr_of_CIFAR_file_bytes=0;
nr_of_CIFAR_file_bytes = get_CIFAR_file_size();
printf("Byte size of data_batch_1.bin = %d\n", nr_of_CIFAR_file_bytes);
///L1
const int CIFAR_height = 32;
const int CIFAR_width = 32;
const int CIFAR_nr_of_img_p_batch = 10000;
const int CIFAR_RGB_pixels = CIFAR_height*CIFAR_width;
int FL1_srt_size = 5;///Must be a odd nubmber 1.3.5... Feature1 side size 5 = 5x5 feature patch
if((FL1_srt_size%2) == 1)
{
printf("FL1_srt_size =%d\n", FL1_srt_size);
}
else
{
printf("Error FL1_srt_size is a Even number not allowed FL1_srt_size =%d\n", FL1_srt_size);
exit(0);
}
int FL1_depth = 3;///BRG
int FL1_size = FL1_srt_size * FL1_srt_size * FL1_depth;///The size of one Feature FL1
int L1_conv_depth = 75;/// 75. L1_conv_depth is the depth of the L1 Convolution cube. This is also the number of Feature on L2.
int L1_conv_hight = CIFAR_height - FL1_srt_size + 1;///No padding. This is the hight of the L1 Convolution cube.
int L1_conv_width = CIFAR_width - FL1_srt_size + 1;///No padding. This is the width of the L1 Convolution cube.
///L2
int FL2_srt_size = 5;///Must be a odd nubmber 1.3.5... Feature2 side size 5 = 5x5 feature
if((FL2_srt_size%2) == 1)
{
printf("FL2_srt_size =%d\n", FL2_srt_size);
}
else
{
printf("Error FL2_srt_size is a Even number not allowed FL2_srt_size =%d\n", FL2_srt_size);
exit(0);
}
int FL2_depth = L1_conv_depth;///This must always be same value
int FL2_size = FL2_srt_size * FL2_srt_size * FL2_depth;///The size of one Feature FL2
int L2_conv_depth = 100;/// L2_conv_depth is the depth of the L2 Convolution cube. This is also the number of Feature on L3.
int L2_conv_hight = (L1_conv_hight/pool_sqr) - FL2_srt_size + 1;///No padding. This is the hight of the L2 Convolution cube.
int L2_conv_width = (L1_conv_width/pool_sqr) - FL2_srt_size + 1;///No padding. This is the width of the L2 Convolution cube.
///L3
int FL3_srt_size = 3;///Must be a odd nubmber 1.3.5... Feature2 side size 5 = 5x5 feature
if((FL3_srt_size%2) == 1)
{
printf("FL3_srt_size =%d\n", FL3_srt_size);
}
else
{
printf("Error FL3_srt_size is a Even number not allowed FL3_srt_size =%d\n", FL3_srt_size);
exit(0);
}
int FL3_depth = L2_conv_depth;///This must always be same value
int FL3_size = FL3_srt_size * FL3_srt_size * FL3_depth;///The size of one Feature FL3
int L3_conv_depth = 100;/// L3_conv_depth is the depth of the L3 Convolution cube. This is also the number of Feature on L3.
int L3_conv_hight = (L2_conv_hight/pool_sqr) - FL3_srt_size + 1;///No padding. This is the hight of the L3 Convolution cube.
int L3_conv_width = (L2_conv_width/pool_sqr) - FL3_srt_size + 1;///No padding. This is the width of the L3 Convolution cube.
printf("L1_conv_hight %d\n", L1_conv_hight);
printf("L1_conv_width %d\n", L1_conv_width);
printf("L1_conv_hight/pool_sqr %d\n", L1_conv_hight/pool_sqr);
printf("L1_conv_width/pool_sqr %d\n", L1_conv_width/pool_sqr);
printf("L2_conv_hight %d\n", L2_conv_hight);
printf("L2_conv_width %d\n", L2_conv_width);
printf("L2_conv_hight/pool_sqr %d\n", L2_conv_hight/pool_sqr);
printf("L2_conv_width/pool_sqr %d\n", L2_conv_width/pool_sqr);
printf("L3_conv_hight %d\n", L3_conv_hight);
printf("L3_conv_width %d\n", L3_conv_width);
printf("L3_conv_hight/pool_sqr %d\n", L3_conv_hight/pool_sqr);
printf("L3_conv_width/pool_sqr %d\n", L3_conv_width/pool_sqr);
int L3toL2_feature_revers_size = FL3_srt_size * pool_sqr + 1 + FL2_srt_size/pool_sqr;
int L3toL2toL1_feature_revers_size = L3toL2_feature_revers_size * pool_sqr + 1 + FL1_srt_size/pool_sqr;
printf("L3toL2_feature_revers_size = %d\n", L3toL2_feature_revers_size);
printf("L3toL2toL1_feature_revers_size = %d\n", L3toL2toL1_feature_revers_size);
int L2toL1_feature_reverse_size = FL2_srt_size * pool_sqr + 1 + FL1_srt_size/pool_sqr;
printf("L2toL1_feature_reverse_size = %d\n", L2toL1_feature_reverse_size);
printf("(FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1) =%d\n", (FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1));
Mat RGB_image, colour, local_norm_colour, noised_input, norm_32FC3_img, L1_patch_img, L1_noise_img, L1_autoenc_reconstructed, L1_autoenc_delta;
Mat norm_B_32FC1img, norm_G_32FC1img, norm_R_32FC1img;
RGB_image.create(CIFAR_height, CIFAR_width, CV_8UC3);
norm_32FC3_img.create(CIFAR_height, CIFAR_width, CV_32FC3);
norm_B_32FC1img.create(CIFAR_height, CIFAR_width, CV_32FC1);
norm_G_32FC1img.create(CIFAR_height, CIFAR_width, CV_32FC1);
norm_R_32FC1img.create(CIFAR_height, CIFAR_width, CV_32FC1);
///L1 autoencoder input, noised, recontruction and delta out
L1_patch_img.create (FL1_srt_size, FL1_srt_size, CV_32FC3);/// This have same size as the Feature L1 size
L1_noise_img.create (FL1_srt_size, FL1_srt_size, CV_32FC3);/// This have same size as the Feature L1 size
L1_autoenc_reconstructed.create (FL1_srt_size, FL1_srt_size, CV_32FC3);
L1_autoenc_delta.create (FL1_srt_size, FL1_srt_size, CV_32FC3);
float *zero_ptr_L1_patch_img = L1_patch_img.ptr<float>(0);
float *index_ptr_L1_patch_img = L1_patch_img.ptr<float>(0);
float *zero_ptr_L1_noise_img = L1_noise_img.ptr<float>(0);
float *index_ptr_L1_noise_img = L1_noise_img.ptr<float>(0);
float *zero_ptr_L1_autoenc_reconstructed = L1_autoenc_reconstructed.ptr<float>(0);
float *index_ptr_L1_autoenc_reconstructed = L1_autoenc_reconstructed.ptr<float>(0);
float *zero_ptr_L1_autoenc_delta = L1_autoenc_delta.ptr<float>(0);
float *index_ptr_L1_autoenc_delta = L1_autoenc_delta.ptr<float>(0);
///======================================
///L1 layer1. setup L1 tied weight's
///======================================
float **L1_weight_matrix_M;//Pointer fo a dynamic array. This weight_matrix_M will then have a size of rows = nr_of_pixels, colums = Hidden_nodes.
float **L1_change_weight_M;//Pointer fo a dynamic array. This weight_matrix_M will then have a size of rows = nr_of_pixels, colums = Hidden_nodes.
L1_weight_matrix_M = new float *[FL1_size];
L1_change_weight_M = new float *[FL1_size];
for(int i=0; i < FL1_size; i++)
{
L1_weight_matrix_M[i] = new float[L1_conv_depth];
L1_change_weight_M[i] = new float[L1_conv_depth];
}
float *f_data;///File data read/write connect to tied weights
f_data = new float[(FL1_size*L1_conv_depth)];///File data is same size as all tied weights
int ix=0;///index to f_data[ix]
///=====================================
///
///L2 autoencoder input, noised, recontruction and delta out
float **L2_patch_vect;
float **L2_noise_vect;
float **L2_autoenc_reconstructed;
float **L2_autoenc_delta;
L2_patch_vect = new float *[FL2_srt_size*FL2_srt_size];
L2_noise_vect = new float *[FL2_srt_size*FL2_srt_size];
L2_autoenc_reconstructed = new float *[FL2_srt_size*FL2_srt_size];
L2_autoenc_delta = new float *[FL2_srt_size*FL2_srt_size];
for(int i=0; i<FL2_srt_size*FL2_srt_size; i++) ///
{
L2_patch_vect[i] = new float[FL2_depth];
L2_noise_vect[i] = new float[FL2_depth];
L2_autoenc_reconstructed[i] = new float[FL2_depth];
L2_autoenc_delta [i] = new float[FL2_depth];
}
///======================================
///L2 layer2. setup L2 tied weight's
///======================================
float **L2_weight_matrix_M;//Pointer fo a dynamic array. This weight_matrix_M will then have a size of rows = nr_of_pixels, colums = Hidden_nodes.
float **L2_change_weight_M;//Pointer fo a dynamic array. This weight_matrix_M will then have a size of rows = nr_of_pixels, colums = Hidden_nodes.
L2_weight_matrix_M = new float *[FL2_size];
L2_change_weight_M = new float *[FL2_size];
for(int i=0; i < FL2_size; i++)
{
L2_weight_matrix_M[i] = new float[L2_conv_depth];
L2_change_weight_M[i] = new float[L2_conv_depth];
}
float *f2_data;///File data read/write connect to tied weights
f2_data = new float[(FL2_size*L2_conv_depth)];///File data is same size as all tied weights
/// int ix=0;///index to f_data[ix]
///=====================================
///=====================================
///
///L3 autoencoder input, noised, recontruction and delta out
float **L3_patch_vect;
float **L3_noise_vect;
float **L3_autoenc_reconstructed;
float **L3_autoenc_delta;
L3_patch_vect = new float *[FL3_srt_size*FL3_srt_size];
L3_noise_vect = new float *[FL3_srt_size*FL3_srt_size];
L3_autoenc_reconstructed = new float *[FL3_srt_size*FL3_srt_size];
L3_autoenc_delta = new float *[FL3_srt_size*FL3_srt_size];
for(int i=0; i<FL3_srt_size*FL3_srt_size; i++) ///
{
L3_patch_vect[i] = new float[FL3_depth];
L3_noise_vect[i] = new float[FL3_depth];
L3_autoenc_reconstructed[i] = new float[FL3_depth];
L3_autoenc_delta [i] = new float[FL3_depth];
}
///======================================
///L3 layer3. setup L3 tied weight's
///======================================
float **L3_weight_matrix_M;//Pointer fo a dynamic array. This weight_matrix_M will then have a size of rows = nr_of_pixels, colums = Hidden_nodes.
float **L3_change_weight_M;//Pointer fo a dynamic array. This weight_matrix_M will then have a size of rows = nr_of_pixels, colums = Hidden_nodes.
L3_weight_matrix_M = new float *[FL3_size];
L3_change_weight_M = new float *[FL3_size];
for(int i=0; i < FL3_size; i++)
{
L3_weight_matrix_M[i] = new float[L3_conv_depth];
L3_change_weight_M[i] = new float[L3_conv_depth];
}
float *f3_data;///File data read/write connect to tied weights
f3_data = new float[(FL3_size*L3_conv_depth)];///File data is same size as all tied weights
/// int ix=0;///index to f_data[ix]
///=====================================
///
///L1 visualize features
int L1_sqr_of_H_nod_plus1=0;
L1_sqr_of_H_nod_plus1 = sqrt(L1_conv_depth);
L1_sqr_of_H_nod_plus1 += 1;///+1 becasue sqrt() result will be round up downwards to an integer and that may result in to small square then
printf("L1_sqr_of_H_nod_plus1 %d\n", L1_sqr_of_H_nod_plus1);
float* L1_ptr_M_matrix;
Mat L1_visual_all_feature;
L1_visual_all_feature.create(FL1_srt_size * L1_sqr_of_H_nod_plus1, FL1_srt_size * L1_sqr_of_H_nod_plus1,CV_32FC3);
///L2 visualize features is trickyer then L1 because the depth now is not fit in CV_32FC3 "BGR" format now this depth is = L1_conv_depth = FL2_depth
int L2_vis_F_Hight = FL2_srt_size * L2_conv_depth;
int L2_vis_F_Width = FL2_srt_size * FL2_depth;
float* L2_ptr_M_matrix;
Mat L2_visual_all_feature;
L2_visual_all_feature.create(L2_vis_F_Hight, L2_vis_F_Width,CV_32FC1);///This is gray because the depth is larger then "BGR"
///L3 visualize features
int L3_vis_F_Hight = FL3_srt_size * L3_conv_depth;
int L3_vis_F_Width = FL3_srt_size * FL3_depth;
float* L3_ptr_M_matrix;
Mat L3_visual_all_feature;
L3_visual_all_feature.create(L3_vis_F_Hight, L3_vis_F_Width,CV_32FC1);///This is gray because the depth is larger then "BGR"
///visualize_L2toL1
/// Mat visualize_L2toL1;///This will show L2 feature how it looks when projected with L1 features
/// visualize_L2toL1.create((FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1) , (FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1)*L2_conv_depth, CV_32FC3);
int sqr_L2_conv_depth_plus1=0;
sqr_L2_conv_depth_plus1 = sqrt(L2_conv_depth);
sqr_L2_conv_depth_plus1 +=1;///+1 becasue sqrt() result will be round up downwards to an integer and that may result in to small square then
Mat sq_visualize_L2toL1;///This will show L2 feature how it looks when projected with L1 features
sq_visualize_L2toL1.create((FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1)*sqr_L2_conv_depth_plus1 , (FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1)*sqr_L2_conv_depth_plus1, CV_32FC3);
///visualize_L3toL1
/// Mat visualize_L3toL1;///This will show L3 feature how it looks when projected with L1 features
/// visualize_L3toL1.create((FL3_srt_size*pool_sqr*pool_sqr + (FL1_srt_size-1)/2 +1) , (FL3_srt_size*pool_sqr*pool_sqr + (FL1_srt_size-1)/2 +1)*L3_conv_depth, CV_32FC3);
int sqr_L3_conv_depth_plus1=0;
sqr_L3_conv_depth_plus1 = sqrt(L3_conv_depth);
sqr_L3_conv_depth_plus1 +=1;///+1 becasue sqrt() result will be round up downwards to an integer and that may result in to small square then
Mat sq_visualize_L3toL1;///This will show L2 feature how it looks when projected with L1 features
sq_visualize_L3toL1.create(L3toL2toL1_feature_revers_size*sqr_L3_conv_depth_plus1 , L3toL2toL1_feature_revers_size*sqr_L3_conv_depth_plus1, CV_32FC3);
///L1 feature start noise
for(int i=0; i<FL1_size; i++)
{
L1_ptr_M_matrix = &L1_weight_matrix_M[i][0];
for(int j=0; j<(L1_conv_depth); j++)
{
Rando = (float) (rand() % 65535) / 65536;//0..1.0 range
Rando -= 0.5f;
Rando *= start_weight_noise_range;
*L1_ptr_M_matrix = Rando;
L1_ptr_M_matrix++;
L1_change_weight_M[i][j] = 0.0f;
}
}
///L2 feature start noise
for(int i=0; i<FL2_size; i++)
{
L2_ptr_M_matrix = &L2_weight_matrix_M[i][0];
for(int j=0; j<(L2_conv_depth); j++)
{
Rando = (float) (rand() % 65535) / 65536;//0..1.0 range
Rando -= 0.5f;
Rando *= start_weight_noise_range;
*L2_ptr_M_matrix = Rando;
L2_ptr_M_matrix++;
L2_change_weight_M[i][j] = 0.0f;
}
}
///L3 feature start noise
for(int i=0; i<FL3_size; i++)
{
L3_ptr_M_matrix = &L3_weight_matrix_M[i][0];
for(int j=0; j<(L3_conv_depth); j++)
{
Rando = (float) (rand() % 65535) / 65536;//0..1.0 range
Rando -= 0.5f;
Rando *= start_weight_noise_range;
*L3_ptr_M_matrix = Rando;
L3_ptr_M_matrix++;
L3_change_weight_M[i][j] = 0.0f;
}
}
///============================================
/// L1 Convolution and Pooling cube
float **L1_conv_cube;
float **L1_pool_cube;
L1_conv_cube = new float*[L1_conv_hight * L1_conv_width];///This is One sheet of the conv code
for(int i=0; i<(L1_conv_hight * L1_conv_width); i++)
{
L1_conv_cube[i] = new float[L1_conv_depth];
}
L1_pool_cube = new float*[L1_conv_hight * L1_conv_width / pooling];
for(int i=0; i<(L1_conv_hight * L1_conv_width / pooling); i++)
{
L1_pool_cube[i] = new float[L1_conv_depth];
}
int L1_pool_tracking=0;///for example if max pooling is arrange 4 -> 1 then 0..3 will be the value depend on which L1_conv_cube[][] node was strongest on that conv pos
///
/// L2 Convolution and Pooling cube
float **L2_conv_cube;
float **L2_pool_cube;
L2_conv_cube = new float*[L2_conv_hight * L2_conv_width];///This is One sheet of the conv code
for(int i=0; i<(L2_conv_hight * L2_conv_width); i++)
{
L2_conv_cube[i] = new float[L2_conv_depth];
}
L2_pool_cube = new float*[L2_conv_hight * L2_conv_width / pooling];
for(int i=0; i<(L2_conv_hight * L2_conv_width / pooling); i++)
{
L2_pool_cube[i] = new float[L2_conv_depth];
}
int L2_pool_tracking=0;///for example if max pooling is arrange 4 -> 1 then 0..3 will be the value depend on which L1_conv_cube[][] node was strongest on that conv pos
///
/// L3 Convolution and Pooling cube
float **L3_conv_cube;
float **L3_pool_cube;
L3_conv_cube = new float*[L3_conv_hight * L3_conv_width];///This is One sheet of the conv code
for(int i=0; i<(L3_conv_hight * L3_conv_width); i++)
{
L3_conv_cube[i] = new float[L3_conv_depth];
}
L3_pool_cube = new float*[L3_conv_hight * L3_conv_width / pooling];
for(int i=0; i<(L3_conv_hight * L3_conv_width / pooling); i++)
{
L3_pool_cube[i] = new float[L3_conv_depth];
}
int L3_pool_tracking=0;///for example if max pooling is arrange 4 -> 1 then 0..3 will be the value depend on which L1_conv_cube[][] node was strongest on that conv pos
///
imshow("RGB_image", RGB_image);
waitKey(1);
// getchar();
fp1 = fopen("data_batch_1.bin", "r");
if (fp1 == NULL)
{
puts("Error while opening file data_batch_1.bin");
exit(0);
}
///read_CIFAR_image()
char* CIFAR_data;
CIFAR_data = new char[nr_of_CIFAR_file_bytes];
int MN_index=0;
char c_data=0;
for(int i=0; i<nr_of_CIFAR_file_bytes; i++)
{
c_data = fgetc(fp1);
if( feof(fp1) )
{
break;
}
//printf("c_data %d\n", c_data);
CIFAR_data[MN_index] = c_data;
MN_index++;
}
fclose(fp1);
printf("data_batch_1.bin data is put into CIFAR_data\n");
int CIFAR_nr = 0;
const int CIFAR_row_size = 3073;/// 1 byte label, 1024 RED ch, 1024 GREEN ch, 1024 BLUE ch
srand (static_cast <unsigned> (time(0)));//Seed the randomizer
char *zero_ptr_RGB_image = RGB_image.ptr<char>(0);
char *index_ptr_RGB_image = RGB_image.ptr<char>(0);
float *zero_ptr_norm_B_32FC1img = norm_B_32FC1img.ptr<float>(0);
float *zero_ptr_norm_G_32FC1img = norm_G_32FC1img.ptr<float>(0);
float *zero_ptr_norm_R_32FC1img = norm_R_32FC1img.ptr<float>(0);
float *index_ptr_norm_B_32FC1img = norm_B_32FC1img.ptr<float>(0);
float *index_ptr_norm_G_32FC1img = norm_G_32FC1img.ptr<float>(0);
float *index_ptr_norm_R_32FC1img = norm_R_32FC1img.ptr<float>(0);
// RGB_image.convertTo(colour, CV_32FC3, 1.0/255.0);
// local_norm_colour = CV_32FC3_local_normalizing(colour);
float *zero_ptr_norm_32FC3_img = local_norm_colour.ptr<float>(0);
float *index_ptr_norm_32FC3_img = local_norm_colour.ptr<float>(0);
///Test mat Conv and Pool L1
Mat test1, test2, test3, pol_t1, pol_t2, pol_t3;
test1.create(L1_conv_hight, L1_conv_width, CV_32FC1);
float *test1_zero_ptr = test1.ptr<float>(0);
float *test1_ptr = test1.ptr<float>(0);
test2.create(L1_conv_hight, L1_conv_width, CV_32FC1);
float *test2_zero_ptr = test2.ptr<float>(0);
float *test2_ptr = test2.ptr<float>(0);
test3.create(L1_conv_hight, L1_conv_width, CV_32FC1);
float *test3_zero_ptr = test3.ptr<float>(0);
float *test3_ptr = test3.ptr<float>(0);
pol_t1.create(L1_conv_hight/pool_sqr, L1_conv_width/pool_sqr, CV_32FC1);
float *pol_t1_zero_ptr = pol_t1.ptr<float>(0);
float *pol_t1_ptr = pol_t1.ptr<float>(0);
pol_t2.create(L1_conv_hight/pool_sqr, L1_conv_width/pool_sqr, CV_32FC1);
float *pol_t2_zero_ptr = pol_t2.ptr<float>(0);
float *pol_t2_ptr = pol_t2.ptr<float>(0);
pol_t3.create(L1_conv_hight/pool_sqr, L1_conv_width/pool_sqr, CV_32FC1);
float *pol_t3_zero_ptr = pol_t3.ptr<float>(0);
float *pol_t3_ptr = pol_t3.ptr<float>(0);
///Test mat Conv and Pool L1
Mat L2_test1, L2_test2, L2_test3, L2_pol_t1, L2_pol_t2, L2_pol_t3;
L2_test1.create(L2_conv_hight, L2_conv_width, CV_32FC1);
float *L2_test1_zero_ptr = L2_test1.ptr<float>(0);
float *L2_test1_ptr = L2_test1.ptr<float>(0);
L2_test2.create(L2_conv_hight, L2_conv_width, CV_32FC1);
float *L2_test2_zero_ptr = L2_test2.ptr<float>(0);
float *L2_test2_ptr = L2_test2.ptr<float>(0);
L2_test3.create(L2_conv_hight, L2_conv_width, CV_32FC1);
float *L2_test3_zero_ptr = L2_test3.ptr<float>(0);
float *L2_test3_ptr = L2_test3.ptr<float>(0);
L2_pol_t1.create(L2_conv_hight/pool_sqr, L2_conv_width/pool_sqr, CV_32FC1);
float *L2_pol_t1_zero_ptr = L2_pol_t1.ptr<float>(0);
float *L2_pol_t1_ptr = L2_pol_t1.ptr<float>(0);
L2_pol_t2.create(L2_conv_hight/pool_sqr, L2_conv_width/pool_sqr, CV_32FC1);
float *L2_pol_t2_zero_ptr = L2_pol_t2.ptr<float>(0);
float *L2_pol_t2_ptr = L2_pol_t2.ptr<float>(0);
L2_pol_t3.create(L2_conv_hight/pool_sqr, L2_conv_width/pool_sqr, CV_32FC1);
float *L2_pol_t3_zero_ptr = L2_pol_t3.ptr<float>(0);
float *L2_pol_t3_ptr = L2_pol_t3.ptr<float>(0);
/// cpp_func2 instanisation
cpp_func2 comon_func_Obj1;
comon_func_Obj1.nr_of_positions = FL1_size;///Size of the FL1_size = FL1_srt_size * FL1_srt_size * FL1_depth
comon_func_Obj1.L2_nr_of_positions = FL2_size;
comon_func_Obj1.L3_nr_of_positions = FL3_size;
comon_func_Obj1.init();
comon_func_Obj1.noise_percent = L1_autoencoder_noise_ratio;///
comon_func_Obj1.L2_noise_percent = L2_autoencoder_noise_ratio;///
comon_func_Obj1.L3_noise_percent = L3_autoencoder_noise_ratio;///
comon_func_Obj1.print_help();
comon_func_Obj1.save_L1_weights=0;
Lx_attach_weight2mat L2_attach_weight2mat;
L2_attach_weight2mat.FL_Height = FL2_srt_size;
L2_attach_weight2mat.FL_Width = FL2_srt_size;
L2_attach_weight2mat.Lx_Hidden_nodes = L2_conv_depth;
Lx_attach_weight2mat L3_attach_weight2mat;
L3_attach_weight2mat.FL_Height = FL3_srt_size;
L3_attach_weight2mat.FL_Width = FL3_srt_size;
L3_attach_weight2mat.Lx_Hidden_nodes = L3_conv_depth;
/// getchar();
printf("Would you like to load stored Lx_weight_matrix_M.dat <Y>/<N> \n");
char answer_character;
answer_character = getchar();
if(answer_character == 'Y' || answer_character == 'y')
{
///L1 load
sprintf(filename, "L1_weight_matrix_M.dat");
fp2 = fopen(filename, "r");
if (fp2 == NULL)
{
printf("Error while opening file L1_weight_matrix_M.dat");
exit(0);
}
fread(f_data, sizeof f_data[0], (FL1_size*L1_conv_depth), fp2);
ix=0;
for(int n=0; n<L1_conv_depth; n++)
{
for(int p=0; p<FL1_size; p++)
{
L1_weight_matrix_M[p][n] = f_data[ix];///File data put in to tied weights
ix++;
}
}
fclose(fp2);
printf("weights are loaded from L1_weight_matrix_M.dat file\n");
///L2 load
sprintf(filename, "L2_weight_matrix_M.dat");
fp2 = fopen(filename, "r");
if (fp2 == NULL)
{
printf("Error while opening file L2_weight_matrix_M.dat");
exit(0);
}
fread(f2_data, sizeof f2_data[0], (FL2_size*L2_conv_depth), fp2);
ix=0;
for(int n=0; n<L2_conv_depth; n++)
{
for(int p=0; p<FL2_size; p++)
{
L2_weight_matrix_M[p][n] = f2_data[ix];///File data put in to tied weights
ix++;
}
}
fclose(fp2);
printf("weights are loaded from L2_weight_matrix_M.dat file\n");
///End L2 load
///L3 load
sprintf(filename, "L3_weight_matrix_M.dat");
fp2 = fopen(filename, "r");
if (fp2 == NULL)
{
printf("Error while opening file L3_weight_matrix_M.dat");
exit(0);
}
fread(f3_data, sizeof f3_data[0], (FL3_size*L3_conv_depth), fp2);
ix=0;
for(int n=0; n<L3_conv_depth; n++)
{
for(int p=0; p<FL3_size; p++)
{
L3_weight_matrix_M[p][n] = f3_data[ix];///File data put in to tied weights
ix++;
}
}
fclose(fp2);
printf("weights are loaded from L3_weight_matrix_M.dat file\n");
///End L3 load
}
float noise;
while(1)
{
CIFAR_nr = (int) (rand() % CIFAR_nr_of_img_p_batch);
/// which is a number in the range 0-9. The next 3072 bytes are the values of the pixels of the image.
/// The first 1024 bytes are the red channel values, the next 1024 the green, and the final 1024 the blue.
/// The values are stored in row-major order, so the first 32 bytes are the red channel values of the first row of the image.
index_ptr_RGB_image = zero_ptr_RGB_image;
for (int i=0; i<CIFAR_RGB_pixels; i++)
{
for(int BGR=0; BGR<3; BGR++)
{
*index_ptr_RGB_image = CIFAR_data[(CIFAR_nr*CIFAR_row_size) + ((2-BGR)*CIFAR_RGB_pixels) + i];
index_ptr_RGB_image++;
}
}
RGB_image.convertTo(colour, CV_32FC3, 1.0/255.0);
#ifdef USE_BGR_NORMALIZER
local_norm_colour = CV_32FC3_local_normalizing(colour);
#else
local_norm_colour = colour;
#endif // USE_BGR_NORMALIZER
imshow("colour", colour);
imshow("local_norm_colour", local_norm_colour);
zero_ptr_norm_32FC3_img = local_norm_colour.ptr<float>(0);
index_ptr_norm_32FC3_img = zero_ptr_norm_32FC3_img;
index_ptr_norm_B_32FC1img = zero_ptr_norm_B_32FC1img;
index_ptr_norm_G_32FC1img = zero_ptr_norm_G_32FC1img;
index_ptr_norm_R_32FC1img = zero_ptr_norm_R_32FC1img;
for (int i=0; i<CIFAR_RGB_pixels; i++)
{
for(int BGR=0; BGR<3; BGR++)
{
///Spit BGR to B, G, R separate 0..255 image
switch(BGR)
{
case(0):
*index_ptr_norm_B_32FC1img = *index_ptr_norm_32FC3_img;
index_ptr_norm_B_32FC1img++;
break;
case(1):
*index_ptr_norm_G_32FC1img = *index_ptr_norm_32FC3_img;
index_ptr_norm_G_32FC1img++;
break;
case(2):
*index_ptr_norm_R_32FC1img = *index_ptr_norm_32FC3_img;
index_ptr_norm_R_32FC1img++;
break;
}
index_ptr_norm_32FC3_img++;
}
}
imshow("norm_B_32FC1img", norm_B_32FC1img);
imshow("norm_G_32FC1img", norm_G_32FC1img);
imshow("norm_R_32FC1img", norm_R_32FC1img);
///randu(RGB_image, Scalar::all(0), Scalar::all(255));
/// cvtColor(RGB_image,RGB_image,CV_BGR2RGB);
imshow("RGB_image", RGB_image);
if(comon_func_Obj1.L1_autoencoder_ON == 1)///Do Autoencoder L1 process (Not L1 Convolution process)
{
///******************************************
///********* Autoencoder L1 process *********
///******************************************
int rand_x_start_pos=0;
int rand_y_start_pos=0;
for(int ittr=0; ittr<nr_of_autoenc_ittr_1_image; ittr++)
{
rand_x_start_pos = (int) (rand() % (L1_conv_width-1));
rand_y_start_pos = (int) (rand() % (L1_conv_hight-1));
comon_func_Obj1.rand_input_data_pos();///Make a table (comon_func_Obj1.nr_of_positions) of randomized position inside FL1 feature size
for(int n=0; n<FL1_size; n++)///comon_func_Obj1.nr_of_positions = FL1_size;///Size of the FL1_size = FL1_srt_size * FL1_srt_size * FL1_depth
{
index_ptr_L1_patch_img = zero_ptr_L1_patch_img + n;
index_ptr_L1_noise_img = zero_ptr_L1_noise_img + n;
index_ptr_norm_32FC3_img = zero_ptr_norm_32FC3_img + norm_32FC3_img.cols * FL1_depth * (rand_y_start_pos + n/(FL1_srt_size * FL1_depth)) + rand_x_start_pos * FL1_depth + n%(FL1_srt_size * FL1_depth);
*index_ptr_L1_patch_img = *index_ptr_norm_32FC3_img;///Insert real data from input vector input image
if(comon_func_Obj1.noise_pos[n] == 1 && comon_func_Obj1.started == 1)
{
///****************************************************
///********** Select noise level ******************
///****************************************************
noise = (float) (rand() % 65535) / 65536;//0..1.0 range
noise -= 0.5f;
noise = noise * noise_amplitude;
noise += 0.5f;
noise += noise_offset;
*index_ptr_L1_noise_img = noise;///Insert noise instead of real pixel value
}
else
{
///Insert a small region of the input vector
*index_ptr_L1_noise_img = *index_ptr_norm_32FC3_img;///Insert real data from input vector input image
}
}
///*********** Forward to hidden nodes ****************
///Make autoencoder forward of FL1 feature
for(int j=0; j<L1_conv_depth; j++)
{
L1_conv_cube[0][j] = 0.0f;///Clear autoencoder hidden node (hidden node = Lx_conv_cube[0][depth] ). [0] because we borrow L1_conv_cube mem this first area sheet pos in the convoution memory area now only for autencoder
index_ptr_L1_noise_img = zero_ptr_L1_noise_img;
for(int i=0; i<FL1_size; i++)
{
L1_conv_cube[0][j] += *index_ptr_L1_noise_img * L1_weight_matrix_M[i][j];///Make the dot product to pruduce the node.[0] because we borrow L1_conv_cube mem this first area sheet pos in the convoution memory area now only for autencoder
index_ptr_L1_noise_img++;
}
///*** Relu this node ***
if(L1_conv_cube[0][j] < 0.0f)
{
L1_conv_cube[0][j] = L1_conv_cube[0][j] * Relu_neg_gain;///Relu function
}
}
///********** Forward to L1 output nodes *******************
///Clear the L1_autoenc_reconstructed
index_ptr_L1_autoenc_reconstructed = zero_ptr_L1_autoenc_reconstructed;
for(int i=0; i<FL1_size; i++)
{
*index_ptr_L1_autoenc_reconstructed = 0.5f;///Clear
index_ptr_L1_autoenc_reconstructed++;
}
///Make autoencoder reconstruction
for(int j=0; j<L1_conv_depth; j++)
{
index_ptr_L1_autoenc_reconstructed = zero_ptr_L1_autoenc_reconstructed;
for(int i=0; i<FL1_size; i++)
{
*index_ptr_L1_autoenc_reconstructed += L1_conv_cube[0][j] * L1_weight_matrix_M[i][j];///Reconstruction using the autoencoder tie weight. L1_conv_cube[0][j] is the hidden node of the autoencoder
index_ptr_L1_autoenc_reconstructed++;
}
}
///Make the autoencoder loss and delta calculation
index_ptr_L1_autoenc_delta = zero_ptr_L1_autoenc_delta;
index_ptr_L1_autoenc_reconstructed = zero_ptr_L1_autoenc_reconstructed;
index_ptr_L1_patch_img = zero_ptr_L1_patch_img;
static float loss=0.0f;
float delta=0.0f;
float L1_output_node;
for(int i=0; i<FL1_size; i++)
{
L1_output_node = *index_ptr_L1_autoenc_reconstructed;
delta = *index_ptr_L1_patch_img - L1_output_node;
loss += delta * delta;/// loss = 1/2 SUM k (input[k] - ouput[k])²
/// if(L1_output_node < 0.0f)///
/// {
/// delta *= Relu_neg_gain;///??????
/// }
*index_ptr_L1_autoenc_delta = delta;
index_ptr_L1_autoenc_reconstructed++;
index_ptr_L1_autoenc_delta++;
index_ptr_L1_patch_img++;
}
///make the backpropagation
index_ptr_L1_autoenc_delta = zero_ptr_L1_autoenc_delta;
for(int i=0; i<FL1_size; i++)
{
for(int j=0; j<L1_conv_depth; j++)
{
/// **** update tied weight regarding delta
L1_change_weight_M[i][j] = LearningRate * L1_conv_cube[0][j] * (*index_ptr_L1_autoenc_delta) + Momentum * L1_change_weight_M[i][j];///hidden_node = L1_conv_cube[0][j];
L1_weight_matrix_M[i][j] += L1_change_weight_M[i][j];
}
index_ptr_L1_autoenc_delta++;
}
///Print Loss
static int print_loss=0;
if(print_loss<200)
{
print_loss++;
}
else
{
loss = loss / 2.0f;/// loss = 1/2 SUM k (input[k] - ouput[k])²
printf("L1 autoencoder loss error = %f\n", loss);
print_loss=0;
loss=0.0f;
}
///End print loss
///L1 visual
L1_visual_all_feature = Scalar(0.0,0.0,0.0);
for(int i=0; i<FL1_size; i++)
{
L1_ptr_M_matrix = &L1_weight_matrix_M[i][0];
attach_weight_2_mat(L1_ptr_M_matrix, i, L1_visual_all_feature, L1_sqr_of_H_nod_plus1, L1_conv_depth, FL1_srt_size, FL1_srt_size);///
}
L1_visual_all_feature += Scalar(0.5,0.5,0.5);
imshow("L1_visual_all_feature", L1_visual_all_feature);
///L1_autoenc_delta += Scalar(0.5,0.5,0.5);
imshow("L1_patch_img", L1_patch_img);
imshow("L1_noise_img", L1_noise_img);
imshow("L1_autoenc_reconstructed", L1_autoenc_reconstructed);
imshow("L1_autoenc_delta", L1_autoenc_delta);
waitKey(1);
}
}
if(comon_func_Obj1.L1_convolution_ON == 1)/// Do convloution L1 process instead of L1 Autoencoder process
{
printf("Lable nr = %d\n", CIFAR_data[(CIFAR_nr*CIFAR_row_size)]);
///**********************************
///********* Convolute L1 ***********
///**********************************
for(int i=0; i<(L1_conv_hight * L1_conv_width); i++)///This loop step throue (convolute) the area of the input "sheet". No padding of the slide on one sheet area of the convolution cube
{
for(int j=0; j<L1_conv_depth; j++)///This loop step throue the depth of the Convolution L1 cube
{
L1_conv_cube[i][j] = 0.0f;///Clear the one node of the conv cube
int input_ptr_offset;
for(int k=0; k<FL1_size; k++)///This loop step throue one Feature cube. FL1_size = (FL1_srt_size * FL1_srt_size * FL1_depth) The size of one Feature FL1
{
input_ptr_offset = (local_norm_colour.cols * local_norm_colour.channels() * ((i/L1_conv_width) + (k/(FL1_srt_size * FL1_depth)))) + ((i%(L1_conv_width)) * FL1_depth) + (k%(FL1_srt_size * FL1_depth));
index_ptr_norm_32FC3_img = zero_ptr_norm_32FC3_img + input_ptr_offset;
///Convolution cube row address = (local_norm_colour.cols * local_norm_colour.channels() * ((i/L1_conv_width) + (k/(FL1_srt_size * FL1_depth))))
///where local_norm_colour.cols is the width if the conv
///Make the dot product
///ConvNode = ConvNode + weigh[][] * input[]
///L1_conv_cube[i][j] += L1_weight_matrix_M[k][j] * ((1.0f/255.0) * (float) (*index_ptr_norm_BGR_img));///Make the dot product of the 0..x Feature * input image to L1 convolution cube
L1_conv_cube[i][j] += L1_weight_matrix_M[k][j] * (*index_ptr_norm_32FC3_img);///Make the dot product of the 0..x Feature * input image to L1 convolution cube
}
}
}
///**************************************
///********* End Convolute L1 ***********
///**************************************
///**************************************
///********* Pooling L1 *****************
///**************************************
for(int h=0; h<(L1_conv_hight / pool_sqr); h++)///This loop togheter with i loop step throue the "sheet" area of of the L1_pool_cube[i][x]
{
for(int i=0; i<(L1_conv_width / pool_sqr); i++)///This loop togheter with h loop step throue the "sheet" area of of the L1_pool_cube[i][x]
{
if(comon_func_Obj1.L1_autoencoder_ON == 1)
{
L1_autoenc_reconstructed = Scalar(0.0f,0.0f,0.0f);
}
for(int j=0; j<L1_conv_depth; j++)///This loop step throue the depth of the Convolution L1 cube
{
float max_node= -1000000.0f;
float compare_max = 0.0f;
int revers_pool_row=0;
for(int p=0; p<pooling; p++)
{
revers_pool_row = p/pool_sqr;///Get a pool row level inside the pooling area to make it poosible to read the right row position on the convolution sheet area
///compare_max = L1_conv_cube[h * pool_sqr * L1_conv_width + L1_conv_width * revers_pool_row + i * pool_sqr + p % pool_sqr][j];///Prepare pooling compare value. Pick the value from the convolute (slide) position node at convolution cube
compare_max = L1_conv_cube[h * pool_sqr * L1_conv_width + L1_conv_width * revers_pool_row + i * pool_sqr + p%pool_sqr][j];///Prepare pooling compare value. Pick the value from the convolute (slide) position node at convolution cube
if(compare_max > max_node)
{
L1_pool_tracking = p;
max_node = compare_max;
}
}
///*** Relu this node ***
if(max_node < 0.0f)
{
max_node = max_node * Relu_neg_gain;///Relu function
}
L1_pool_cube[h*(L1_conv_hight / pool_sqr) + i][j] = max_node;
///****************************************************************************************************************
///******** Do the L1 autoencoder here when the fully depth of the pooled nodes on L1_pool_cube[][] is done *******
///****************************************************************************************************************
if(comon_func_Obj1.L1_autoencoder_ON == 1)
{
///3-steps to make a delta node "pixel" to each feature. Unsupervised learning
///1. Make the reconstruction vector from the tie feature weights from pool_cube node. If feature was 5x5 then reconstruction vector is 6x6 when pooling=4, 7x7 if pooling=9
///2. Make the input (without noise) compare vector L1_patch_img. If feature was 5x5 then input compare vector is 6x6 when pooling=4, 7x7 if pooling=9
///3. Make delta vector from differance input vector - reconstruction vector.
///4. Update L1 features tie weight with respect to delta vector and this slide positions in the pool_cube.
for(int k=0; k<FL1_size; k++) ///Go throue the Feature cube FL1_size = (FL1_srt_size * FL1_srt_size * FL1_depth) of the input features so the reconstruction vector will have same depth as the input depth
{
///Step 1. Make the reconstruction vector from the tie feature weights from pool_cube node. If feature was 5x5 then reconstruction vector is 6x6 when pooling=4, 7x7 if pooling=9
index_ptr_L1_autoenc_reconstructed = zero_ptr_L1_autoenc_reconstructed + (L1_autoenc_reconstructed.cols * FL1_depth * ((L1_pool_tracking / pool_sqr) + k/(FL1_srt_size * FL1_depth)) + FL1_depth * (L1_pool_tracking % pool_sqr) + k%(FL1_srt_size * FL1_depth));
///********** Forward to L1 (output nodes) reconstruction node *******************
*index_ptr_L1_autoenc_reconstructed += max_node * L1_weight_matrix_M[k][j];///revers the dot product, reconstruct the orginal vector
///End Step 1.
}
}
}
/// Pooling of this convolute (slide) position is now done throue the full depth of nodes at L1_conv_cube[][] and L1_pool_cube[h*i][j]
/// h, i, pooltracking gives the convolute (slide) position to prepare the input patch/part for the autoencoder compare to reconstruction
}
}
///**************************************
///********* END Pooling L1 *************
///**************************************
///show one layer of conv L1
///void show_sheet_2_mat(float* cube, int show_layer_nr, Mat dst)
test1_ptr = test1_zero_ptr;
test2_ptr = test2_zero_ptr;
test3_ptr = test3_zero_ptr;
for(int i=0; i<L1_conv_hight*L1_conv_width; i++)
{
*test1_ptr = L1_conv_cube[i][0];
test1_ptr++;
*test2_ptr = L1_conv_cube[i][1];
test2_ptr++;
*test3_ptr = L1_conv_cube[i][2];
test3_ptr++;
}
// printf("L1_conv_hight*L1_conv_width %d\n", L1_conv_hight*L1_conv_width);
// printf("test.cols*test.channels() * test.rows %d\n", test.cols*test.channels() * test.rows);
test1 += 0.5f;///Scalar(0.5);
test2 += 0.5f;///Scalar(0.5);
test3 += 0.5f;///Scalar(0.5);
imshow("test1", test1);
imshow("test2", test2);
imshow("test3", test3);
pol_t1_ptr = pol_t1_zero_ptr;
pol_t2_ptr = pol_t2_zero_ptr;
pol_t3_ptr = pol_t3_zero_ptr;
for(int i=0; i<(L1_conv_hight*L1_conv_width/pooling); i++)
{
*pol_t1_ptr = L1_pool_cube[i][0];
pol_t1_ptr++;
*pol_t2_ptr = L1_pool_cube[i][1];
pol_t2_ptr++;
*pol_t3_ptr = L1_pool_cube[i][2];
pol_t3_ptr++;
}
pol_t1 += 0.5f;
pol_t2 += 0.5f;
pol_t3 += 0.5f;
imshow("pol_t1", pol_t1);
imshow("pol_t2", pol_t2);
imshow("pol_t3", pol_t3);
} ///End convloution L1 process
///L2
if(comon_func_Obj1.L2_autoencoder_ON == 1)///Do Autoencoder L2 process (Not L2 Convolution process)
{
///******************************************
///********* Autoencoder L2 process *********
///******************************************
int rand_x_start_pos=0;
int rand_y_start_pos=0;
for(int ittr=0; ittr<L2_nr_of_autoenc_ittr_1_image; ittr++)
{
rand_x_start_pos = (int) (rand() % (L2_conv_width-1));///-1 because then it fit exactly between Feature and Convolution
rand_y_start_pos = (int) (rand() % (L2_conv_hight-1));
/// printf("rand_x_start_pos %d\n", rand_x_start_pos);
comon_func_Obj1.L2_rand_input_data_pos();///Make a table (comon_func_Obj1.L2_nr_of_positions) of randomized position inside FL2 feature size
///Get a patch vector from L1_pool_cube and run it thoue the autoencoder
///Insert noise on L2_patch_vect[][]
float pool_temporary;
//int addr_offset;
for(int j=0; j<FL2_depth; j++)
{
for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)///comon_func_Obj1.L2_nr_of_positions = FL2_size;///Size of the FL2_size = FL2_srt_size * FL2_srt_size * FL2_depth
{
//addr_offset = (L1_conv_width/pool_sqr) * (rand_y_start_pos + i/FL2_srt_size) + rand_x_start_pos + i%FL2_srt_size;
pool_temporary = L1_pool_cube[(L1_conv_width/pool_sqr) * (rand_y_start_pos + i/FL2_srt_size) + rand_x_start_pos + i%FL2_srt_size][j];
///L2_patch_vect[area][depth]
///pool_temporary = L1_pool_cube[addr_offset][j];
L2_patch_vect[i][j] = pool_temporary;///Insert real data from input vector
if(comon_func_Obj1.L2_noise_pos[i + (FL2_srt_size * FL2_srt_size)*j] == 1)
{
///****************************************************
///********** Select noise level ******************
///****************************************************
noise = (float) (rand() % 65535) / 65536;//0..1.0 range
noise -= 0.5f;
noise = noise * noise_amplitude;
noise += 0.5f;
noise += noise_offset;
L2_noise_vect[i][j] = noise;///Insert noise instead of real value
}
else
{
///Insert a small region of the input vector
L2_noise_vect[i][j] = pool_temporary;///Insert real data from input vector
}
}
}
///*********** Forward to hidden nodes ****************
///Make autoencoder forward of FL2 feature
for(int k=0; k<L2_conv_depth; k++)
{
L2_conv_cube[0][k] = 0.0f;///Clear autoencoder hidden node (hidden node = Lx_conv_cube[0][depth] ). [0] because we borrow L1_conv_cube mem this first area sheet pos in the convoution memory area now only for autencoder
for(int j=0; j<FL2_depth; j++)
{
for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)
{
L2_conv_cube[0][k] += L2_noise_vect[i][j] * L2_weight_matrix_M[i + (FL2_srt_size * FL2_srt_size)*j][k];///Make the dot product to pruduce the node.[0] because we borrow L1_conv_cube mem this first area sheet pos in the convoution memory area now only for autencoder
}
///*** Relu this node ***
if(L2_conv_cube[0][k] < 0.0f)
{
L2_conv_cube[0][k] = L2_conv_cube[0][k] * Relu_neg_gain;///Relu function
}
}
}
///********** Forward to L2 output nodes *******************
///Clear the L2_autoenc_reconstructed
for(int j=0; j<FL2_depth; j++)
{
for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)
{
L2_autoenc_reconstructed[i][j] = 0.0f;///Clear
}
}
///Make autoencoder reconstruction
for(int k=0; k<L2_conv_depth; k++)
{
for(int j=0; j<FL2_depth; j++)
{
for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)
{
///Make autoencoder reconstruction
L2_autoenc_reconstructed[i][j] += L2_conv_cube[0][k] * L2_weight_matrix_M[i + (FL2_srt_size * FL2_srt_size)*j][k];///Reconstruction using the autoencoder tie weight. L1_conv_cube[0][j] is the hidden node of the autoencoder
}
}
}
///Make the autoencoder loss and delta calculation
static float L2_loss=0.0f;
float L2_delta=0.0f;
float L2_output_node=0.0f;
for(int j=0; j<FL2_depth; j++)
{
for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)
{
//L2_delta = *index_ptr_L1_patch_img - *index_ptr_L1_autoenc_reconstructed;
L2_output_node = L2_autoenc_reconstructed[i][j];
L2_delta = L2_patch_vect[i][j] - L2_output_node ;
L2_loss += L2_delta * L2_delta;/// loss = 1/2 SUM k (input[k] - ouput[k])²
/// if(L2_output_node < 0.0f)///
/// {
/// L2_delta *= Relu_neg_gain;
/// }
L2_autoenc_delta[i][j] = L2_delta;
}
}
///make the backpropagation
for(int k=0; k<L2_conv_depth; k++)
{
for(int j=0; j<FL2_depth; j++)
{
for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)
{
/// **** update tied weight regarding delta
L2_change_weight_M[i + (FL2_srt_size * FL2_srt_size)*j][k] = L2_LearningRate * L2_conv_cube[0][k] * (L2_autoenc_delta[i][j]) + L2_Momentum * L2_change_weight_M[i + (FL2_srt_size * FL2_srt_size)*j][k];///hidden_node = L1_conv_cube[0][j];
L2_weight_matrix_M[i + (FL2_srt_size * FL2_srt_size)*j][k] += L2_change_weight_M[i + (FL2_srt_size * FL2_srt_size)*j][k];
}
}
}
///Print Loss
static int L2_print_loss=0;
if(L2_print_loss<200)
{
L2_print_loss++;
}
else
{
L2_loss = L2_loss / 2.0f;/// loss = 1/2 SUM k (input[k] - ouput[k])²
printf("L2 autoencoder L2_loss error = %f\n", L2_loss);
L2_print_loss=0;
L2_loss=0.0f;
}
///End print loss
}///End ittr loop
///L2 visual
static int visualL2_now_counter=1000;
if(visualL2_now_counter > 100)
{
visualL2_now_counter=0;
printf("show L2\n");
///Debugg
/// for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)
/// {
/// L2_weight_matrix_M[i + (FL2_srt_size * FL2_srt_size)*1][2] = -0.45f;
/// }
///
L2_attach_weight2mat.Lx_src = L2_visual_all_feature;///attach Mat pointer
for(int j=0; j<FL2_depth; j++)
{
for(int i=0; i<(FL2_srt_size * FL2_srt_size); i++)
{
L2_attach_weight2mat.Lx_ptr_M_matrix = &L2_weight_matrix_M[i + (FL2_srt_size * FL2_srt_size)*j][0];
/// L2_attach_weight2mat.k = k;
L2_attach_weight2mat.FLx_i_location_area = i;
L2_attach_weight2mat.FLx_j_location_depth = j;
L2_attach_weight2mat.Xattach_weight2mat();
}
}
L2_visual_all_feature += 0.5f;
imshow("L2_visual_all_feature", L2_visual_all_feature);
waitKey(1);
}///Visual now end
else
{
visualL2_now_counter++;
}
///Show L2toL1
static int visuL2L1_now_counter=1000;
if(visuL2L1_now_counter>50)
{
visuL2L1_now_counter=0;
///visualize_L2toL1 = Scalar(0.5,0.5,0.5);
sq_visualize_L2toL1 = Scalar(0.5,0.5,0.5);
///float* zero_ptr_visualize_L2toL1 = visualize_L2toL1.ptr<float>(0);
///float* index_ptr_visualize_L2toL1 = visualize_L2toL1.ptr<float>(0);
float* zero_ptr_sq_visualize_L2toL1 = sq_visualize_L2toL1.ptr<float>(0);
float* index_ptr_sq_visualize_L2toL1 = sq_visualize_L2toL1.ptr<float>(0);
int temp_offset=0;
int sq_temp_offset=0;
/// visualize_L2toL1.create((FL2_srt_size*pool_sqr + FL1_srt_size-1) , (FL2_srt_size*pool_sqr + FL1_srt_size-1)*L2_conv_depth, CV_32FC3);
///sq_visualize_L2toL1.create((FL2_srt_size*pool_sqr + FL1_srt_size-1)*sqr_L2_conv_depth_plus1 , (FL2_srt_size*pool_sqr + FL1_srt_size-1)*sqr_L2_conv_depth_plus1, CV_32FC3);
int show_node_patch_width_C1 = (FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1);
int show_node_patch_hight_C1 = (FL2_srt_size*pool_sqr + (FL1_srt_size-1)/2 +1);
///Show now L2toL1
for(int k=0; k<L2_conv_depth; k++)
{
for(int j2=0; j2<FL2_depth; j2++) ///L1_conv_depth = FL2_depth
{
for(int i2=0; i2<FL2_srt_size*FL2_srt_size; i2++)
{
for(int j1=0; j1<FL1_depth; j1++)
{
for(int i1=0; i1<FL1_srt_size*FL1_srt_size;i1++)
{
/// temp_offset = show_node_patch_width_C1*FL1_depth*k;///Add the start left corner colum offset for the show of L2 hidden node patch
/// temp_offset += (i2%FL2_srt_size)*FL1_depth*pool_sqr;///horizontal inc pos regarding horiz inc on FL2 horiz pos
/// temp_offset += (i1%FL1_srt_size)*FL1_depth + j1;///horizontal inc pos regarding horiz inc on FL1 horiz pos
/// temp_offset += visualize_L2toL1.cols*FL1_depth*(i2/FL2_srt_size)*pool_sqr;///Vertical inc pos regarding FL2 vertical pos
/// temp_offset += visualize_L2toL1.cols*FL1_depth*(i1/FL1_srt_size);///Vertical inc pos regarding FL1 vertical pos
/// index_ptr_visualize_L2toL1 = zero_ptr_visualize_L2toL1 + temp_offset;
/// *index_ptr_visualize_L2toL1 += L1_weight_matrix_M[j1 + i1*FL1_depth][j2] * L2_weight_matrix_M[i2 + (FL2_srt_size * FL2_srt_size)*j2][k];
sq_temp_offset = show_node_patch_width_C1*FL1_depth*(k%sqr_L2_conv_depth_plus1) + sq_visualize_L2toL1.cols*FL1_depth*show_node_patch_hight_C1*(k/sqr_L2_conv_depth_plus1);///Add the start left corner colum offset for the show of L2 hidden node patch
sq_temp_offset += (i2%FL2_srt_size)*FL1_depth*pool_sqr;///horizontal inc pos regarding horiz inc on FL2 horiz pos
sq_temp_offset += (i1%FL1_srt_size)*FL1_depth + j1;///horizontal inc pos regarding horiz inc on FL1 horiz pos
sq_temp_offset += sq_visualize_L2toL1.cols*FL1_depth*(i2/FL2_srt_size)*pool_sqr;///Vertical inc pos regarding FL2 vertical pos
sq_temp_offset += sq_visualize_L2toL1.cols*FL1_depth*(i1/FL1_srt_size);///Vertical inc pos regarding FL1 vertical pos
index_ptr_sq_visualize_L2toL1 = zero_ptr_sq_visualize_L2toL1 + sq_temp_offset;
*index_ptr_sq_visualize_L2toL1 += L1_weight_matrix_M[j1 + i1*FL1_depth][j2] * L2_weight_matrix_M[i2 + (FL2_srt_size * FL2_srt_size)*j2][k];
}
}
}
}
}
/// imshow("visualize_L2toL1", visualize_L2toL1);
imshow("sq_visualize_L2toL1", sq_visualize_L2toL1);
}
else
{
visuL2L1_now_counter++;
}
///End L2tL1 show
}
///**************** End L2 Autoencoder *****************
///**************** End L2 Convloution *****************
if(comon_func_Obj1.L2_convolution_ON == 1)/// Do convloution L2 process instead of L2 Autoencoder process
{
///**********************************
///********* Convolute L2 ***********
///**********************************
for(int i=0; i<(L2_conv_hight * L2_conv_width); i++)///This loop step throue (convolute) the area of the input "sheet". No padding of the slide on one sheet area of the convolution cube
{
for(int j=0; j<L2_conv_depth; j++)///This loop step throue the depth of the Convolution L1 cube
{
L2_conv_cube[i][j] = 0.0f;///Clear the one node of the conv cube
//int input_ptr_offset;
float input_node;
for(int k=0; k<FL2_size; k++)///This loop step throue one Feature cube. FL2_size = (FL2_srt_size * FL2_srt_size * FL2_depth) The size of one Feature FL2
{
///L1_pool_cube[area][depth]
input_node = L1_pool_cube[(L1_conv_hight/pool_sqr)*((i/L2_conv_width) + (k/(FL2_srt_size * FL2_depth))) + (i%L2_conv_width) + (k/FL2_depth)%FL2_srt_size][k%FL2_depth];
L2_conv_cube[i][j] += L2_weight_matrix_M[k][j] * input_node;///Make the dot product of the 0..x Feature * input image to L1 convolution cube
}
}
}
///**************************************
///********* End Convolute L2 ***********
///**************************************
///**************************************
///********* Pooling L2 *****************
///**************************************
for(int h=0; h<(L2_conv_hight / pool_sqr); h++)///This loop togheter with i loop step throue the "sheet" area of of the L1_pool_cube[i][x]
{
for(int i=0; i<(L2_conv_width / pool_sqr); i++)///This loop togheter with h loop step throue the "sheet" area of of the L1_pool_cube[i][x]
{
for(int j=0; j<L2_conv_depth; j++)///This loop step throue the depth of the Convolution L1 cube
{
float max_node= -1000000.0f;
float compare_max = 0.0f;
int revers_pool_row=0;
for(int p=0; p<pooling; p++)
{
revers_pool_row = p/pool_sqr;///Get a pool row level inside the pooling area to make it poosible to read the right row position on the convolution sheet area
///compare_max = L1_conv_cube[h * pool_sqr * L1_conv_width + L1_conv_width * revers_pool_row + i * pool_sqr + p % pool_sqr][j];///Prepare pooling compare value. Pick the value from the convolute (slide) position node at convolution cube
compare_max = L2_conv_cube[h * pool_sqr * L2_conv_width + L2_conv_width * revers_pool_row + i * pool_sqr + p%pool_sqr][j];///Prepare pooling compare value. Pick the value from the convolute (slide) position node at convolution cube
if(compare_max > max_node)
{
L2_pool_tracking = p;
max_node = compare_max;
}
}
///*** Relu this node ***
if(max_node < 0.0f)
{
max_node = max_node * Relu_neg_gain;///Relu function
}
L2_pool_cube[h*(L2_conv_hight / pool_sqr) + i][j] = max_node;
}
/// Pooling of this convolute (slide) position is now done throue the full depth of nodes at L1_conv_cube[][] and L1_pool_cube[h*i][j]
/// h, i, pooltracking gives the convolute (slide) position to prepare the input patch/part for the autoencoder compare to reconstruction
}
}
///**************************************
///********* END Pooling L2 *************
///**************************************
///show one layer of conv L2
///void show_sheet_2_mat(float* cube, int show_layer_nr, Mat dst)
L2_test1_ptr = L2_test1_zero_ptr;
L2_test2_ptr = L2_test2_zero_ptr;
L2_test3_ptr = L2_test3_zero_ptr;
for(int i=0; i<L2_conv_hight*L2_conv_width; i++)
{
*L2_test1_ptr = L2_conv_cube[i][0];
L2_test1_ptr++;
*L2_test2_ptr = L2_conv_cube[i][1];
L2_test2_ptr++;
*L2_test3_ptr = L2_conv_cube[i][2];
L2_test3_ptr++;
}
// printf("L1_conv_hight*L1_conv_width %d\n", L1_conv_hight*L1_conv_width);
// printf("test.cols*test.channels() * test.rows %d\n", test.cols*test.channels() * test.rows);
L2_test1 += 0.5f;///Scalar(0.5);
L2_test2 += 0.5f;///Scalar(0.5);
L2_test3 += 0.5f;///Scalar(0.5);
imshow("L2_test1", L2_test1);
imshow("L2_test2", L2_test2);
imshow("L2_test3", L2_test3);
L2_pol_t1_ptr = L2_pol_t1_zero_ptr;
L2_pol_t2_ptr = L2_pol_t2_zero_ptr;
L2_pol_t3_ptr = L2_pol_t3_zero_ptr;
for(int i=0; i<(L2_conv_hight*L2_conv_width/pooling); i++)
{
*L2_pol_t1_ptr = L2_pool_cube[i][0];
L2_pol_t1_ptr++;
*L2_pol_t2_ptr = L2_pool_cube[i][1];
L2_pol_t2_ptr++;
*L2_pol_t3_ptr = L2_pool_cube[i][2];
L2_pol_t3_ptr++;
}
L2_pol_t1 += 0.5f;
L2_pol_t2 += 0.5f;
L2_pol_t3 += 0.5f;
imshow("L2_pol_t1", L2_pol_t1);
imshow("L2_pol_t2", L2_pol_t2);
imshow("L2_pol_t3", L2_pol_t3);
} ///End convloution L2 process
///L3
int do_noise=0;
if(comon_func_Obj1.L3_autoencoder_ON == 1)///Do Autoencoder L3 process (Not L3 Convolution process)
{
///******************************************
///********* Autoencoder L3 process *********
///******************************************
int L3_rand_x_start_pos=0;
int L3_rand_y_start_pos=0;
for(int ittr=0; ittr<L3_nr_of_autoenc_ittr_1_image; ittr++)
{
if(L3_conv_width>FL3_srt_size && L3_conv_hight>FL3_srt_size)
{
L3_rand_x_start_pos = (int) (rand() % (L3_conv_width-1));///-1 because then it fit exactly between Feature and Convolution
L3_rand_y_start_pos = (int) (rand() % (L3_conv_hight-1));
do_noise = 1;
comon_func_Obj1.L3_rand_input_data_pos();///Make a table (comon_func_Obj1.L3_nr_of_positions) of randomized position inside FL2 feature size
}
else
{
L3_rand_x_start_pos = 0;
L3_rand_y_start_pos = 0;
do_noise = 0;
}
///Get a patch vector from L2_pool_cube and run it thoue the autoencoder
///Insert noise on L3_patch_vect[][]
float pool_temporary;
//int addr_offset;
int test=0;
for(int j=0; j<FL3_depth; j++)
{
for(int i=0; i<(FL3_srt_size * FL3_srt_size); i++)///comon_func_Obj1.L2_nr_of_positions = FL2_size;///Size of the FL2_size = FL2_srt_size * FL2_srt_size * FL2_depth
{
//addr_offset = (L1_conv_width/pool_sqr) * (rand_y_start_pos + i/FL2_srt_size) + rand_x_start_pos + i%FL2_srt_size;
// test = (L2_conv_width/pool_sqr) * (L3_rand_y_start_pos + i/FL3_srt_size) + L3_rand_x_start_pos + i%FL3_srt_size;
// printf("test %d\n", test);
pool_temporary = L2_pool_cube[(L2_conv_width/pool_sqr) * (L3_rand_y_start_pos + i/FL3_srt_size) + L3_rand_x_start_pos + i%FL3_srt_size][j];
// pool_temporary = L2_pool_cube[i][j];
///L3_patch_vect[area][depth]
L3_patch_vect[i][j] = pool_temporary;///Insert real data from input vector
if(comon_func_Obj1.L3_noise_pos[i + (FL3_srt_size * FL3_srt_size)*j] == 1 && do_noise == 1)
{
///****************************************************
///********** Select noise level ******************
///****************************************************
noise = (float) (rand() % 65535) / 65536;//0..1.0 range
noise -= 0.5f;
noise = noise * noise_amplitude;
noise += 0.5f;
noise += noise_offset;
L3_noise_vect[i][j] = noise;///Insert noise instead of real value
}
else
{
///Insert a small region of the input vector
L3_noise_vect[i][j] = pool_temporary;///Insert real data from input vector
}
}
}
///*********** Forward to hidden nodes ****************
///Make autoencoder forward of FL3 feature
for(int k=0; k<L3_conv_depth; k++)
{
L3_conv_cube[0][k] = 0.0f;///Clear autoencoder hidden node (hidden node = Lx_conv_cube[0][depth] ). [0] because we borrow L1_conv_cube mem this first area sheet pos in the convoution memory area now only for autencoder
for(int j=0; j<FL3_depth; j++)
{
for(int i=0; i<(FL3_srt_size * FL3_srt_size); i++)
{
L3_conv_cube[0][k] += L3_noise_vect[i][j] * L3_weight_matrix_M[i + (FL3_srt_size * FL3_srt_size)*j][k];///Make the dot product to pruduce the node.[0] because we borrow L1_conv_cube mem this first area sheet pos in the convoution memory area now only for autencoder
}
///*** Relu this node ***
if(L3_conv_cube[0][k] < 0.0f)
{
L3_conv_cube[0][k] = L3_conv_cube[0][k] * Relu_neg_gain;///Relu function
}
}
}
///********** Forward to L3 output nodes *******************
///Clear the L3_autoenc_reconstructed
for(int j=0; j<FL3_depth; j++)
{
for(int i=0; i<(FL3_srt_size * FL3_srt_size); i++)
{
L3_autoenc_reconstructed[i][j] = 0.0f;///Clear
}
}
///Make autoencoder reconstruction
for(int k=0; k<L3_conv_depth; k++)
{
for(int j=0; j<FL3_depth; j++)
{
for(int i=0; i<(FL3_srt_size * FL3_srt_size); i++)
{
L3_autoenc_reconstructed[i][j] += L3_conv_cube[0][k] * L3_weight_matrix_M[i + (FL3_srt_size * FL3_srt_size)*j][k];///Reconstruction using the autoencoder tie weight. L1_conv_cube[0][j] is the hidden node of the autoencoder
}
}
}
///Make the autoencoder loss and delta calculation
static float L3_loss=0.0f;
float L3_delta=0.0f;
float L3_output_node=0.0f;
for(int j=0; j<FL3_depth; j++)
{
for(int i=0; i<(FL3_srt_size * FL3_srt_size); i++)
{
//L2_delta = *index_ptr_L1_patch_img - *index_ptr_L1_autoenc_reconstructed;
L3_output_node = L3_autoenc_reconstructed[i][j];
L3_delta = L3_patch_vect[i][j] - L3_output_node ;
L3_loss += L3_delta * L3_delta;/// loss = 1/2 SUM k (input[k] - ouput[k])²
/// if(L3_output_node < 0.0f)///
/// {
/// L3_delta *= Relu_neg_gain;
/// }
L3_autoenc_delta[i][j] = L3_delta;
}
}
///make the backpropagation
for(int k=0; k<L3_conv_depth; k++)
{
for(int j=0; j<FL3_depth; j++)
{
for(int i=0; i<(FL3_srt_size * FL3_srt_size); i++)
{
/// **** update tied weight regarding delta
L3_change_weight_M[i + (FL3_srt_size * FL3_srt_size)*j][k] = L3_LearningRate * L3_conv_cube[0][k] * (L3_autoenc_delta[i][j]) + L3_Momentum * L3_change_weight_M[i + (FL3_srt_size * FL3_srt_size)*j][k];///hidden_node = L3_conv_cube[0][j];
L3_weight_matrix_M[i + (FL3_srt_size * FL3_srt_size)*j][k] += L3_change_weight_M[i + (FL3_srt_size * FL3_srt_size)*j][k];
}
}
}
///Print Loss
static int L3_print_loss=0;
if(L3_print_loss<200)
{
L3_print_loss++;
}
else
{
L3_loss = L3_loss / 2.0f;/// loss = 1/2 SUM k (input[k] - ouput[k])²
printf("L3 autoencoder L3_loss error = %f\n", L3_loss);
L3_print_loss=0;
L3_loss=0.0f;
}
///End print loss
}///End ittr loop
///L3 visual
static int visualL3_now_counter=1000;
if(visualL3_now_counter > 100)
{
visualL3_now_counter=0;
printf("show L3\n");
L3_attach_weight2mat.Lx_src = L3_visual_all_feature;///attach Mat pointer
for(int j=0; j<FL3_depth; j++)
{
for(int i=0; i<(FL3_srt_size * FL3_srt_size); i++)
{
L3_attach_weight2mat.Lx_ptr_M_matrix = &L3_weight_matrix_M[i + (FL3_srt_size * FL3_srt_size)*j][0];
/// L3_attach_weight2mat.k = k;
L3_attach_weight2mat.FLx_i_location_area = i;
L3_attach_weight2mat.FLx_j_location_depth = j;
L3_attach_weight2mat.Xattach_weight2mat();
}
}
L3_visual_all_feature += 0.5f;
imshow("L3_visual_all_feature", L3_visual_all_feature);
waitKey(1);
}///Visual now end
else
{
visualL3_now_counter++;
}
///Show L3toL1
static int visuL3L1_now_counter=100000;
if(visuL3L1_now_counter>1000)
{
visuL3L1_now_counter=0;
/// visualize_L3toL1 = Scalar(0.5,0.5,0.5);
sq_visualize_L3toL1 = Scalar(0.5,0.5,0.5);
/// float* zero_ptr_visualize_L3toL1 = visualize_L3toL1.ptr<float>(0);
/// float* index_ptr_visualize_L3toL1 = visualize_L3toL1.ptr<float>(0);
float* zero_ptr_sq_visualize_L3toL1 = sq_visualize_L3toL1.ptr<float>(0);
float* index_ptr_sq_visualize_L3toL1 = sq_visualize_L3toL1.ptr<float>(0);
int temp_offset=0;
int sq_temp_offset=0;
int show_node_patch_width_C1 = L3toL2toL1_feature_revers_size;
int show_node_patch_hight_C1 = L3toL2toL1_feature_revers_size;
///Show now L3toL1
for(int k3=0; k3<L3_conv_depth; k3++)
{
for(int k2=0; k2<L2_conv_depth; k2++)///L2_conv_depth = FL3_depth
{
for(int i3=0; i3<FL3_srt_size*FL3_srt_size; i3++)
{
for(int j2=0; j2<FL2_depth; j2++) ///L1_conv_depth = FL2_depth
{
for(int i2=0; i2<FL2_srt_size*FL2_srt_size; i2++)
{
for(int j1=0; j1<FL1_depth; j1++)
{
for(int i1=0; i1<FL1_srt_size*FL1_srt_size; i1++)
{
///Add the start left corner colum offset for the show of L3 hidden node patch
sq_temp_offset = show_node_patch_width_C1*FL1_depth*(k3%sqr_L3_conv_depth_plus1) + sq_visualize_L3toL1.cols*FL1_depth*show_node_patch_hight_C1*(k3/sqr_L3_conv_depth_plus1);
sq_temp_offset += (i3%FL3_srt_size)*FL1_depth*pool_sqr*pool_sqr;///horizontal inc pos regarding horiz inc on FL3 horiz pos
sq_temp_offset += (i2%FL2_srt_size)*FL1_depth*pool_sqr;///horizontal inc pos regarding horiz inc on FL2 horiz pos
sq_temp_offset += (i1%FL1_srt_size)*FL1_depth + j1;///horizontal inc pos regarding horiz inc on FL1 horiz pos
sq_temp_offset += sq_visualize_L3toL1.cols*FL1_depth*(i3/FL3_srt_size)*pool_sqr*pool_sqr;///Vertical inc pos regarding FL3 vertical pos
sq_temp_offset += sq_visualize_L3toL1.cols*FL1_depth*(i2/FL2_srt_size)*pool_sqr;///Vertical inc pos regarding FL2 vertical pos
sq_temp_offset += sq_visualize_L3toL1.cols*FL1_depth*(i1/FL1_srt_size);///Vertical inc pos regarding FL1 vertical pos
index_ptr_sq_visualize_L3toL1 = zero_ptr_sq_visualize_L3toL1 + sq_temp_offset;
*index_ptr_sq_visualize_L3toL1 += L1_weight_matrix_M[i1*FL1_depth + j1][j2] * L2_weight_matrix_M[i2 + (FL2_srt_size * FL2_srt_size)*j2][k2] * L3_weight_matrix_M[i3 + (FL3_srt_size * FL3_srt_size)*k2][k3];
}
}
}
}
}
}
printf("k3=%d\n", k3);
imshow("sq_visualize_L3toL1", sq_visualize_L3toL1);
waitKey(1);
}
/// imshow("visualize_L2toL1", visualize_L2toL1);
// imshow("sq_visualize_L3toL1", sq_visualize_L3toL1);
}
else
{
visuL3L1_now_counter++;
}
///End L3tL1 show
}
waitKey(1);
comon_func_Obj1.keyboard_event();///Check keyboard event
if(comon_func_Obj1.started==0)
{
waitKey(2000);
}
if(comon_func_Obj1.save_L1_weights==1)
{
comon_func_Obj1.save_L1_weights=0;
///L1 save weights
//Save weights
sprintf(filename, "L1_weight_matrix_M.dat");//Assigne a filename with index number added
fp2 = fopen(filename, "w+");
if (fp2 == NULL)
{
printf("Error while opening file L1_weight_matrix_M.dat");
exit(0);
}
//size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
ix=0;
for(int n=0; n<L1_conv_depth; n++)
{
for(int p=0; p<FL1_size; p++)
{
f_data[ix] = L1_weight_matrix_M[p][n];
ix++;
}
}
fwrite(f_data, sizeof f_data[0], (FL1_size*L1_conv_depth), fp2);
fclose(fp2);
printf("weights are saved at L1_weight_matrix_M.dat file\n");
///End L1 save weights
///L2 save weights
//Save weights
sprintf(filename, "L2_weight_matrix_M.dat");//Assigne a filename with index number added
fp2 = fopen(filename, "w+");
if (fp2 == NULL)
{
printf("Error while opening file L2_weight_matrix_M.dat");
exit(0);
}
//size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
ix=0;
for(int n=0; n<L2_conv_depth; n++)
{
for(int p=0; p<FL2_size; p++)
{
f2_data[ix] = L2_weight_matrix_M[p][n];
ix++;
}
}
fwrite(f2_data, sizeof f2_data[0], (FL2_size*L2_conv_depth), fp2);
fclose(fp2);
printf("weights are saved at L2_weight_matrix_M.dat file\n");
///End L2 save weights
///L3 save weights
//Save weights
sprintf(filename, "L3_weight_matrix_M.dat");//Assigne a filename with index number added
fp2 = fopen(filename, "w+");
if (fp2 == NULL)
{
printf("Error while opening file L3_weight_matrix_M.dat");
exit(0);
}
//size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
ix=0;
for(int n=0; n<L3_conv_depth; n++)
{
for(int p=0; p<FL3_size; p++)
{
f3_data[ix] = L3_weight_matrix_M[p][n];
ix++;
}
}
fwrite(f3_data, sizeof f3_data[0], (FL3_size*L3_conv_depth), fp2);
fclose(fp2);
printf("weights are saved at L3_weight_matrix_M.dat file\n");
///End L3 save weights
}///End save Lx
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment