void CrossValidation::k10folder(const char* folder_path) { //split samples to 10 folder std::vector<Matrix<float>> folder_10_samples(10); //sample matrix in every folder std::vector<Matrix<float>> folder_10_labels(10); //label matrix in every folder std::vector<int> folder_10_num(10); //sample number in every folder std::vector<std::vector<int>> folder_10_index(10); //sample index in every folder int samples_num = m_samples.rows(); //total sample number int samples_dim = m_samples.cols(); //sample dimension //finding sample index with different label std::map<int,std::vector<int>> labels_map; for (int i = 0; i < samples_num; ++i) { int label = int(m_labels(i,0)); labels_map[label].push_back(i); } //total labels number int total_labels_num = labels_map.size(); //disturb sample order in different label by using shuffling algorithm if (m_disturb_order_flag) { for (int label_index = 0; label_index < total_labels_num; ++label_index) { std::vector<int> order_index_vec = labels_map[label_index]; //shuffling shuffling(order_index_vec); //now,it's unordered labels_map[label_index] = order_index_vec; } } //finding sample index in every folder for (int label_index = 0; label_index < total_labels_num; ++label_index) { int num_in_label = labels_map[label_index].size(); std::vector<int> samples_index_in_label = labels_map[label_index]; //10 folder for (int i = 0; i < 10; ++i) { int select_index = i; while(select_index < num_in_label) { folder_10_index[i].push_back(samples_index_in_label[select_index]); select_index += 10; } } } //compute number in every folder for (int i = 0; i < 10; ++i) { folder_10_num[i] = folder_10_index[i].size(); } //copy data to folder for (int i = 0; i < 10; ++i) { int samples_num_in_folder = folder_10_index[i].size(); folder_10_samples[i] = Matrix<float>(samples_num_in_folder,samples_dim); folder_10_labels[i] = Matrix<float>(samples_num_in_folder,1); int count = 0; while(count < samples_num_in_folder) { int sample_index = folder_10_index[i][count]; folder_10_samples[i](Range(count,count + 1),Range(0,samples_dim)).copy(m_samples(Range(sample_index,sample_index + 1),Range(0,samples_dim))); folder_10_labels[i](count) = m_labels(sample_index,0); count++; } } //training for (int pick_index = 0; pick_index < 10; ++pick_index) { //finding samples number int num = 0; for (int i = 0; i < 10; ++i) if (i != pick_index) num += folder_10_num[i]; Matrix<float> training_samples(num,samples_dim); Matrix<float> training_labels(num,1); //using 9 folders to learn int count = 0; for (int i = 0; i < 10; ++i) { if (i != pick_index) { training_samples(Range(count,count + folder_10_num[i]),Range(0,samples_dim)).copy(folder_10_samples[i]); training_labels(Range(count,count + folder_10_num[i]),Range(0,1)).copy(folder_10_labels[i]); count += folder_10_num[i]; } } //check if (m_dummy_learner == NULL) { EAGLEEYE_ERROR("learner is NULL\n"); return; } //learning m_dummy_learner->learn(training_samples,training_labels); //evaluation float error = m_dummy_learner->evalution(folder_10_samples[pick_index],folder_10_labels[pick_index]); m_average_error += error; if (m_optimum_error > error) { m_optimum_error = error; m_optimum_index = pick_index; } if (m_maximum_error < error) m_maximum_error = error; if (folder_path) { char str[100]; std::string model_name = itoa(pick_index,str,10); m_dummy_learner->save((std::string(folder_path) + model_name).c_str()); } } m_average_error /= 10.0f; //write file FILE* fp = fopen((std::string(folder_path) + "cross_validation.dat").c_str(),"wt+"); print_info(fp," optimum error %f\n average error %f\n max error %f\n optimum model index %d",m_optimum_error,m_average_error,m_maximum_error,m_optimum_index); fclose(fp); }
// The number of training examples should always be a positive integer. int NeuralNetwork::ComputeGradient(const DataMulti &data_multi) { const int kNumTrainEx = data_multi.num_train_ex(); assert(kNumTrainEx >= 1); arma::mat accum_hidden_layer_grad = \ arma::zeros<arma::mat>(theta_.at(0).n_rows,\ data_multi.training_features().n_cols); arma::mat accum_output_layer_grad = \ arma::zeros<arma::mat>(theta_.at(1).n_rows,\ theta_.at(0).n_rows+1); // Iterates over the training examples. for(int example_index=0; example_index<kNumTrainEx; example_index++) { // Performs step 1. arma::rowvec example_features = \ data_multi.training_features().row(example_index); arma::mat sigmoid_arg = example_features*theta_.at(0).t(); arma::mat hidden_layer_activation = ComputeSigmoid(sigmoid_arg); const arma::mat kOnesMat = arma::ones(hidden_layer_activation.n_rows,1); arma::mat hidden_layer_activation_mod = \ arma::join_horiz(kOnesMat,hidden_layer_activation); sigmoid_arg = hidden_layer_activation_mod*theta_.at(1).t(); arma::mat output_layer_activation = ComputeSigmoid(sigmoid_arg); // Performs step 2. arma::rowvec training_labels = \ arma::zeros<arma::rowvec>(1,output_layer_size_); int column_index = \ (int)as_scalar(data_multi.training_labels().row(example_index)); training_labels(column_index-1) = 1; arma::colvec output_layer_error = \ (output_layer_activation-training_labels).t(); // Performs step 3. arma::colvec hidden_layer_error_term = theta_.at(1).t()*output_layer_error; arma::colvec hidden_layer_error = \ hidden_layer_error_term.rows(1,hidden_layer_size_) % \ ComputeSigmoidGradient((example_features*theta_.at(0).t()).t()); // Performs step 4. accum_hidden_layer_grad = \ accum_hidden_layer_grad+hidden_layer_error*example_features; accum_output_layer_grad = \ accum_output_layer_grad+output_layer_error*\ arma::join_horiz(arma::ones<arma::mat>(1,1),hidden_layer_activation); } // Performs step 5 (without regularization). arma::mat hidden_layer_grad = (1.0/kNumTrainEx)*accum_hidden_layer_grad; arma::mat output_layer_grad = (1.0/kNumTrainEx)*accum_output_layer_grad; // Performs step 5 (with regularization). hidden_layer_grad.cols(1,theta_.at(0).n_cols-1) = \ hidden_layer_grad.cols(1,theta_.at(0).n_cols-1)+\ (lambda_/kNumTrainEx)*theta_.at(0).cols(1,theta_.at(0).n_cols-1); output_layer_grad.cols(1,theta_.at(1).n_cols-1) = \ output_layer_grad.cols(1,theta_.at(1).n_cols-1)+\ (lambda_/kNumTrainEx)*theta_.at(1).cols(1,theta_.at(1).n_cols-1); // Sets gradient. arma::vec hidden_layer_grad_stack = arma::vectorise(hidden_layer_grad); arma::vec output_layer_grad_stack = arma::vectorise(output_layer_grad); arma::vec gradient_stack = \ arma::join_vert(hidden_layer_grad_stack,output_layer_grad_stack); set_gradient(gradient_stack); return 0; }