Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dlib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
钟尚武
dlib
Commits
fc65fab0
Commit
fc65fab0
authored
Oct 28, 2011
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changed find_max_factor_graph_viterbi() so you can use run-time
defined order and num_states parameters.
parent
afddb2d4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
85 additions
and
50 deletions
+85
-50
find_max_factor_graph_viterbi.h
dlib/optimization/find_max_factor_graph_viterbi.h
+53
-27
find_max_factor_graph_viterbi_abstract.h
dlib/optimization/find_max_factor_graph_viterbi_abstract.h
+24
-15
find_max_factor_graph_viterbi.cpp
dlib/test/find_max_factor_graph_viterbi.cpp
+8
-8
No files found.
dlib/optimization/find_max_factor_graph_viterbi.h
View file @
fc65fab0
...
...
@@ -62,11 +62,14 @@ namespace dlib
)
{
using
namespace
dlib
::
impl
;
const
unsigned
long
order
=
map_problem
::
order
;
const
unsigned
long
num_states
=
map_problem
::
num_states
;
COMPILE_TIME_ASSERT
(
num_states
>
0
);
const
unsigned
long
order
=
prob
.
order
();
const
unsigned
long
num_states
=
prob
.
num_states
();
DLIB_ASSERT
(
prob
.
num_states
()
>
0
,
"
\t
void find_max_factor_graph_viterbi()"
<<
"
\n\t
The nodes in a factor graph have to be able to take on more than 0 states."
);
DLIB_ASSERT
(
std
::
pow
(
num_states
,(
double
)
order
)
<
std
::
numeric_limits
<
unsigned
long
>::
max
(),
"
\t
void find_max_factor_graph_viterbi()"
<<
"
\n\t
The order is way too large for this algorithm to handle."
...
...
@@ -144,32 +147,55 @@ namespace dlib
}
}
else
else
if
(
order
==
1
)
{
matrix
<
unsigned
long
,
1
,
order
+
1
>
node_states
;
node_states
=
0
;
unsigned
long
count
=
0
;
for
(
unsigned
long
i
=
0
;
i
<
trellis_size
;
++
i
)
{
unsigned
long
back_index
=
0
;
double
best_score
=
-
std
::
numeric_limits
<
double
>::
infinity
();
for
(
unsigned
long
s
=
0
;
s
<
num_states
;
++
s
)
{
const
double
temp
=
prob
.
factor_value
(
node
,
node_states
)
+
trellis
[
node
-
1
][
count
%
trellis_size
].
val
;
if
(
temp
>
best_score
)
{
best_score
=
temp
;
back_index
=
count
%
trellis_size
;
}
advance_state
(
node_states
,
num_states
);
++
count
;
}
trellis
[
node
][
i
].
val
=
best_score
;
trellis
[
node
][
i
].
back_index
=
back_index
;
/*
WHAT'S THE DEAL WITH THIS PREPROCESSOR MACRO?
Well, if we can declare the dimensions of node_states as a compile
time constant then this function runs significantly faster. So this macro
is here to let us do that. It just lets us avoid replicating this code
block in the following if statements for different order sizes.
*/
#define DLIB_FMFGV_WORK \
node_states = 0; \
unsigned long count = 0; \
for (unsigned long i = 0; i < trellis_size; ++i) \
{ \
unsigned long back_index = 0; \
double best_score = -std::numeric_limits<double>::infinity(); \
for (unsigned long s = 0; s < num_states; ++s) \
{ \
const double temp = prob.factor_value(node,node_states) + trellis[node-1][count%trellis_size].val; \
if (temp > best_score) \
{ \
best_score = temp; \
back_index = count%trellis_size; \
} \
advance_state(node_states,num_states); \
++count; \
} \
trellis[node][i].val = best_score; \
trellis[node][i].back_index = back_index; \
}
matrix
<
unsigned
long
,
1
,
2
>
node_states
;
DLIB_FMFGV_WORK
}
else
if
(
order
==
2
)
{
matrix
<
unsigned
long
,
1
,
3
>
node_states
;
DLIB_FMFGV_WORK
}
else
if
(
order
==
3
)
{
matrix
<
unsigned
long
,
1
,
4
>
node_states
;
DLIB_FMFGV_WORK
}
else
{
// The general case, here we don't define the size of node_states at compile time.
matrix
<
unsigned
long
,
1
,
0
>
node_states
(
order
+
1
);
DLIB_FMFGV_WORK
}
}
...
...
dlib/optimization/find_max_factor_graph_viterbi_abstract.h
View file @
fc65fab0
...
...
@@ -29,13 +29,22 @@ namespace dlib
public
:
// This model can represent a high order Markov chain. If order==1 then map_problem
// represents a basic chain-structured graph where nodes only depend on their immediate
// neighbors. However, high order Markov models can also be used by setting order > 1.
const
static
unsigned
long
order
;
unsigned
long
order
(
)
const
;
/*!
ensures
- returns the order of this model. The order has the following interpretation:
This model can represent a high order Markov chain. If order()==1 then map_problem
represents a basic chain-structured graph where nodes only depend on their immediate
neighbors. However, high order Markov models can also be used by setting order() > 1.
!*/
// Defines the number of states attainable by each variable/node in the graph.
const
static
unsigned
long
num_states
;
unsigned
long
num_states
(
)
const
;
/*!
ensures
- returns the number of states attainable by each variable/node in the graph.
!*/
unsigned
long
number_of_nodes
(
)
const
;
...
...
@@ -57,13 +66,13 @@ namespace dlib
- EXP::type == unsigned long
(i.e. node_states contains unsigned longs)
- node_id < number_of_nodes()
- node_states.size() == min(node_id, order) + 1
- node_states.size() == min(node_id, order
()
) + 1
- is_vector(node_states) == true
- max(node_states) < num_states
- max(node_states) < num_states
()
ensures
- In a chain-structured graph, each node has a potential function associated with
it. The potential function operates on the variable given by the node as well
as the order previous variables. Therefore, factor_value() returns the value
as the order
()
previous variables. Therefore, factor_value() returns the value
of the factor/potential function associated with node node_id where the following
nodes take on the values defined below:
- node_states(0) == the value of the node with ID node_id
...
...
@@ -83,8 +92,8 @@ namespace dlib
);
/*!
requires
-
map_problem::num_states
> 0
- std::pow(
map_problem::num_states, map_problem::order
) < std::numeric_limits<unsigned long>::max()
-
prob.num_states()
> 0
- std::pow(
prob.num_states(), prob.order()
) < std::numeric_limits<unsigned long>::max()
(i.e. The Viterbi algorithm is exponential in the order of the map problem. So don't
make order too large.)
- map_problem == an object with an interface compatible with the map_problem
...
...
@@ -94,11 +103,11 @@ namespace dlib
graphical model or factor graph. That is, it attempts to solve a certain kind of
optimization problem which can be defined as follows:
- Let X denote a set of prob.number_of_nodes() integer valued variables, each taking
a value in the range [0,
map_problem::num_states
).
a value in the range [0,
prob.num_states()
).
- Let X(i) = the ith variable in X.
- Let F(i) = factor_value_i(X(i), X(i-1), ..., X(i-
map_problem::order
))
- Let F(i) = factor_value_i(X(i), X(i-1), ..., X(i-
prob.order()
))
(This is the value returned by prob.factor_value(i, node_states). Note that
each factor
value function operates on at most map_problem::order
+1 variables.
each factor
's value function operates on at most prob.order()
+1 variables.
Moreover, the variables are adjacent and hence the graph is "chain-structured".)
Then this function finds the assignments to the X variables which
...
...
@@ -107,7 +116,7 @@ namespace dlib
- #map_assignment == the result of the optimization.
- #map_assignment.size() == prob.number_of_nodes()
- for all valid i:
- #map_assignment[i] <
map_problem::num_states
- #map_assignment[i] <
prob.num_states()
- #map_assignment[i] == The MAP assignment for node/variable i.
!*/
...
...
dlib/test/find_max_factor_graph_viterbi.cpp
View file @
fc65fab0
...
...
@@ -31,12 +31,12 @@ namespace
class
map_problem
{
public
:
const
static
unsigned
long
order
=
O
;
const
static
unsigned
long
num_states
=
NS
;
unsigned
long
order
()
const
{
return
O
;
}
unsigned
long
num_states
()
const
{
return
NS
;
}
map_problem
()
{
data
=
randm
(
number_of_nodes
(),(
long
)
std
::
pow
(
num_states
,(
double
)
order
+
1
),
rnd
);
data
=
randm
(
number_of_nodes
(),(
long
)
std
::
pow
(
num_states
(),(
double
)
order
()
+
1
),
rnd
);
}
unsigned
long
number_of_nodes
(
...
...
@@ -56,11 +56,11 @@ namespace
if
(
node_states
.
size
()
==
1
)
return
data
(
node_id
,
node_states
(
0
));
else
if
(
node_states
.
size
()
==
2
)
return
data
(
node_id
,
node_states
(
0
)
+
node_states
(
1
)
*
num_states
);
return
data
(
node_id
,
node_states
(
0
)
+
node_states
(
1
)
*
NS
);
else
if
(
node_states
.
size
()
==
3
)
return
data
(
node_id
,
(
node_states
(
0
)
+
node_states
(
1
)
*
num_states
)
*
num_states
+
node_states
(
2
));
return
data
(
node_id
,
(
node_states
(
0
)
+
node_states
(
1
)
*
NS
)
*
NS
+
node_states
(
2
));
else
return
data
(
node_id
,
((
node_states
(
0
)
+
node_states
(
1
)
*
num_states
)
*
num_states
+
node_states
(
2
))
*
num_states
+
node_states
(
3
));
return
data
(
node_id
,
((
node_states
(
0
)
+
node_states
(
1
)
*
NS
)
*
NS
+
node_states
(
2
))
*
NS
+
node_states
(
3
));
}
matrix
<
double
>
data
;
...
...
@@ -78,8 +78,8 @@ namespace
)
{
using
namespace
dlib
::
impl
;
const
int
order
=
map_problem
::
order
;
const
int
num_states
=
map_problem
::
num_states
;
const
int
order
=
prob
.
order
()
;
const
int
num_states
=
prob
.
num_states
()
;
map_assignment
.
resize
(
prob
.
number_of_nodes
());
double
best_score
=
-
std
::
numeric_limits
<
double
>::
infinity
();
...
...
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