TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
keras_model.h
1// TRUST_NO_INDENT
2// Reproduced from https://github.com/moof2k/kerasify
3/*
4 * Copyright (c) 2016 Robert W. Rose
5 *
6 * MIT License, see LICENSE file.
7 */
8
9#ifndef KERAS_MODEL_H_
10#define KERAS_MODEL_H_
11
12#include <algorithm>
13#include <chrono>
14#include <math.h>
15#include <numeric>
16#include <string>
17#include <vector>
18#include <arch.h>
19
20#define KASSERT(x, ...) \
21 if (!(x)) { \
22 printf("KASSERT: %s(%d): ", __FILE__, __LINE__); \
23 printf(__VA_ARGS__); \
24 printf("\n"); \
25 return false; \
26 }
27
28#define KASSERT_EQ(x, y, eps) \
29 if (std::fabs(x - y) > eps) { \
30 printf("KASSERT: Expected %f, got %f\n", y, x); \
31 return false; \
32 }
33
34#ifdef DEBUG
35#define KDEBUG(x, ...) \
36 if (!(x)) { \
37 printf("%s(%d): ", __FILE__, __LINE__); \
38 printf(__VA_ARGS__); \
39 printf("\n"); \
40 Process::exit(); \
41 }
42#else
43#define KDEBUG(x, ...) ;
44#endif
45
46class Tensor {
47 public:
48 Tensor() {}
49
50 Tensor(int i) { Resize(i); }
51
52 Tensor(int i, int j) { Resize(i, j); }
53
54 Tensor(int i, int j, int k) { Resize(i, j, k); }
55
56 Tensor(int i, int j, int k, int l) { Resize(i, j, k, l); }
57
58 void Resize(int i) {
59 dims_ = {i};
60 data_.resize(i);
61 }
62
63 void Resize(int i, int j) {
64 dims_ = {i, j};
65 data_.resize(i * j);
66 }
67
68 void Resize(int i, int j, int k) {
69 dims_ = {i, j, k};
70 data_.resize(i * j * k);
71 }
72
73 void Resize(int i, int j, int k, int l) {
74 dims_ = {i, j, k, l};
75 data_.resize(i * j * k * l);
76 }
77
78 inline void Flatten() {
79 KDEBUG(dims_.size() > 0, "Invalid tensor");
80
81 int elements = dims_[0];
82 for (unsigned int i = 1; i < dims_.size(); i++) {
83 elements *= dims_[i];
84 }
85 dims_ = {elements};
86 }
87
88 inline float& operator()(int i) {
89 KDEBUG(dims_.size() == 1, "Invalid indexing for tensor");
90 KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]);
91
92 return data_[i];
93 }
94
95 inline float& operator()(int i, int j) {
96 KDEBUG(dims_.size() == 2, "Invalid indexing for tensor");
97 KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]);
98 KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]);
99
100 return data_[dims_[1] * i + j];
101 }
102
103 inline float operator()(int i, int j) const {
104 KDEBUG(dims_.size() == 2, "Invalid indexing for tensor");
105 KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]);
106 KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]);
107
108 return data_[dims_[1] * i + j];
109 }
110
111 inline float& operator()(int i, int j, int k) {
112 KDEBUG(dims_.size() == 3, "Invalid indexing for tensor");
113 KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]);
114 KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]);
115 KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]);
116
117 return data_[dims_[2] * (dims_[1] * i + j) + k];
118 }
119
120 inline float& operator()(int i, int j, int k, int l) {
121 KDEBUG(dims_.size() == 4, "Invalid indexing for tensor");
122 KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]);
123 KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]);
124 KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]);
125 KDEBUG(l < dims_[3] && l >= 0, "Invalid l: %d (max %d)", l, dims_[3]);
126
127 return data_[dims_[3] * (dims_[2] * (dims_[1] * i + j) + k) + l];
128 }
129
130 inline void Fill(float value) {
131 std::fill(data_.begin(), data_.end(), value);
132 }
133
134 Tensor Unpack(int row) const {
135 KASSERT(dims_.size() >= 2, "Invalid tensor");
136 std::vector<int> pack_dims =
137 std::vector<int>(dims_.begin() + 1, dims_.end());
138 int pack_size = std::accumulate(pack_dims.begin(), pack_dims.end(), 0);
139
140 std::vector<float>::const_iterator first =
141 data_.begin() + (row * pack_size);
142 std::vector<float>::const_iterator last =
143 data_.begin() + (row + 1) * pack_size;
144
145 Tensor x = Tensor();
146 x.dims_ = pack_dims;
147 x.data_ = std::vector<float>(first, last);
148
149 return x;
150 }
151
152 Tensor Select(int row) const {
153 Tensor x = Unpack(row);
154 x.dims_.insert(x.dims_.begin(), 1);
155
156 return x;
157 }
158
159 Tensor operator+(const Tensor& other) {
160 KASSERT(dims_ == other.dims_,
161 "Cannot add tensors with different dimensions");
162
163 Tensor result;
164 result.dims_ = dims_;
165 result.data_.reserve(data_.size());
166
167 std::transform(data_.begin(), data_.end(), other.data_.begin(),
168 std::back_inserter(result.data_),
169 [](float x, float y) { return x + y; });
170
171 return result;
172 }
173
174 Tensor Multiply(const Tensor& other) {
175 KASSERT(dims_ == other.dims_,
176 "Cannot multiply elements with different dimensions");
177
178 Tensor result;
179 result.dims_ = dims_;
180 result.data_.reserve(data_.size());
181
182 std::transform(data_.begin(), data_.end(), other.data_.begin(),
183 std::back_inserter(result.data_),
184 [](float x, float y) { return x * y; });
185
186 return result;
187 }
188
189 Tensor Dot(const Tensor& other) {
190 KDEBUG(dims_.size() == 2, "Invalid tensor dimensions");
191 KDEBUG(other.dims_.size() == 2, "Invalid tensor dimensions");
192 KASSERT(dims_[1] == other.dims_[0],
193 "Cannot multiply with different inner dimensions");
194
195 Tensor tmp(dims_[0], other.dims_[1]);
196
197 for (int i = 0; i < dims_[0]; i++) {
198 for (int j = 0; j < other.dims_[1]; j++) {
199 for (int k = 0; k < dims_[1]; k++) {
200 tmp(i, j) += (*this)(i, k) * other(k, j);
201 }
202 }
203 }
204
205 return tmp;
206 }
207
208 void Print() {
209 if (dims_.size() == 1) {
210 printf("[ ");
211 for (int i = 0; i < dims_[0]; i++) {
212 printf("%f ", (*this)(i));
213 }
214 printf("]\n");
215 } else if (dims_.size() == 2) {
216 printf("[\n");
217 for (int i = 0; i < dims_[0]; i++) {
218 printf(" [ ");
219 for (int j = 0; j < dims_[1]; j++) {
220 printf("%f ", (*this)(i, j));
221 }
222 printf("]\n");
223 }
224 printf("]\n");
225 } else if (dims_.size() == 3) {
226 printf("[\n");
227 for (int i = 0; i < dims_[0]; i++) {
228 printf(" [\n");
229 for (int j = 0; j < dims_[1]; j++) {
230 printf(" [ ");
231 for (int k = 0; k < dims_[2]; k++) {
232 printf("%f ", (*this)(i, j, k));
233 }
234 printf(" ]\n");
235 }
236 printf(" ]\n");
237 }
238 printf("]\n");
239 } else if (dims_.size() == 4) {
240 printf("[\n");
241 for (int i = 0; i < dims_[0]; i++) {
242 printf(" [\n");
243 for (int j = 0; j < dims_[1]; j++) {
244 printf(" [\n");
245 for (int k = 0; k < dims_[2]; k++) {
246 printf(" [");
247 for (int l = 0; l < dims_[3]; l++) {
248 printf("%f ", (*this)(i, j, k, l));
249 }
250 printf("]\n");
251 }
252 printf(" ]\n");
253 }
254 printf(" ]\n");
255 }
256 printf("]\n");
257 }
258 }
259
260 void PrintShape() {
261 printf("(");
262 for (unsigned int i = 0; i < dims_.size(); i++) {
263#if INT_is_64_ == 1
264 printf("%ld ", dims_[i]);
265#else
266 printf("%d ", dims_[i]);
267#endif
268 }
269 printf(")\n");
270 }
271
272 std::vector<int> dims_;
273 std::vector<float> data_;
274};
275
277 public:
279
280 virtual ~KerasLayer() {}
281
282 virtual bool LoadLayer(std::ifstream* file) = 0;
283
284 virtual bool Apply(Tensor* in, Tensor* out) = 0;
285};
286
288 public:
297
299
301
302 bool LoadLayer(std::ifstream* file) override;
303
304 bool Apply(Tensor* in, Tensor* out) override;
305
306 private:
307 ActivationType activation_type_;
308};
309
311 public:
313
314 ~KerasLayerDense() override {}
315
316 bool LoadLayer(std::ifstream* file) override;
317
318 bool Apply(Tensor* in, Tensor* out) override;
319
320 private:
321 Tensor weights_;
322 Tensor biases_;
323
324 KerasLayerActivation activation_;
325};
326
328 public:
330
332
333 bool LoadLayer(std::ifstream* file) override;
334
335 bool Apply(Tensor* in, Tensor* out) override;
336
337 private:
338 Tensor weights_;
339 Tensor biases_;
340
341 KerasLayerActivation activation_;
342};
343
345 public:
347
348 ~KerasLayerFlatten() override {}
349
350 bool LoadLayer(std::ifstream* file) override;
351
352 bool Apply(Tensor* in, Tensor* out) override;
353
354 private:
355};
356
357class KerasLayerElu : public KerasLayer {
358 public:
359 KerasLayerElu() : alpha_(1.0f) {}
360
361 ~KerasLayerElu() override {}
362
363 bool LoadLayer(std::ifstream* file) override;
364
365 bool Apply(Tensor* in, Tensor* out) override;
366
367 private:
368 float alpha_;
369};
370
372 public:
373 KerasLayerMaxPooling2d() : pool_size_j_(0), pool_size_k_(0) {}
374
376
377 bool LoadLayer(std::ifstream* file) override;
378
379 bool Apply(Tensor* in, Tensor* out) override;
380
381 private:
382 unsigned int pool_size_j_;
383 unsigned int pool_size_k_;
384};
385
387 public:
389
390 ~KerasLayerLSTM() override {}
391
392 bool LoadLayer(std::ifstream* file) override;
393
394 bool Apply(Tensor* in, Tensor* out) override;
395
396 private:
397 bool Step(Tensor* x, Tensor* out, Tensor* ht_1, Tensor* ct_1);
398
399 Tensor Wi_;
400 Tensor Ui_;
401 Tensor bi_;
402 Tensor Wf_;
403 Tensor Uf_;
404 Tensor bf_;
405 Tensor Wc_;
406 Tensor Uc_;
407 Tensor bc_;
408 Tensor Wo_;
409 Tensor Uo_;
410 Tensor bo_;
411
412 KerasLayerActivation innerActivation_;
413 KerasLayerActivation activation_;
414 bool return_sequences_ = false;
415};
416
418 public:
420
422
423 bool LoadLayer(std::ifstream* file) override;
424
425 bool Apply(Tensor* in, Tensor* out) override;
426
427 private:
428 Tensor weights_;
429};
430
432 public:
443
445
446 virtual ~KerasModel() {
447 for (unsigned int i = 0; i < layers_.size(); i++) {
448 delete layers_[i];
449 }
450 }
451
452 virtual bool LoadModel(const std::string& filename);
453
454 virtual bool Apply(Tensor* in, Tensor* out);
455
456 private:
457 std::vector<KerasLayer*> layers_;
458};
459
461 public:
463
464 void Start() { start_ = std::chrono::high_resolution_clock::now(); }
465
466 double Stop() {
467 std::chrono::time_point<std::chrono::high_resolution_clock> now =
468 std::chrono::high_resolution_clock::now();
469
470 std::chrono::duration<double> diff = now - start_;
471
472 return diff.count();
473 }
474
475 private:
476 std::chrono::time_point<std::chrono::high_resolution_clock> start_;
477};
478
479#endif // KERAS_MODEL_H_
~KerasLayerActivation() override
bool LoadLayer(std::ifstream *file) override
bool Apply(Tensor *in, Tensor *out) override
bool Apply(Tensor *in, Tensor *out) override
~KerasLayerConvolution2d() override
bool LoadLayer(std::ifstream *file) override
bool LoadLayer(std::ifstream *file) override
bool Apply(Tensor *in, Tensor *out) override
~KerasLayerDense() override
bool Apply(Tensor *in, Tensor *out) override
~KerasLayerElu() override
bool LoadLayer(std::ifstream *file) override
bool Apply(Tensor *in, Tensor *out) override
~KerasLayerEmbedding() override
bool LoadLayer(std::ifstream *file) override
bool Apply(Tensor *in, Tensor *out) override
bool LoadLayer(std::ifstream *file) override
~KerasLayerFlatten() override
~KerasLayerLSTM() override
bool Apply(Tensor *in, Tensor *out) override
bool LoadLayer(std::ifstream *file) override
bool LoadLayer(std::ifstream *file) override
bool Apply(Tensor *in, Tensor *out) override
~KerasLayerMaxPooling2d() override
virtual bool Apply(Tensor *in, Tensor *out)=0
virtual ~KerasLayer()
virtual bool LoadLayer(std::ifstream *file)=0
virtual bool LoadModel(const std::string &filename)
virtual bool Apply(Tensor *in, Tensor *out)
virtual ~KerasModel()
double Stop()
void Start()
std::vector< float > data_
float & operator()(int i, int j, int k)
void Flatten()
Definition keras_model.h:78
Tensor(int i)
Definition keras_model.h:50
std::vector< int > dims_
Tensor Select(int row) const
float & operator()(int i, int j)
Definition keras_model.h:95
Tensor Multiply(const Tensor &other)
void Resize(int i, int j, int k, int l)
Definition keras_model.h:73
float & operator()(int i)
Definition keras_model.h:88
Tensor Unpack(int row) const
void Print()
Tensor Dot(const Tensor &other)
Tensor(int i, int j, int k, int l)
Definition keras_model.h:56
void Fill(float value)
void Resize(int i)
Definition keras_model.h:58
Tensor(int i, int j)
Definition keras_model.h:52
float operator()(int i, int j) const
Tensor(int i, int j, int k)
Definition keras_model.h:54
void Resize(int i, int j)
Definition keras_model.h:63
void PrintShape()
Tensor operator+(const Tensor &other)
void Resize(int i, int j, int k)
Definition keras_model.h:68
float & operator()(int i, int j, int k, int l)