Commit 8aa4bef7 authored by Andrey Filippov's avatar Andrey Filippov

regularization to alpha

parent 836e9158
...@@ -37,6 +37,11 @@ public class VegetationLMA { ...@@ -37,6 +37,11 @@ public class VegetationLMA {
// private double default_alpha; // private double default_alpha;
private int num_pars_terrain; private int num_pars_terrain;
private int num_pars_vegetation; private int num_pars_vegetation;
private int num_pars_vegetation_alpha; //== num_pars_vegetation
private int ind_pars_terrain = 0; // index of the first terrain parameter
private int ind_pars_vegetation; // index of the first vegetation parameter
private int ind_pars_vegetation_alpha; // index of the first alpha parameter
private int ind_pars_scenes; // index of the first scene parameter
private int num_pars_scenes; private int num_pars_scenes;
private int [][][] data_source; // [index][windx][3]: private int [][][] data_source; // [index][windx][3]:
// 0:{ scene, full_indx, terr_indx, scale_indx} - always present as parameters // 0:{ scene, full_indx, terr_indx, scale_indx} - always present as parameters
...@@ -48,10 +53,13 @@ public class VegetationLMA { ...@@ -48,10 +53,13 @@ public class VegetationLMA {
private double [] y_vector = null; private double [] y_vector = null;
private double weight_pure = 0; private double weight_pure = 0;
private double [] weights; // normalized so sum is 1.0 for all - samples and extra regularization private double [] weights; // normalized so sum is 1.0 for all - samples and extra regularization
public double alpha_loss;
public double alpha_offset = 0; // if >0, start losses above 0.0 and below 1.0;
public double delta= 1e-5; // 7; public double delta= 1e-5; // 7;
public int debug_index;
public double [][] debug_image;
public static double [] debug_alpha_scales = {100,150};
public int [] indices; public int [] indices;
public int [][] cpairs = null; public int [][] cpairs = null;
...@@ -101,8 +109,13 @@ public class VegetationLMA { ...@@ -101,8 +109,13 @@ public class VegetationLMA {
final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence
final double default_alpha, final double default_alpha,
final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? final double [] scene_weights, // null or per-scene weights (higher for larger offsets)?
final double reg_weights, // fraction of the total weight used for regularization
final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0
final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0
final int debugLevel) { final int debugLevel) {
this.woi = woi; this.woi = woi;
this.alpha_loss = alpha_loss;
this.alpha_offset = alpha_offset;
// this.default_alpha = default_alpha; // this.default_alpha = default_alpha;
int min_scenes_uses = min_scenes; int min_scenes_uses = min_scenes;
int min_scenes_used = min_scenes * 4; int min_scenes_used = min_scenes * 4;
...@@ -114,16 +127,14 @@ public class VegetationLMA { ...@@ -114,16 +127,14 @@ public class VegetationLMA {
setupParametersVector (default_alpha); // areas where both terrain and vegetation are available setupParametersVector (default_alpha); // areas where both terrain and vegetation are available
setupDataSource(); // condensed setupDataSource(); // condensed
setupYVector(); setupYVector();
setupWeights(scene_weights); setupWeights( // after setupParametersIndices
scene_weights,
reg_weights); // final double reg_weights);
last_jt = new double [parameters_vector.length][]; last_jt = new double [parameters_vector.length][];
return weights.length; return weights.length;
} }
private double [] getYminusFxWeighted( private double [] getYminusFxWeighted(
final double [] fx, final double [] fx,
final double [] rms_fp // null or [2] final double [] rms_fp // null or [2]
...@@ -154,6 +165,9 @@ public class VegetationLMA { ...@@ -154,6 +165,9 @@ public class VegetationLMA {
// System.out.println("ai.get()="+ai.get()); // System.out.println("ai.get()="+ai.get());
// important to set - after first cycle ai is left 16(number of threads) larger than number of cycles! // important to set - after first cycle ai is left 16(number of threads) larger than number of cycles!
// It is so, because it first increments, then tests if (n < num_pairs) // It is so, because it first increments, then tests if (n < num_pairs)
// Regularization part where y is assumed==0, only fX is used
ai.set(y_vector.length); // not yet used ai.set(y_vector.length); // not yet used
ati.set(0); ati.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
...@@ -312,22 +326,25 @@ public class VegetationLMA { ...@@ -312,22 +326,25 @@ public class VegetationLMA {
} }
if (debug_level > 3) { // 0) { if (debug_level > 3) { // 0) {
double delta = this.delta; // 1E-3; double delta = this.delta; // 1E-3;
double delta_err= debugDerivs ( if (debug_level > 4) {
parameters_vector, // double [] vector, double delta_err= debugDerivs (
delta, // double delta, parameters_vector, // double [] vector,
debug_level, //int debugLevel, delta, // double delta,
false); // boolean show_img) debug_level, //int debugLevel,
System.out.println("\nMaximal error = "+delta_err); false); // boolean show_img)
System.out.println("\nMaximal error = "+delta_err);
}
int [] wh = new int[2]; int [] wh = new int[2];
double [] debug_image = parametersImage ( double [] debug_image = parametersImage (
parameters_vector, // double [] vector, parameters_vector, // double [] vector,
1, // int gap) 1, // int gap)
wh); wh,
null); // String title)
ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays(
debug_image, debug_image,
wh[0], wh[0],
wh[1], wh[1],
"parameters.vector"); "parameters.vector-"+debug_index);
} }
...@@ -402,13 +419,27 @@ public class VegetationLMA { ...@@ -402,13 +419,27 @@ public class VegetationLMA {
rslt[0] = true; rslt[0] = true;
rslt[1] = rms[0] >=(this.last_rms[0] * (1.0 - rms_diff)); rslt[1] = rms[0] >=(this.last_rms[0] * (1.0 - rms_diff));
this.last_rms = rms.clone(); this.last_rms = rms.clone();
this.parameters_vector = new_vector.clone(); this.parameters_vector = new_vector.clone();
if (debug_level > 3) { if (debug_level > 2) {
double [] debug_image = parametersImage ( String title = (debug_level > 3)? "parameters.vector":null;
int [] wh = new int [2];
double [] debug_img = parametersImage (
parameters_vector, // double [] vector, parameters_vector, // double [] vector,
1, // int gap) 1, // int gap)
null); wh,
title);
if ((debug_image != null) && (debug_index < debug_image.length)) {
debug_image[debug_index++] = debug_img;
}
if (debug_level > 4) {
ShowDoubleFloatArrays.showArrays(
debug_image,
wh[0],
wh[1],
true,
"parameters_vector_live.tiff");
}
// print vectors in some format // print vectors in some format
/* /*
...@@ -514,7 +545,7 @@ public class VegetationLMA { ...@@ -514,7 +545,7 @@ public class VegetationLMA {
public void run() { public void run() {
double [] vegetation = new double [4]; double [] vegetation = new double [4];
double [] alpha = new double [4]; double [] alpha = new double [4];
for (int n = ai.getAndIncrement(); n < weights.length; n = ai.getAndIncrement()) { for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) {
// int nscene = data_source[n][0][0]; // int nscene = data_source[n][0][0];
// int indx = data_source[n][0][1]; // int indx = data_source[n][0][1];
double terrain = vector[data_source[n][0][2]]; double terrain = vector[data_source[n][0][2]];
...@@ -563,6 +594,35 @@ public class VegetationLMA { ...@@ -563,6 +594,35 @@ public class VegetationLMA {
}; };
} }
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
// regularization weights and derivatives
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int n = ai.getAndIncrement(); n < num_pars_vegetation_alpha; n = ai.getAndIncrement()) {
int np = ind_pars_vegetation_alpha + n; // index of the alpha parameter
int nx = n + y_vector.length; // x - index
double d = 0;
fX[nx] = 0.0;
double alpha = vector[np];
if (alpha < alpha_offset) {
d = alpha- alpha_offset;
} else if (alpha > (1 - alpha_offset)) {
d = alpha - (1.0 - alpha_offset);
}
if (d != 0) {
fX[nx] = d * d * alpha_loss;
if (jt != null) {
jt[np][nx] = 2 * alpha_loss * d; // d/dalpha[i]
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return fX; return fX;
} }
...@@ -624,7 +684,8 @@ public class VegetationLMA { ...@@ -624,7 +684,8 @@ public class VegetationLMA {
public double [] parametersImage ( public double [] parametersImage (
double [] vector, double [] vector,
int gap, int gap,
int [] wh) { int [] wh,
String title) {
int [] indices = getParamDebugIndices (gap); int [] indices = getParamDebugIndices (gap);
int woi_width3=woi.width*3 + 2 * gap; int woi_width3=woi.width*3 + 2 * gap;
double [] dbg_img = new double [indices.length]; double [] dbg_img = new double [indices.length];
...@@ -633,18 +694,24 @@ public class VegetationLMA { ...@@ -633,18 +694,24 @@ public class VegetationLMA {
dbg_img[i] = Double.NaN; dbg_img[i] = Double.NaN;
} else { } else {
dbg_img[i]= vector[indices[i]]; dbg_img[i]= vector[indices[i]];
// scale alpha for the same image
int w = i % woi_width3;
if (w > 2 *( woi.width+ gap)) {
dbg_img[i] = debug_alpha_scales[0] + (debug_alpha_scales[1] - debug_alpha_scales[0]) * dbg_img[i];
}
} }
} }
if (wh != null) { if (wh != null) {
wh[0] = woi_width3; wh[0] = woi_width3;
wh[1] = indices.length/woi_width3; wh[1] = indices.length/woi_width3;
} }
ShowDoubleFloatArrays.showArrays( if (title != null) {
dbg_img, ShowDoubleFloatArrays.showArrays(
woi_width3, dbg_img,
indices.length/woi_width3, woi_width3,
"parameters.vector"); indices.length/woi_width3,
title);
}
return dbg_img; return dbg_img;
} }
...@@ -683,9 +750,11 @@ public class VegetationLMA { ...@@ -683,9 +750,11 @@ public class VegetationLMA {
} }
private void setupWeights(final double [] scene_weights) { private void setupWeights( // after setupParametersIndices
int extra_samples = 0; // in the future may be regularization final double [] scene_weights,
double extra_weights = 0.0; final double reg_weights) {
int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization
double reg_sample_weight = reg_weights/num_pars_vegetation_alpha; // weight of each regularization sample
final double [] sw = (scene_weights != null) ? scene_weights : new double [num_scenes]; final double [] sw = (scene_weights != null) ? scene_weights : new double [num_scenes];
if (scene_weights == null) { if (scene_weights == null) {
Arrays.fill (sw, 1.0); Arrays.fill (sw, 1.0);
...@@ -693,15 +762,17 @@ public class VegetationLMA { ...@@ -693,15 +762,17 @@ public class VegetationLMA {
weights = new double [data_source.length + extra_samples]; weights = new double [data_source.length + extra_samples];
double s = 0; double s = 0;
for (int ny = 0; ny < data_source.length; ny++) { for (int ny = 0; ny < data_source.length; ny++) {
s += sw[data_source[ny][0][0]]; int nscene = data_source[ny][0][0];
// int indx = data_source[ny][0][1];
s += sw[nscene];
} }
final double s0 = s; final double s0 = s;
for (int i = 0; i < extra_samples; i++) { s *= (1+ reg_weights);
s+=extra_weights;
}
final double k = 1.0/s; final double k = 1.0/s;
weight_pure = s0/s; weight_pure = s0/s;
// for (int i = 0; i < extra_samples; i++) {
// s+=extra_weights;
// }
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX); final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
...@@ -711,7 +782,7 @@ public class VegetationLMA { ...@@ -711,7 +782,7 @@ public class VegetationLMA {
if (nw < data_source.length) { if (nw < data_source.length) {
weights[nw] = sw[data_source[nw][0][0]] * k; weights[nw] = sw[data_source[nw][0][0]] * k;
} else { } else {
weights[nw] = extra_weights * k; weights[nw] = reg_sample_weight;
} }
} }
} }
...@@ -872,6 +943,7 @@ public class VegetationLMA { ...@@ -872,6 +943,7 @@ public class VegetationLMA {
Arrays.fill(par_index[TVAO_VEGETATION], -1); Arrays.fill(par_index[TVAO_VEGETATION], -1);
Arrays.fill(par_index[TVAO_VEGETATION_ALPHA], -1); Arrays.fill(par_index[TVAO_VEGETATION_ALPHA], -1);
int par_num = 0; int par_num = 0;
ind_pars_terrain = 0;
for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) {
int row = woi.y + drow; int row = woi.y + drow;
for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) {
...@@ -883,7 +955,8 @@ public class VegetationLMA { ...@@ -883,7 +955,8 @@ public class VegetationLMA {
} }
} }
} }
num_pars_terrain = par_num; num_pars_terrain = par_num;
ind_pars_vegetation = par_num;
for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) {
int row = woi.y + drow; int row = woi.y + drow;
for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) {
...@@ -895,7 +968,8 @@ public class VegetationLMA { ...@@ -895,7 +968,8 @@ public class VegetationLMA {
} }
} }
} }
num_pars_vegetation = par_num - num_pars_terrain; ind_pars_vegetation_alpha = par_num;
num_pars_vegetation = par_num - ind_pars_vegetation;
for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) {
int row = woi.y + drow; int row = woi.y + drow;
for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) {
...@@ -907,11 +981,13 @@ public class VegetationLMA { ...@@ -907,11 +981,13 @@ public class VegetationLMA {
} }
} }
} }
int num_pars_pixel = par_num; num_pars_vegetation_alpha = par_num - ind_pars_vegetation_alpha; // normally should be == num_pars_vegetation
// int num_pars_pixel = par_num;
ind_pars_scenes = par_num;
for (int i = 0; i < par_index[TVAO_SCENE_OFFSET].length; i++) { for (int i = 0; i < par_index[TVAO_SCENE_OFFSET].length; i++) {
par_index[TVAO_SCENE_OFFSET][i] = par_num++; par_index[TVAO_SCENE_OFFSET][i] = par_num++;
} }
num_pars_scenes = par_num - num_pars_pixel; num_pars_scenes = par_num - ind_pars_scenes;
parameters_vector = new double [par_num]; parameters_vector = new double [par_num];
} }
......
...@@ -636,7 +636,7 @@ public class VegetationModel { ...@@ -636,7 +636,7 @@ public class VegetationModel {
double [] terrain_average, // full image average terrain (no nulls) double [] terrain_average, // full image average terrain (no nulls)
double [] vegetation_average, // full image average vegetation (with nulls) double [] vegetation_average, // full image average vegetation (with nulls)
double [][] terrain_rendered, // terrain rendered for scenes (has nulls) double [][] terrain_rendered, // terrain rendered for scenes (has nulls)
double [][][] vegetation_offsets, // [num_scenes][pixel]{dx,dy} differential offsets of vegetation to terrain grid double [][][] vegetation_offsets, // [num_scenes][pixel]{dx,dy} differential offsets of vegetation to terrain grid
String [] titles, String [] titles,
int debugLevel) { int debugLevel) {
boolean diff_mode = true; boolean diff_mode = true;
...@@ -698,11 +698,18 @@ public class VegetationModel { ...@@ -698,11 +698,18 @@ public class VegetationModel {
int min_scenes = 10; int min_scenes = 10;
double default_alpha = 0.8; double default_alpha = 0.8;
double [] scene_weights = null; double [] scene_weights = null;
double reg_weights = 0.25; // fraction of the total weight used for regularization
double alpha_loss = 1.0; // quadratic loss when alpha reaches -1.0 or 2.0
double alpha_offset = 0.0; // if >0, start losses above 0.0 and below 1.0;
int num_samples = vegetationLMA.prepareLMA( int num_samples = vegetationLMA.prepareLMA(
woi50, // final Rectangle woi, woi50, // final Rectangle woi,
min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence
default_alpha, // final double default_alpha, default_alpha, // final double default_alpha,
scene_weights, // final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? scene_weights, // final double [] scene_weights, // null or per-scene weights (higher for larger offsets)?
reg_weights, // final double reg_weights, // fraction of the total weight used for regularization
alpha_loss, // final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0
alpha_offset, // final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0
debugLevel); // final int debugLevel); debugLevel); // final int debugLevel);
double lambda = 0.1; double lambda = 0.1;
...@@ -712,6 +719,9 @@ public class VegetationModel { ...@@ -712,6 +719,9 @@ public class VegetationModel {
boolean last_run = false; boolean last_run = false;
double rms_diff = 0.0001; double rms_diff = 0.0001;
int num_iter = 100; int num_iter = 100;
vegetationLMA.debug_index = 0;
vegetationLMA.debug_image = new double [num_iter][];
int lma_rslt= vegetationLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately) int lma_rslt= vegetationLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately)
lambda, // double lambda, // 0.1 lambda, // double lambda, // 0.1
lambda_scale_good,// double lambda_scale_good,// 0.5 lambda_scale_good,// double lambda_scale_good,// 0.5
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment