Last active
July 27, 2017 21:09
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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