// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include #include #include #include #include #include "gflags/gflags.h" #include "paddle/fluid/framework/generator.h" #include "paddle/fluid/operators/truncated_gaussian_random_op.h" namespace paddle { namespace distributed { class Initializer { public: Initializer() {} explicit Initializer(const std::vector &attrs) {} virtual float GetValue() = 0; virtual void GetValue(std::vector *values, int numel) { for (int x = 0; x < numel; ++x) { values->push_back(GetValue()); } } virtual void GetValue(float *value, int numel) { for (int x = 0; x < numel; ++x) { value[x] = GetValue(); } } virtual ~Initializer() {} protected: std::string name_; unsigned int seed_; }; class UniformInitializer : public Initializer { public: explicit UniformInitializer(const std::vector &attrs) { name_ = attrs[0]; seed_ = static_cast(std::stoi(attrs[1])); min_ = std::stof(attrs[2]); max_ = std::stof(attrs[3]); dist_ = std::uniform_real_distribution(min_, max_); random_engine_ = framework::GetCPURandomEngine(seed_); } float GetValue() override { return dist_(*random_engine_); } void GetValue(float *value, int numel) { for (int x = 0; x < numel; ++x) { value[x] = dist_(*random_engine_); } } private: float min_; float max_; std::shared_ptr random_engine_; std::uniform_real_distribution dist_; }; class GaussianInitializer : public Initializer { public: explicit GaussianInitializer(const std::vector &attrs) { name_ = attrs[0]; seed_ = static_cast(std::stoi(attrs[1])); mean_ = std::stof(attrs[2]); std_ = std::stof(attrs[3]); random_engine_ = framework::GetCPURandomEngine(seed_); dist_ = std::normal_distribution(mean_, std_); } float GetValue() override { return dist_(*random_engine_); } void GetValue(float *value, int numel) { for (int x = 0; x < numel; ++x) { value[x] = dist_(*random_engine_); } } private: float std_; float mean_; std::shared_ptr random_engine_; std::normal_distribution dist_; }; class TruncatedGaussianInitializer : public Initializer { public: explicit TruncatedGaussianInitializer(const std::vector &attrs) { name_ = attrs[0]; seed_ = static_cast(std::stoi(attrs[1])); mean_ = std::stof(attrs[2]); std_ = std::stof(attrs[3]); auto normal_cdf = [](float x) { return (1.0 + std::erf(x / std::sqrt(2.0))) / 2.0; }; float a_normal_cdf = normal_cdf((-2.0 - mean_) / std_); float b_normal_cdf = normal_cdf((2.0 - mean_) / std_); std::uniform_real_distribution dist_(2.0 * a_normal_cdf - 1.0, 2.0 * b_normal_cdf - 1.0); random_engine_ = framework::GetCPURandomEngine(seed_); } float GetValue() override { paddle::operators::TruncatedNormal truncated_normal(mean_, std_); float value = truncated_normal(dist_(*random_engine_)); return value; } void GetValue(float *value, int numel) { paddle::operators::TruncatedNormal truncated_normal(mean_, std_); for (int x = 0; x < numel; ++x) { value[x] = truncated_normal(dist_(*random_engine_)); } } private: float std_; float mean_; std::shared_ptr random_engine_; std::uniform_real_distribution dist_; }; class FillConstantInitializer : public Initializer { public: explicit FillConstantInitializer(const std::vector &attrs) { name_ = attrs[0]; value_ = std::stof(attrs[1]); } float GetValue() override { return value_; } void GetValue(float *value, int numel) { std::fill_n(value, numel, value_); } private: float value_; }; } // namespace distributed } // namespace paddle