23 #include "mxx/bcast.hpp"
24 #include "CVs/CVManager.h"
25 #include "Drivers/DriverException.h"
26 #include "Validator/ObjectRequirement.h"
28 using namespace Eigen;
34 ANN::ANN(
const MPI_Comm& world,
36 const VectorXi& topol,
40 const std::vector<double>& lowerb,
41 const std::vector<double>& upperb,
42 const std::vector<double>& lowerk,
43 const std::vector<double>& upperk,
46 unsigned int nsweep) :
47 Method(1, world, comm), topol_(topol), sweep_(0), nsweep_(nsweep),
48 citers_(0), net_(topol), pweight_(1.), weight_(weight), temp_(temperature),
49 kbt_(0), fgrid_(fgrid), hgrid_(hgrid), ugrid_(ugrid), hist_(), bias_(),
50 lowerb_(lowerb), upperb_(upperb), lowerk_(lowerk), upperk_(upperk),
51 outfile_(
"ann.out"), preloaded_(false), overwrite_(true)
60 auto coord = it.coordinates();
61 for(
size_t j = 0; j < coord.size(); ++j)
62 hist_(i, j) = coord[j];
73 bias_.array() =
net_.get_activation().col(0).array();
82 VectorXd vec = VectorXd::Zero(ndim);
88 bias_.array() =
net_.get_activation().col(0).array();
96 auto ncvs = cvs.size();
98 for(
int i = 0; i <
hist_.rows(); ++i)
100 auto cval =
hist_.row(i);
101 for(
size_t j = 0; j < ncvs; ++j)
105 else if(cval[j] > upperb_[j])
106 rbias_(i,j) = upperk_[j]*(cval[j] - upperb_[j])*(cval[j] - upperb_[j]);
132 std::vector<double> val(n);
133 bool inbounds =
true;
134 for(
size_t i = 0; i < n; ++i)
136 val[i] = cvs[i]->GetValue();
137 vec[i] = cvs[i]->GetValue();
143 VectorXd derivatives = VectorXd::Zero(n);
152 net_.forward_pass(vec);
153 derivatives =
net_.get_gradient(0);
159 std::cerr <<
"ANN (" << snapshot->
GetIteration() <<
"): out of bounds ( ";
161 std::cerr << v <<
" ";
162 std::cerr <<
")" << std::endl;
167 for(
size_t i = 0; i < n; ++i)
169 auto cval = cvs[i]->GetValue();
172 else if(cval > upperb_[i])
173 derivatives[i] += upperk_[i]*cvs[i]->GetDifference(upperb_[i]);
180 for(
size_t i = 0; i < cvs.size(); ++i)
182 auto& grad = cvs[i]->GetGradient();
183 auto& boxgrad = cvs[i]->GetBoxGradient();
187 for (
size_t j = 0; j < forces.size(); ++j)
188 forces[j] -= derivatives[i]*grad[j];
190 virial += derivatives[i]*boxgrad;
213 uhist.array() =
pweight_*uhist.array() + hist.cast<
double>()*(1./kbt_*bias_).array().exp()*weight_;
217 bias_.array() = kbt_*uhist.array().log();
218 bias_.array() -= bias_.minCoeff();
228 vector_t wb =
net_.get_wb();
229 mxx::bcast(wb.data(), wb.size(), 0,
world_);
234 bias_.array() =
net_.get_activation().col(0).array();
235 bias_.array() -= bias_.minCoeff();
240 MatrixXd forces =
net_.get_gradient(i);
241 fgrid_->
data()[i] = forces.row(i).transpose();
247 net_.write(
"netstate.dat");
250 std::ofstream file(filename);
253 matrix_t y =
net_.get_activation();
254 for(
int i = 0; i < y.rows(); ++i)
256 for(
int j = 0; j <
hist_.cols(); ++j)
257 file << std::fixed <<
hist_(i,j) <<
" ";
258 file << std::fixed <<
ugrid_->
data()[i] <<
" " << std::fixed << y(i) <<
"\n";
264 void ANN::ReadBias(
const std::string& state_file,
const std::string& bias_file)
266 std::ifstream file(bias_file, std::ios::in);
269 throw BuildException({
"ANN::ReadBias() could not read file "+bias_file});
272 net_ = nnet::neural_net(state_file.c_str());
274 for(
int i = 0; i <
hist_.rows(); ++i)
277 for(
int j = 0; j <
hist_.cols(); ++j)
288 const Json::Value& json,
289 const MPI_Comm& world,
290 const MPI_Comm& comm,
291 const std::string& path)
295 CharReaderBuilder rbuilder;
296 CharReader* reader = rbuilder.newCharReader();
298 reader->parse(JsonSchema::ANNMethod.c_str(),
299 JsonSchema::ANNMethod.c_str() + JsonSchema::ANNMethod.size(),
301 validator.
Parse(schema, path);
314 auto nlayers = json[
"topology"].size() + 2;
315 VectorXi topol(nlayers);
316 topol[0] = fgrid->GetDimension();
317 topol[nlayers-1] = 1;
318 for(
int i = 0; i < static_cast<int>(json[
"topology"].size()); ++i)
319 topol[i+1] = json[
"topology"][i].asInt();
321 auto weight = json.get(
"weight", 1.).asDouble();
322 auto temp = json[
"temperature"].asDouble();
323 auto nsweep = json[
"nsweep"].asUInt();
326 std::vector<double> lowerb, upperb, lowerk, upperk;
327 for(
int i = 0; i < static_cast<int>(json[
"lower_bound_restraints"].size()); ++i)
329 lowerk.push_back(json[
"lower_bound_restraints"][i].asDouble());
330 upperk.push_back(json[
"upper_bound_restraints"][i].asDouble());
331 lowerb.push_back(json[
"lower_bounds"][i].asDouble());
332 upperb.push_back(json[
"upper_bounds"][i].asDouble());
335 auto* m =
new ANN(world, comm, topol, fgrid, hgrid, ugrid, lowerb, upperb, lowerk, upperk, temp, weight, nsweep);
338 m->SetPrevWeight(json.get(
"prev_weight", 1).asDouble());
339 m->SetOutput(json.get(
"output_file",
"ann.out").asString());
340 m->SetOutputOverwrite( json.get(
"overwrite_output",
true).asBool());
341 m->SetConvergeIters(json.get(
"converge_iters", 0).asUInt());
342 m->SetMaxIters(json.get(
"max_iters", 1000).asUInt());
343 m->SetMinLoss(json.get(
"min_loss", 0).asDouble());
345 if(json.isMember(
"net_state") && json.isMember(
"load_bias"))
346 m->ReadBias(json[
"net_state"].asString(), json[
"load_bias"].asString());
Requirements on an object.
virtual void Parse(Value json, const std::string &path) override
Parse JSON value to generate Requirement(s).
virtual void Validate(const Value &json, const std::string &path) override
Validate JSON value.
std::vector< std::string > GetErrors()
Get list of error messages.
bool HasErrors()
Check if errors have occured.
Artificial Neural Network Method.
std::vector< double > lowerb_
void PostSimulation(Snapshot *snapshot, const class CVManager &cvmanager) override
Method call post simulation.
Grid< unsigned int > * hgrid_
Histogram grid.
std::vector< double > lowerk_
static ANN * Build(const Json::Value &json, const MPI_Comm &world, const MPI_Comm &comm, const std::string &path)
Build a derived method from JSON node.
bool preloaded_
Is the network preloaded?
void TrainNetwork()
Trains the neural network.
void PreSimulation(Snapshot *snapshot, const class CVManager &cvmanager) override
Method call prior to simulation initiation.
Grid< Eigen::VectorXd > * fgrid_
Force grid.
nnet::neural_net net_
Neural network.
ANN(const MPI_Comm &world, const MPI_Comm &comm, const Eigen::VectorXi &topol, Grid< Eigen::VectorXd > *fgrid, Grid< unsigned int > *hgrid, Grid< double > *ugrid, const std::vector< double > &lowerb, const std::vector< double > &upperb, const std::vector< double > &lowerk, const std::vector< double > &upperk, double temperature, double weight, unsigned int nsweep)
Constructor.
void ReadBias(const std::string &, const std::string &)
Load network state and bias from file.
unsigned int citers_
Number of iterations after which we turn on full weight.
void WriteBias()
Writes out the bias to file.
void PostIntegration(Snapshot *snapshot, const class CVManager &cvmanager) override
Method call post integration.
std::string outfile_
Output filename.
Grid< double > * ugrid_
Unbiased histogram grid.
bool overwrite_
Overwrite outputs?
Exception to be thrown when building the Driver fails.
Collective variable manager.
CVList GetCVs(const std::vector< unsigned int > &mask=std::vector< unsigned int >()) const
Get CV iterator.
static bool IsMasterRank(const MPI_Comm &comm)
Check if current processor is master.
const std::vector< double > GetLower() const
Return the lower edges of the Grid.
size_t size() const
Get the size of the internal storage vector.
T * data()
Get pointer to the internal data storage vector.
size_t GetDimension() const
Get the dimension.
const T & at(const std::vector< int > &indices) const
Access Grid element read-only.
const std::vector< double > GetUpper() const
Return the upper edges of the Grid.
void syncGrid()
Sync the grid.
static Grid< T > * BuildGrid(const Json::Value &json)
Set up the grid.
iterator begin()
Return iterator at first grid point.
iterator end()
Return iterator after last valid grid point.
Interface for Method implementations.
mxx::comm comm_
Local MPI communicator.
std::vector< unsigned int > cvmask_
Mask which identifies which CVs to act on.
mxx::comm world_
Global MPI communicator.
Class containing a snapshot of the current simulation in time.
double GetKb() const
Get system Kb.
const Matrix3 & GetVirial() const
Get box virial.
const std::vector< Vector3 > & GetForces() const
Access the per-particle forces.
size_t GetIteration() const
Get the current iteration.
Map for histogram and coefficients.