Commit a0220801 authored by Davis King's avatar Davis King

Upgraded the con_ layer so that you can set the nr or nc to 0 in the layer

specification and this means "make the filter cover the whole input image
dimension".  So it's just an easy way to make a filter sized exactly so that it
will have one output along that dimension.
parent 692ddb8c
......@@ -41,12 +41,14 @@ namespace dlib
public:
static_assert(_num_filters > 0, "The number of filters must be > 0");
static_assert(_nr > 0, "The number of rows in a filter must be > 0");
static_assert(_nc > 0, "The number of columns in a filter must be > 0");
static_assert(_nr >= 0, "The number of rows in a filter must be >= 0");
static_assert(_nc >= 0, "The number of columns in a filter must be >= 0");
static_assert(_stride_y > 0, "The filter stride must be > 0");
static_assert(_stride_x > 0, "The filter stride must be > 0");
static_assert(0 <= _padding_y && _padding_y < _nr, "The padding must be smaller than the filter size.");
static_assert(0 <= _padding_x && _padding_x < _nc, "The padding must be smaller than the filter size.");
static_assert(_nr==0 || (0 <= _padding_y && _padding_y < _nr), "The padding must be smaller than the filter size.");
static_assert(_nc==0 || (0 <= _padding_x && _padding_x < _nc), "The padding must be smaller than the filter size.");
static_assert(_nr!=0 || 0 == _padding_y, "If _nr==0 then the padding must be set to 0 as well.");
static_assert(_nc!=0 || 0 == _padding_x, "If _nr==0 then the padding must be set to 0 as well.");
con_(
num_con_outputs o
......@@ -65,8 +67,20 @@ namespace dlib
con_() : con_(num_con_outputs(_num_filters)) {}
long num_filters() const { return num_filters_; }
long nr() const { return _nr; }
long nc() const { return _nc; }
long nr() const
{
if (_nr==0)
return filters.nr();
else
return _nr;
}
long nc() const
{
if (_nc==0)
return filters.nc();
else
return _nc;
}
long stride_y() const { return _stride_y; }
long stride_x() const { return _stride_x; }
long padding_y() const { return padding_y_; }
......@@ -154,7 +168,10 @@ namespace dlib
template <typename SUBNET>
void setup (const SUBNET& sub)
{
long num_inputs = _nr*_nc*sub.get_output().k();
const long filt_nr = _nr!=0 ? _nr : sub.get_output().nr();
const long filt_nc = _nc!=0 ? _nc : sub.get_output().nc();
long num_inputs = filt_nr*filt_nc*sub.get_output().k();
long num_outputs = num_filters_;
// allocate params for the filters and also for the filter bias values.
params.set_size(num_inputs*num_filters_ + num_filters_);
......@@ -162,7 +179,7 @@ namespace dlib
dlib::rand rnd(std::rand());
randomize_parameters(params, num_inputs+num_outputs, rnd);
filters = alias_tensor(num_filters_, sub.get_output().k(), _nr, _nc);
filters = alias_tensor(num_filters_, sub.get_output().k(), filt_nr, filt_nc);
biases = alias_tensor(1,num_filters_);
// set the initial bias values to zero
......@@ -263,8 +280,8 @@ namespace dlib
{
out << "con\t ("
<< "num_filters="<<item.num_filters_
<< ", nr="<<_nr
<< ", nc="<<_nc
<< ", nr="<<item.nr()
<< ", nc="<<item.nc()
<< ", stride_y="<<_stride_y
<< ", stride_x="<<_stride_x
<< ", padding_y="<<item.padding_y_
......@@ -281,8 +298,8 @@ namespace dlib
{
out << "<con"
<< " num_filters='"<<item.num_filters_<<"'"
<< " nr='"<<_nr<<"'"
<< " nc='"<<_nc<<"'"
<< " nr='"<<item.nr()<<"'"
<< " nc='"<<item.nc()<<"'"
<< " stride_y='"<<_stride_y<<"'"
<< " stride_x='"<<_stride_x<<"'"
<< " padding_y='"<<item.padding_y_<<"'"
......
......@@ -673,10 +673,22 @@ namespace dlib
{
/*!
REQUIREMENTS ON TEMPLATE ARGUMENTS
All of them must be > 0.
Also, we require that:
- 0 <= _padding_y && _padding_y < _nr
- 0 <= _padding_x && _padding_x < _nc
- _num_filters > 0
- _nr >= 0
- _nc >= 0
- _stride_y > 0
- _stride_x > 0
- _padding_y >= 0
- _padding_x >= 0
- Also, we require that:
- if (_nr == 0) then
- _padding_y == 0
- else
- _padding_y < _nr
- if (_nc == 0) then
- _padding_x == 0
- else
- _padding_x < _nc
WHAT THIS OBJECT REPRESENTS
This is an implementation of the EXAMPLE_COMPUTATIONAL_LAYER_ interface
......@@ -690,6 +702,15 @@ namespace dlib
- OUT.k() == num_filters()
- OUT.nr() == 1+(IN.nr() + 2*padding_y() - nr())/stride_y()
- OUT.nc() == 1+(IN.nc() + 2*padding_x() - nc())/stride_x()
Note also that setting _nr or _nc to 0 has a special meaning of "set the
filter size equal to the input image size". Specifically, it means:
- if (_nr == 0) then
- nr() == IN.nr()
- OUT.nr() == 1
- if (_nc == 0) then
- nc() == IN.nc()
- OUT.nc() == 1
!*/
public:
......@@ -754,14 +775,22 @@ namespace dlib
) const;
/*!
ensures
- returns the number of rows in the filters in this layer.
- returns the number of rows in the filters in this layer. Note that if
nr()==0 then it means the size of the filter is not yet assigned, but
once setup() is called nr() will be set to the input tensor's nr().
Therefore, nr()==0 has the special interpretation of "be the same size as
the input tensor".
!*/
long nc(
) const;
/*!
ensures
- returns the number of columns in the filters in this layer.
- returns the number of columns in the filters in this layer. Note that if
nc()==0 then it means the size of the filter is not yet assigned, but
once setup() is called nc() will be set to the input tensor's nc().
Therefore, nc()==0 has the special interpretation of "be the same size as
the input tensor".
!*/
long stride_y(
......
......@@ -1715,6 +1715,24 @@ namespace
auto res = test_layer(l);
DLIB_TEST_MSG(res, res);
}
{
print_spinner();
con_<3,0,2,2,2> l;
auto res = test_layer(l);
DLIB_TEST_MSG(res, res);
}
{
print_spinner();
con_<3,2,0,2,2> l;
auto res = test_layer(l);
DLIB_TEST_MSG(res, res);
}
{
print_spinner();
con_<3,0,0,2,2> l;
auto res = test_layer(l);
DLIB_TEST_MSG(res, res);
}
{
print_spinner();
fc_<1,FC_HAS_BIAS> l;
......
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