コード例 #1
0
ファイル: tsne.cpp プロジェクト: RoysamLab/STrend
// Evaluate t-SNE cost function (approximately)
double TSNE::evaluateError(int* row_P, int* col_P, double* val_P, double* Y, int N, int D, double theta)
{
    
    // Get estimate of normalization term
    SPTree* tree = new SPTree(D, Y, N);
    double* buff = (double*) calloc(D, sizeof(double));
    double sum_Q = .0;
    for(int n = 0; n < N; n++) tree->computeNonEdgeForces(n, theta, buff, &sum_Q);
    
    // Loop over all edges to compute t-SNE error
    int ind1, ind2;
    double C = .0, Q;
    for(int n = 0; n < N; n++) {
        ind1 = n * D;
        for(int i = row_P[n]; i < row_P[n + 1]; i++) {
            Q = .0;
            ind2 = col_P[i] * D;
            for(int d = 0; d < D; d++) buff[d]  = Y[ind1 + d];
            for(int d = 0; d < D; d++) buff[d] -= Y[ind2 + d];
            for(int d = 0; d < D; d++) Q += buff[d] * buff[d];
            Q = (1.0 / (1.0 + Q)) / sum_Q;
            C += val_P[i] * log((val_P[i] + FLT_MIN) / (Q + FLT_MIN));
        }
    }
    
    // Clean up memory
    free(buff);
    delete tree;
    return C;
}
コード例 #2
0
ファイル: tsne.cpp プロジェクト: HBPSP8Repo/Rtsne
void TSNE<NDims>::computeGradient(double* P, unsigned int* inp_row_P, unsigned int* inp_col_P, double* inp_val_P, double* Y, unsigned int N, int D, double* dC, double theta)
{
    // Construct space-partitioning tree on current map
    SPTree<NDims>* tree = new SPTree<NDims>(Y, N);

    // Compute all terms required for t-SNE gradient
    double* pos_f = (double*) calloc(N * D, sizeof(double));
    double* neg_f = (double*) calloc(N * D, sizeof(double));
    if(pos_f == NULL || neg_f == NULL) { Rcpp::stop("Memory allocation failed!\n"); }
    tree->computeEdgeForces(inp_row_P, inp_col_P, inp_val_P, N, pos_f, num_threads);

    // Storing the output to sum in single-threaded mode; avoid randomness in rounding errors.
    std::vector<double> output(N);

    #pragma omp parallel for schedule(guided) num_threads(num_threads)
    for (unsigned int n = 0; n < N; n++) {
      output[n]=tree->computeNonEdgeForces(n, theta, neg_f + n * D);
    }

    double sum_Q = .0;
    for (unsigned int n=0; n<N; ++n) {
        sum_Q += output[n];
    }

    // Compute final t-SNE gradient
    for(unsigned int i = 0; i < N * D; i++) {
        dC[i] = pos_f[i] - (neg_f[i] / sum_Q);
    }

    free(pos_f);
    free(neg_f);
    delete tree;
}
コード例 #3
0
ファイル: tsne.cpp プロジェクト: HBPSP8Repo/Rtsne
void TSNE<NDims>::getCost(unsigned int* row_P, unsigned int* col_P, double* val_P, double* Y, unsigned int N, int D, double theta, double* costs)
{

  // Get estimate of normalization term
  SPTree<NDims>* tree = new SPTree<NDims>(Y, N);
  double* buff = (double*) calloc(D, sizeof(double));
  double sum_Q = .0;
  for(unsigned int n = 0; n < N; n++) sum_Q += tree->computeNonEdgeForces(n, theta, buff);

  // Loop over all edges to compute t-SNE error
  int ind1, ind2;
  double  Q;
  for(unsigned int n = 0; n < N; n++) {
    ind1 = n * D;
    costs[n] = 0.0;
    for(unsigned int i = row_P[n]; i < row_P[n + 1]; i++) {
      Q = .0;
      ind2 = col_P[i] * D;
      for(int d = 0; d < D; d++) buff[d]  = Y[ind1 + d];
      for(int d = 0; d < D; d++) buff[d] -= Y[ind2 + d];
      for(int d = 0; d < D; d++) Q += buff[d] * buff[d];
      Q = (1.0 / (1.0 + Q)) / sum_Q;
      costs[n] += val_P[i] * log((val_P[i] + FLT_MIN) / (Q + FLT_MIN));
    }
  }

  // Clean up memory
  free(buff);
  delete tree;
}
コード例 #4
0
ファイル: tsne.cpp プロジェクト: RoysamLab/STrend
// Compute gradient of the t-SNE cost function (using Barnes-Hut algorithm)
void TSNE::computeGradient(double* P, int* inp_row_P, int* inp_col_P, double* inp_val_P, double* Y, int N, int D, double* dC, double theta)
{
    
    // Construct space-partitioning tree on current map
    SPTree* tree = new SPTree(D, Y, N);
    
    // Compute all terms required for t-SNE gradient
    double sum_Q = .0;
    double* pos_f = (double*) calloc(N * D, sizeof(double));
    double* neg_f = (double*) calloc(N * D, sizeof(double));
    if(pos_f == NULL || neg_f == NULL) { cout<<"Memory allocation failed!\n"; }
    tree->computeEdgeForces(inp_row_P, inp_col_P, inp_val_P, N, pos_f);
    for(int n = 0; n < N; n++) tree->computeNonEdgeForces(n, theta, neg_f + n * D, &sum_Q);
    
    // Compute final t-SNE gradient
    for(int i = 0; i < N * D; i++) {
        dC[i] = pos_f[i] - (neg_f[i] / sum_Q);
    }
    free(pos_f);
    free(neg_f);
    delete tree;
}
コード例 #5
0
ファイル: driver4.cpp プロジェクト: kjyang/knn
int main(int argc, char** argv) {

  std::ifstream imageFile;
  std::ifstream labelFile;

  if(argc != 5) {
    std::cerr << "Invalid command." << std::endl;
    return -1;
  }

  // Open training images and their labels for reading.
  imageFile.open(argv[1], std::ios::binary);
  labelFile.open(argv[2], std::ios::binary);

  labelFile.seekg(8);

  BitInputStream* input = new BitInputStream(imageFile);
  BitInputStream* label = new BitInputStream(labelFile);

  // Get the magic number, the rows, and the columns of each training image. 
  int magic = input->readInt();
  int total = input->readInt();
  std::cerr << "Loading training images" << std::endl;
  std::cerr << "Total image: " << total << std::endl;
  int rows = input->readInt();
  std::cerr << "Each image contains " << rows << " rows." << std::endl;
  int columns = input->readInt();
  std::cerr << "Each image contains " << columns << " columns." << std::endl;

  // Load the training data to memory.
  Training* training = new Training(total, rows * columns);
  for(int i = 0; i < total; i++) {
    int lbl = (int)(label->readChar());
    TRPoint* point = new TRPoint(lbl, rows * columns, i);
    for(int j = 0; j < (rows * columns); j++) {
      int pixel = (int)(input->readChar());
      point->addPixel(pixel);
    }
    training->addElement(point);
  }
  imageFile.close(); labelFile.close();


  std::ifstream testImageFile;
  std::ifstream testLabelFile;

  // Open testing images and their actual labels for reading.
  testImageFile.open(argv[3], std::ios::binary);
  testLabelFile.open(argv[4], std::ios::binary); testLabelFile.seekg(8);

  input = new BitInputStream(testImageFile);
  label = new BitInputStream(testLabelFile);

  magic = input->readInt();
  total = input->readInt();
  std::cerr << "Loading testing images" << std::endl;
  std::cerr << "Total image: " << total << std::endl;
  rows = input->readInt();
  std::cerr << "Each image contains " << rows << " rows." << std::endl;
  columns = input->readInt();
  std::cerr << "Each image contains " << columns << " columns." << std::endl;

  // Construct the K-D for nearest neighbor search.
  std::cerr << "Please enter the number of elements in each leaf for your K-D tree: ";
  std::string numImages;
  getline(std::cin, numImages); 
  std::cerr << "Ok, at least " << atoi(numImages.c_str()) << " images." << std::endl;
  std::cerr << "Constructing K-D tree for training set." << std::endl;


  srand(time(0));
  SPTree* tree = new SPTree();
  tree->root = tree->build(tree->root, training, training->size(), atoi(numImages.c_str()));

  // Load the testing data to memory.
  Training* testing = new Training(total, rows * columns);
  for(int i = 0; i < total; i++) {
    int lbl = (int)(label->readChar());
    TRPoint* point = new TRPoint(lbl, rows * columns);
    for(int j = 0; j < (rows * columns); j++) {
      int pixel = (int)(input->readChar());
      point->addPixel(pixel);
    }
    testing->addElement(point);
  }
  testImageFile.close(); testLabelFile.close();

  // Loading the actual true nearest neighbor of each testing images to memory.
  std::ifstream actualLabels;
  actualLabels.open("actual");
  std::string in;
  int* trueLabels = new int[total];
  int index = 0;
  for(int i = 0; getline(actualLabels, in); i++) trueLabels[i] = atoi(in.c_str());

  int errors = 0;
  int notTrueNN = 0;

  // Perform the nearest neighbor search.
  for(int o = 0; o < testing->size(); o++) {
    std::cerr << "classifying image " << o+1 << std::endl;
    int currentDist = INT_MAX;
    int currentLabel = -1;
    int imageNumber = -1;

    // Find the leaf that contains the elements closest to the test point.
    TRPoint* testPoint = testing->getElement(o);
    Training* set = tree->find(testing->getElement(o))->set;

    // Compute the shortest distance from training images, update if needed.
    for(int i = 0; i < set->size(); i++) {
      TRPoint* trainPoint = set->getElement(i);
      int distance = 0;
      for(int j = 0; j < trainPoint->size; j++) {
	int difference = trainPoint->feature[j] - testPoint->feature[j];
	if(difference < 0) difference = (-1) * difference;
	distance = distance + difference;
      }
      if(distance < currentDist) {
	currentDist = distance;
	currentLabel = trainPoint->label;
	imageNumber = trainPoint->index;
      }
    }

    std::cerr << "classified label: " << currentLabel << std::endl;
    std::cerr << "actual label: " << testPoint->label << std::endl;

    // There's an error if this image is not classified correctly.
    if(currentLabel != testPoint->label) {
     std::cerr << "image " << o+1 << " has an error" << std::endl;
     //std::cout << "image " << o+1 << " has an error" << std::endl;
      std::cerr << "classified with label " << currentLabel << std::endl;
      //std::cout << "classified with label " << currentLabel << std::endl;
      //printImage(training->getElement(imageNumber), columns, rows);
      std::cerr << "actual label is " << testPoint->label << std::endl;
      //std::cout << "actual label is " << testPoint->label << std::endl;
      //printImage(testPoint, columns, rows);
      errors++;
    }

    // Not a true nearest neighbor. 
    if(imageNumber != trueLabels[o]) notTrueNN++;

  }

  // Print out the result here.
  std::cerr << "errors: " << errors << std::endl;
  std::cerr << "not true nearest neighbors: " << notTrueNN << std::endl;

  return 0;

}