factory.cpp (6733B)
1 /** 2 * @file 3 * @brief Definition of factories for nmlp classes. 4 * 5 * Since, the code of nmlp must remain distinct, a separate registration of classes is useless. 6 * As a result, these functions does not implement real factory pattern but simple "if-else" lists. 7 */ 8 9 #include <cstddef> 10 #include <iostream> 11 #include <string> 12 #include <stdexcept> 13 #include <vector> 14 15 #include <boost/make_shared.hpp> 16 #include <boost/program_options.hpp> 17 #include <boost/shared_ptr.hpp> 18 #include <nmlp/Criterion.h> 19 #include <nmlp/criterions/CPUHingeLoss.h> 20 #include <nmlp/criterions/CPUMaxLoss.h> 21 #include <nmlp/criterions/CPUSquareLoss.h> 22 #include <nmlp/criterions/GPUHingeLoss.h> 23 #include <nmlp/criterions/GPUSquareLoss.h> 24 #include <nmlp/modules/CPUIdentity.h> 25 #include <nmlp/modules/CPULinear.h> 26 #include <nmlp/modules/CPULogistic.h> 27 #include <nmlp/modules/CPUPositiveShrink.h> 28 #include <nmlp/modules/CPUSparseLinear.h> 29 #include <nmlp/modules/CPUTanH.h> 30 #include <nmlp/modules/GPUIdentity.h> 31 #include <nmlp/modules/GPULinear.h> 32 #include <nmlp/modules/GPUPositiveShrink.h> 33 #include <nmlp/modules/GPUTanH.h> 34 #include <nmlp/modules/SequentialModule.h> 35 36 37 #include "factory.hpp" 38 39 boost::shared_ptr<SequentialModule> interactive_module_factory(std::istream &in, std::ostream &out, std::size_t input_size, std::size_t output_size){ 40 boost::shared_ptr<SequentialModule> module=boost::make_shared<SequentialModule>(); 41 std::string type; 42 43 while(out << "Module? ", in >> type, type!="end"){ 44 if(type=="CPULinear" || type=="CPUSparseLinear" || type=="GPULinear"){ 45 std::size_t is=input_size; 46 out << "Output size? "; 47 in >> input_size; 48 out << "Randomization variance? "; 49 double variance; 50 in >> variance; 51 52 if(type=="CPULinear"){ 53 boost::shared_ptr<CPULinear> p=boost::make_shared<CPULinear>(is, input_size); 54 p->randomize(variance); 55 module->addModule(p); 56 } else if(type=="CPUSparseLinear"){ 57 boost::shared_ptr<CPUSparseLinear> p=boost::make_shared<CPUSparseLinear>(is, input_size); 58 p->randomize(variance); 59 module->addModule(p); 60 } else if(type=="GPULinear"){ 61 boost::shared_ptr<GPULinear> p=boost::make_shared<GPULinear>(is, input_size); 62 p->randomize(variance); 63 module->addModule(p); 64 } 65 } 66 else if(type=="CPUIdentity") module->addModule(boost::make_shared<CPUIdentity>(input_size)); 67 else if(type=="CPULogistic") module->addModule(boost::make_shared<CPULogistic>(input_size)); 68 else if(type=="CPUTanH") module->addModule(boost::make_shared<CPUTanH>(input_size)); 69 else if(type=="CPUPositiveShrink") module->addModule(boost::make_shared<CPUPositiveShrink>(input_size)); 70 else if(type=="GPUIdentity") module->addModule(boost::make_shared<GPUIdentity>(input_size)); 71 else if(type=="GPULogistic") module->addModule(boost::make_shared<GPULogistic>(input_size)); 72 else if(type=="GPUTanH") module->addModule(boost::make_shared<GPUTanH>(input_size)); 73 else if(type=="GPUPositiveShrink") module->addModule(boost::make_shared<GPUPositiveShrink>(input_size)); 74 75 else out << "Unknown module name.\n"; 76 } 77 78 if(input_size!=output_size) 79 throw std::runtime_error("The size of the last module and the output size differs."); 80 81 return module; 82 } 83 84 boost::shared_ptr<SequentialModule> detached_module_factory(boost::program_options::variables_map const &vm, std::string const &prefix, std::size_t input_size, std::size_t output_size){ 85 boost::shared_ptr<SequentialModule> module=boost::make_shared<SequentialModule>(); 86 87 std::vector<std::string> modules_str=vm[prefix+"module"].as<std::vector<std::string> >(); 88 std::vector<std::size_t> sizes=vm[prefix+"size"].as<std::vector<std::size_t> >(); 89 std::vector<float> variances=vm[prefix+"variance"].as<std::vector<float> >(); 90 91 std::vector<std::string>::const_iterator module_it=modules_str.begin(); 92 std::vector<std::size_t>::const_iterator size_it=sizes.begin(); 93 std::vector<float>::const_iterator variance_it=variances.begin(); 94 95 for(; module_it!=modules_str.end(); ++module_it){ 96 if(*module_it=="CPULinear" || *module_it=="CPUSparseLinear" || *module_it=="GPULinear"){ 97 if(size_it==sizes.end()) 98 throw std::runtime_error("Missing a size value in configuration file"); 99 if(variance_it==variances.end()) 100 throw std::runtime_error("Missing a variance value in configuration file"); 101 102 std::size_t is=input_size; 103 input_size=*size_it++; 104 105 if(*module_it=="CPULinear"){ 106 boost::shared_ptr<CPULinear> p=boost::make_shared<CPULinear>(is, input_size); 107 p->randomize(*variance_it++); 108 module->addModule(p); 109 } else if(*module_it=="CPUSparseLinear"){ 110 boost::shared_ptr<CPUSparseLinear> p=boost::make_shared<CPUSparseLinear>(is, input_size); 111 p->randomize(*variance_it++); 112 module->addModule(p); 113 } else if(*module_it=="GPULinear"){ 114 boost::shared_ptr<GPULinear> p=boost::make_shared<GPULinear>(is, input_size); 115 p->randomize(*variance_it++); 116 module->addModule(p); 117 } 118 } 119 else if(*module_it=="CPUIdentity") module->addModule(boost::make_shared<CPUIdentity>(input_size)); 120 else if(*module_it=="CPULogistic") module->addModule(boost::make_shared<CPULogistic>(input_size)); 121 else if(*module_it=="CPUTanH") module->addModule(boost::make_shared<CPUTanH>(input_size)); 122 else if(*module_it=="CPUPositiveShrink") module->addModule(boost::make_shared<CPUPositiveShrink>(input_size)); 123 else if(*module_it=="GPUIdentity") module->addModule(boost::make_shared<GPUIdentity>(input_size)); 124 else if(*module_it=="GPULogistic") module->addModule(boost::make_shared<GPULogistic>(input_size)); 125 else if(*module_it=="GPUTanH") module->addModule(boost::make_shared<GPUTanH>(input_size)); 126 else if(*module_it=="GPUPositiveShrink") module->addModule(boost::make_shared<GPUPositiveShrink>(input_size)); 127 else throw std::runtime_error("Unknown module name in configuration file"); 128 } 129 130 if(size_it!=sizes.end()) 131 throw std::runtime_error("Extra size value in configuration file (size must be specified for Linear modules only)"); 132 if(variance_it!=variances.end()) 133 throw std::runtime_error("Extra variance value in configuration file (variance must be specified for Linear modules only)"); 134 135 return module; 136 } 137 138 boost::shared_ptr<Criterion> criterion_factory(std::string const &name, std::size_t size){ 139 if(name=="CPUSquareLoss") return boost::make_shared<CPUSquareLoss>(size); 140 if(name=="CPUHingeLoss") return boost::make_shared<CPUHingeLoss>(size); 141 if(name=="CPUMaxLoss") return boost::make_shared<CPUMaxLoss>(); 142 if(name=="GPUSquareLoss") return boost::make_shared<GPUSquareLoss>(size); 143 if(name=="GPUHingeLoss") return boost::make_shared<GPUHingeLoss>(size); 144 throw std::runtime_error("Criterion factory called on an unknown identifier"); 145 } 146