Пример #1
0
double a_plus() {
	// Allocate patches
	float *patches = (float*)malloc(N*K*sizeof(float));
	// Allocate patches_sr
	float *patches_sr = (float*)malloc(N*F*sizeof(float));
	// Allocate LR dictionary
	float *dict_lr = (float*)malloc(K*C*sizeof(float));
	// Allocate Projections
	float* projs = (float*)malloc(C*K*F*sizeof(float));
	// Allocate nearest indices
	int *nn_inds = (int*)malloc(N*sizeof(int));
	// Allocate similarities
	float *similarities = (float*)malloc(N*C*sizeof(float));
	
	// Calculate nearest dictionary atoms
	double start_time = omp_get_wtime();
	dot(patches, dict_lr, similarities, N, K, C);
	arr_abs(similarities, N, C);
	nearest_atoms(similarities, nn_inds, N, C);
	
	// Project back to HR space
	for (int n=0; n<N; n++) {
		int ind = nn_inds[n];
		for (int f=0; f<F; f++) {
			float acc = 0;
			for (int k=0; k<K; k++)
				acc += patches[n*K+k] * projs[ind*K*F+k*F+f];
			patches_sr[n*F+f] = acc;
		}
	}
	double duration = omp_get_wtime();
	
	// Deallocate
	free(patches);
	free(patches_sr);
	free(dict_lr);
	free(projs);
	free(nn_inds);
	free(similarities);

	return duration;
}
Пример #2
0
/** Train the unsupervised SOM network.
 *
 * The network is initialized with random (non-graduate) values. It is then
 * trained with the image pixels (RGB). Once the network is done training the
 * centroids of the resulting clusters is returned.
 *
 * @note The length of the clusters depends on the parameter 'n'. The greatest
 *  n, the more colors in the clusters, the less posterized the image.
 *
 * @param[out] res       The resulting R, G and B clusters centroids.
 * @param[in]  imgPixels The original image pixels.
 * @param[in]  nbPixels  The number of pixels of th image (height * width).
 * @param[in]  nbNeurons The posterization leveldefined by its number of 
 *                       neurons.
 * @param[in]  noEpoch   Number of training passes (a too small number of epochs
 *  won't be enough for the network to correctly know the image but a too high
 *  value will force the network to modify the wieghts so much that the image
 *  can actually looks "ugly").
 * @param[in]  thresh    The threshold value. The SOM delta parameter and the
 *  training rate are dicreasing from one epoch to the next. The treshold value
 *  set a stop condifition in case the value has fallen under this minimum 
 *  value.
 *
 * @return SOM_OK if everything goes right or SOM_NO_MEMORY if a memory 
 *  allocation (malloc) fail.
 */
