[LayerV1] Delete for LayerV1
[platform/core/ml/nntrainer.git] / Applications / ProductRatings / jni / main.cpp
1 // SPDX-License-Identifier: Apache-2.0
2 /**
3  * Copyright (C) 2021 Jijoong Moon <jijoong.moon@samsung.com>
4  *
5  * @file   main.cpp
6  * @date   10 March 2021
7  * @see    https://github.com/nnstreamer/nntrainer
8  * @author Jijoong Moon <jijoong.moon@samsung.com>
9  * @bug    No known bugs except for NYI items
10  * @brief  This is a simple recommendation system Example
11  *
12  *              Trainig set (embedding_input.txt) : 4 colume data + result (1.0
13  * or 0.0) Configuration file : ../../res/Embedding.ini
14  *
15  */
16
17 #include <cmath>
18 #include <fstream>
19 #include <iostream>
20 #include <sstream>
21 #include <stdlib.h>
22 #include <time.h>
23
24 #include <dataset.h>
25 #include <ml-api-common.h>
26 #include <neuralnet.h>
27 #include <tensor.h>
28
29 std::string data_file;
30
31 const unsigned int total_train_data_size = 25;
32
33 unsigned int train_count = 0;
34
35 const unsigned int batch_size = 20;
36
37 const unsigned int feature_size = 2;
38
39 const unsigned int total_val_data_size = 25;
40
41 bool training = false;
42
43 /**
44  * @brief     step function
45  * @param[in] x value to be distinguished
46  * @retval 0.0 or 1.0
47  */
48 float stepFunction(float x) {
49   if (x > 0.5) {
50     return 1.0;
51   }
52
53   if (x < 0.5) {
54     return 0.0;
55   }
56
57   return x;
58 }
59
60 /**
61  * @brief     get idth Data
62  * @param[in] F file stream
63  * @param[out] outVec feature data
64  * @param[out] outLabel label data
65  * @param[in] id id th
66  * @retval boolean true if there is no error
67  */
68 bool getData(std::ifstream &F, std::vector<float> &outVec,
69              std::vector<float> &outLabel, unsigned int id) {
70   std::string temp;
71   F.clear();
72   F.seekg(0, std::ios_base::beg);
73   char c;
74   unsigned int i = 0;
75   while (F.get(c) && i < id)
76     if (c == '\n')
77       ++i;
78
79   F.putback(c);
80
81   if (!std::getline(F, temp)) {
82     return false;
83   }
84
85   std::istringstream buffer(temp);
86   float x;
87   for (unsigned int j = 0; j < feature_size; ++j) {
88     buffer >> x;
89     outVec[j] = x;
90   }
91   buffer >> x;
92   outLabel[0] = x;
93
94   return true;
95 }
96
97 template <typename T> void loadFile(const char *filename, T &t) {
98   std::ifstream file(filename);
99   if (!file.good()) {
100     throw std::runtime_error("could not read, check filename");
101   }
102   t.read(file);
103   file.close();
104 }
105
106 /**
107  * @brief     get Data as much as batch size
108  * @param[out] outVec feature data
109  * @param[out] outLabel label data
110  * @param[out] last end of data
111  * @param[in] user_data user data
112  * @retval int 0 if there is no error
113  */
114 int getBatch_train(float **outVec, float **outLabel, bool *last,
115                    void *user_data) {
116   std::ifstream dataFile(data_file);
117   unsigned int data_size = total_train_data_size;
118   unsigned int count = 0;
119
120   if (data_size - train_count < batch_size) {
121     *last = true;
122     train_count = 0;
123     return 0;
124   }
125
126   std::vector<float> o;
127   std::vector<float> l;
128   o.resize(feature_size);
129   l.resize(1);
130
131   for (unsigned int i = train_count; i < train_count + batch_size; ++i) {
132     if (!getData(dataFile, o, l, i)) {
133       return -1;
134     }
135
136     for (unsigned int j = 0; j < feature_size; ++j) {
137       outVec[0][count * feature_size + j] = o[j];
138     }
139     outLabel[0][count] = l[0];
140
141     count++;
142   }
143
144   dataFile.close();
145   *last = false;
146   train_count += batch_size;
147   return 0;
148 }
149
150 /**
151  * @brief     create NN
152  *            back propagation of NN
153  * @param[in]  arg 1 : train / inference
154  * @param[in]  arg 2 : configuration file path
155  * @param[in]  arg 3 : resource path (data) with below format
156  * (int) (int) (float) #first data
157  * ...
158  * in each row represents user id, product id, rating (0 to 10)
159  */
160 int main(int argc, char *argv[]) {
161   if (argc < 4) {
162     std::cout << "./Embedding train (| inference) Config.ini data.txt\n";
163     exit(1);
164   }
165
166   const std::vector<std::string> args(argv + 1, argv + argc);
167   std::string config = args[1];
168   data_file = args[2];
169
170   if (!args[0].compare("train"))
171     training = true;
172
173   srand(time(NULL));
174
175   std::shared_ptr<ml::train::Dataset> dataset_train, dataset_val;
176   try {
177     dataset_train =
178       createDataset(ml::train::DatasetType::GENERATOR, getBatch_train);
179     dataset_val =
180       createDataset(ml::train::DatasetType::GENERATOR, getBatch_train);
181   } catch (std::exception &e) {
182     std::cerr << "Error creating dataset" << e.what() << std::endl;
183     return 1;
184   }
185
186   /**
187    * @brief     Create NN
188    */
189   std::vector<std::vector<float>> inputVector, outputVector;
190   nntrainer::NeuralNetwork NN;
191   /**
192    * @brief     Initialize NN with configuration file path
193    */
194
195   try {
196     auto status = NN.loadFromConfig(config);
197     if (status != ML_ERROR_NONE) {
198       std::cerr << "Error during loading" << std::endl;
199       return 1;
200     }
201
202     status = NN.compile();
203     if (status != ML_ERROR_NONE) {
204       std::cerr << "Error during compile" << std::endl;
205       return 1;
206     }
207     status = NN.initialize();
208     if (status != ML_ERROR_NONE) {
209       std::cerr << "Error during initialize" << std::endl;
210       return 1;
211     }
212     NN.readModel();
213
214     std::cout << "Input dimension: " << NN.getInputDimension()[0];
215
216   } catch (std::exception &e) {
217     std::cerr << "Unexpected Error during init " << e.what() << std::endl;
218     return 1;
219   }
220
221   if (training) {
222     NN.setDataset(ml::train::DatasetDataUsageType::DATA_TRAIN, dataset_train);
223     NN.setDataset(ml::train::DatasetDataUsageType::DATA_VAL, dataset_val);
224     try {
225       NN.train({"batch_size=" + std::to_string(batch_size)});
226     } catch (std::exception &e) {
227       std::cerr << "Error during train " << e.what() << std::endl;
228       return 1;
229     }
230
231     try {
232       /****** testing with a golden data if any ********/
233       nntrainer::Tensor golden(1, 1, 15, 8);
234
235       loadFile("embedding_weight_golden.out", golden);
236       golden.print(std::cout);
237
238       nntrainer::Tensor weight_out_fc(1, 1, 32, 1);
239       loadFile("fc_weight_golden.out", weight_out_fc);
240       weight_out_fc.print(std::cout);
241     } catch (...) {
242       std::cerr << "Warning: during loading golden data\n";
243     }
244   } else {
245     try {
246       NN.readModel();
247     } catch (std::exception &e) {
248       std::cerr << "Error during readModel: " << e.what() << "\n";
249       return 1;
250     }
251     std::ifstream dataFile(data_file);
252     int cn = 0;
253     for (unsigned int j = 0; j < total_val_data_size; ++j) {
254       nntrainer::Tensor d;
255       std::vector<float> o;
256       std::vector<float> l;
257       o.resize(feature_size);
258       l.resize(1);
259
260       getData(dataFile, o, l, j);
261
262       try {
263         float answer =
264           NN.inference({MAKE_SHARED_TENSOR(nntrainer::Tensor({o}))})[0]
265             ->apply(stepFunction)
266             .getValue(0, 0, 0, 0);
267
268         std::cout << answer << " : " << l[0] << std::endl;
269         cn += answer == l[0];
270       } catch (...) {
271         std::cerr << "Error during forwarding the model" << std::endl;
272         return 1;
273       }
274     }
275     std::cout << "[ Accuracy ] : "
276               << ((float)(cn) / total_val_data_size) * 100.0 << "%"
277               << std::endl;
278   }
279
280   /**
281    * @brief     Finalize NN
282    */
283   return 0;
284 }