Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
2ab7afe9
Commit
2ab7afe9
authored
Apr 29, 2012
by
Davis King
Browse files
Added some more unit tests. Also fixed a bug in the potts_model_score() routine.
parent
9cc3947a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
211 additions
and
2 deletions
+211
-2
dlib/graph_cuts/find_max_factor_graph_potts.h
dlib/graph_cuts/find_max_factor_graph_potts.h
+46
-1
dlib/graph_cuts/find_max_factor_graph_potts_abstract.h
dlib/graph_cuts/find_max_factor_graph_potts_abstract.h
+38
-1
dlib/test/graph_cuts.cpp
dlib/test/graph_cuts.cpp
+127
-0
No files found.
dlib/graph_cuts/find_max_factor_graph_potts.h
View file @
2ab7afe9
...
@@ -439,7 +439,9 @@ namespace dlib
...
@@ -439,7 +439,9 @@ namespace dlib
for
(
unsigned
long
n
=
0
;
n
<
g
.
number_of_neighbors
(
i
);
++
n
)
for
(
unsigned
long
n
=
0
;
n
<
g
.
number_of_neighbors
(
i
);
++
n
)
{
{
const
unsigned
long
idx2
=
g
.
get_neighbor
(
i
,
n
);
const
unsigned
long
idx2
=
g
.
get_neighbor
(
i
,
n
);
if
(
g
.
get_label
(
i
)
!=
g
.
get_label
(
idx2
)
&&
i
<
idx2
)
const
bool
label_i
=
(
g
.
get_label
(
i
)
!=
0
);
const
bool
label_idx2
=
(
g
.
get_label
(
idx2
)
!=
0
);
if
(
label_i
!=
label_idx2
&&
i
<
idx2
)
score
-=
g
.
factor_value_disagreement
(
i
,
idx2
);
score
-=
g
.
factor_value_disagreement
(
i
,
idx2
);
}
}
}
}
...
@@ -447,6 +449,49 @@ namespace dlib
...
@@ -447,6 +449,49 @@ namespace dlib
return
score
;
return
score
;
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
graph_type
>
typename
graph_type
::
edge_type
potts_model_score
(
const
graph_type
&
g
,
const
std
::
vector
<
node_label
>&
labels
)
{
DLIB_ASSERT
(
graph_contains_length_one_cycle
(
g
)
==
false
,
"
\t
edge_type potts_model_score(g,labels)"
<<
"
\n\t
Invalid inputs were given to this function."
);
typedef
typename
graph_type
::
edge_type
edge_type
;
typedef
typename
graph_type
::
type
type
;
// The edges and node's have to use the same type to represent factor weights!
COMPILE_TIME_ASSERT
((
is_same_type
<
edge_type
,
type
>::
value
==
true
));
typename
graph_type
::
edge_type
score
=
0
;
for
(
unsigned
long
i
=
0
;
i
<
g
.
number_of_nodes
();
++
i
)
{
const
bool
label
=
(
labels
[
i
]
!=
0
);
if
(
label
)
score
+=
g
.
node
(
i
).
data
;
}
for
(
unsigned
long
i
=
0
;
i
<
g
.
number_of_nodes
();
++
i
)
{
for
(
unsigned
long
n
=
0
;
n
<
g
.
node
(
i
).
number_of_neighbors
();
++
n
)
{
const
unsigned
long
idx2
=
g
.
node
(
i
).
neighbor
(
n
).
index
();
const
bool
label_i
=
(
labels
[
i
]
!=
0
);
const
bool
label_idx2
=
(
labels
[
idx2
]
!=
0
);
if
(
label_i
!=
label_idx2
&&
i
<
idx2
)
score
-=
g
.
node
(
i
).
edge
(
n
);
}
}
return
score
;
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
...
dlib/graph_cuts/find_max_factor_graph_potts_abstract.h
View file @
2ab7afe9
...
@@ -191,6 +191,42 @@ namespace dlib
...
@@ -191,6 +191,42 @@ namespace dlib
- Then this function returns F - D
- Then this function returns F - D
!*/
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
graph_type
>
typename
graph_type
::
edge_type
potts_model_score
(
const
graph_type
&
g
,
const
std
::
vector
<
node_label
>&
labels
);
/*!
requires
- graph_type is an implementation of dlib/graph/graph_kernel_abstract.h
- graph_type::edge_type is some signed type such as int or double
- graph_type::type must be the same type as graph_type::edge_type
- graph_contains_length_one_cycle(g) == false
ensures
- This function does the same thing as the version of potts_model_score()
defined above, except that this version operates on a dlib::graph
instead of a potts_problem object.
- computes the model score for the given graph and labeling. We define this
precisely below:
- let L(i) == the boolean label of the ith variable in g. Or in other
words, L(i) == (labels[i] != 0).
- let F == the sum of values of g.node(i).data for only i values
where L(i) == true.
- Let D == the sum of values of edge(g,i,j) for only i and j
values which meet the following conditions:
- i and j are neighbors in the graph defined by g, that is,
it is valid to call edge(g,i,j).
- L(i) != L(j)
- i < j
(i.e. We want to make sure to only count the edge between i and j once)
- Then this function returns F - D
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
template
<
...
@@ -232,7 +268,8 @@ namespace dlib
...
@@ -232,7 +268,8 @@ namespace dlib
- This routine simply converts g into a potts_problem and calls the
- This routine simply converts g into a potts_problem and calls the
version of find_max_factor_graph_potts() defined above on it. Therefore,
version of find_max_factor_graph_potts() defined above on it. Therefore,
this routine is just a convenience wrapper that lets you use a dlib::graph
this routine is just a convenience wrapper that lets you use a dlib::graph
to represent a potts problem.
to represent a potts problem. This means that this function maximizes
the value of potts_model_score(g, #labels).
- #labels.size() == g.number_of_nodes()
- #labels.size() == g.number_of_nodes()
- for all valid i:
- for all valid i:
- #labels[i] == the optimal label for g.node(i)
- #labels[i] == the optimal label for g.node(i)
...
...
dlib/test/graph_cuts.cpp
View file @
2ab7afe9
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#include <dlib/graph_cuts.h>
#include <dlib/graph_cuts.h>
#include <dlib/graph_utils.h>
#include <dlib/graph_utils.h>
#include <dlib/directed_graph.h>
#include <dlib/directed_graph.h>
#include <dlib/graph.h>
#include <dlib/rand.h>
#include <dlib/rand.h>
#include "tester.h"
#include "tester.h"
...
@@ -338,6 +339,125 @@ namespace
...
@@ -338,6 +339,125 @@ namespace
}
}
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
graph_type
>
void
brute_force_potts_model_on_graph
(
const
graph_type
&
g
,
std
::
vector
<
node_label
>&
labels_
)
{
std
::
vector
<
node_label
>
labels
;
labels
.
resize
(
g
.
number_of_nodes
());
const
unsigned
long
num
=
(
unsigned
long
)
std
::
pow
(
2.0
,
(
double
)
g
.
number_of_nodes
());
double
best_score
=
-
std
::
numeric_limits
<
double
>::
infinity
();
for
(
unsigned
long
i
=
0
;
i
<
num
;
++
i
)
{
for
(
unsigned
long
j
=
0
;
j
<
g
.
number_of_nodes
();
++
j
)
{
unsigned
long
T
=
(
1
)
<<
j
;
T
=
(
T
&
i
);
if
(
T
!=
0
)
labels
[
j
]
=
SINK_CUT
;
else
labels
[
j
]
=
SOURCE_CUT
;
}
double
score
=
potts_model_score
(
g
,
labels
);
if
(
score
>
best_score
)
{
best_score
=
score
;
labels_
=
labels
;
}
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
graph_type
>
void
make_random_undirected_graph
(
dlib
::
rand
&
rnd
,
graph_type
&
g
)
{
typedef
typename
graph_type
::
edge_type
edge_weight_type
;
g
.
clear
();
const
unsigned
int
num_nodes
=
rnd
.
get_random_32bit_number
()
%
8
;
g
.
set_number_of_nodes
(
num_nodes
);
const
unsigned
int
num_edges
=
static_cast
<
unsigned
int
>
(
num_nodes
*
(
num_nodes
-
1
)
/
2
*
rnd
.
get_random_double
()
+
0.5
);
// add the right number of randomly selected edges
unsigned
int
count
=
0
;
while
(
count
<
num_edges
)
{
unsigned
long
i
=
rnd
.
get_random_32bit_number
()
%
g
.
number_of_nodes
();
unsigned
long
j
=
rnd
.
get_random_32bit_number
()
%
g
.
number_of_nodes
();
if
(
i
!=
j
&&
g
.
has_edge
(
i
,
j
)
==
false
)
{
++
count
;
g
.
add_edge
(
i
,
j
);
edge
(
g
,
i
,
j
)
=
static_cast
<
edge_weight_type
>
(
rnd
.
get_random_double
()
*
50
);
}
}
for
(
unsigned
long
i
=
0
;
i
<
g
.
number_of_nodes
();
++
i
)
{
g
.
node
(
i
).
data
=
static_cast
<
edge_weight_type
>
(
rnd
.
get_random_gaussian
()
*
200
);
}
}
// ----------------------------------------------------------------------------------------
void
test_graph_potts_model
(
dlib
::
rand
&
rnd
)
{
using
namespace
std
;
double
brute_force_score
;
double
graph_cut_score
;
graph
<
double
,
double
>::
kernel_1a_c
temp
;
make_random_undirected_graph
(
rnd
,
temp
);
{
std
::
vector
<
node_label
>
labels
;
brute_force_potts_model_on_graph
(
temp
,
labels
);
for
(
unsigned
long
i
=
0
;
i
<
temp
.
number_of_nodes
();
++
i
)
{
dlog
<<
LTRACE
<<
"node "
<<
i
<<
": "
<<
(
int
)
labels
[
i
];
}
brute_force_score
=
potts_model_score
(
temp
,
labels
);
dlog
<<
LTRACE
<<
"brute force score: "
<<
brute_force_score
;
}
dlog
<<
LTRACE
<<
"******************"
;
{
std
::
vector
<
node_label
>
labels
;
find_max_factor_graph_potts
(
temp
,
labels
);
DLIB_TEST
(
temp
.
number_of_nodes
()
==
labels
.
size
());
for
(
unsigned
long
i
=
0
;
i
<
temp
.
number_of_nodes
();
++
i
)
{
dlog
<<
LTRACE
<<
"node "
<<
i
<<
": "
<<
(
int
)
labels
[
i
];
}
graph_cut_score
=
potts_model_score
(
temp
,
labels
);
dlog
<<
LTRACE
<<
"graph cut score: "
<<
graph_cut_score
;
}
DLIB_TEST_MSG
(
graph_cut_score
==
brute_force_score
,
std
::
abs
(
graph_cut_score
-
brute_force_score
));
dlog
<<
LTRACE
<<
"##################"
;
dlog
<<
LTRACE
<<
"##################"
;
dlog
<<
LTRACE
<<
"##################"
;
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
potts_prob
>
template
<
typename
potts_prob
>
...
@@ -732,6 +852,13 @@ namespace
...
@@ -732,6 +852,13 @@ namespace
dense_potts_problem
p
(
6
,
rnd
);
dense_potts_problem
p
(
6
,
rnd
);
impl_test_potts_model
(
p
);
impl_test_potts_model
(
p
);
}
}
for
(
int
k
=
0
;
k
<
300
;
++
k
)
{
dlog
<<
LTRACE
<<
"dense_potts_problem iter "
<<
k
;
print_spinner
();
test_graph_potts_model
(
rnd
);
}
}
}
}
a
;
}
a
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment