* @brief General interface of first-order optimizers * * The optimizer class is implemented in a way to trade off compile-time binding and run-time binding. * * In CPU code, optimizers are binded at run time to reduce the size of executables. * In GPU code, optimizers are binded at compile time to maximize the run-time speed. * * @note To add a new optimizer, you need to * - add a value in
| 100 | * - add python binding of the helper class in bind.h & graphvite.cu |
| 101 | */ |
| 102 | class Optimizer { |
| 103 | public: |
| 104 | int num_moment; |
| 105 | std::string type; |
| 106 | float init_lr, lr, weight_decay; |
| 107 | LRSchedule schedule; |
| 108 | // auxiliary fields for different optimizers |
| 109 | union { |
| 110 | struct { // Momentum |
| 111 | float momentum; |
| 112 | }; |
| 113 | struct { // RMSprop |
| 114 | float alpha; |
| 115 | }; |
| 116 | struct { // Adam |
| 117 | float beta1, beta2; |
| 118 | }; |
| 119 | }; |
| 120 | float epsilon; |
| 121 | |
| 122 | /** Construct a default optimizer */ |
| 123 | Optimizer(int _type) : type("Default"), init_lr(0), lr(0) { |
| 124 | CHECK(_type == kAuto) << "Only kAuto can be used for initializing a default optimizer. " |
| 125 | << "Please use a float value if you want to specify the learning rate."; |
| 126 | } |
| 127 | |
| 128 | /** Construct a default optimizer with learning rate */ |
| 129 | Optimizer(float _lr = 1e-4) : type("Default"), init_lr(_lr), lr(_lr) {} |
| 130 | |
| 131 | /** Compute current learning rate according to the schedule */ |
| 132 | void apply_schedule(int batch_id, int num_batch) { |
| 133 | lr = init_lr * schedule(batch_id, num_batch); |
| 134 | } |
| 135 | |
| 136 | /** Return information about the optimizer */ |
| 137 | std::string info() const { |
| 138 | std::stringstream ss; |
| 139 | ss << "optimizer: " << type << std::endl; |
| 140 | ss << "learning rate: " << init_lr << ", " << schedule.info() << std::endl; |
| 141 | ss << "weight decay: " << weight_decay; |
| 142 | |
| 143 | if (type != "Default" && type != "SGD") { |
| 144 | ss << std::endl; |
| 145 | if (type == "Momentum") |
| 146 | ss << "momentum: " << momentum; |
| 147 | if (type == "AdaGrad") |
| 148 | ss << "epsilon: " << epsilon; |
| 149 | if (type == "RMSprop") |
| 150 | ss << "alpha: " << alpha << ", epsilon: " << epsilon; |
| 151 | if (type == "Adam") |
| 152 | ss << "beta1: " << beta1 << ", beta2: " << beta2 << ", epsilon: " << epsilon; |
| 153 | } |
| 154 | return ss.str(); |
| 155 | } |
| 156 | |
| 157 | /** |
| 158 | * @brief SGD update rule |
| 159 | * @tparam Float floating type of parameters |
no outgoing calls
no test coverage detected