0

Dans le cadre de notre projet de conception finale, nous devons concevoir un échantillonneur de Gibbs pour dénouer une image. Nous avons choisi d'utiliser l'algorithme de Metropolis au lieu d'un échantillonneur Gibbs régulier. Une esquisse de l'algorithme est la suivante: tous les pixels ont des valeurs de niveaux de gris comprises entre 0 et 255. En outre, nous utilisons une distribution a priori simple et lisse.L'échantillonnage de Gibbs donne de petites probabilités

main() 
    get input image as img 
    originalImg = img 
    for k = 1 to 1000 
     beta = 3/log(1+k) 
     initialEnergy = energy(img,originalImg) 
     for i = 0 to imageRows 
      for j = 0 to imageCols 
       img[i][j] = metropolisSample(beta,originalImg,img,initialEnergy,i,j) 


energy(img,originalImg) 
    for i = 1 to imageRows 
     for j = 1 to imageCols 
      ans += (img[i][j] - originalImg[i][j])^2/(255*255) 
      ans += (img[i][j] - image[i][j+1])^2/(255*255) 
      ans += (img[i][j] - image[i][j-1])^2/(255*255) 
      ans += (img[i][j] - image[i+1][j])^2/(255*255) 
      ans += (img[i][j] - image[i-1][j])^2/(255*255) 
    return ans 


metropolisSample(beta,originalImg,img,initialEnergy,i,j) 
    imageCopy = img 
    imageCopy[i][j] = random int between 0 and 255 
    newEnergy = energy(imageCopy,originalImg) 
    if (newEnergy < initialEnergy) 
     initialEnergy = newEnergy 
     return imageCopy[i][j] 
    else 
     rand = random float between 0 and 1 
     prob = exp(-(1/beta) * (newEnergy - initialEnergy)) 
     if rand < prob 
      initialEnergy = newEnergy 
      return imageCopy[i][j] 
     else 
      return img[i][j] 

Voilà à peu près l'essentiel du programme. Mon problème est que, dans l'étape où je calcule la probabilité

prob = exp(-(1/beta) * (newEnergy - initialEnergy)) 

La différence dans les énergies est si grande que la probabilité est presque toujours zéro. Quelle est la bonne façon d'atténuer cela? Nous avons également essayé l'approche d'échantillonnage de Gibbs, mais nous rencontrons un problème similaire. Le code de l'échantillonneur Gibbs est le suivant. Au lieu d'utiliser metropolisSample, nous utilisons gibbsSample à la place

gibbsSample(beta,originalImg,img,initialEnergy,i,j) 
    imageCopy = img 
    sum = 0 
    for k = 0 to 255 
     imageCopy[i][j] = k 
     energies[k] = energy(imageCopy,originalImg) 
     prob[k] = exp(-(1/beta) * energies[k]) 
     sum += prob[k] 

    for k = 0 to 255 
     prob[k]/sum 

    for k = 1 to 255 
     prob[k] = prob[k-1] + prob[k] //Convert our PDF to a CDF 

    rand = random float between 0 and 1 
    k = 0 
    while (1) 
     if (rand < prob[k]) 
      break 
     k++ 
    initialEnergy = energy[k] 
    return k 

Nous avions des problèmes similaires avec cette mise en œuvre ainsi. Lorsque nous avons calculé

prob[k] = exp(-(1/beta) * energies[k]) 

nos énergies étaient si grandes que nos probabilités sont toutes passées à zéro. Théoriquement, cela ne devrait pas poser de problème parce que nous les additionnons tous, puis nous divisons par la somme, mais la représentation en virgule flottante n'est tout simplement pas assez précise. Quel serait un bon moyen de résoudre ce problème?

Répondre

1

Je ne sais rien de votre problème spécifique, mais ma première réponse serait d'augmenter les énergies. Vos pixels sont dans la plage de 0..255, ce qui est arbitraire. Si les pixels étaient des fractions entre zéro et un, vous obtiendriez des résultats très différents.

Si les unités d'énergie sont en pixel^2, essayez de diviser les énergies par 256^2. Sinon, essayez de diviser par 256.

De plus, étant donné que les données sont entièrement aléatoires, il est possible qu'il y ait des énergies très élevées et qu'il ne devrait pas y avoir de fortes probabilités.

Mon manque de connaissance de votre problème peut avoir abouti à une réponse inutile. Si oui, veuillez l'ignorer.