未验证 提交 6d23261a 编写于 作者: B Bo Zhou 提交者: GitHub

update code format to meet icode requirement (#243)

* update code format to meet icode requirement

* update torch code
上级 53da94b8
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef ADAM_OPTIMIZER_H #ifndef ADAM_OPTIMIZER_H
#define ADAM_OPTIMIZER_H #define ADAM_OPTIMIZER_H
...@@ -20,7 +19,7 @@ ...@@ -20,7 +19,7 @@
#include <cmath> #include <cmath>
#include "optimizer.h" #include "optimizer.h"
namespace DeepES{ namespace deep_es {
/*@brief AdamOptimizer. /*@brief AdamOptimizer.
* Implements Adam algorithm. * Implements Adam algorithm.
...@@ -33,7 +32,8 @@ namespace DeepES{ ...@@ -33,7 +32,8 @@ namespace DeepES{
*/ */
class AdamOptimizer: public Optimizer { class AdamOptimizer: public Optimizer {
public: public:
AdamOptimizer(float base_lr, float beta1=0.9, float beta2=0.999, float epsilon=1e-8):Optimizer(base_lr), \ AdamOptimizer(float base_lr, float beta1 = 0.9, float beta2 = 0.999,
float epsilon = 1e-8): Optimizer(base_lr), \
_beta1(beta1), _beta2(beta2), _epsilon(epsilon) {} _beta1(beta1), _beta2(beta2), _epsilon(epsilon) {}
~AdamOptimizer(); ~AdamOptimizer();
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "utils.h" #include "utils.h"
#include <glog/logging.h> #include <glog/logging.h>
namespace DeepES{ namespace deep_es {
class CachedGaussianSampling: public SamplingMethod { class CachedGaussianSampling: public SamplingMethod {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "sampling_method.h" #include "sampling_method.h"
#include "utils.h" #include "utils.h"
namespace DeepES{ namespace deep_es {
class GaussianSampling: public SamplingMethod { class GaussianSampling: public SamplingMethod {
......
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
#include <map> #include <map>
#include <glog/logging.h> #include <glog/logging.h>
namespace deep_es {
namespace DeepES{
/*@brief Optimizer. Base class for optimizers. /*@brief Optimizer. Base class for optimizers.
* *
...@@ -41,7 +40,7 @@ public: ...@@ -41,7 +40,7 @@ public:
} }
template<typename T> template<typename T>
bool update(T weights, float* gradient, int size, std::string param_name="") { bool update(T weights, float* gradient, int size, std::string param_name = "") {
/*@ Performs a single optimization step (parameter update) at the parameter level. /*@ Performs a single optimization step (parameter update) at the parameter level.
* *
*@Args: *@Args:
...@@ -53,21 +52,23 @@ public: ...@@ -53,21 +52,23 @@ public:
if (_params_size.count(param_name) == 0) { if (_params_size.count(param_name) == 0) {
_params_size[param_name] = size; _params_size[param_name] = size;
} else if (_params_size[param_name] != size) { } else if (_params_size[param_name] != size) {
LOG(WARNING) << "[Warning] Update times: "<< int(_update_times / _params_size.size()) \ LOG(WARNING) << "[Warning] Update times: " << int(_update_times / _params_size.size()) \
<< ". Size of weights[" << param_name << "] is " << _params_size[param_name] << ", not " << size; << ". Size of weights[" << param_name << "] is " << _params_size[param_name] << ", not " << size;
return false; return false;
} }
++_update_times; ++_update_times;
compute_step(gradient, size, param_name); compute_step(gradient, size, param_name);
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
weights[i] -= _base_lr * gradient[i]; weights[i] -= _base_lr * gradient[i];
} }
return true; return true;
} // template function } // template function
protected: protected:
virtual void compute_step(float* graident, int size, std::string param_name="") = 0; virtual void compute_step(float* graident, int size, std::string param_name = "") = 0;
float _base_lr; float _base_lr;
float _update_times; float _update_times;
std::map<std::string, int> _params_size; std::map<std::string, int> _params_size;
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "deepes.pb.h" #include "deepes.pb.h"
#include <glog/logging.h> #include <glog/logging.h>
namespace DeepES{ namespace deep_es {
/* @brief: create an optimizer according to the configuration" /* @brief: create an optimizer according to the configuration"
* @args: * @args:
* config: configuration for the optimizer * config: configuration for the optimizer
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "deepes.pb.h" #include "deepes.pb.h"
#include <glog/logging.h> #include <glog/logging.h>
namespace DeepES{ namespace deep_es {
/* @brief: create an sampling_method according to the configuration" /* @brief: create an sampling_method according to the configuration"
* @args: * @args:
* config: configuration for the DeepES * config: configuration for the DeepES
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <random> #include <random>
#include "deepes.pb.h" #include "deepes.pb.h"
namespace DeepES{ namespace deep_es {
/*Base class for sampling algorithms. All algorithms are required to override the following functions: /*Base class for sampling algorithms. All algorithms are required to override the following functions:
* *
...@@ -30,7 +30,7 @@ namespace DeepES{ ...@@ -30,7 +30,7 @@ namespace DeepES{
* View an demostrative algorithm in gaussian_sampling.h * View an demostrative algorithm in gaussian_sampling.h
* */ * */
class SamplingMethod{ class SamplingMethod {
public: public:
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
Usally you won't have to modify the configuration items of other algorithms Usally you won't have to modify the configuration items of other algorithms
if you are not using them. if you are not using them.
*/ */
virtual bool load_config(const DeepESConfig& config)=0; virtual bool load_config(const DeepESConfig& config) = 0;
/*@brief generate Gaussian noise and the related key. /*@brief generate Gaussian noise and the related key.
* *
...@@ -56,7 +56,7 @@ public: ...@@ -56,7 +56,7 @@ public:
*@return: *@return:
* success: generate Gaussian successfully or not. * success: generate Gaussian successfully or not.
*/ */
virtual bool sampling(int* key, float* noise, int64_t size)=0; virtual bool sampling(int* key, float* noise, int64_t size) = 0;
/*@brief reconstruct the Gaussion noise given the key. /*@brief reconstruct the Gaussion noise given the key.
* This function is often used for updating the neuron network parameters in the offline environment. * This function is often used for updating the neuron network parameters in the offline environment.
...@@ -69,7 +69,7 @@ public: ...@@ -69,7 +69,7 @@ public:
*@return: *@return:
* success: reconstruct Gaussian successfully or not. * success: reconstruct Gaussian successfully or not.
*/ */
virtual bool resampling(int key, float* noise, int64_t size)=0; virtual bool resampling(int key, float* noise, int64_t size) = 0;
bool set_seed(int seed) { bool set_seed(int seed) {
_seed = seed; _seed = seed;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <cmath> #include <cmath>
#include "optimizer.h" #include "optimizer.h"
namespace DeepES{ namespace deep_es {
/*@brief SGDOptimizer. /*@brief SGDOptimizer.
* Implements stochastic gradient descent (optionally with momentum). * Implements stochastic gradient descent (optionally with momentum).
...@@ -30,7 +30,7 @@ namespace DeepES{ ...@@ -30,7 +30,7 @@ namespace DeepES{
*/ */
class SGDOptimizer: public Optimizer { class SGDOptimizer: public Optimizer {
public: public:
SGDOptimizer(float base_lr, float momentum=0.9):Optimizer(base_lr), _momentum(momentum) {} SGDOptimizer(float base_lr, float momentum = 0.9): Optimizer(base_lr), _momentum(momentum) {}
~SGDOptimizer(); ~SGDOptimizer();
protected: protected:
......
...@@ -23,13 +23,13 @@ ...@@ -23,13 +23,13 @@
#include <google/protobuf/text_format.h> #include <google/protobuf/text_format.h>
#include <fstream> #include <fstream>
namespace DeepES{ namespace deep_es {
/*Return ranks that is normliazed to [-0.5, 0.5] with the rewards as input. /*Return ranks that is normliazed to [-0.5, 0.5] with the rewards as input.
Args: Args:
reward: an array of rewards reward: an array of rewards
*/ */
bool compute_centered_ranks(std::vector<float> &reward); bool compute_centered_ranks(std::vector<float>& reward);
std::string read_file(const std::string& filename); std::string read_file(const std::string& filename);
...@@ -43,6 +43,7 @@ template<typename T> ...@@ -43,6 +43,7 @@ template<typename T>
bool load_proto_conf(const std::string& config_file, T& proto_config) { bool load_proto_conf(const std::string& config_file, T& proto_config) {
bool success = true; bool success = true;
std::ifstream fin(config_file); std::ifstream fin(config_file);
if (!fin || fin.fail()) { if (!fin || fin.fail()) {
LOG(ERROR) << "open prototxt config failed: " << config_file; LOG(ERROR) << "open prototxt config failed: " << config_file;
success = false; success = false;
...@@ -55,31 +56,38 @@ bool load_proto_conf(const std::string& config_file, T& proto_config) { ...@@ -55,31 +56,38 @@ bool load_proto_conf(const std::string& config_file, T& proto_config) {
fin.read(file_content_buffer, file_size); fin.read(file_content_buffer, file_size);
std::string proto_str(file_content_buffer, file_size); std::string proto_str(file_content_buffer, file_size);
if (!google::protobuf::TextFormat::ParseFromString(proto_str, &proto_config)) { if (!google::protobuf::TextFormat::ParseFromString(proto_str, &proto_config)) {
LOG(ERROR) << "Failed to load config: " << config_file; LOG(ERROR) << "Failed to load config: " << config_file;
success = false; success = false;
} }
delete[] file_content_buffer; delete[] file_content_buffer;
fin.close(); fin.close();
} }
return success; return success;
} }
template<typename T> template<typename T>
bool save_proto_conf(const std::string& config_file, T&proto_config) { bool save_proto_conf(const std::string& config_file, T& proto_config) {
bool success = true; bool success = true;
std::ofstream ofs(config_file, std::ofstream::out); std::ofstream ofs(config_file, std::ofstream::out);
if (!ofs || ofs.fail()) { if (!ofs || ofs.fail()) {
LOG(ERROR) << "open prototxt config failed: " << config_file; LOG(ERROR) << "open prototxt config failed: " << config_file;
success = false; success = false;
} else { } else {
std::string config_str; std::string config_str;
success = google::protobuf::TextFormat::PrintToString(proto_config, &config_str); success = google::protobuf::TextFormat::PrintToString(proto_config, &config_str);
if (!success) { if (!success) {
return success; return success;
} }
ofs << config_str; ofs << config_str;
} }
return success; return success;
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
syntax = "proto2"; syntax = "proto2";
package DeepES; package deep_es;
message DeepESConfig { message DeepESConfig {
//sampling configuration //sampling configuration
......
...@@ -14,33 +14,40 @@ ...@@ -14,33 +14,40 @@
#include "adam_optimizer.h" #include "adam_optimizer.h"
namespace DeepES { namespace deep_es {
AdamOptimizer::~AdamOptimizer() { AdamOptimizer::~AdamOptimizer() {
for (auto iter = _momentum.begin(); iter != _momentum.end(); iter++) { for (auto iter = _momentum.begin(); iter != _momentum.end(); iter++) {
delete[] iter->second; delete[] iter->second;
} }
for (auto iter = _velocity.begin(); iter != _velocity.end(); iter++) { for (auto iter = _velocity.begin(); iter != _velocity.end(); iter++) {
delete[] iter->second; delete[] iter->second;
} }
_momentum.clear(); _momentum.clear();
_velocity.clear(); _velocity.clear();
} }
void AdamOptimizer::compute_step(float* gradient, int size, std::string param_name="") { void AdamOptimizer::compute_step(float* gradient, int size, std::string param_name = "") {
if (_momentum.count(param_name) == 0) { if (_momentum.count(param_name) == 0) {
_momentum[param_name] = new float [size]; _momentum[param_name] = new float [size];
memset(_momentum[param_name], 0, size * sizeof(float)); memset(_momentum[param_name], 0, size * sizeof(float));
} }
if (_velocity.count(param_name) == 0) { if (_velocity.count(param_name) == 0) {
_velocity[param_name] = new float [size]; _velocity[param_name] = new float [size];
memset(_velocity[param_name], 0, size * sizeof(float)); memset(_velocity[param_name], 0, size * sizeof(float));
} }
int true_update_times = int(_update_times / _velocity.size()); int true_update_times = int(_update_times / _velocity.size());
float alpha = std::sqrt(1 - std::pow(_beta2, _update_times)) / (1 - std::pow(_beta1, _update_times)); float alpha = std::sqrt(1 - std::pow(_beta2, _update_times)) / (1 - std::pow(_beta1,
_update_times));
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
_momentum[param_name][i] = _beta1 * _momentum[param_name][i] + (1 - _beta1) * gradient[i]; _momentum[param_name][i] = _beta1 * _momentum[param_name][i] + (1 - _beta1) * gradient[i];
_velocity[param_name][i] = _beta2 * _velocity[param_name][i] + (1 - _beta2) * gradient[i] * gradient[i]; _velocity[param_name][i] = _beta2 * _velocity[param_name][i] + (1 - _beta2) * gradient[i] *
gradient[i];
gradient[i] = alpha * _momentum[param_name][i] / (std::sqrt(_velocity[param_name][i]) + _epsilon); gradient[i] = alpha * _momentum[param_name][i] / (std::sqrt(_velocity[param_name][i]) + _epsilon);
} }
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "cached_gaussian_sampling.h" #include "cached_gaussian_sampling.h"
namespace DeepES{ namespace deep_es {
CachedGaussianSampling::CachedGaussianSampling() {} CachedGaussianSampling::CachedGaussianSampling() {}
...@@ -37,66 +37,83 @@ bool CachedGaussianSampling::load_config(const DeepESConfig& config) { ...@@ -37,66 +37,83 @@ bool CachedGaussianSampling::load_config(const DeepESConfig& config) {
bool CachedGaussianSampling::sampling(int* key, float* noise, int64_t size) { bool CachedGaussianSampling::sampling(int* key, float* noise, int64_t size) {
bool success = true; bool success = true;
if (_noise_cache == nullptr) { if (_noise_cache == nullptr) {
LOG(ERROR) << "[DeepES] Please use load_config() first."; LOG(ERROR) << "[DeepES] Please use load_config() first.";
success = false; success = false;
return success; return success;
} }
if (noise == nullptr) { if (noise == nullptr) {
LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr."; LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr.";
success = false; success = false;
return success; return success;
} }
if ((size >= _cache_size) || (size < 0)) { if ((size >= _cache_size) || (size < 0)) {
LOG(ERROR) << "[DeepES] Input size " << size << " is out of bounds [0, " << _cache_size << "), cache_size: " << _cache_size; LOG(ERROR) << "[DeepES] Input size " << size << " is out of bounds [0, " << _cache_size <<
"), cache_size: " << _cache_size;
success = false; success = false;
return success; return success;
} }
int rand_key = rand(); int rand_key = rand();
std::default_random_engine generator(rand_key); std::default_random_engine generator(rand_key);
std::uniform_int_distribution<unsigned int> uniform(0, _cache_size - size); std::uniform_int_distribution<unsigned int> uniform(0, _cache_size - size);
int index = uniform(generator); int index = uniform(generator);
*key = index; *key = index;
for (int64_t i = 0; i < size; ++i) { for (int64_t i = 0; i < size; ++i) {
*(noise + i) = *(_noise_cache + index + i); *(noise + i) = *(_noise_cache + index + i);
} }
return success; return success;
} }
bool CachedGaussianSampling::resampling(int key, float* noise, int64_t size) { bool CachedGaussianSampling::resampling(int key, float* noise, int64_t size) {
bool success = true; bool success = true;
if (_noise_cache == nullptr) { if (_noise_cache == nullptr) {
LOG(ERROR) << "[DeepES] Please use load_config() first."; LOG(ERROR) << "[DeepES] Please use load_config() first.";
success = false; success = false;
return success; return success;
} }
if (noise == nullptr) { if (noise == nullptr) {
LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr."; LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr.";
success = false; success = false;
return success; return success;
} }
if ((size >= _cache_size) || (size < 0)) { if ((size >= _cache_size) || (size < 0)) {
LOG(ERROR) << "[DeepES] Input size " << size << " is out of bounds [0, " << _cache_size << "), cache_size: " << _cache_size; LOG(ERROR) << "[DeepES] Input size " << size << " is out of bounds [0, " << _cache_size <<
"), cache_size: " << _cache_size;
success = false; success = false;
return success; return success;
} }
if ((key > _cache_size - size) || (key < 0)) { if ((key > _cache_size - size) || (key < 0)) {
LOG(ERROR) << "[DeepES] Resampling key " << key << " is out of bounds [0, " << _cache_size - size << "], cache_size: " << _cache_size << ", size: " << size; LOG(ERROR) << "[DeepES] Resampling key " << key << " is out of bounds [0, " << _cache_size - size <<
"], cache_size: " << _cache_size << ", size: " << size;
success = false; success = false;
return success; return success;
} }
for (int64_t i = 0; i < size; ++i) { for (int64_t i = 0; i < size; ++i) {
*(noise + i) = *(_noise_cache + key + i); *(noise + i) = *(_noise_cache + key + i);
} }
return success; return success;
} }
bool CachedGaussianSampling::_create_noise_cache() { bool CachedGaussianSampling::_create_noise_cache() {
std::default_random_engine generator(_seed); std::default_random_engine generator(_seed);
std::normal_distribution<float> norm; std::normal_distribution<float> norm;
for (int64_t i = 0; i < _cache_size; ++i) { for (int64_t i = 0; i < _cache_size; ++i) {
*(_noise_cache + i) = norm(generator) * _std; *(_noise_cache + i) = norm(generator) * _std;
} }
return true; return true;
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "gaussian_sampling.h" #include "gaussian_sampling.h"
namespace DeepES{ namespace deep_es {
bool GaussianSampling::load_config(const DeepESConfig& config) { bool GaussianSampling::load_config(const DeepESConfig& config) {
bool success = true; bool success = true;
...@@ -25,33 +25,40 @@ bool GaussianSampling::load_config(const DeepESConfig& config) { ...@@ -25,33 +25,40 @@ bool GaussianSampling::load_config(const DeepESConfig& config) {
bool GaussianSampling::sampling(int* key, float* noise, int64_t size) { bool GaussianSampling::sampling(int* key, float* noise, int64_t size) {
bool success = true; bool success = true;
if (noise == nullptr) { if (noise == nullptr) {
LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr."; LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr.";
success = false; success = false;
return success; return success;
} }
int rand_key = rand(); int rand_key = rand();
*key = rand_key; *key = rand_key;
std::default_random_engine generator(rand_key); std::default_random_engine generator(rand_key);
std::normal_distribution<float> norm; std::normal_distribution<float> norm;
for (int64_t i = 0; i < size; ++i) { for (int64_t i = 0; i < size; ++i) {
*(noise + i) = norm(generator) * _std; *(noise + i) = norm(generator) * _std;
} }
return success; return success;
} }
bool GaussianSampling::resampling(int key, float* noise, int64_t size) { bool GaussianSampling::resampling(int key, float* noise, int64_t size) {
bool success = true; bool success = true;
if (noise == nullptr) { if (noise == nullptr) {
LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr."; LOG(ERROR) << "[DeepES] Input noise array cannot be nullptr.";
success = false; success = false;
} else { } else {
std::default_random_engine generator(key); std::default_random_engine generator(key);
std::normal_distribution<float> norm; std::normal_distribution<float> norm;
for (int64_t i = 0; i < size; ++i) { for (int64_t i = 0; i < size; ++i) {
*(noise + i) = norm(generator) * _std; *(noise + i) = norm(generator) * _std;
} }
} }
return success; return success;
} }
......
...@@ -14,13 +14,13 @@ ...@@ -14,13 +14,13 @@
#include "optimizer_factory.h" #include "optimizer_factory.h"
namespace DeepES{ namespace deep_es {
std::shared_ptr<Optimizer> create_optimizer(const OptimizerConfig& optimizer_config) { std::shared_ptr<Optimizer> create_optimizer(const OptimizerConfig& optimizer_config) {
std::shared_ptr<Optimizer> optimizer; std::shared_ptr<Optimizer> optimizer;
std::string opt_type = optimizer_config.type(); std::string opt_type = optimizer_config.type();
std::transform(opt_type.begin(), opt_type.end(), opt_type.begin(), ::tolower); std::transform(opt_type.begin(), opt_type.end(), opt_type.begin(), ::tolower);
if (opt_type == "sgd") { if (opt_type == "sgd") {
optimizer = std::make_shared<SGDOptimizer>(optimizer_config.base_lr(), \ optimizer = std::make_shared<SGDOptimizer>(optimizer_config.base_lr(), \
optimizer_config.momentum()); optimizer_config.momentum());
...@@ -32,6 +32,7 @@ std::shared_ptr<Optimizer> create_optimizer(const OptimizerConfig& optimizer_con ...@@ -32,6 +32,7 @@ std::shared_ptr<Optimizer> create_optimizer(const OptimizerConfig& optimizer_con
} else { } else {
LOG(ERROR) << "type of OptimizerConfig must be SGD or Adam."; // NotImplementedError LOG(ERROR) << "type of OptimizerConfig must be SGD or Adam."; // NotImplementedError
} }
return optimizer; return optimizer;
} }
......
...@@ -14,12 +14,13 @@ ...@@ -14,12 +14,13 @@
#include "sampling_factory.h" #include "sampling_factory.h"
namespace DeepES{ namespace deep_es {
std::shared_ptr<SamplingMethod> create_sampling_method(const DeepESConfig& config) { std::shared_ptr<SamplingMethod> create_sampling_method(const DeepESConfig& config) {
std::shared_ptr<SamplingMethod> sampling_method; std::shared_ptr<SamplingMethod> sampling_method;
bool cached = config.gaussian_sampling().cached(); bool cached = config.gaussian_sampling().cached();
if (cached) { if (cached) {
sampling_method = std::make_shared<CachedGaussianSampling>(); sampling_method = std::make_shared<CachedGaussianSampling>();
} else { } else {
...@@ -27,7 +28,8 @@ std::shared_ptr<SamplingMethod> create_sampling_method(const DeepESConfig& confi ...@@ -27,7 +28,8 @@ std::shared_ptr<SamplingMethod> create_sampling_method(const DeepESConfig& confi
} }
bool success = sampling_method->load_config(config); bool success = sampling_method->load_config(config);
if(success) {
if (success) {
return sampling_method; return sampling_method;
} else { } else {
LOG(ERROR) << "[DeepES] Fail to create sampling_method"; LOG(ERROR) << "[DeepES] Fail to create sampling_method";
......
...@@ -14,20 +14,22 @@ ...@@ -14,20 +14,22 @@
#include "sgd_optimizer.h" #include "sgd_optimizer.h"
namespace DeepES { namespace deep_es {
SGDOptimizer::~SGDOptimizer() { SGDOptimizer::~SGDOptimizer() {
for (auto iter = _velocity.begin(); iter != _velocity.end(); iter++) { for (auto iter = _velocity.begin(); iter != _velocity.end(); iter++) {
delete[] iter->second; delete[] iter->second;
} }
_velocity.clear(); _velocity.clear();
} }
void SGDOptimizer::compute_step(float* gradient, int size, std::string param_name="") { void SGDOptimizer::compute_step(float* gradient, int size, std::string param_name = "") {
if (_velocity.count(param_name) == 0) { if (_velocity.count(param_name) == 0) {
_velocity[param_name] = new float [size]; _velocity[param_name] = new float [size];
memset(_velocity[param_name], 0, size * sizeof(float)); memset(_velocity[param_name], 0, size * sizeof(float));
} }
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
_velocity[param_name][i] = _momentum * _velocity[param_name][i] + (1 - _momentum) * gradient[i]; _velocity[param_name][i] = _momentum * _velocity[param_name][i] + (1 - _momentum) * gradient[i];
gradient[i] = _velocity[param_name][i]; gradient[i] = _velocity[param_name][i];
......
...@@ -15,52 +15,65 @@ ...@@ -15,52 +15,65 @@
#include "utils.h" #include "utils.h"
#include <dirent.h> #include <dirent.h>
namespace DeepES { namespace deep_es {
bool compute_centered_ranks(std::vector<float> &reward) { bool compute_centered_ranks(std::vector<float>& reward) {
std::vector<std::pair<float, int>> reward_index; std::vector<std::pair<float, int>> reward_index;
float gap = 1.0 / (reward.size() - 1); float gap = 1.0 / (reward.size() - 1);
float normlized_rank = -0.5; float normlized_rank = -0.5;
int id = 0; int id = 0;
for (auto& rew: reward) {
for (auto& rew : reward) {
reward_index.push_back(std::make_pair(rew, id)); reward_index.push_back(std::make_pair(rew, id));
++id; ++id;
} }
std::sort(reward_index.begin(), reward_index.end()); std::sort(reward_index.begin(), reward_index.end());
for (int i = 0; i < reward.size(); ++i) { for (int i = 0; i < reward.size(); ++i) {
id = reward_index[i].second; id = reward_index[i].second;
reward[id] = normlized_rank; reward[id] = normlized_rank;
normlized_rank += gap; normlized_rank += gap;
} }
return true; return true;
} }
std::vector<std::string> list_all_model_dirs(std::string path) { std::vector<std::string> list_all_model_dirs(std::string path) {
std::vector<std::string> model_dirs; std::vector<std::string> model_dirs;
DIR *dpdf; DIR* dpdf;
struct dirent *epdf; struct dirent* epdf;
dpdf = opendir(path.data()); dpdf = opendir(path.data());
if (dpdf != NULL){
while (epdf = readdir(dpdf)){ if (dpdf != NULL) {
while (epdf = readdir(dpdf)) {
std::string dir(epdf->d_name); std::string dir(epdf->d_name);
if (dir.find("model_iter_id") != std::string::npos) { if (dir.find("model_iter_id") != std::string::npos) {
model_dirs.push_back(path + "/" + dir); model_dirs.push_back(path + "/" + dir);
} }
} }
} }
closedir(dpdf); closedir(dpdf);
return model_dirs; return model_dirs;
} }
std::string read_file(const std::string& filename) { std::string read_file(const std::string& filename) {
std::ifstream ifile(filename.c_str()); std::ifstream ifile(filename.c_str());
if (!ifile.is_open()) { if (!ifile.is_open()) {
LOG(ERROR) << "Open file: [" << filename << "] failed."; LOG(ERROR) << "Open file: [" << filename << "] failed.";
return ""; return "";
} }
std::ostringstream buf; std::ostringstream buf;
char ch; char ch = '\n';
while (buf && ifile.get(ch)) buf.put(ch);
while (buf && ifile.get(ch)) {
buf.put(ch);
}
ifile.close(); ifile.close();
return buf.str(); return buf.str();
} }
......
seed: 1024 seed: 1024
gaussian_sampling { gaussian_sampling {
std: 0.5 std: 0.5
cached: true cached: true
cache_size : 100000 cache_size : 100000
} }
optimizer { optimizer {
type: "Adam" type: "Adam"
base_lr: 0.05 base_lr: 0.05
...@@ -12,6 +14,7 @@ optimizer { ...@@ -12,6 +14,7 @@ optimizer {
beta2: 0.999 beta2: 0.999
epsilon: 1e-08 epsilon: 1e-08
} }
async_es { async_es {
model_iter_id: 0 model_iter_id: 0
} }
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "async_es_agent.h" #include "async_es_agent.h"
#include "paddle_api.h" #include "paddle_api.h"
using namespace DeepES; using namespace deep_es;
using namespace paddle::lite_api; using namespace paddle::lite_api;
const int ITER = 10; const int ITER = 10;
...@@ -59,24 +59,32 @@ float evaluate(CartPole& env, std::shared_ptr<AsyncESAgent> agent) { ...@@ -59,24 +59,32 @@ float evaluate(CartPole& env, std::shared_ptr<AsyncESAgent> agent) {
float reward = env.getReward(); float reward = env.getReward();
bool done = env.isDone(); bool done = env.isDone();
total_reward += reward; total_reward += reward;
if (done) break;
if (done) {
break;
}
obs = env.getState(); obs = env.getState();
} }
return total_reward; return total_reward;
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
std::vector<CartPole> envs; std::vector<CartPole> envs;
for (int i = 0; i < ITER; ++i) { for (int i = 0; i < ITER; ++i) {
envs.push_back(CartPole()); envs.push_back(CartPole());
} }
std::shared_ptr<AsyncESAgent> agent = std::make_shared<AsyncESAgent>("../demo/paddle/cartpole_init_model", std::shared_ptr<AsyncESAgent> agent =
"../demo/cartpole_config.prototxt"); std::make_shared<AsyncESAgent>("./demo/paddle/cartpole_init_model",
"./demo/cartpole_config.prototxt");
// Clone agents to sample (explore). // Clone agents to sample (explore).
std::vector< std::shared_ptr<AsyncESAgent> > sampling_agents; std::vector< std::shared_ptr<AsyncESAgent> > sampling_agents;
for (int i = 0; i < ITER; ++i) { for (int i = 0; i < ITER; ++i) {
sampling_agents.push_back(agent->clone()); sampling_agents.push_back(agent->clone());
} }
...@@ -88,16 +96,20 @@ int main(int argc, char* argv[]) { ...@@ -88,16 +96,20 @@ int main(int argc, char* argv[]) {
noisy_info.resize(ITER); noisy_info.resize(ITER);
omp_set_num_threads(10); omp_set_num_threads(10);
for (int epoch = 0; epoch < 100; ++epoch) { for (int epoch = 0; epoch < 100; ++epoch) {
last_noisy_info.clear(); last_noisy_info.clear();
last_noisy_rewards.clear(); last_noisy_rewards.clear();
if (epoch != 0) { if (epoch != 0) {
for (int i = 0; i < ITER; ++i){ for (int i = 0; i < ITER; ++i) {
last_noisy_info.push_back(noisy_info[i]); last_noisy_info.push_back(noisy_info[i]);
last_noisy_rewards.push_back(noisy_rewards[i]); last_noisy_rewards.push_back(noisy_rewards[i]);
} }
} }
#pragma omp parallel for schedule(dynamic, 1)
#pragma omp parallel for schedule(dynamic, 1)
for (int i = 0; i < ITER; ++i) { for (int i = 0; i < ITER; ++i) {
std::shared_ptr<AsyncESAgent> sampling_agent = sampling_agents[i]; std::shared_ptr<AsyncESAgent> sampling_agent = sampling_agents[i];
SamplingInfo info; SamplingInfo info;
...@@ -108,7 +120,7 @@ int main(int argc, char* argv[]) { ...@@ -108,7 +120,7 @@ int main(int argc, char* argv[]) {
noisy_rewards[i] = reward; noisy_rewards[i] = reward;
} }
for (int i = 0; i < ITER; ++i){ for (int i = 0; i < ITER; ++i) {
last_noisy_info.push_back(noisy_info[i]); last_noisy_info.push_back(noisy_info[i]);
last_noisy_rewards.push_back(noisy_rewards[i]); last_noisy_rewards.push_back(noisy_rewards[i]);
} }
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "es_agent.h" #include "es_agent.h"
#include "paddle_api.h" #include "paddle_api.h"
using namespace DeepES; using namespace deep_es;
using namespace paddle::lite_api; using namespace paddle::lite_api;
const int ITER = 10; const int ITER = 10;
...@@ -59,24 +59,31 @@ float evaluate(CartPole& env, std::shared_ptr<ESAgent> agent) { ...@@ -59,24 +59,31 @@ float evaluate(CartPole& env, std::shared_ptr<ESAgent> agent) {
float reward = env.getReward(); float reward = env.getReward();
bool done = env.isDone(); bool done = env.isDone();
total_reward += reward; total_reward += reward;
if (done) break;
if (done) {
break;
}
obs = env.getState(); obs = env.getState();
} }
return total_reward; return total_reward;
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
std::vector<CartPole> envs; std::vector<CartPole> envs;
for (int i = 0; i < ITER; ++i) { for (int i = 0; i < ITER; ++i) {
envs.push_back(CartPole()); envs.push_back(CartPole());
} }
std::shared_ptr<ESAgent> agent = std::make_shared<ESAgent>("../demo/paddle/cartpole_init_model", std::shared_ptr<ESAgent> agent = std::make_shared<ESAgent>("./demo/paddle/cartpole_init_model",
"../demo/cartpole_config.prototxt"); "./demo/cartpole_config.prototxt");
// Clone agents to sample (explore). // Clone agents to sample (explore).
std::vector< std::shared_ptr<ESAgent> > sampling_agents; std::vector< std::shared_ptr<ESAgent> > sampling_agents;
for (int i = 0; i < ITER; ++i) { for (int i = 0; i < ITER; ++i) {
sampling_agents.push_back(agent->clone()); sampling_agents.push_back(agent->clone());
} }
...@@ -86,8 +93,9 @@ int main(int argc, char* argv[]) { ...@@ -86,8 +93,9 @@ int main(int argc, char* argv[]) {
noisy_keys.resize(ITER); noisy_keys.resize(ITER);
omp_set_num_threads(10); omp_set_num_threads(10);
for (int epoch = 0; epoch < 100; ++epoch) { for (int epoch = 0; epoch < 100; ++epoch) {
#pragma omp parallel for schedule(dynamic, 1) #pragma omp parallel for schedule(dynamic, 1)
for (int i = 0; i < ITER; ++i) { for (int i = 0; i < ITER; ++i) {
std::shared_ptr<ESAgent> sampling_agent = sampling_agents[i]; std::shared_ptr<ESAgent> sampling_agent = sampling_agents[i];
SamplingInfo key; SamplingInfo key;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <map> #include <map>
#include <stdlib.h> #include <stdlib.h>
namespace DeepES{ namespace deep_es {
/* DeepES agent with PaddleLite as backend. This agent supports asynchronous update. /* DeepES agent with PaddleLite as backend. This agent supports asynchronous update.
* Users mainly focus on the following functions: * Users mainly focus on the following functions:
* 1. clone: clone an agent for multi-thread evaluation * 1. clone: clone an agent for multi-thread evaluation
...@@ -27,7 +27,7 @@ namespace DeepES{ ...@@ -27,7 +27,7 @@ namespace DeepES{
* 3. update: update parameters given data collected during evaluation. * 3. update: update parameters given data collected during evaluation.
*/ */
class AsyncESAgent: public ESAgent { class AsyncESAgent: public ESAgent {
public: public:
AsyncESAgent() {} AsyncESAgent() {}
~AsyncESAgent(); ~AsyncESAgent();
...@@ -58,7 +58,7 @@ class AsyncESAgent: public ESAgent { ...@@ -58,7 +58,7 @@ class AsyncESAgent: public ESAgent {
std::vector<SamplingInfo>& noisy_info, std::vector<SamplingInfo>& noisy_info,
std::vector<float>& noisy_rewards); std::vector<float>& noisy_rewards);
private: private:
std::map<int, std::shared_ptr<PaddlePredictor>> _previous_predictors; std::map<int, std::shared_ptr<PaddlePredictor>> _previous_predictors;
std::map<int, float*> _param_delta; std::map<int, float*> _param_delta;
std::string _config_path; std::string _config_path;
......
...@@ -22,11 +22,13 @@ ...@@ -22,11 +22,13 @@
#include "deepes.pb.h" #include "deepes.pb.h"
#include <vector> #include <vector>
using namespace paddle::lite_api; namespace deep_es {
namespace DeepES { typedef paddle::lite_api::PaddlePredictor PaddlePredictor;
typedef paddle::lite_api::CxxConfig CxxConfig;
typedef paddle::lite_api::Tensor Tensor;
int64_t ShapeProduction(const shape_t& shape); int64_t ShapeProduction(const paddle::lite_api::shape_t& shape);
/** /**
* @brief DeepES agent with PaddleLite as backend. * @brief DeepES agent with PaddleLite as backend.
...@@ -37,7 +39,7 @@ int64_t ShapeProduction(const shape_t& shape); ...@@ -37,7 +39,7 @@ int64_t ShapeProduction(const shape_t& shape);
* *
*/ */
class ESAgent { class ESAgent {
public: public:
ESAgent() {} ESAgent() {}
~ESAgent(); ~ESAgent();
...@@ -79,9 +81,7 @@ class ESAgent { ...@@ -79,9 +81,7 @@ class ESAgent {
return _param_size; return _param_size;
} }
protected:
protected:
int64_t _calculate_param_size(); int64_t _calculate_param_size();
std::shared_ptr<PaddlePredictor> _predictor; std::shared_ptr<PaddlePredictor> _predictor;
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
#include "async_es_agent.h" #include "async_es_agent.h"
namespace DeepES { namespace deep_es {
AsyncESAgent::AsyncESAgent( AsyncESAgent::AsyncESAgent(
const std::string& model_dir, const std::string& model_dir,
...@@ -21,29 +21,32 @@ AsyncESAgent::AsyncESAgent( ...@@ -21,29 +21,32 @@ AsyncESAgent::AsyncESAgent(
_config_path = config_path; _config_path = config_path;
} }
AsyncESAgent::~AsyncESAgent() { AsyncESAgent::~AsyncESAgent() {
for(const auto kv: _param_delta) { for (const auto kv : _param_delta) {
float* delta = kv.second; float* delta = kv.second;
delete[] delta; delete[] delta;
} }
} }
bool AsyncESAgent::_save() { bool AsyncESAgent::_save() {
using namespace paddle::lite_api;
bool success = true; bool success = true;
if (_is_sampling_agent) { if (_is_sampling_agent) {
LOG(ERROR) << "[DeepES] Cloned AsyncESAgent cannot call `save`.Please use original AsyncESAgent."; LOG(ERROR) << "[DeepES] Cloned AsyncESAgent cannot call `save`.Please use original AsyncESAgent.";
success = false; success = false;
return success; return success;
} }
int model_iter_id = _config->async_es().model_iter_id() + 1; int model_iter_id = _config->async_es().model_iter_id() + 1;
//current time //current time
time_t rawtime; time_t rawtime;
struct tm * timeinfo; struct tm* timeinfo;
char buffer[80]; char buffer[80];
time (&rawtime); time(&rawtime);
timeinfo = localtime(&rawtime); timeinfo = localtime(&rawtime);
std::string model_name = "model_iter_id-"+ std::to_string(model_iter_id); std::string model_name = "model_iter_id-" + std::to_string(model_iter_id);
std::string model_path = _config->async_es().model_warehouse() + "/" + model_name; std::string model_path = _config->async_es().model_warehouse() + "/" + model_name;
LOG(INFO) << "[save]model_path: " << model_path; LOG(INFO) << "[save]model_path: " << model_path;
_predictor->SaveOptimizedModel(model_path, LiteModelType::kProtobuf); _predictor->SaveOptimizedModel(model_path, LiteModelType::kProtobuf);
...@@ -51,11 +54,13 @@ bool AsyncESAgent::_save() { ...@@ -51,11 +54,13 @@ bool AsyncESAgent::_save() {
auto async_es = _config->mutable_async_es(); auto async_es = _config->mutable_async_es();
async_es->set_model_iter_id(model_iter_id); async_es->set_model_iter_id(model_iter_id);
success = save_proto_conf(_config_path, *_config); success = save_proto_conf(_config_path, *_config);
if (!success) { if (!success) {
LOG(ERROR) << "[]unable to save config for AsyncESAgent"; LOG(ERROR) << "[]unable to save config for AsyncESAgent";
success = false; success = false;
return success; return success;
} }
int max_to_keep = _config->async_es().max_to_keep(); int max_to_keep = _config->async_es().max_to_keep();
success = _remove_expired_model(max_to_keep); success = _remove_expired_model(max_to_keep);
return success; return success;
...@@ -66,11 +71,14 @@ bool AsyncESAgent::_remove_expired_model(int max_to_keep) { ...@@ -66,11 +71,14 @@ bool AsyncESAgent::_remove_expired_model(int max_to_keep) {
std::string model_path = _config->async_es().model_warehouse(); std::string model_path = _config->async_es().model_warehouse();
std::vector<std::string> model_dirs = list_all_model_dirs(model_path); std::vector<std::string> model_dirs = list_all_model_dirs(model_path);
int model_iter_id = _config->async_es().model_iter_id() + 1; int model_iter_id = _config->async_es().model_iter_id() + 1;
for (const auto& dir: model_dirs) {
for (const auto& dir : model_dirs) {
int dir_model_iter_id = _parse_model_iter_id(dir); int dir_model_iter_id = _parse_model_iter_id(dir);
if (model_iter_id - dir_model_iter_id >= max_to_keep) { if (model_iter_id - dir_model_iter_id >= max_to_keep) {
std::string rm_command = std::string("rm -rf ") + dir; std::string rm_command = std::string("rm -rf ") + dir;
int ret = system(rm_command.c_str()); int ret = system(rm_command.c_str());
if (ret == 0) { if (ret == 0) {
LOG(INFO) << "[DeepES] remove expired Model: " << dir; LOG(INFO) << "[DeepES] remove expired Model: " << dir;
} else { } else {
...@@ -80,30 +88,37 @@ bool AsyncESAgent::_remove_expired_model(int max_to_keep) { ...@@ -80,30 +88,37 @@ bool AsyncESAgent::_remove_expired_model(int max_to_keep) {
} }
} }
} }
return success; return success;
} }
bool AsyncESAgent::_compute_model_diff() { bool AsyncESAgent::_compute_model_diff() {
bool success = true; bool success = true;
for (const auto& kv: _previous_predictors) {
for (const auto& kv : _previous_predictors) {
int model_iter_id = kv.first; int model_iter_id = kv.first;
std::shared_ptr<PaddlePredictor> old_predictor = kv.second; std::shared_ptr<PaddlePredictor> old_predictor = kv.second;
float* diff = new float[_param_size]; float* diff = new float[_param_size];
memset(diff, 0, _param_size * sizeof(float)); memset(diff, 0, _param_size * sizeof(float));
int offset = 0; int offset = 0;
for (const std::string& param_name: _param_names) {
for (const std::string& param_name : _param_names) {
auto des_tensor = old_predictor->GetTensor(param_name); auto des_tensor = old_predictor->GetTensor(param_name);
auto src_tensor = _predictor->GetTensor(param_name); auto src_tensor = _predictor->GetTensor(param_name);
const float* des_data = des_tensor->data<float>(); const float* des_data = des_tensor->data<float>();
const float* src_data = src_tensor->data<float>(); const float* src_data = src_tensor->data<float>();
int64_t tensor_size = ShapeProduction(src_tensor->shape()); int64_t tensor_size = ShapeProduction(src_tensor->shape());
for (int i = 0; i < tensor_size; ++i) { for (int i = 0; i < tensor_size; ++i) {
diff[i + offset] = des_data[i] - src_data[i]; diff[i + offset] = des_data[i] - src_data[i];
} }
offset += tensor_size; offset += tensor_size;
} }
_param_delta[model_iter_id] = diff; _param_delta[model_iter_id] = diff;
} }
return success; return success;
} }
...@@ -111,35 +126,45 @@ bool AsyncESAgent::_load() { ...@@ -111,35 +126,45 @@ bool AsyncESAgent::_load() {
bool success = true; bool success = true;
std::string model_path = _config->async_es().model_warehouse(); std::string model_path = _config->async_es().model_warehouse();
std::vector<std::string> model_dirs = list_all_model_dirs(model_path); std::vector<std::string> model_dirs = list_all_model_dirs(model_path);
if (model_dirs.size() == 0) { if (model_dirs.size() == 0) {
int model_iter_id = _config->async_es().model_iter_id(); int model_iter_id = _config->async_es().model_iter_id();
success = model_iter_id == 0 ? true: false; success = model_iter_id == 0 ? true : false;
if (!success) { if (!success) {
LOG(WARNING) << "[DeepES] current_model_iter_id is nonzero, but no model is \ LOG(WARNING) << "[DeepES] current_model_iter_id is nonzero, but no model is \
found at the dir: " << model_path; found at the dir: " << model_path;
} }
return success; return success;
} }
for(auto &dir: model_dirs) {
for (auto& dir : model_dirs) {
int model_iter_id = _parse_model_iter_id(dir); int model_iter_id = _parse_model_iter_id(dir);
if (model_iter_id == -1) { if (model_iter_id == -1) {
LOG(WARNING) << "[DeepES] fail to parse model_iter_id: " << dir; LOG(WARNING) << "[DeepES] fail to parse model_iter_id: " << dir;
success = false; success = false;
return success; return success;
} }
std::shared_ptr<PaddlePredictor> predictor = _load_previous_model(dir); std::shared_ptr<PaddlePredictor> predictor = _load_previous_model(dir);
if (predictor == nullptr) { if (predictor == nullptr) {
success = false; success = false;
LOG(WARNING) << "[DeepES] fail to load model: " << dir; LOG(WARNING) << "[DeepES] fail to load model: " << dir;
return success; return success;
} }
_previous_predictors[model_iter_id] = predictor; _previous_predictors[model_iter_id] = predictor;
} }
success = _compute_model_diff(); success = _compute_model_diff();
return success; return success;
} }
std::shared_ptr<PaddlePredictor> AsyncESAgent::_load_previous_model(std::string model_dir) { std::shared_ptr<PaddlePredictor> AsyncESAgent::_load_previous_model(std::string model_dir) {
using namespace paddle::lite_api;
// 1. Create CxxConfig // 1. Create CxxConfig
CxxConfig config; CxxConfig config;
config.set_model_file(model_dir + "/model"); config.set_model_file(model_dir + "/model");
...@@ -161,7 +186,7 @@ std::shared_ptr<AsyncESAgent> AsyncESAgent::clone() { ...@@ -161,7 +186,7 @@ std::shared_ptr<AsyncESAgent> AsyncESAgent::clone() {
float* noise = new float [_param_size]; float* noise = new float [_param_size];
new_agent->_predictor = _predictor; new_agent->_predictor = _predictor;
new_agent->_sampling_predictor = CreatePaddlePredictor<CxxConfig>(*_cxx_config); new_agent->_sampling_predictor = paddle::lite_api::CreatePaddlePredictor<CxxConfig>(*_cxx_config);
new_agent->_is_sampling_agent = true; new_agent->_is_sampling_agent = true;
new_agent->_sampling_method = _sampling_method; new_agent->_sampling_method = _sampling_method;
new_agent->_param_names = _param_names; new_agent->_param_names = _param_names;
...@@ -183,9 +208,11 @@ bool AsyncESAgent::update( ...@@ -183,9 +208,11 @@ bool AsyncESAgent::update(
CHECK(success) << "[DeepES] fail to load previous models."; CHECK(success) << "[DeepES] fail to load previous models.";
int current_model_iter_id = _config->async_es().model_iter_id(); int current_model_iter_id = _config->async_es().model_iter_id();
// validate model_iter_id for each sample before the update // validate model_iter_id for each sample before the update
for (int i = 0; i < noisy_info.size(); ++i) { for (int i = 0; i < noisy_info.size(); ++i) {
int model_iter_id = noisy_info[i].model_iter_id(); int model_iter_id = noisy_info[i].model_iter_id();
if (model_iter_id != current_model_iter_id if (model_iter_id != current_model_iter_id
&& _previous_predictors.count(model_iter_id) == 0) { && _previous_predictors.count(model_iter_id) == 0) {
LOG(WARNING) << "[DeepES] The sample with model_dir_id: " << model_iter_id \ LOG(WARNING) << "[DeepES] The sample with model_dir_id: " << model_iter_id \
...@@ -205,6 +232,7 @@ bool AsyncESAgent::update( ...@@ -205,6 +232,7 @@ bool AsyncESAgent::update(
bool success = _sampling_method->resampling(key, _noise, _param_size); bool success = _sampling_method->resampling(key, _noise, _param_size);
CHECK(success) << "[DeepES] resampling error occurs at sample: " << i; CHECK(success) << "[DeepES] resampling error occurs at sample: " << i;
float* delta = _param_delta[model_iter_id]; float* delta = _param_delta[model_iter_id];
// compute neg_gradients // compute neg_gradients
if (model_iter_id == current_model_iter_id) { if (model_iter_id == current_model_iter_id) {
for (int64_t j = 0; j < _param_size; ++j) { for (int64_t j = 0; j < _param_size; ++j) {
...@@ -216,6 +244,7 @@ bool AsyncESAgent::update( ...@@ -216,6 +244,7 @@ bool AsyncESAgent::update(
} }
} }
} }
for (int64_t j = 0; j < _param_size; ++j) { for (int64_t j = 0; j < _param_size; ++j) {
_neg_gradients[j] /= -1.0 * noisy_info.size(); _neg_gradients[j] /= -1.0 * noisy_info.size();
} }
...@@ -223,13 +252,14 @@ bool AsyncESAgent::update( ...@@ -223,13 +252,14 @@ bool AsyncESAgent::update(
//update //update
int64_t counter = 0; int64_t counter = 0;
for (std::string param_name: _param_names) { for (std::string param_name : _param_names) {
std::unique_ptr<Tensor> tensor = _predictor->GetMutableTensor(param_name); std::unique_ptr<Tensor> tensor = _predictor->GetMutableTensor(param_name);
float* tensor_data = tensor->mutable_data<float>(); float* tensor_data = tensor->mutable_data<float>();
int64_t tensor_size = ShapeProduction(tensor->shape()); int64_t tensor_size = ShapeProduction(tensor->shape());
_optimizer->update(tensor_data, _neg_gradients + counter, tensor_size, param_name); _optimizer->update(tensor_data, _neg_gradients + counter, tensor_size, param_name);
counter += tensor_size; counter += tensor_size;
} }
success = _save(); success = _save();
CHECK(success) << "[DeepES] fail to save model."; CHECK(success) << "[DeepES] fail to save model.";
return true; return true;
...@@ -238,15 +268,20 @@ bool AsyncESAgent::update( ...@@ -238,15 +268,20 @@ bool AsyncESAgent::update(
int AsyncESAgent::_parse_model_iter_id(const std::string& model_path) { int AsyncESAgent::_parse_model_iter_id(const std::string& model_path) {
int model_iter_id = -1; int model_iter_id = -1;
int pow = 1; int pow = 1;
for (int i = model_path.size() - 1; i >= 0; --i) { for (int i = model_path.size() - 1; i >= 0; --i) {
if (model_path[i] >= '0' && model_path[i] <= '9') { if (model_path[i] >= '0' && model_path[i] <= '9') {
if (model_iter_id == -1) model_iter_id = 0; if (model_iter_id == -1) {
model_iter_id = 0;
}
} else { } else {
break; break;
} }
model_iter_id += pow * (model_path[i] - '0'); model_iter_id += pow * (model_path[i] - '0');
pow *= 10; pow *= 10;
} }
return model_iter_id; return model_iter_id;
} }
......
...@@ -15,21 +15,28 @@ ...@@ -15,21 +15,28 @@
#include "es_agent.h" #include "es_agent.h"
#include <ctime> #include <ctime>
namespace DeepES { namespace deep_es {
int64_t ShapeProduction(const shape_t& shape) { int64_t ShapeProduction(const paddle::lite_api::shape_t& shape) {
int64_t res = 1; int64_t res = 1;
for (auto i : shape) res *= i;
for (auto i : shape) {
res *= i;
}
return res; return res;
} }
ESAgent::~ESAgent() { ESAgent::~ESAgent() {
delete[] _noise; delete[] _noise;
if (!_is_sampling_agent)
if (!_is_sampling_agent) {
delete[] _neg_gradients; delete[] _neg_gradients;
}
} }
ESAgent::ESAgent(const std::string& model_dir, const std::string& config_path) { ESAgent::ESAgent(const std::string& model_dir, const std::string& config_path) {
using namespace paddle::lite_api;
// 1. Create CxxConfig // 1. Create CxxConfig
_cxx_config = std::make_shared<CxxConfig>(); _cxx_config = std::make_shared<CxxConfig>();
std::string model_path = model_dir + "/model"; std::string model_path = model_dir + "/model";
...@@ -68,11 +75,12 @@ std::shared_ptr<ESAgent> ESAgent::clone() { ...@@ -68,11 +75,12 @@ std::shared_ptr<ESAgent> ESAgent::clone() {
LOG(ERROR) << "[DeepES] only original ESAgent can call `clone` function."; LOG(ERROR) << "[DeepES] only original ESAgent can call `clone` function.";
return nullptr; return nullptr;
} }
std::shared_ptr<ESAgent> new_agent = std::make_shared<ESAgent>(); std::shared_ptr<ESAgent> new_agent = std::make_shared<ESAgent>();
float* noise = new float [_param_size]; float* noise = new float [_param_size];
new_agent->_sampling_predictor = CreatePaddlePredictor<CxxConfig>(*_cxx_config); new_agent->_sampling_predictor = paddle::lite_api::CreatePaddlePredictor<CxxConfig>(*_cxx_config);
new_agent->_predictor = _predictor; new_agent->_predictor = _predictor;
new_agent->_cxx_config = _cxx_config; new_agent->_cxx_config = _cxx_config;
new_agent->_is_sampling_agent = true; new_agent->_is_sampling_agent = true;
...@@ -96,15 +104,18 @@ bool ESAgent::update( ...@@ -96,15 +104,18 @@ bool ESAgent::update(
compute_centered_ranks(noisy_rewards); compute_centered_ranks(noisy_rewards);
memset(_neg_gradients, 0, _param_size * sizeof(float)); memset(_neg_gradients, 0, _param_size * sizeof(float));
for (int i = 0; i < noisy_info.size(); ++i) { for (int i = 0; i < noisy_info.size(); ++i) {
int key = noisy_info[i].key(0); int key = noisy_info[i].key(0);
float reward = noisy_rewards[i]; float reward = noisy_rewards[i];
bool success = _sampling_method->resampling(key, _noise, _param_size); bool success = _sampling_method->resampling(key, _noise, _param_size);
CHECK(success) << "[DeepES] resampling error occurs at sample: " << i; CHECK(success) << "[DeepES] resampling error occurs at sample: " << i;
for (int64_t j = 0; j < _param_size; ++j) { for (int64_t j = 0; j < _param_size; ++j) {
_neg_gradients[j] += _noise[j] * reward; _neg_gradients[j] += _noise[j] * reward;
} }
} }
for (int64_t j = 0; j < _param_size; ++j) { for (int64_t j = 0; j < _param_size; ++j) {
_neg_gradients[j] /= -1.0 * noisy_info.size(); _neg_gradients[j] /= -1.0 * noisy_info.size();
} }
...@@ -112,20 +123,23 @@ bool ESAgent::update( ...@@ -112,20 +123,23 @@ bool ESAgent::update(
//update //update
int64_t counter = 0; int64_t counter = 0;
for (std::string param_name: _param_names) { for (std::string param_name : _param_names) {
std::unique_ptr<Tensor> tensor = _predictor->GetMutableTensor(param_name); std::unique_ptr<Tensor> tensor = _predictor->GetMutableTensor(param_name);
float* tensor_data = tensor->mutable_data<float>(); float* tensor_data = tensor->mutable_data<float>();
int64_t tensor_size = ShapeProduction(tensor->shape()); int64_t tensor_size = ShapeProduction(tensor->shape());
_optimizer->update(tensor_data, _neg_gradients + counter, tensor_size, param_name); _optimizer->update(tensor_data, _neg_gradients + counter, tensor_size, param_name);
counter += tensor_size; counter += tensor_size;
} }
return true; return true;
} }
bool ESAgent::add_noise(SamplingInfo& sampling_info) { bool ESAgent::add_noise(SamplingInfo& sampling_info) {
bool success = true; bool success = true;
if (!_is_sampling_agent) { if (!_is_sampling_agent) {
LOG(ERROR) << "[DeepES] Original ESAgent cannot call add_noise function, please use cloned ESAgent."; LOG(ERROR) <<
"[DeepES] Original ESAgent cannot call add_noise function, please use cloned ESAgent.";
success = false; success = false;
return success; return success;
} }
...@@ -138,13 +152,15 @@ bool ESAgent::add_noise(SamplingInfo& sampling_info) { ...@@ -138,13 +152,15 @@ bool ESAgent::add_noise(SamplingInfo& sampling_info) {
sampling_info.set_model_iter_id(model_iter_id); sampling_info.set_model_iter_id(model_iter_id);
int64_t counter = 0; int64_t counter = 0;
for (std::string param_name: _param_names) { for (std::string param_name : _param_names) {
std::unique_ptr<Tensor> sample_tensor = _sampling_predictor->GetMutableTensor(param_name); std::unique_ptr<Tensor> sample_tensor = _sampling_predictor->GetMutableTensor(param_name);
std::unique_ptr<const Tensor> tensor = _predictor->GetTensor(param_name); std::unique_ptr<const Tensor> tensor = _predictor->GetTensor(param_name);
int64_t tensor_size = ShapeProduction(tensor->shape()); int64_t tensor_size = ShapeProduction(tensor->shape());
for (int64_t j = 0; j < tensor_size; ++j) { for (int64_t j = 0; j < tensor_size; ++j) {
sample_tensor->mutable_data<float>()[j] = tensor->data<float>()[j] + _noise[counter + j]; sample_tensor->mutable_data<float>()[j] = tensor->data<float>()[j] + _noise[counter + j];
} }
counter += tensor_size; counter += tensor_size;
} }
...@@ -157,10 +173,12 @@ std::shared_ptr<PaddlePredictor> ESAgent::get_predictor() { ...@@ -157,10 +173,12 @@ std::shared_ptr<PaddlePredictor> ESAgent::get_predictor() {
int64_t ESAgent::_calculate_param_size() { int64_t ESAgent::_calculate_param_size() {
int64_t param_size = 0; int64_t param_size = 0;
for (std::string param_name: _param_names) {
for (std::string param_name : _param_names) {
std::unique_ptr<const Tensor> tensor = _predictor->GetTensor(param_name); std::unique_ptr<const Tensor> tensor = _predictor->GetTensor(param_name);
param_size += ShapeProduction(tensor->shape()); param_size += ShapeProduction(tensor->shape());
} }
return param_size; return param_size;
} }
......
...@@ -36,7 +36,7 @@ else ...@@ -36,7 +36,7 @@ else
fi fi
#----------------protobuf-------------# #----------------protobuf-------------#
cp ./core/src/proto/deepes.proto ./ cp ./core/proto/deepes.proto ./
protoc deepes.proto --cpp_out ./ protoc deepes.proto --cpp_out ./
mv deepes.pb.h core/include mv deepes.pb.h core/include
mv deepes.pb.cc core/src mv deepes.pb.cc core/src
...@@ -49,6 +49,7 @@ mkdir build ...@@ -49,6 +49,7 @@ mkdir build
cd build cd build
cmake ../ ${FLAGS} cmake ../ ${FLAGS}
make -j10 make -j10
cd -
#-----------------run----------------# #-----------------run----------------#
./parallel_main ./build/parallel_main
...@@ -12,7 +12,7 @@ echo "Cannot find the torch library: ../libtorch" ...@@ -12,7 +12,7 @@ echo "Cannot find the torch library: ../libtorch"
fi fi
#----------------protobuf-------------# #----------------protobuf-------------#
cp ./core/src/proto/deepes.proto ./ cp ./core/proto/deepes.proto ./
protoc deepes.proto --cpp_out ./ protoc deepes.proto --cpp_out ./
mv deepes.pb.h core/include mv deepes.pb.h core/include
mv deepes.pb.cc core/src mv deepes.pb.cc core/src
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "optimizer_factory.h" #include "optimizer_factory.h"
#include <memory> #include <memory>
namespace DeepES { namespace deep_es {
TEST(SGDOptimizersTest, Method_update) { TEST(SGDOptimizersTest, Method_update) {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "cached_gaussian_sampling.h" #include "cached_gaussian_sampling.h"
#include <memory> #include <memory>
namespace DeepES { namespace deep_es {
class SamplingTest : public ::testing::Test { class SamplingTest : public ::testing::Test {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <random> #include <random>
#include <math.h> #include <math.h>
namespace DeepES { namespace deep_es {
// The fixture for testing class Foo. // The fixture for testing class Foo.
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <vector> #include <vector>
#include "utils.h" #include "utils.h"
namespace DeepES { namespace deep_es {
// Tests that the Utils::compute_centered_rank() method. // Tests that the Utils::compute_centered_rank() method.
TEST(UtilsTest, Method_compute_centered_ranks) { TEST(UtilsTest, Method_compute_centered_ranks) {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "utils.h" #include "utils.h"
#include "deepes.pb.h" #include "deepes.pb.h"
namespace DeepES{ namespace deep_es{
/** /**
* @brief DeepES agent for Torch. * @brief DeepES agent for Torch.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册