int som_train(float **res, float **imgPixels, unsigned int nbPixels,
              int nbNeurons, int noEpoch, float thresh){
    int mapWidth =              // Map width. This can be calculated from its
        (int)sqrt(nbNeurons);   // number of neurons as the map is square.
    int mapHeight =             // Map height. This can be calculated from its
        (int)sqrt(nbNeurons);   // number of neurons as the map is square.
    float delta = INT_MAX;      // Start with an almost impossible value
    int it = 0;                 // Count the network iterations
    unsigned int pick;          // The choosen input pixel
    float rad;                  // Neighbooring radius (keep dicreasing)
    float eta;                  // Learning rate (keep dicreasing)
    float pickRGB[3] = {0};     // Contains the choosen input RGB vector
    size_t choosen;             // Best Matching Unit (BMU)
    int choosen_x;              // BMU abscissa
    int choosen_y;              // BMU ordinate
    float *neigh =              // Neighbooring mask
        malloc(sizeof(float) * nbNeurons);
	if(neigh == NULL){
		return SOM_NO_MEMORY;
    }
    memset(neigh, 0, nbNeurons);

    float *WR =                 // RED part of the network weight vectors
        malloc(sizeof(float) * nbNeurons);
	if(WR == NULL){
		return SOM_NO_MEMORY;
    }
    memset(WR, 0, nbNeurons);
    float *WG =                 // GREEN part of the network weight vectors
        malloc(sizeof(float) * nbNeurons);
	if(WG == NULL){
		return SOM_NO_MEMORY;
    }
    memset(WG, 0, nbNeurons);
    float *WB =                 // BLUE part of the network weight vectors
        malloc(sizeof(float) * nbNeurons);
	if(WB == NULL){
		return SOM_NO_MEMORY;
    }
    memset(WB, 0, nbNeurons);

    float *deltaR =             // New RED part of the network weight vectors
        malloc(sizeof(float) * nbNeurons);
	if(deltaR == NULL){
		return SOM_NO_MEMORY;
    }
    memset(deltaR, 0, nbNeurons);
    float *deltaG =             // New GREEN part of the network weight vectors
        malloc(sizeof(float) * nbNeurons);
	if(deltaG == NULL){
		return SOM_NO_MEMORY;
    }
    memset(deltaG, 0, nbNeurons);
    float *deltaB =             // New BLUE part of the network weight vectors
        malloc(sizeof(float) * nbNeurons);
	if(deltaB == NULL){
		return SOM_NO_MEMORY;
    }
    memset(deltaB, 0, nbNeurons);

    float *absDeltaR =          // Absolute value of deltaR
        malloc(sizeof(float) * nbNeurons);
	if(absDeltaR == NULL){
		return SOM_NO_MEMORY;
    }
    memset(absDeltaR, 0, nbNeurons);
    float *absDeltaG =          // Absolute value of deltaG
        malloc(sizeof(float) * nbNeurons);
	if(absDeltaG == NULL){
		return SOM_NO_MEMORY;
    }
    memset(absDeltaG, 0, nbNeurons);
    float *absDeltaB =          // Absolute value of deltaB
        malloc(sizeof(float) * nbNeurons);
	if(absDeltaB == NULL){
		return SOM_NO_MEMORY;
    }
    memset(absDeltaB, 0, nbNeurons);

    float *dists =              // Vectors euclidian distances from input form
        malloc(sizeof(float) * nbNeurons);
	if(dists == NULL){
		return SOM_NO_MEMORY;
    }
    memset(dists, 0, nbNeurons);

    /* Randomly initialize weight vectors */
    srand(time(NULL));
    random_sample(WR, nbNeurons);
    random_sample(WG, nbNeurons);
    random_sample(WB, nbNeurons);

    while(it < noEpoch && delta >= thresh){
        /* Randomly choose an input form */
        pick = random_uint(nbPixels);
        pickRGB[0] = imgPixels[pick][0];
        pickRGB[1] = imgPixels[pick][1];
        pickRGB[2] = imgPixels[pick][2];

        /* Compute every vectors euclidian distance from the input form */
        euclidian(dists, nbNeurons, WR, WG, WB, pickRGB);
        /* Determine the BMU */
        choosen = arr_min_idx(dists, nbNeurons);
        choosen_x = (int)choosen % mapWidth;
        choosen_y = choosen / mapHeight;

        /* Compute the new neighbooring radius */
        rad = som_radius(it, noEpoch, mapWidth, mapHeight);
        /* Find the BMU neighboors */
        som_neighbourhood(neigh, choosen_x, choosen_y, rad, mapWidth, 
                          mapHeight);

        /* Compute the new learning rate */
        eta = som_learning_rate(it, noEpoch);
        /* Compute new value of the network weight vectors */
        compute_delta(deltaR, eta, neigh, nbNeurons, pickRGB[0], WR);
        compute_delta(deltaG, eta, neigh, nbNeurons, pickRGB[1], WG);
        compute_delta(deltaB, eta, neigh, nbNeurons, pickRGB[2], WB);
        /* Update the network weight vectors values */
        arr_add(WR, deltaR, nbNeurons);
        arr_add(WG, deltaG, nbNeurons);
        arr_add(WB, deltaB, nbNeurons);

        arr_abs(absDeltaR, deltaR, nbNeurons);
        arr_abs(absDeltaG, deltaG, nbNeurons);
        arr_abs(absDeltaB, deltaB, nbNeurons);
        delta = arr_sum(absDeltaR, nbNeurons) +
                arr_sum(absDeltaG, nbNeurons) +
                arr_sum(absDeltaB, nbNeurons);

        it++;
    }
    res[0] = WR;
    res[1] = WG;
    res[2] = WB;

    free(dists);
    free(deltaR);
    free(deltaG);
    free(deltaB);
    free(absDeltaR);
    free(absDeltaG);
    free(absDeltaB);
    free(neigh);

    return SOM_OK;
}