Skip to content

Instantly share code, notes, and snippets.

@ollewelin
Last active May 24, 2017 15:58
Show Gist options
  • Save ollewelin/5d88ab7406690ec7414be568004e83b0 to your computer and use it in GitHub Desktop.
Save ollewelin/5d88ab7406690ec7414be568004e83b0 to your computer and use it in GitHub Desktop.
Autoencoder test on MNIST data
//Test2 improved and also show (visualize) the noise input stimulu
//Autoencoder learning test with raspicam
//press <Y> at start It's tested with 0..9 28x28 pixel digits pattern mnist.png filname 289x289 orginal
//orginal image taken from
// https://blog.webkid.io/datasets-for-machine-learning/
//#define USE_RASPICAM_INPUT //If you want to use raspicam input data
#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>
char filename[100];
char filename2[100];
char filename_dst[100];
using namespace std;
using namespace cv;
//const float LearningRate =0.05;
//const float Momentum = 0.025;
const float LearningRate =0.02;
const float Momentum = 0.00;
// float noise_percent =50.0f;
float noise_percent =40.0f;
float noise_amplitude = 1.0f;
//float noise_offset = -0.5f;
float noise_offset = 0.0f;
//#define USE_IND_NOISE
float start_noise_range = 0.025f;//+/- Weight startnoise range
float noise = 0.0f;
const int MNIST_hidd_node = 60;
const int MNIST_nr_pic = 80;
void sigmoid_mat(Mat image)
{
float* ptr_src_index;
ptr_src_index = image.ptr<float>(0);
int nRows = image.rows;
int nCols = image.cols;
for(int i=0;i<nRows;i++)
{
for(int j=0;j<nCols;j++)
{
*ptr_src_index = 1.0/(1.0 + exp(-(*ptr_src_index)));//Sigmoid function
ptr_src_index++;
}
}
}
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;
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;
}
void local_normalizing(Mat gray)
{
#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);
//imshow("demo", gray);
}
//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 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);
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++;
}
}
int main()
{
float Rando=0.0f;
// float start_noise_range = 0.25f;//+/- start weight noise range
printf("Auto encoder test program\n");
//int get_data =0;
int Height=0;
int Width=0;
int nr_of_pixels=0;
int Hidden_nodes=0;
int nr_of_pictures=0;
int training_image=0;
char answer_character;
printf("Do you want default settings <Y>/<N> ? \n");
answer_character = getchar();
if(answer_character == 'Y' || answer_character == 'y')
{
// Height = 48;
// Width = 64;
Height = 28;
Width = 28;
Hidden_nodes = MNIST_hidd_node;
nr_of_pictures = MNIST_nr_pic;
}
else
{
printf("Enter number of pixel Height of input pictures\n");
scanf("%d", &Height);
printf("Enter number of pixel Width of input pictures\n");
scanf("%d", &Width);
printf("Enter number of hidden nodes of input pictures\n");
scanf("%d", &Hidden_nodes);
printf("Enter number of hidden training pictures posXXX.JPG \n");
scanf("%d", &nr_of_pictures);
}
nr_of_pixels = Height * Width;
printf("Number of pixels = %d\n", nr_of_pixels);
Mat src, image, mnist,m_gray;
///************** Raspicam **************
#ifdef USE_RASPICAM_INPUT
raspicam::RaspiCam_Cv Camera;
Camera.set( CV_CAP_PROP_FRAME_WIDTH, Width);
Camera.set( CV_CAP_PROP_FRAME_HEIGHT, Height);
Camera.set( CV_CAP_PROP_FORMAT, CV_8UC1 );
//Camera.set( CV_CAP_PROP_FORMAT, CV_8U );
//Open camera
cout<<"Opening Camera..."<<endl;
if (!Camera.open()) {cerr<<"Error opening the camera"<<endl;return -1;}
Camera.grab();
Camera.retrieve (src);
waitKey(1);
src.convertTo(image, CV_32F, 1.0/255.0);//Convert pixels from 0..255 char to float 0..1
#endif // USE_RASPICAM_INPUT
///***************************************
#ifndef USE_RASPICAM_INPUT
///************Open mnist image ********
sprintf(filename2, "mnist_480_360.jpg");//Assigne a filename "pos" with index number added
sprintf(filename2, "mnist.png");//Assigne a filename "pos" with index number added
mnist = imread( filename2, 1 );
if ( !mnist.data )
{
printf("\n");
printf("==================================================\n");
printf("No image data Error! Probably not find mnist_480_360.jpg \n");
printf("==================================================\n");
printf("\n");
//return -1;
}
cvtColor(mnist,m_gray,CV_BGR2GRAY);
imshow("m_gray", m_gray);
waitKey(1);
int mnist_h1 = 28;
int mnist_w1 = 28;
int mnh=0;
int mnw=0;
int pos = 0;
int ret;
// Mat m1;
for(int j=0;j<8;j++)
{
for(int i=0;i<10;i++)
{
// Mat m1(image, Rect(0, 0, T0_FRAME_WIDTH, T0_FRAME_HEIGHT));// Rect(<start_x>, <start_y>, <width>, <hight>)
//48 x 45
mnh = j*mnist_h1+j*1;
mnw = i*mnist_w1+i*1;
Mat m1(m_gray, Rect(mnw, mnh, mnist_w1, mnist_h1));// Rect(<start_x>, <start_y>, <width>, <hight>)
cv::imwrite("temporary_file.JPG",m1);
sprintf(filename_dst, "pos%d.JPG", pos);
ret = rename("temporary_file.JPG", filename_dst);
if(ret == 0)
{
printf("File renamed successfully");
}
else
{
printf("Error: unable to rename the file");
}
pos++;
}
}
///*************************************
#endif // USE_RASPICAM_INPUT
// mat_H =
float *input_node;
input_node = new float[nr_of_pixels];
float *hidden_node;
hidden_node = new float[Hidden_nodes];
float *output_node;
output_node = new float[nr_of_pixels];
float **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 **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.
weight_matrix_M = new float *[nr_of_pixels];
change_weight_M = new float *[nr_of_pixels];
for(int i=0; i < nr_of_pixels; i++)
{
weight_matrix_M[i] = new float[Hidden_nodes];
change_weight_M[i] = new float[Hidden_nodes];
}
printf("size of weight_matrix_M[2][0] =%d\n", sizeof weight_matrix_M[2][0]);
int sqr_of_H_nod_plus1=0;
sqr_of_H_nod_plus1 = sqrt(Hidden_nodes);
sqr_of_H_nod_plus1 += 1;
printf("sqr_of_H_nod_plus1 %d\n", sqr_of_H_nod_plus1);
float* ptr_M_matrix;
Mat visual_all_feature, outimg;
visual_all_feature.create(Height * sqr_of_H_nod_plus1, Width * sqr_of_H_nod_plus1,CV_32F);
outimg.create(Height, Width, CV_32F);
srand (static_cast <unsigned> (time(0)));//Seed the randomizer
for(int i=0;i<nr_of_pixels;i++)
{
ptr_M_matrix = &weight_matrix_M[i][0];
for(int j=0;j<(Hidden_nodes);j++)
{
Rando = (float) (rand() % 65535) / 65536;//0..1.0 range
Rando -= 0.5f;
Rando *= start_noise_range;
*ptr_M_matrix = Rando;
ptr_M_matrix++;
change_weight_M[i][j] = 0.0f;
}
}
for(int i=0;i<nr_of_pixels;i++)
{
ptr_M_matrix = &weight_matrix_M[i][0];
attach_weight_2_mat(ptr_M_matrix, i, visual_all_feature, sqr_of_H_nod_plus1, Hidden_nodes, Height, Width);
}
// local_normalizing(visual_all_feature);
//test on
visual_all_feature += 0.5f;
Mat color_img, gray, noised_input;
srand (static_cast <unsigned> (time(0)));//Seed the randomizer
noised_input.create(Height, Width, CV_32F);
float error=0.0;
float *zero_ptr_gray = gray.ptr<float>(0);
float *ptr_gray = gray.ptr<float>(0);
float *ptr_noised_inp = noised_input.ptr<float>(0);
float *zero_ptr_noised_inp = noised_input.ptr<float>(0);
ptr_gray = zero_ptr_gray + (gray.cols * (gray.rows/2)) + gray.cols/2;
float test_pixel_value = *ptr_gray;
int *noise_pixels;
noise_pixels = new int[nr_of_pixels];
int noise_p_counter=0;
float noise_ratio=0.0f;
int nr_of_noise_rand_ittr=0;
int rand_pix_pos=0;
char keyboard;
int started = 1;
while(1)
{
#ifdef USE_RASPICAM_INPUT
Camera.grab();
Camera.retrieve (src);
waitKey(1);
src.convertTo(image, CV_32F, 1.0/255.0);//Convert pixels from 0..255 char to float 0..1
imshow("image", image);
gray = image;//Connect raspberry camera instead of posXXX.jpg image
#else
training_image = rand() % nr_of_pictures;
// printf("training_image %d\n", training_image);
sprintf(filename, "pos%d.JPG", training_image);//Assigne a filename "pos" with index number added
color_img = imread( filename, 1 );
if ( !color_img.data )
{
printf("\n");
printf("==================================================\n");
printf("No image data Error! Probably not find pos%d.JPG \n", training_image);
printf("==================================================\n");
printf("\n");
//return -1;
}
cvtColor(color_img,gray,CV_BGR2GRAY);
imshow("color_img", color_img);
gray.convertTo(gray, CV_32F, 1.0/255.0);//Convert pixels from 0..255 char to float 0..1
#endif // USE_RASPICAM_INPUT
// local_normalizing(gray);
sigmoid_mat(gray);
zero_ptr_gray = gray.ptr<float>(0);
ptr_gray = gray.ptr<float>(0);
///******************************************************
///************ Select noise pixels positions ***********
///******************************************************
noise_p_counter=0;
noise_ratio=0.0f;
nr_of_noise_rand_ittr=0;
rand_pix_pos=0;
for(int n=0;n<nr_of_pixels;n++)
{
noise_pixels[n] = 0;
}
while(noise_ratio < (noise_percent*0.01f))
{
rand_pix_pos = (int) (rand() % nr_of_pixels);
if(noise_pixels[rand_pix_pos] == 0)
{
noise_p_counter++;
}
noise_pixels[rand_pix_pos] = 1;
noise_ratio = ((float)noise_p_counter) / ((float)nr_of_pixels);
nr_of_noise_rand_ittr++;
if(nr_of_noise_rand_ittr > 2*nr_of_pixels)
{
printf("give up fill random up noise this turn\n");
printf("noise_ratio %f\n", noise_ratio);
break;
}
}
#ifndef USE_IND_NOISE
///****************************************************
///********** 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;
#endif // USE_IND_NOISE
///****************************************************
///**************** Feed forward **********************
///****************************************************
///Connect image pixel and also insert noise to input_node[]
for(int n=0;n<nr_of_pixels;n++)
{
if(noise_pixels[n] == 1 && started == 1)
{
#ifdef USE_IND_NOISE
///****************************************************
///********** 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;
#endif // USE_IND_NOISE
input_node[n] = noise;///Insert noise 0.5f instead of real pixel value
}
else
{
ptr_gray = zero_ptr_gray + n;
input_node[n] = *ptr_gray;///Insert pixel value
}
ptr_noised_inp = zero_ptr_noised_inp + n;
*ptr_noised_inp = input_node[n];//To show
}
imshow("noised_input ", noised_input);
///*********** Forward to hidden nodes ****************
for(int j=0;j<Hidden_nodes;j++)
{
hidden_node[j] = 0;
for(int i=0;i<nr_of_pixels;i++)
{
hidden_node[j] += input_node[i] * weight_matrix_M[i][j];///Sum up values from input gained with weight
}
///*** Sigmoid this node ***
hidden_node[j] = 1.0/(1.0 + exp(-(hidden_node[j])));///Sigmoid function
}
///********** Forward to output nodes *******************
for(int i=0;i<nr_of_pixels;i++)
{
output_node[i] = 0.0f;
for(int j=0;j<Hidden_nodes;j++)
{
output_node[i] += hidden_node[j] * weight_matrix_M[i][j];///Sum up values from hidden gained with weight
}
output_node[i] = 1.0/(1.0 + exp(-(output_node[i])));///Sigmoid function
}
float input_pixel =0.0f;
///****************************************************
///************* Calculate total loss *****************
///****************************************************
/// k = nr_of_pixel
/// loss = -SUM k (output[k] * log(input[k]) + (1.0 - output[k]) * log(1.0 - input[k]))
/// or
/// loss = 1/2 SUM k (input[k] - ouput[k])²
float loss=0.0f;
loss=0.0f;
for(int i=0;i<nr_of_pixels;i++)
{
ptr_gray = zero_ptr_gray + i;///pick real input pixel
input_pixel = *ptr_gray;///Insert pixel value
loss += (input_pixel - output_node[i]) * (input_pixel - output_node[i]);/// loss = 1/2 SUM k (input[k] - ouput[k])²
}
static int print_loss=0;
if(print_loss<10)
{
print_loss++;
}
else
{
printf("loss error = %f\n", loss);
print_loss=0;
}
///****************************************************
///**************** Backpropagation *******************
///****************************************************
/// **** make Delta value for backpropagation and loss calculation ****
float delta_pixel=0.0f;
for(int i=0;i<nr_of_pixels;i++)
{
ptr_gray = zero_ptr_gray + i;///pick real input pixel
input_pixel = *ptr_gray;///Insert pixel value
delta_pixel = input_pixel - output_node[i] ;/// detal calculus
/// **** update tied weight regarding delta
for(int j=0;j<Hidden_nodes;j++)
{
if(started == 1)
{
change_weight_M[i][j] = LearningRate * hidden_node[j] * delta_pixel + Momentum * change_weight_M[i][j];
weight_matrix_M[i][j] += change_weight_M[i][j];
}
}
}
float *zero_ptr_outimg = outimg.ptr<float>(0);
float *ptr_outimg = outimg.ptr<float>(0);
for(int i=0;i<nr_of_pixels;i++)
{
ptr_outimg = zero_ptr_outimg + i;
*ptr_outimg = output_node[i];
}
// gray -= 0.5;
outimg -= 0.5;
visual_all_feature -= 0.5;
// gray *= 2;
outimg *= 2;
visual_all_feature *= 2;
// gray += 0.5;
outimg += 0.5;
visual_all_feature += 0.5;
for(int i=0;i<nr_of_pixels;i++)
{
ptr_M_matrix = &weight_matrix_M[i][0];
attach_weight_2_mat(ptr_M_matrix, i, visual_all_feature, sqr_of_H_nod_plus1, Hidden_nodes, Height, Width);
}
visual_all_feature += 0.5f;
imshow("visual_all_feature", visual_all_feature);
imshow("gray", gray);
imshow("outimg", outimg);
waitKey(1);
///******** start stop
if(kbhit()){
keyboard = getchar();
if(keyboard== ' ')
{
if(started == 1)
{
started = 0;
printf("Stop training\n");
}
else
{
started = 1;
printf("Start training\n");
}
}
}
///***************
if(started == 0)
{
waitKey(2000);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment