3 #include "tbb/parallel_for.h" 16 for (
int n = 0;
n < cols; ++
n) {
18 arr.push_back(tmp_float);
26 ifstream
fin(fname.c_str());
27 fin >> m_depth >> m_rows >> m_cols;
29 for (
int d = 0;
d < m_depth; ++
d) {
30 vector<vector<float>> tmp_single_depth;
31 for (
int r = 0;
r < m_rows; ++
r) {
33 tmp_single_depth.push_back(tmp_row);
35 data.push_back(tmp_single_depth);
46 fin >> m_kernels_cnt >> m_depth >> m_rows >> m_cols >> m_border_mode;
47 if (m_border_mode ==
"[") {
48 m_border_mode =
"valid";
52 cout <<
"LayerConv2D " << m_kernels_cnt <<
"x" << m_depth <<
"x" << m_rows <<
"x" << m_cols
53 <<
" border_mode " << m_border_mode << endl;
55 for (
int k = 0; k < m_kernels_cnt; ++k) {
56 vector<vector<vector<float>>> tmp_depths;
57 for (
int d = 0;
d < m_depth; ++
d) {
58 vector<vector<float>> tmp_single_depth;
59 for (
int r = 0;
r < m_rows; ++
r) {
60 if (!skip) { fin >> tmp_char; }
64 vector<float> tmp_row;
65 for (
int c = 0; c < m_cols; ++c) {
68 tmp_row.push_back(tmp_float);
71 tmp_single_depth.push_back(tmp_row);
73 tmp_depths.push_back(tmp_single_depth);
75 m_kernels.push_back(tmp_depths);
79 for (
int k = 0; k < m_kernels_cnt; ++k) {
81 m_bias.push_back(tmp_float);
88 fin >> m_activation_type;
89 cout <<
"Activation type " << m_activation_type << endl;
94 fin >> m_pool_x >> m_pool_y;
95 cout <<
"MaxPooling " << m_pool_x <<
"x" << m_pool_y << endl;
100 fin >> m_input_cnt >> m_neurons;
103 for (
int i = 0; i < m_input_cnt; ++i) {
106 for (
int n = 0;
n < m_neurons; ++
n) {
108 tmp_n.push_back(tmp_float);
111 m_weights.push_back(tmp_n);
113 cout <<
"weights " << m_weights.size() << endl;
115 for (
int n = 0;
n < m_neurons; ++
n) {
117 m_bias.push_back(tmp_float);
120 cout <<
"bias " << m_bias.size() << endl;
125 load_weights(input_fname);
130 vector<vector<vector<float>>> im = dc->
get_3d();
132 size_t csize = im[0].size();
133 size_t rsize = im[0][0].size();
134 size_t size = im.size() * csize * rsize;
137 for (
size_t i = 0, dst = 0; i < im.size(); ++i) {
138 for (
size_t j = 0; j < csize; ++j) {
139 float* row = im[i][j].data();
140 for (
size_t k = 0; k < rsize; ++k) {
141 y_ret[dst++] = row[k];
151 vector<vector<vector<float>>> im = dc->
get_3d();
152 vector<vector<vector<float>>> y_ret;
153 for (
unsigned int i = 0; i < im.size(); ++i) {
154 vector<vector<float>> tmp_y;
155 for (
unsigned int j = 0; j < (
unsigned int)(im[0].
size() / m_pool_x); ++j) {
156 tmp_y.push_back(vector<float>((
int)(im[0][0].
size() / m_pool_y), 0.0));
158 y_ret.push_back(tmp_y);
160 for (
unsigned int d = 0;
d < y_ret.size(); ++
d) {
161 for (
unsigned int x = 0;
x < y_ret[0].size(); ++
x) {
162 unsigned int start_x =
x * m_pool_x;
163 unsigned int end_x = start_x + m_pool_x;
164 for (
unsigned int y = 0;
y < y_ret[0][0].size(); ++
y) {
165 unsigned int start_y =
y * m_pool_y;
166 unsigned int end_y = start_y + m_pool_y;
169 for (
unsigned int i = start_x; i < end_x; ++i) {
170 for (
unsigned int j = start_y; j < end_y; ++j) {
171 values.push_back(im[
d][i][j]);
174 y_ret[
d][
x][
y] = *max_element(values.begin(), values.end());
179 out->set_data(y_ret);
185 cout <<
"Activation " << act <<
" not defined!" << endl;
186 cout <<
"Please add its implementation before use." << endl;
194 vector<vector<vector<float>>>
y = dc->
get_3d();
195 if (m_activation_type ==
"relu") {
196 for (
unsigned int i = 0; i < y.size(); ++i) {
197 for (
unsigned int j = 0; j < y[0].size(); ++j) {
198 for (
unsigned int k = 0; k < y[0][0].size(); ++k) {
199 if (y[i][j][k] < 0) y[i][j][k] = 0;
204 else if (m_activation_type ==
"tanh") {
205 for (
unsigned int i = 0; i < y.size(); ++i) {
206 for (
unsigned int j = 0; j < y[0].size(); ++j) {
207 for (
unsigned int k = 0; k < y[0][0].size(); ++k) {
208 y[i][j][k] = tanh(y[i][j][k]);
222 vector<float>
y = dc->
get_1d();
223 if (m_activation_type ==
"relu") {
224 for (
unsigned int k = 0; k < y.size(); ++k) {
225 if (y[k] < 0) y[k] = 0;
228 else if (m_activation_type ==
"softmax") {
230 for (
unsigned int k = 0; k < y.size(); ++k) {
234 for (
unsigned int k = 0; k < y.size(); ++k) {
238 else if (m_activation_type ==
"tanh") {
239 for (
unsigned int k = 0; k < y.size(); ++k) {
243 else if (m_activation_type ==
"sigmoid") {
244 for (
unsigned int k = 0; k < y.size(); ++k) {
245 y[k] = 1.0F / (1.0F + exp(-y[k]));
257 throw "data dim not supported";
268 size_t k1_size = k.size(), k2_size = k[0].size();
269 unsigned int st_x = (k1_size - 1) >> 1;
270 unsigned int st_y = (k2_size - 1) >> 1;
272 for (
unsigned int i = st_x; i < im.size() - st_x; ++i) {
273 for (
unsigned int j = st_y; j < im[0].size() - st_y; ++j) {
276 for (
unsigned int k1 = 0; k1 < k1_size; ++k1) {
279 for (
unsigned int k2 = 0; k2 < k2_size; ++k2) {
281 sum += k[k1_size - k1 - 1][k2_size - k2 - 1] * im[i - st_x + k1][j - st_y + k2];
284 y[i - st_x][j - st_y] +=
sum;
294 size_t k1_size = k.size(), k2_size = k[0].size();
295 unsigned int st_x = (k1_size - 1) >> 1;
296 unsigned int st_y = (k2_size - 1) >> 1;
298 size_t max_imc = im.size() - 1;
299 size_t max_imr = im[0].size() - 1;
301 for (
unsigned int i = 0; i < im.size(); ++i) {
302 for (
unsigned int j = 0; j < im[0].size(); ++j) {
305 for (
unsigned int k1 = 0; k1 < k1_size; ++k1) {
308 for (
unsigned int k2 = 0; k2 < k2_size; ++k2) {
309 if (i + k1 < st_x)
continue;
310 if (i + k1 > max_imc + st_x)
continue;
311 if (j + k2 < st_y)
continue;
312 if (j + k2 > max_imr + st_y)
continue;
315 sum += k[k1_size - k1 - 1][k2_size - k2 - 1] * im[i - st_x + k1][j - st_y + k2];
325 unsigned int st_x = (m_kernels[0][0].size() - 1) >> 1;
326 unsigned int st_y = (m_kernels[0][0][0].size() - 1) >> 1;
327 auto const& im = dc->
get_3d();
329 size_t size_x = (m_border_mode ==
"valid") ? im[0].
size() - 2 * st_x : im[0].size();
330 size_t size_y = (m_border_mode ==
"valid") ? im[0][0].
size() - 2 * st_y : im[0][0].size();
339 tbb::parallel_for(
size_t(0),
size_t(m_kernels.size()), [&](
size_t j) {
340 for (
unsigned int m = 0; m < im.size(); ++m) {
341 if (m_border_mode ==
"valid")
347 for (
unsigned int x = 0;
x < y_ret[0].size(); ++
x) {
349 size_t size = y_ret[0][0].size();
350 float bias = m_bias[j];
353 for (
unsigned int y = 0;
y < size / 8; ++
y) {
354 y_ret[j][
x][k] += bias;
355 y_ret[j][
x][k + 1] += bias;
356 y_ret[j][
x][k + 2] += bias;
357 y_ret[j][
x][k + 3] += bias;
358 y_ret[j][
x][k + 4] += bias;
359 y_ret[j][
x][k + 5] += bias;
360 y_ret[j][
x][k + 6] += bias;
361 y_ret[j][
x][k + 7] += bias;
365 y_ret[j][
x][k] += bias;
386 size_t size = m_weights[0].size();
387 size_t size8 = size >> 3;
392 auto const& im = dc->
get_1d();
394 for (
size_t j = 0; j < m_weights.size(); ++j) {
395 const float*
w = m_weights[j].data();
398 for (
size_t i = 0; i < size8; ++i) {
399 y_ret[k] += w[k] * p;
400 y_ret[k + 1] += w[k + 1] * p;
401 y_ret[k + 2] += w[k + 2] * p;
402 y_ret[k + 3] += w[k + 3] * p;
403 y_ret[k + 4] += w[k + 4] * p;
404 y_ret[k + 5] += w[k + 5] * p;
405 y_ret[k + 6] += w[k + 6] * p;
406 y_ret[k + 7] += w[k + 7] * p;
410 y_ret[k] += w[k] * p;
414 for (
size_t i = 0; i <
size; ++i) {
415 y_ret[i] += m_bias[i];
429 for (
int l = 0; l < (int)m_layers.size(); ++l) {
431 out = m_layers[l]->compute_output(inp);
438 if (inp != dc)
delete inp;
446 std::vector<float> flat_out = out->
get_1d();
454 cout <<
"Reading model from " << input_fname << endl;
455 ifstream
fin(input_fname.c_str());
456 string layer_type =
"";
460 fin >> tmp_str >> m_layers_cnt;
461 cout <<
"Layers " << m_layers_cnt << endl;
463 for (
int layer = 0; layer < m_layers_cnt; ++layer) {
464 fin >> tmp_str >> tmp_int >> layer_type;
465 cout <<
"Layer " << tmp_int <<
" " << layer_type << endl;
468 if (layer_type ==
"Convolution2D") { l =
new LayerConv2D(); }
469 else if (layer_type ==
"Activation") {
472 else if (layer_type ==
"MaxPooling2D") {
475 else if (layer_type ==
"Flatten") {
478 else if (layer_type ==
"Dense") {
481 else if (layer_type ==
"Dropout") {
485 cout <<
"Layer is empty, maybe it is not defined? Cannot define network." << endl;
489 m_layers.push_back(l);
497 for (
int i = 0; i < (int)m_layers.size(); ++i) {
504 int i = m_layers.size() - 1;
505 while ((i > 0) && (m_layers[i]->get_output_units() == 0))
507 return m_layers[i]->get_output_units();
void load_weights(std::ifstream &fin)
KerasModel(const std::string &input_fname)
keras::DataChunk * compute_output(keras::DataChunk *)
virtual void set_data(std::vector< std::vector< std::vector< float >>> const &)
int get_output_length() const
void load_weights(const std::string &input_fname)
virtual void load_weights(std::ifstream &fin)=0
virtual std::vector< std::vector< std::vector< float > > > const & get_3d() const
virtual size_t get_data_dim(void) const
keras::DataChunk * compute_output(keras::DataChunk *)
keras::DataChunk * compute_output(keras::DataChunk *)
std::vector< float > compute_output(keras::DataChunk *dc)
void conv_single_depth_same(std::vector< std::vector< float >> &y, std::vector< std::vector< float >> const &im, std::vector< std::vector< float >> const &k)
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void conv_single_depth_valid(std::vector< std::vector< float >> &y, std::vector< std::vector< float >> const &im, std::vector< std::vector< float >> const &k)
void read_from_file(const std::string &fname)
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
keras::DataChunk * compute_output(keras::DataChunk *)
void missing_activation_impl(const std::string &act)
void load_weights(std::ifstream &fin)
keras::DataChunk * compute_output(keras::DataChunk *)
std::vector< std::vector< std::vector< float > > > & get_3d_rw()
std::vector< float > & get_1d_rw()
void load_weights(std::ifstream &fin)
void load_weights(std::ifstream &fin)
virtual std::vector< float > const & get_1d() const
std::vector< float > read_1d_array(std::ifstream &fin, int cols)