Skip to content

Commit 1806ba3

Browse files
Bug with lenet
1 parent 6ee1818 commit 1806ba3

15 files changed

+120
-68
lines changed

CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ if (UNIX)
4040
endif(UNIX)
4141

4242
# moved the CXX flags to after the cuda_add_library call
43-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -fPIC -lopenblas\
43+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC -lopenblas\
4444
-lcudnn -lcurand -L /usr/lib/cuda/lib64 -lcudart -lcublas\
4545
-L /usr/lib/x86_64-linux-gnu -lblas\
4646
-Wall -std=c++17 -Wno-error=unused-command-line-argument")
4747
set(${LIBRARY_TARGET_NAME}_TEST
4848
#test/normalization.cpp
4949
#test/cifar10.cpp
50-
#test/mnist_lenet.cpp
50+
test/mnist_lenet.cpp
5151
test/mnist.cpp
5252
#test/inits.cpp
5353
#test/im2col_layer.cpp

include/layer/im2col_layer.h

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ class Im2ColLayer : public Layer {
2626
Stride _stride;
2727
ImageShape _inp, _out;
2828
Channels _channels;
29-
//std::shared_ptr<Convolution> next;
3029

3130
void initialize_output_dimension() override;
3231
void check_size(const SharedStorage&, const SharedStorage&);

include/layer/layer.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ class Layer {
99
friend class NeuralNetwork;
1010
typedef std::shared_ptr<Storage> SharedStorage;
1111
typedef std::vector<std::shared_ptr<Storage>> VecSharedStorage;
12+
std::string _name;
1213
std::vector<int> _out_dim;
1314
std::vector<SharedStorage> parameters;
1415
std::vector<SharedStorage> gradients;
15-
std::string _name;
1616
std::shared_ptr<Layer> _previous;
1717
virtual void initialize_output_dimension(const std::shared_ptr<Layer>&);
1818
virtual void initialize_output_dimension();
1919

2020
public:
21-
Layer() : _name("Template"){};
22-
explicit Layer(const std::string& s): _name(s) {};
21+
Layer();
22+
explicit Layer(const std::string& s);
2323
virtual ~Layer() = default;
2424
virtual int input_dimension() {return 0;}
2525
virtual int input_dimension() const {return 0;}

include/layer/pooling.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Pooling : public Layer {
88
public:
99
//Pooling(int);
1010
Pooling(Window, Stride, ImageShape, Channels);
11-
Pooling(Window, Stride, const std::shared_ptr<Convolution>&);
11+
Pooling(Window, Stride, const std::shared_ptr<Layer>&);
1212
virtual ~Pooling() = default;
1313
void forward_gpu(const std::shared_ptr<Storage>&,
1414
std::shared_ptr<Storage>&, const std::string&) override;
@@ -32,6 +32,6 @@ class Pooling : public Layer {
3232
void initialize_masking();
3333
void inline check_input_size(const SharedStorage&);
3434
void initialize_output_dimension() override;
35-
//void initialize_previous(Layer*);
35+
void initialize_from_previous(const std::shared_ptr<Layer>&);
3636
};
3737
#endif

include/network.h

+1
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,6 @@ class NeuralNetwork {
9595
std::mt19937&);
9696
void prepare_subset(const std::vector<int>&, std::vector<int>&, int&,
9797
const int&);
98+
int check_input_dimension(const std::vector<int>&);
9899
};
99100
#endif

src/layer/convolution.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//#include "/usr/lib/x86_64-linux-gnu/cblas_atlas.h>
55
// c
66
#include <iostream>
7+
#include <iterator>
78
#include <memory>
89
#include <random>
910
#include <stdexcept>
@@ -23,7 +24,7 @@ Convolution::Convolution(FilterShape filtershape, Pad pad, Stride stride,
2324
_channels(channels) {
2425
cublasStatus_t stat = cublasCreate(&_handle);
2526
CHECK_CUBLAS(stat);
26-
//initialize_output_dimension();
27+
// initialize_output_dimension();
2728
initialize_weight(init);
2829
initialize_bias();
2930
initialize_grad();
@@ -42,8 +43,8 @@ Convolution::Convolution(FilterShape filtershape, Pad pad, Stride stride,
4243
_channels(0) {
4344
cublasStatus_t stat = cublasCreate(&_handle);
4445
CHECK_CUBLAS(stat);
45-
initialize_output_dimension();
4646
initialize_input_dimension(previous);
47+
initialize_output_dimension();
4748
initialize_weight(init);
4849
initialize_bias();
4950
initialize_grad();
@@ -60,7 +61,14 @@ void Convolution::initialize_input_dimension(
6061
_channels = Channels(channels);
6162
_inp = ImageShape(height, width);
6263
} else {
63-
throw std::invalid_argument("Cannot construct the thing");
64+
std::stringstream ss;
65+
ss << "Cannot construct the convolution layer as the previous layer's"
66+
" output don't match. Received\n";
67+
std::copy(shapes.begin(), shapes.end(),
68+
std::ostream_iterator<int>(ss, " "));
69+
ss << "in:\n" << __PRETTY_FUNCTION__ << "\ncalled from " << __FILE__
70+
<< " at " << __LINE__;
71+
throw std::invalid_argument(ss.str());
6472
}
6573
}
6674

@@ -76,7 +84,7 @@ void Convolution::initialize_output_dimension() {
7684
int out_width =
7785
(_inp.second() + 2 * _pad.get() - _kernel.second()) / _stride.get() + 1;
7886
_out = ImageShape(out_height, out_width);
79-
_out_dim.push_back(_channels.get());
87+
_out_dim[0] = _channels.get();
8088
_out_dim.push_back(out_height);
8189
_out_dim.push_back(out_width);
8290
}

src/layer/dense.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void Dense::initialize_input_dimension(const std::shared_ptr<Layer>& previous) {
7171
_in = Features(i);
7272
}
7373

74-
void Dense::initialize_output_dimension() { _out_dim.push_back(_out.get()); }
74+
void Dense::initialize_output_dimension() { _out_dim[0] =_out.get(); }
7575

7676
void Dense::forward_cpu(const SharedStorage& in, SharedStorage& out,
7777
const std::string&) {

src/layer/im2col_layer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Im2ColLayer::Im2ColLayer(const std::shared_ptr<Convolution>& convolution_layer)
1313
_out(convolution_layer->_out),
1414
_channels(convolution_layer->_channels) {
1515
_previous = convolution_layer->_previous;
16-
//convolution_layer->reset_previous(std::make_shared<Layer>(this));
16+
// convolution_layer->reset_previous(std::make_shared<Layer>(this));
1717
initialize_output_dimension();
1818
;
1919
}

src/layer/input.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ Input::Input(Features features)
55
_features(features),
66
_channels(0),
77
_img(0, 0) {
8-
_out_dim.push_back(_features.get());
8+
_out_dim[0] = _features.get();
99
}
1010

1111
Input::Input(Channels channels, ImageShape img)
1212
: Layer("Input"), _features(0), _channels(channels), _img(img) {
13-
_out_dim.push_back(_channels.get());
13+
_out_dim[0] = _channels.get();
1414
_out_dim.push_back(_img.first());
1515
_out_dim.push_back(_img.second());
1616
};

src/layer/layer.cpp

+26-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
#include "../../include/layer/layer.h"
2+
3+
Layer::Layer(const std::string& s)
4+
: _name(s), _out_dim(1), parameters(), gradients(), _previous(NULL) {
5+
_out_dim[0] = 0;
6+
}
7+
8+
Layer::Layer()
9+
: _name("Layer"), _out_dim(1), parameters(), gradients(), _previous(NULL) {
10+
_out_dim[0] = 0;
11+
}
12+
213
typedef std::vector<std::shared_ptr<Storage>> VecSharedStorage;
314

4-
void Layer::forward_gpu(const SharedStorage&, SharedStorage&, const std::string&) { ; };
5-
void Layer::forward_cpu(const SharedStorage&, SharedStorage&, const std::string&) { ; };
15+
void Layer::forward_gpu(const SharedStorage&, SharedStorage&,
16+
const std::string&) {
17+
;
18+
};
19+
void Layer::forward_cpu(const SharedStorage&, SharedStorage&,
20+
const std::string&) {
21+
;
22+
};
623
void Layer::backward_gpu(const SharedStorage&, const SharedStorage&,
7-
SharedStorage&) { ; };
24+
SharedStorage&) {
25+
;
26+
};
827
void Layer::backward_cpu(const SharedStorage&, const SharedStorage&,
9-
SharedStorage&) { ; };
28+
SharedStorage&) {
29+
;
30+
};
1031
VecSharedStorage Layer::return_parameters() { return parameters; };
1132
VecSharedStorage Layer::return_gradients() { return gradients; };
1233
VecSharedStorage Layer::return_parameters() const { return parameters; };
@@ -21,6 +42,4 @@ void Layer::initialize_output_dimension(
2142
}
2243
}
2344

24-
void Layer::initialize_output_dimension() {
25-
_out_dim.push_back(0);
26-
}
45+
void Layer::initialize_output_dimension() { _out_dim.push_back(0); }

src/layer/pooling.cpp

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "../../include/layer/pooling.h"
2+
#include <stdexcept>
23
#include <sys/time.h>
34
#include <iostream>
45
#include <memory>
@@ -19,20 +20,33 @@ Pooling::Pooling(Window window, Stride stride, ImageShape imageshape,
1920
}
2021

2122
Pooling::Pooling(Window window, Stride stride,
22-
const std::shared_ptr<Convolution>& previous)
23+
const std::shared_ptr<Layer>& previous)
2324
: Layer("Pooling"),
2425
_window(window),
2526
_stride(stride),
26-
_inp(previous->_inp),
27-
_channels(previous->_channels),
28-
_out(previous->_out),
27+
_inp(0,0),
28+
_channels(0),
29+
_out(0, 0),
2930
batch_size(0) {
30-
// initialize_previous();
31+
initialize_from_previous(previous);
3132
initialize_masking();
3233
initialize_output_dimension();
3334
_previous = previous;
3435
}
3536

37+
void Pooling::initialize_from_previous(const std::shared_ptr<Layer>& previous) {
38+
if (previous->name() == "Convolution") {
39+
std::shared_ptr<Convolution> conv =
40+
std::dynamic_pointer_cast<Convolution>(previous);
41+
_inp = conv->_inp;
42+
_channels = conv->_channels;
43+
_out = conv->_out;
44+
}
45+
else {
46+
throw std::runtime_error("Can only convert conv\n");
47+
}
48+
}
49+
3650
void Pooling::initialize_output_dimension() {
3751
int out_height =
3852
static_cast<int>(ceil(static_cast<float>(_inp.first() - _window.get()) /
@@ -43,7 +57,7 @@ void Pooling::initialize_output_dimension() {
4357
_stride.get())) +
4458
1;
4559
_out = ImageShape(out_height, out_width);
46-
_out_dim.push_back(_channels.get());
60+
_out_dim[0] = _channels.get();
4761
_out_dim.push_back(out_height);
4862
_out_dim.push_back(out_width);
4963
}

src/math.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ void my_add_vec_to_mat_colwise(SharedStorage& A, const SharedStorage& B,
5959
dtype* d_A = A->gpu_pointer();
6060
const dtype* d_B = B->gpu_pointer_const();
6161
if (rows != B->get_rows()) {
62-
throw std::runtime_error("Invalid size in addtion");
62+
std::stringstream ss;
63+
ss << "\nCannot add the two matrices as row numbers differ."
64+
" A rows: " << rows << " vs B rows: " << B->get_rows() << " in:\n"
65+
<< __PRETTY_FUNCTION__ << "\ncalled from " << __FILE__ << " at "
66+
<< __LINE__;
67+
throw std::invalid_argument(ss.str());
6368
}
6469
add_vec_to_mat_colwise(rows, cols, d_A, d_B, alpha);
6570
// cudaDeviceSyncronize();

src/network.cpp

+8-13
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ NeuralNetwork::NeuralNetwork(const std::shared_ptr<Layer>& last_layer,
4949

5050
void NeuralNetwork::insert_cnn_layer(const std::shared_ptr<Layer>& layer) {
5151
std::shared_ptr<Convolution> derived =
52-
std::dynamic_pointer_cast<Convolution> (layer);
53-
//std::shared_ptr<Convolution> d = dynamic_cast<Derived<int> *>(b);
54-
std::shared_ptr<Layer> im2col =
55-
std::make_shared<Im2ColLayer>(Im2ColLayer(derived));
52+
std::dynamic_pointer_cast<Convolution>(layer);
53+
std::shared_ptr<Layer> im2col = std::make_shared<Im2ColLayer>(derived);
5654
layer->_previous = im2col;
5755
layers.push_front(im2col);
5856
layers.push_front(layer);
@@ -68,9 +66,13 @@ void NeuralNetwork::construct_layers(std::shared_ptr<Layer> curr) {
6866
curr.swap(tmp);
6967
}
7068
if (curr->name() == "Input")
71-
layers.push_front(curr);
69+
layers.push_front(curr);
7270
else {
73-
throw std::runtime_error("Must finish with the input");
71+
std::stringstream ss;
72+
ss << "Cannot recognize the layer name " << curr->name() << " in:\n"
73+
<< __PRETTY_FUNCTION__ << "\ncalled from " << __FILE__ << " at "
74+
<< __LINE__;
75+
throw std::invalid_argument(ss.str());
7476
}
7577
}
7678

@@ -91,7 +93,6 @@ void NeuralNetwork::allocate_storage(int obs, std::vector<SharedStorage>& inp,
9193

9294
vector<SharedStorage> NeuralNetwork::allocate_forward(int obs) {
9395
vector<SharedStorage> vals;
94-
// int out_dim(0);
9596
for (shared_ptr<Layer> layer : layers) {
9697
allocate_storage(obs, vals, layer);
9798
}
@@ -100,12 +101,10 @@ vector<SharedStorage> NeuralNetwork::allocate_forward(int obs) {
100101

101102
vector<SharedStorage> NeuralNetwork::allocate_backward(int obs) {
102103
vector<SharedStorage> vals;
103-
// int out_dim(0);
104104
std::deque<shared_ptr<Layer>>::iterator layer = layers.begin();
105105
std::deque<shared_ptr<Layer>>::iterator end = layers.end();
106106
--end;
107107
while (layer != end) {
108-
// for (size_t i = 0; i < layers.size() - 1; i++) {
109108
allocate_storage(obs, vals, *layer);
110109
++layer;
111110
}
@@ -128,8 +127,6 @@ void NeuralNetwork::forward_gpu(vector<SharedStorage>& values,
128127
std::deque<shared_ptr<Layer>>::iterator layer = layers.begin();
129128
++layer;
130129
while (layer != layers.end()) {
131-
// for (; it != layers.end(); ++it) {
132-
// for (size_t layer_idx = 1; layer_idx < layers.size(); ++layer_idx) {
133130
(*layer)->forward_gpu(values[i], values[i + 1], type);
134131
i++;
135132
++layer;
@@ -142,8 +139,6 @@ void NeuralNetwork::forward_cpu(vector<SharedStorage>& values,
142139
std::deque<shared_ptr<Layer>>::iterator layer = layers.begin();
143140
++layer;
144141
while (layer != layers.end()) {
145-
// for (; it != layers.end(); ++it) {
146-
// for (size_t layer_idx = 1; layer_idx < layers.size(); ++layer_idx) {
147142
(*layer)->forward_gpu(values[i], values[i + 1], type);
148143
i++;
149144
++layer;

src/train.cpp

+19-3
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,28 @@ void NeuralNetwork::get_new_sample(const vector<int>& samples, Matrix& x_train,
155155

156156
// I need to instantiate a vector of shared pointers to SGD one for each layer
157157
// use this as part of train args!!!
158+
//
159+
int NeuralNetwork::check_input_dimension(const std::vector<int>& dim) {
160+
int i = 1;
161+
for (int shape : dim) i *= shape;
162+
return i;
163+
}
164+
158165
void NeuralNetwork::train(const Matrix& features, const Matrix& targets,
159166
std::shared_ptr<GradientDescent>& sgd, Epochs _epoch,
160167
Patience _patience, BatchSize _batch_size) {
161-
if ((*layers.begin())->output_dimension()[0] != features.cols()) {
162-
std::string m("N of input features != col in features, in:\n");
163-
throw std::invalid_argument(m + __PRETTY_FUNCTION__);
168+
std::vector<int> input_dim = layers[0]->output_dimension();
169+
int expected_cols = check_input_dimension(input_dim);
170+
if (expected_cols != features.cols()) {
171+
std::stringstream ss;
172+
ss << "The number of input features is: " << features.cols()
173+
<< " but the input layer expects: ";
174+
std::copy(input_dim.begin(), input_dim.end(),
175+
std::ostream_iterator<int>(ss, " "));
176+
ss << "in:\n"
177+
<< __PRETTY_FUNCTION__ << "\ncalled from " << __FILE__ << " at "
178+
<< __LINE__;
179+
throw std::invalid_argument(ss.str());
164180
}
165181
train_args = std::make_unique<trainArgs>(
166182
features, targets, _epoch, _patience, _batch_size, sgd, layers);

0 commit comments

Comments
 (0)