예제 #1
0
void MFSolver::Run() {
	double bestValRMSE = INFINITY;
	int bestValIteration = -1;
	
	// Iteratively run SGD
	for (int it = 0; it < iterations; it++) {
		// Get next user from data
		User *u = data->getNextUser();
		while (u != NULL) {
			// For every item of the user
			for (Item i = Item(0); i != Item(ItemCount); i = Item(i+1)) {
				// Check if there's rating for item				
				if (u->ratings[i].score == UNKNOWN || u->ratings[i].type == Validation) {
					continue;
				}
				
				// Train on this rating
				TrainOnRating(*u, i);
			}
			
			// Get next user
			u = data->getNextUser();
		}
		
		// End of this iteration
		Print(it);
		double valRMSE = RMSE(Validation);
		if (valRMSE < bestValRMSE) {
			bestValRMSE	= valRMSE;
			bestValIteration = it;
		}
	}
	
	// Print best result
	cout.setf(ios::fixed, ios::floatfield);
	cout.precision(2);
	cout << ASCII_RED << "========================================= ";
	cout << "Final Results ";
	cout << " =========================================\n" << ASCII_RESET;
	cout << "Final Train RMSE = " << RMSE(Training) << endl;
	cout << ASCII_PURPLE << "Final Validation RMSE = " << RMSE(Validation) << ASCII_RESET << endl;
	cout << ASCII_YELLOW << "Best Validation RMSE = " << bestValRMSE;
	cout << " (on iteration " << bestValIteration + 1 << ")\n" << ASCII_RESET;
	cout.unsetf(ios::floatfield);
}
예제 #2
0
void wcCostEstimator::update( const wcMetaVector& meta, const wcFloat& nla )
{
	wcFloat cost0 = cost(meta);
	wcFloat step  = 0;

	iteration++;
	if(unseeded)
	{
		optima_expref = meta;
		unseeded	  = false;
	}


	/// Value Function Update
	Vtp	= Vt;
	rt  = 1-cost0;
	dVt = learning_rate*(rt - Vtp);
	Vt += dVt; 



	/// Predicted Optimal Document Update
	input_layer		.activate(meta);
	hidden1_layer	.activate(input_layer);
	hidden2_layer	.activate(hidden1_layer);
	output_layer	.activate(hidden2_layer);
	optima			= output_layer.output;



	if( training && (RMSE() < WC_ENDOFTRAINING) && (iteration > 5UL) )
	{
		training = false;
	}

	
	if( training /*&& (dVt>0)*/ )
	{
		optima_expref	+= dVt*(meta-optima_expref);
		output_layer	.reweightOutput(meta,			learning_rate);
		hidden2_layer	.reweightHidden(output_layer,	learning_rate);
		hidden1_layer	.reweightHidden(hidden2_layer,	learning_rate);
		input_layer		.reweightHidden(hidden1_layer,	learning_rate);

		output_layer	.reweightSet();
		hidden2_layer	.reweightSet();
		hidden1_layer	.reweightSet();
		input_layer		.reweightSet();
	}
}
예제 #3
0
//--------------------------------------
// main function
//--------------------------------------
int main(int argc, char** argv)
{
  // Open channels to the FPGA board.
  // These channels appear as files to the Linux OS
  int fdr = open("/dev/xillybus_read_32", O_RDONLY);
  int fdw = open("/dev/xillybus_write_32", O_WRONLY);

  // Check that the channels are correctly opened
  if ((fdr < 0) || (fdw < 0)) {
    fprintf (stderr, "Failed to open Xillybus device channels\n");
    exit(-1);
  }

  // sin output
  cos_sin_type s = 0;
  // cos output
  cos_sin_type c = 0;
  // radian input
  double radian; 
  // sin & cos calculated by math.h
  double m_s = 0.0, m_c = 0.0;

  // Error terms
  double err_ratio_sin = 0.0;
  double err_ratio_cos = 0.0;
  double accum_err_sin = 0.0;
  double accum_err_cos = 0.0;

  // arrays to store the output
  double c_array[NUM_DEGREE];
  double s_array[NUM_DEGREE];

  int nbytes;
  Timer timer("CORDIC fpga (batch)");

  timer.start();

  //----------------------------------------------------------------------
  // Send all values to the module
  //----------------------------------------------------------------------
  for (int i = 1; i < NUM_DEGREE; ++i) {
    radian = i * M_PI / 180;

    // Convert double value to fixed-point representation
    theta_type theta(radian);

    // Convert fixed-point to int64
    bit64_t theta_i;
    theta_i(theta.length()-1,0) = theta(theta.length()-1,0);
    int64_t input = theta_i;

    // Send bytes through the write channel
    // and assert that the right number of bytes were sent
    nbytes = write (fdw, (void*)&input, sizeof(input));
    assert (nbytes == sizeof(input));
  }

  //----------------------------------------------------------------------
  // Read all results
  //----------------------------------------------------------------------
  for (int i = 1; i < NUM_DEGREE; ++i) {
    // Receive bytes through the read channel
    // and assert that the right number of bytes were recieved
    int64_t c_out, s_out;
    nbytes = read (fdr, (void*)&c_out, sizeof(c_out));
    assert (nbytes == sizeof(c_out));
    nbytes = read (fdr, (void*)&s_out, sizeof(s_out));
    assert (nbytes == sizeof(s_out));
    
    // convert int64 to fixed point
    bit64_t c_i = c_out;
    bit64_t s_i = s_out;
    c(c.length()-1,0) = c_i(c.length()-1,0);
    s(s.length()-1,0) = s_i(s.length()-1,0);
    
    // Store to array
    c_array[i] = c;
    s_array[i] = s;
  }

  timer.stop();
  
  //------------------------------------------------------------ 
  // Check results
  //------------------------------------------------------------ 
  for (int i = 1; i < NUM_DEGREE; ++i) {
    // Load the stored result
    c = c_array[i];
    s = s_array[i];

    // Call math lib
    radian = i * M_PI / 180;
    m_s = sin( radian );
    m_c = cos( radian );
    
    // Calculate normalized error
    err_ratio_sin = ( abs_double( (double)s - m_s) / (m_s) ) * 100.0;
    err_ratio_cos = ( abs_double( (double)c - m_c) / (m_c) ) * 100.0;
    
    // Accumulate error ratios
    accum_err_sin += err_ratio_sin * err_ratio_sin;
    accum_err_cos += err_ratio_cos * err_ratio_cos;
  }

  //------------------------------------------------------------ 
  // Write out root mean squared error (RMSE) of error ratios
  //------------------------------------------------------------ 
  // Print to screen
  std::cout << "#------------------------------------------------\n"
            << "Overall_Error_Sin = " << RMSE(accum_err_sin) << "\n"
            << "Overall_Error_Cos = " << RMSE(accum_err_cos) << "\n"
            << "#------------------------------------------------\n";

  // Clean up
  close(fdr);
  close(fdw);

  return 0;
}
예제 #4
0
void ModelMFWt::hogTrain(const Data &data, Model &bestModel, 
    std::unordered_set<int>& invalidUsers,
    std::unordered_set<int>& invalidItems) {

  //copy passed known factors
  //uFac = data.origUFac;
  //iFac = data.origIFac;
  
  std::cout << "\nModelMFWt::hogTrain trainSeed: " << trainSeed;
  
  int nnz = data.trainNNZ;
  
  std::cout << "\nObj b4 svd: " << objective(data, invalidUsers, invalidItems) 
    << " Train RMSE: " << RMSE(data.trainMat) 
    << " Train nnz: " << nnz << std::endl;
  
  std::chrono::time_point<std::chrono::system_clock> startSVD, endSVD;
  startSVD = std::chrono::system_clock::now();
  //initialization with svd of the passed matrix
  //svdFrmSvdlibCSR(data.trainMat, facDim, uFac, iFac, false); 
  
  endSVD = std::chrono::system_clock::now();
  std::chrono::duration<double> durationSVD =  (endSVD - startSVD) ;
  std::cout << "\nsvd duration: " << durationSVD.count();

  int iter, bestIter = -1; 
  double bestObj, prevObj;
  double bestValRMSE, prevValRMSE;

  gk_csr_t *trainMat = data.trainMat;

 
  //vector to hold user gradient accumulation
  std::vector<std::vector<double>> uGradsAcc (nUsers, 
      std::vector<double>(facDim,0)); 

  //vector to hold item gradient accumulation
  std::vector<std::vector<double>> iGradsAcc (nItems, 
      std::vector<double>(facDim,0)); 

  //std::cout << "\nNNZ = " << nnz;
  prevObj = objective(data, invalidUsers, invalidItems);
  bestObj = prevObj;
  std::cout << "\nObj aftr svd: " << prevObj << " Train RMSE: " << RMSE(data.trainMat);


  std::chrono::time_point<std::chrono::system_clock> start, end;
  std::chrono::duration<double> duration;
  
  std::vector<std::unordered_set<int>> uISet(nUsers);
  genStats(trainMat, uISet, std::to_string(trainSeed));
  getInvalidUsersItems(trainMat, uISet, invalidUsers, invalidItems);
  
  std::unordered_set<int> headItems = getHeadItems(trainMat, 0.5);
  std::unordered_set<int> headUsers = getHeadItems(trainMat, 0.5);
  double lambda0 = 0.8;
  double lambda1 = 1.0 - lambda0;

  //random engine
  std::mt19937 mt(trainSeed);
  //get user-item ratings from training data
  auto uiRatings = getUIRatings(trainMat, invalidUsers, invalidItems);
  //index to above uiRatings pair
  std::vector<size_t> uiRatingInds(uiRatings.size());
  std::iota(uiRatingInds.begin(), uiRatingInds.end(), 0);


  std::cout << "\nTrain NNZ after removing invalid users and items: " 
    << uiRatings.size() << std::endl;
  double subIterDuration = 0;
  for (iter = 0; iter < maxIter; iter++) {  
    
    //shuffle the user item rating indexes
    std::shuffle(uiRatingInds.begin(), uiRatingInds.end(), mt);

    start = std::chrono::system_clock::now();
    const int indsSz = uiRatingInds.size();
#pragma omp parallel for
    for (int k = 0; k < indsSz; k++) {
      auto ind = uiRatingInds[k];
      //get user, item and rating
      int u       = std::get<0>(uiRatings[ind]);
      int item    = std::get<1>(uiRatings[ind]);
      float itemRat = std::get<2>(uiRatings[ind]);
      
      double r_ui_est = dotProd(uFac[u], iFac[item], facDim);
      double diff = itemRat - r_ui_est;

      if (headItems.find(item) != headItems.end()) {
        diff = diff*lambda0;
      } else {
        diff = diff*(lambda0 + lambda1);
      }

      //update user
      for (int i = 0; i < facDim; i++) {
        uFac[u][i] -= learnRate*(-2.0*diff*iFac[item][i] + 2.0*uReg*uFac[u][i]);
      }


      r_ui_est = dotProd(uFac[u], iFac[item], facDim);
      diff = itemRat - r_ui_est;
    
      if (headItems.find(item) != headItems.end()) {
        diff = diff*lambda0;
      } else {
        diff = diff*(lambda0 + lambda1);
      }

      //update item
      for (int i = 0; i < facDim; i++) {
        iFac[item][i] -= learnRate*(-2.0*diff*uFac[u][i] + 2.0*iReg*iFac[item][i]);
      }
    }
    end = std::chrono::system_clock::now();  
   
    duration =  end - start;
    subIterDuration = duration.count();

    //check objective
    if (iter % OBJ_ITER == 0 || iter == maxIter-1) {
      if (isTerminateModel(bestModel, data, iter, bestIter, bestObj, prevObj,
            invalidUsers, invalidItems)) {
        break; 
      }

      if (iter % 50 == 0) {
        std::cout << "ModelMFWt::train trainSeed: " << trainSeed
                  << " Iter: " << iter << " Objective: " << std::scientific << prevObj 
                  << " Train RMSE: " << RMSE(data.trainMat, invalidUsers, invalidItems)
                  << " Val RMSE: " << prevValRMSE
                  << " sub duration: " << subIterDuration
                  << std::endl;
      }

      if (iter % 500 == 0 || iter == maxIter - 1) {
        std::string modelFName = std::string(data.prefix);
        bestModel.saveFacs(modelFName);
      }

    }
     
  }
      
  //save best model found till now
  std::string modelFName = std::string(data.prefix);
  bestModel.saveFacs(modelFName);

  std::cout << "\nBest model validation RMSE: " << bestModel.RMSE(data.valMat, 
      invalidUsers, invalidItems);
}
예제 #5
0
void MFSolver::Print(int currentIteration) {
	cout << ASCII_RED << "========================================= ";
	cout << "Iteration " << currentIteration + 1;
	cout << " =========================================\n" << ASCII_RESET;
	
	cout.setf(ios::fixed, ios::floatfield);
	cout.precision(2);

	// Print qi
	if (featureSize <= data->getUserCount()) {
		cout << ASCII_CYAN << "[qi]" << ASCII_RESET << endl;
		for (int i = 0; i < (5 * featureSize - 3) / 2 + 8; i++) cout << " ";
		cout << ASCII_YELLOW << "Feature" << ASCII_RESET << endl;
		for (int i = 0; i < data->getItemCount(); i++) {
			if (i == data->getItemCount() / 2) {
				cout << ASCII_YELLOW << "  Item  " << ASCII_RESET;
			} else {
				cout << "        ";
			}
			
			cout << "|";
			for (int f = 0; f < featureSize; f++) {
				cout.width(5);
				cout << q[i][f];
			}
			cout << " |\n";
		}
	}
	
	// Print pu
	if (featureSize <= data->getUserCount()) {
		cout << ASCII_CYAN << "[pu]" << ASCII_RESET << endl;
		for (int i = 0; i < (5 * data->getUserCount()) / 2 + 8; i++) cout << " ";
		cout << ASCII_YELLOW << "User" << ASCII_RESET << endl;
		for (int f = 0; f < featureSize; f++) {
			if (f == featureSize / 2) {
				cout << ASCII_YELLOW << "Feature " << ASCII_RESET;
			} else {
				cout << "        ";
			}
			
			cout << "|";
			for (int u = 0; u < data->getUserCount(); u++) {
				cout.width(5);
				cout << p[u][f];
			}
			cout << " |\n";
		}
		cout << endl;
	}
	
	// Print prediction
	cout << ASCII_CYAN << "[Prediction]" << ASCII_RESET << endl;
	cout << "  White: Train Set" << endl;
	cout << ASCII_PURPLE << "  Purple: Validation Set" << ASCII_RESET << endl;
	cout << ASCII_YELLOW << "              ";
	for (Item i = Item(0); i < Item(ItemCount); i = Item(i+1)) {
		if (Data::ItemName(i).length() < 5) cout.width(5);
		cout << Data::ItemName(i);
		cout << "  ";
	}
	cout << ASCII_RESET << endl;
	User *u = data->getNextUser();
	while (u != NULL) {
		
		cout << ASCII_GREEN;
		cout.width(12);
		cout << u->name << ASCII_RESET;
		
		for (Item i = Item(0); i < Item(ItemCount); i = Item(i+1)) {
			int length = Data::ItemName(i).length();
			if (length < 5) length = 5;

			Rating r = u->ratings[i];
			if (r.score < 0) {
				cout.width(length + 2);
				cout << "";
			} else if (r.type == Training) {
				cout.width(length);
				cout << Predict(*u, i);
				cout << ":" << r.score;
			} else {
				cout << ASCII_PURPLE;
				cout.width(length);
				cout << Predict(*u, i);
				cout << ":" << r.score;
				cout << ASCII_RESET;
			}
		}
		cout << endl;
		
		u = data->getNextUser();
	}
	cout << endl;
	
	// Print results
	cout << ASCII_CYAN << "[Results]" << ASCII_RESET << endl;
	cout << "  Training RMSE = " << RMSE(Training) << endl;
	cout << ASCII_PURPLE << "  Validation RMSE = " << RMSE(Validation) << ASCII_RESET << endl;
	cout << endl;
	
	cout.unsetf(ios::floatfield);
}
예제 #6
0
//--------------------------------------
// main function of TB
//--------------------------------------
int main(int argc, char** argv)
{
  // sin output
  double ans = 0;
  // cos output

  // sin & cos calculated by math.h
  double m_an = 0.0;

  // Error terms
  double err_ratio;
  double accum_err;

  // arrays to store the output
  double array[NUM_DEGREE];

  // HLS streams for communicating with the cordic block
  //hls::stream<bit32_t> cordic_in;
  hls::stream<bit32_t> cordic_out;

  //------------------------------------------------------------ 
  // Send data to CORDIC sim
  //------------------------------------------------------------ 
  for (int i = 1; i < NUM_DEGREE; i++) {

    
    bit32_t input = i;


    // Send both words to the HLS module
   // cordic_in.write( input );
    //cordic_in.write( input+1 );
  }

  //------------------------------------------------------------ 
  // Execute CORDIC sim and store results
  //------------------------------------------------------------ 
  for (int i = 1; i < NUM_DEGREE; i++) {
    // Run the HLS function 
    dut( cordic_out );

    // Read the two 32-bit cosine output words, low word first
    bit32_t output;
    output = cordic_out.read();

    
    // Store to array
    array[i] = output;
  }

   //------------------------------------------------------------ 
  // Check results
  //------------------------------------------------------------ 
  for (int i = 1; i < NUM_DEGREE; ++i) {
    // Load the stored result
    ans = array[i];

    m_an = i;

    
    // Calculate normalized error
    err_ratio = ( abs_double( (double)ans - m_an) / (m_an) ) * 100.0;
    
    // Accumulate error ratios
    accum_err += err_ratio * err_ratio;
    std::cout << "ans = "<< ans <<" m_an = "<<m_an<<"\n";
  }

  //------------------------------------------------------------ 
  // Write out root mean squared error (RMSE) of error ratios
  //------------------------------------------------------------ 
  // Print to screen
  std::cout << "#------------------------------------------------\n"
            << "Overall_Error_Test = " << RMSE(accum_err) << "\n"
            << "#------------------------------------------------\n";


  return 0;
}