@@ -170,172 +170,6 @@ inline void deactivate(Eigen::MatrixXf& mat, Activation act) {
170170}
171171
172172
173-
174- struct MNIST {
175-
176- // Ctor
177- MNIST () {
178- std::string path = std::experimental::filesystem::current_path ();
179- // path = path.substr(0, path.rfind("cpp-taskflow") + 12);
180- // path += "/benchmark/mnist/";
181-
182- images = read_mnist_image (" ./train-images.data" );
183- labels = read_mnist_label (" ./train-labels.data" );
184-
185- test_images = read_mnist_image (" ./t10k-images-idx3-ubyte" );
186- test_labels = read_mnist_label (" ./t10k-labels-idx1-ubyte" );
187- }
188-
189- void add_layer (size_t in_degree, size_t out_degree, Activation act) {
190- acts.emplace_back (act);
191- Ys.emplace_back ().resize (batch_size, out_degree);
192- Ws.push_back (Eigen::MatrixXf::Random (in_degree, out_degree));
193- Bs.push_back (Eigen::MatrixXf::Random (1 , out_degree));
194-
195- dW.emplace_back ().resize (in_degree, out_degree);
196- dB.emplace_back ().resize (1 , out_degree);
197- }
198-
199- void forward (size_t layer, const Eigen::MatrixXf& mat) {
200- Ys[layer] = mat * Ws[layer] + Bs[layer].replicate (mat.rows (), 1 );
201- activate (Ys[layer], acts[layer]);
202- }
203-
204- void loss (const Eigen::VectorXi& labels) {
205- delta = Ys.back ();
206- delta = (delta - delta.rowwise ().maxCoeff ().replicate (1 , delta.cols ())).array ().exp ().matrix ();
207- delta = delta.cwiseQuotient (delta.rowwise ().sum ().replicate (1 , delta.cols ()));
208- for (size_t i=beg_row, j=0 ; j<batch_size; i++, j++) {
209- delta (j, labels[i]) -= 1.0 ;
210- }
211- }
212-
213- void backward (size_t layer, const Eigen::MatrixXf& Xin) {
214- deactivate (Ys[layer], acts[layer]);
215- delta = delta.cwiseProduct (Ys[layer]);
216- // std::cout << Xin.rows() << "/" << Xin.cols() << " = " << delta.rows() << "/" << delta.cols() << std::endl;
217- dB[layer] = delta.colwise ().sum ();
218- dW[layer] = Xin.transpose () * delta;
219- // dW[layer] = Xin * delta;
220-
221- if (layer > 0 ) {
222- delta = delta * Ws[layer].transpose ();
223- }
224- }
225-
226- void update (size_t layer) {
227- Ws[layer] -= lrate*(dW[layer] + decay*Ws[layer]);
228- Bs[layer] -= lrate*(dB[layer] + decay*Bs[layer]);
229- }
230-
231- void shuffle (Eigen::MatrixXf& mat, Eigen::VectorXi& vec, const size_t row_num) {
232-
233- static thread_local std::mt19937 gen (0 );
234-
235- Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> p (row_num);
236- p.setIdentity ();
237- std::shuffle (p.indices ().data (), p.indices ().data () + p.indices ().size (), gen);
238-
239- mat = p * mat;
240- vec = p * vec;
241- }
242-
243- void validate () {
244- Eigen::MatrixXf res = test_images;
245- // auto t1 = std::chrono::high_resolution_clock::now();
246- for (size_t i=0 ; i<acts.size (); i++) {
247- res = res * Ws[i] + Bs[i].replicate (res.rows (), 1 );
248- if (acts[i] == Activation::RELU) {
249- relu (res);
250- }
251- else if (acts[i] == Activation::SIGMOID) {
252- sigmoid (res);
253- }
254- }
255- // auto t2 = std::chrono::high_resolution_clock::now();
256- // std::cout << "Infer runtime: " << time_diff(t1, t2) << " ms\n";
257-
258- size_t correct_num {0 };
259- for (int k=0 ; k<res.rows (); k++) {
260- int pred ;
261- res.row (k).maxCoeff (&pred);
262- if (pred == test_labels[k]) {
263- correct_num ++;
264- }
265- }
266- // std::cout << "Accuracy: " << correct_num << '/' << res.rows() << '\n';
267- }
268-
269-
270- // Parameter functions ------------------------------------------------------
271- auto & epoch_num (unsigned e) {
272- epoch = e;
273- return *this ;
274- }
275- auto & batch (size_t b) {
276- batch_size = b;
277- assert (images.rows ()%batch_size == 0 );
278- return *this ;
279- }
280- auto & learning_rate (float l) {
281- lrate = l;
282- return *this ;
283- }
284-
285- std::vector<Eigen::MatrixXf> Ys;
286- std::vector<Eigen::MatrixXf> Ws;
287- std::vector<Eigen::MatrixXf> Bs;
288- std::vector<Eigen::MatrixXf> dW;
289- std::vector<Eigen::MatrixXf> dB;
290-
291- std::vector<Activation> acts;
292-
293- // Training images # = 60000 x 784 (28 x 28)
294- Eigen::MatrixXf images;
295- Eigen::VectorXi labels;
296- Eigen::MatrixXf delta;
297-
298- // Testing images # = 10000 x 784 (28 x 28)
299- Eigen::MatrixXf test_images;
300- Eigen::VectorXi test_labels;
301-
302- int beg_row {0 };
303-
304- float lrate {0 .01f };
305- float decay {0 .01f };
306-
307- unsigned epoch {0 };
308- size_t batch_size {1 };
309- };
310-
311- inline auto build_dnn (unsigned epoch) {
312- MNIST dnn;
313- dnn.epoch_num (epoch).batch (60 ).learning_rate (0.001 );
314-
315- // dnn.add_layer(784, 64, Activation::RELU);
316- // dnn.add_layer(64, 32, Activation::RELU);
317- // dnn.add_layer(32, 10, Activation::NONE);
318-
319- // dnn.add_layer(784, 64, Activation::RELU);
320- // dnn.add_layer(64, 32, Activation::RELU);
321- // dnn.add_layer(32, 16, Activation::RELU);
322- // dnn.add_layer(16, 8, Activation::RELU);
323- // dnn.add_layer(8, 10, Activation::NONE);
324-
325- // dnn.add_layer(784, 256, Activation::RELU);
326- // dnn.add_layer(256, 128, Activation::RELU);
327- // dnn.add_layer(128, 64, Activation::RELU);
328- // dnn.add_layer(64, 32, Activation::RELU);
329- // dnn.add_layer(32, 10, Activation::NONE);
330-
331- dnn.add_layer (784 , 100 , Activation::RELU);
332- dnn.add_layer (100 , 30 , Activation::RELU);
333- dnn.add_layer (30 , 10 , Activation::NONE);
334-
335- return dnn;
336- }
337-
338-
339173// ----------------------------------------------------------------------------
340174
341175struct MNIST_DNN {
@@ -544,11 +378,5 @@ inline void report_runtime(std::chrono::time_point<std::chrono::high_resolution_
544378void run_tbb (unsigned , unsigned );
545379void run_taskflow (unsigned , unsigned );
546380void run_omp (unsigned , unsigned );
547-
548- // void run_omp(MNIST&, unsigned);
549- void run_sequential (MNIST&, unsigned );
550- void run_sequential (MNIST_DNN&, unsigned );
551-
552- // void run_sequential2(MNIST_DNN&, unsigned);
553- void run_sequential2 (unsigned , unsigned );
381+ void run_sequential (unsigned , unsigned );
554382
0 commit comments