📄 lvq_rout.cpp
字号:
lensam = length/sammon->times;
}
else
lensam = length + 1;
for (le = 0; le < length; le++, datatmp = next_entry(&p))
{
if (datatmp == NULL)
{
datatmp = rewind_entries(data, &p);
if (datatmp == NULL)
{
Msg(0, "lvq1_training: can't rewind data (%ld/%ld iterations)",
le, length);
return NULL;
}
}
find_winner(codes, datatmp, &win, 1);
shortest = win.diff;
best = win.winner;
label = get_entry_label(best);
talpha = get_alpha(le, length, alpha);
/* Was the classification correct? If classification was
correct; move towards, else move away */
if (label == get_entry_label(datatmp))
adapt_vector(best, datatmp, dim, talpha);
else
adapt_vector(best, datatmp, dim, -talpha);
/* save snapshot when needed */
if ((snap) && ((le % snap->interval) == 0) && (le > 0))
{
ifverbose(3)
Msg(0, "Saving snapshot, %ld iterations", le);
if (save_snapshot(teach, le))
{
Msg(0, "snapshot failed");
}
}
ifverbose(1)
mprint(length - le);
if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
{
put_sammon(teach, "lvq1 training", le, sammon->times);
}
}
ifverbose(1)
Msg(0, "");
return(codes);
}
/* Train by olvq1, whereby optimized alpha values are used. The
nearest code vector is modified; If classification is correct, move
it towards the input entry, if classification is incorrect, move it
away from the input entry */
struct entries *olvq1_training(struct teach_params *teach,
char *infile, char *outfile)
{
long i, le, noc, length = teach->length;
int label;
int numofe;
int potobe, dim;
float shortest;
float *talpha;
struct data_entry *datatmp, *best;
VECTOR_ADAPT *adapt = teach->vector_adapt;
WINNER_FUNCTION *find_winner = teach->winner;
/* ALPHA_FUNC *get_alpha = teach->alpha_func; */
struct entries *data = teach->data;
struct entries *codes = teach->codes;
struct snapshot_info *snap = teach->snapshot;
float alpha = teach->alpha;
struct winner_info win;
eptr p;
long lensam;
CSammon *sammon = teach->sammon;
dim = codes->dimension;
rewind_entries(codes, &p); /* make sure codes are loaded */
noc = codes->num_entries;
/* Get the initial alpha values: */
/* There are several possibilities: the user may define them; */
/* if not, then they may be read from file; */
/* if no file exists, then default values are used. */
talpha = (float *) oalloc(sizeof(float) * noc);
if (alpha == 0.0) {
if (!alpha_read(talpha, noc, infile)) {
alpha = 0.3;
for (i = 0; i < noc; i++) {
talpha[i] = alpha;
}
}
}
else {
for (i = 0; i < noc; i++) {
talpha[i] = alpha;
}
}
if ((datatmp = rewind_entries(data, &p)) == NULL)
{
Msg(0, "olvq1_training: can't get data");
return NULL;
}
numofe = data->flags.totlen_known ? data->num_entries : 0;
if (sammon != NULL)
{
lensam = length/sammon->times;
}
else
lensam = length + 1;
for (le = 0; le < length; le++, datatmp = next_entry(&p))
{
if (datatmp == NULL)
{
datatmp = rewind_entries(data, &p);
if (datatmp == NULL)
{
Msg(0, "olvq1_training: can't rewind data (%ld/%ld iterations)",
le, length);
return NULL;
}
}
find_winner(codes, datatmp, &win, 1);
shortest = win.diff;
best = win.winner;
label = get_entry_label(best);
potobe = win.index;
/* Individual alphas for every codebook vector; */
/* Was the classification correct? */
if (label == get_entry_label(datatmp)) {
/* If classification was correct, move towards */
adapt(best, datatmp, dim, talpha[potobe]);
talpha[potobe] = talpha[potobe] / (1 + talpha[potobe]);
}
else {
/* If classification was incorrect, move away */
adapt(best, datatmp, dim, -talpha[potobe]);
talpha[potobe] = talpha[potobe] / (1 - talpha[potobe]);
if (talpha[potobe] > alpha)
talpha[potobe] = alpha;
}
if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
{
put_sammon(teach, "olvq1 training", le, sammon->times);
}
/* save snapshot when needed */
if ((snap) && ((le % snap->interval) == 0) && (le > 0))
{
ifverbose(3)
Msg(0, "Saving snapshot, %ld iterations", le);
if (save_snapshot(teach, le))
{
Msg(0, "snapshot failed");
}
}
ifverbose(1)
mprint(length - le);
}
ifverbose(1)
Msg(0, "");
/* Store the alphas */
alpha_write(talpha, noc, outfile);
return(codes);
}
/* Train by lvq2. Two nearest codebook vectors are modified under
specified conditions */
struct entries *lvq2_training(struct teach_params *teach, float winlen)
{
long le, total_length, numofe;
int label, nlabel, datalabel, dim;
float shortest, nshortest;
float talpha;
struct data_entry *datatmp;
struct data_entry *best, *nbest, *ntmp;
VECTOR_ADAPT *adapt = teach->vector_adapt;
/*MODIFICATION*/
WINNER_FUNCTION *find_winners = find_winner_knn/*teach->winner*/;
ALPHA_FUNC *get_alpha = teach->alpha_func;
struct entries *data = teach->data;
struct entries *codes = teach->codes;
long length = teach->length;
float alpha = teach->alpha;
struct snapshot_info *snap = teach->snapshot;
struct winner_info win[2];
eptr p;
long lensam;
CSammon *sammon = teach->sammon;
dim = codes->dimension;
total_length = length;
if ((datatmp = rewind_entries(data, &p)) == NULL)
{
Msg(0, "lvq2_training: can't get data");
return NULL;
}
numofe = data->flags.totlen_known ? data->num_entries : 0;
if (sammon != NULL)
{
lensam = length/sammon->times;
}
else
lensam = length + 1;
for (le = 0; le < length; le++, datatmp = next_entry(&p))
{
if (datatmp == NULL)
{
datatmp = rewind_entries(data, &p);
if (datatmp == NULL)
{
Msg(0, "lvq2_training: can't rewind data (%ld/%ld iterations)",
le, length);
return NULL;
}
}
/* True alpha is decreasing linearly during the training */
talpha = get_alpha(le, length, alpha);
/* find two best mathing units */
find_winners(codes, datatmp, win, 2);
shortest = win[0].diff;
best = win[0].winner;
label = get_entry_label(best);
nshortest = win[1].diff;
nbest = win[1].winner;
nlabel = get_entry_label(nbest);
datalabel = get_entry_label(datatmp);
/* Corrections are made only if the two nearest codebook vectors
belong to different classes, one of them correct, and if the
input entry is located inside a window between the nearest codebook
vectors */
if (label != nlabel) {
if ((label == datalabel) || (nlabel == datalabel)) {
/* If the ration of distances to the two nearest codebook vectors
satisfies a condition */
if ((shortest/nshortest) > ((1-winlen)/(1+winlen))) {
/* If the second best is correct swap the entries */
if (nlabel == datalabel) {
ntmp = best;
best = nbest;
nbest = ntmp;
}
/* Move the entries */
adapt(best, datatmp, dim, talpha);
adapt(nbest, datatmp, dim, -talpha);
}
}
}
if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
{
put_sammon(teach, "lvq2 training", le, sammon->times);
}
/* save snapshot when needed */
if ((snap) && ((le % snap->interval) == 0) && (le > 0))
{
ifverbose(3)
Msg(0, "Saving snapshot, %ld iterations", le);
if (save_snapshot(teach, le))
{
Msg(0, "snapshot failed");
}
}
ifverbose(1)
mprint(length - le);
}
ifverbose(1)
Msg(0, "");
return(codes);
}
/* Train by lvq3. Two nearest codebook vectors are modified under
specified conditions */
struct entries *lvq3_training(struct teach_params *teach,
float epsilon, float winlen)
{
long le, numofe, total_length;
int label, nlabel, datalabel, dim;
float shortest, nshortest;
float talpha;
struct data_entry *datatmp, *best, *nbest, *ntmp;
VECTOR_ADAPT *adapt = teach->vector_adapt;
/*MODIFICATION*/
WINNER_FUNCTION *find_winners = find_winner_knn/*teach->winner*/;
ALPHA_FUNC *get_alpha = teach->alpha_func;
struct entries *data = teach->data;
struct entries *codes = teach->codes;
struct snapshot_info *snap = teach->snapshot;
long length = teach->length;
float alpha = teach->alpha;
struct winner_info win[2];
eptr p;
long lensam;
CSammon *sammon = teach->sammon;
dim = codes->dimension;
total_length = length;
if ((datatmp = rewind_entries(data, &p)) == NULL)
{
Msg(0, "lvq3_training: can't get data");
return NULL;
}
numofe = data->flags.totlen_known ? data->num_entries : 0;
if (sammon != NULL)
{
lensam = length/sammon->times;
}
else
lensam = length + 1;
for (le = 0; le < length; le++, datatmp = next_entry(&p))
{
if (datatmp == NULL)
{
datatmp = rewind_entries(data, &p);
if (datatmp == NULL)
{
Msg(0, "lvq3_training: can't rewind data (%ld/%ld iterations)",
le, length);
return NULL;
}
}
/* True alpha is decreasing linearly during the training */
talpha = get_alpha(le, length, alpha);
/* find two best mathing units */
find_winners(codes, datatmp, win, 2);
shortest = win[0].diff;
best = win[0].winner;
label = get_entry_label(best);
nshortest = win[1].diff;
nbest = win[1].winner;
nlabel = get_entry_label(nbest);
datalabel = get_entry_label(datatmp);
/* Corrections are made if the two nearest codebook vectors
belong to different classes, one of them correct, and if the
input entry is located inside a window between the nearest codebook
vectors OR the two nearest codebook vectors both belong to the
correct Class */
if (label != nlabel) {
if ((label == datalabel) || (nlabel == datalabel)) {
/* If the ration of distances to the two nearest codebook vectors
satisfies a condition */
if ((shortest/nshortest) > ((1-winlen)/(1+winlen))) {
/* If the second best is correct swap the entries */
if (nlabel == datalabel) {
ntmp = best;
best = nbest;
nbest = ntmp;
}
/* Move the entries */
adapt(best, datatmp, dim, talpha);
adapt(nbest, datatmp, dim, -talpha);
}
}
}
else {
if (label == datalabel) {
/* Move the entries, both toward */
adapt(best, datatmp, dim, talpha * epsilon);
adapt(nbest, datatmp, dim, talpha * epsilon);
}
}
if (sammon != NULL && sammon->length != 0 && (le % lensam) == 0)
{
put_sammon(teach, "lvq3 training", le, sammon->times);
}
/* save snapshot when needed */
if ((snap) && ((le % snap->interval) == 0) && (le > 0))
{
ifverbose(3)
Msg(0, "Saving snapshot, %ld iterations", le);
if (save_snapshot(teach, le))
{
Msg(0, "snapshot failed");
}
}
ifverbose(1)
mprint(length - le);
}
ifverbose(1)
Msg(0, "");
return(codes);
}
float devdist( float *v1, float *v2, int dim)
{
float diff, d;
d = 0.0;
while (dim-- > 0) {
diff = *v1++ - *v2++;
d += diff*diff;
}
return(d);
}
struct mindists *deviations(struct entries *codes, struct mindists *md)
{
int i, j;
int nol, dim, *noe, label;
int *count;
float *devs;
float *avers;
struct data_entry *entr;
eptr p;
dim = codes->dimension;
nol = md->num_classes;
noe = md->noe;
count = (int *) oalloc(sizeof(int) * nol);
devs = (float*)calloc(nol, sizeof(float));
if ((md->devs = devs) == NULL)
{
return NULL;
}
avers = (float *) oalloc(sizeof(float) * nol * dim);
for (i = 0; i < nol; i++) {
devs[i] = 0.0;
for (j = 0; j < dim; j++) {
avers[i*dim+j] = 0.0;
}
count[i] = 0;
}
/* Compute averages */
entr = rewind_entries(codes, &p);
while (entr != NULL) {
label = get_entry_label(entr);
for (i = 0; i < nol; i++)
if (label == md->Class[i])
break;
for (j = 0; j < dim; j++)
if (!((entr->mask != NULL) && (entr->mask[j] != 0)))
{
avers[i*dim+j] += entr->points[j];
}
/* count[i]++; */
entr = next_entry(&p);
}
for (i = 0; i < nol; i++) {
for (j = 0; j < dim; j++) {
avers[i*dim+j] /= noe[i];
}
}
/* Compute deviations */
entr = rewind_entries(codes, &p);
while (entr != NULL) {
label = get_entry_label(entr);
for (i = 0; i < nol; i++)
if (label == md->Class[i])
break;
devs[i] += devdist(entr->points,
&(avers[i*dim]), dim);
entr = next_entry(&p);
}
for (i = 0; i < nol; i++) {
devs[i] = sqrt(devs[i]/noe[i]);
}
return(md);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -