https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Standardizer.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9#ifdef MOOSE_LIBTORCH_ENABLED
10
11#include "Standardizer.h"
12#include "DataIO.h"
13
14namespace StochasticTools
15{
16
17namespace
18{
19
20void
21checkInputCompatibility(const torch::Tensor & input, const torch::Tensor & reference)
22{
23 if (input.dim() != 2)
24 mooseError("Standardizer input must be a rank-2 tensor.");
25 if (reference.dim() != 1)
26 mooseError("Standardizer moments must be stored as feature vectors.");
27 if (input.size(1) != reference.size(0))
28 mooseError("Standardizer input dimension mismatch.");
29}
30
31torch::Tensor
32toStandardizerOptions(const torch::Tensor & tensor, const torch::TensorOptions & options)
33{
34 auto result = tensor.to(options.device());
35 if (result.scalar_type() != at::kDouble)
36 result = result.to(at::kDouble);
37 return result;
38}
39
40torch::Tensor
41asFeatureVector(const torch::Tensor & feature_vector, const torch::Tensor & input)
42{
43 return toStandardizerOptions(feature_vector, input.options().dtype(at::kDouble));
44}
45
46} // namespace
47
48void
49Standardizer::set(const Real & n)
50{
51 _mean = torch::zeros({long(n)}, at::kDouble);
52 _stdev = torch::ones({long(n)}, at::kDouble);
53}
54
55void
56Standardizer::set(const Real & mean, const Real & stdev)
57{
58 _mean = torch::full({1}, mean, at::kDouble);
59 _stdev = torch::full({1}, stdev, at::kDouble);
60}
61
62void
63Standardizer::set(const Real & mean, const Real & stdev, const Real & n)
64{
65 auto options = torch::TensorOptions().dtype(at::kDouble);
66 _mean = torch::full({long(n)}, mean, options);
67 _stdev = torch::full({long(n)}, stdev, options);
68}
69
70void
71Standardizer::set(const std::vector<Real> & mean, const std::vector<Real> & stdev)
72{
73 mooseAssert(mean.size() == stdev.size(),
74 "Provided mean and standard deviation vectors are of differing size.");
75 _mean = LibtorchUtils::vectorToTensorCopy(mean, {long(mean.size())});
76 _stdev = LibtorchUtils::vectorToTensorCopy(stdev, {long(stdev.size())});
77}
78
79void
80Standardizer::computeSet(const torch::Tensor & input)
81{
82 if (input.dim() != 2)
83 mooseError("Standardizer input must be a rank-2 tensor.");
84 // Compute mean and standard deviation
85 _mean = torch::mean(input, 0, false);
86 _stdev = torch::std(input, 0, 0, false);
87}
88
89void
90Standardizer::getStandardized(torch::Tensor & input) const
91{
92 checkInputCompatibility(input, _mean);
93 input.sub_(asFeatureVector(_mean, input)).div_(asFeatureVector(_stdev, input));
94}
95
96void
97Standardizer::getDestandardized(torch::Tensor & input) const
98{
99 checkInputCompatibility(input, _mean);
100 input.mul_(asFeatureVector(_stdev, input)).add_(asFeatureVector(_mean, input));
101}
102
103void
104Standardizer::getDescaled(torch::Tensor & input) const
105{
106 checkInputCompatibility(input, _stdev);
107 input.mul_(asFeatureVector(_stdev, input));
108}
109
110void
111Standardizer::getScaled(torch::Tensor & input) const
112{
113 checkInputCompatibility(input, _stdev);
114 input.div_(asFeatureVector(_stdev, input));
115}
116
118void
119Standardizer::dataStore(std::ostream & stream, void * context) const
120{
121 mooseAssert(_mean.defined() == _stdev.defined(),
122 "Standardizer has inconsistent restart state: one of _mean and _stdev is "
123 "defined while the other is undefined.");
124 const bool defined = _mean.defined();
125 ::dataStore(stream, defined, nullptr);
126 if (!defined)
127 return;
128
129 const auto mean = LibtorchUtils::toCPUContiguous(_mean);
130 const auto stdev = LibtorchUtils::toCPUContiguous(_stdev);
131 auto mean_accessor = mean.accessor<Real, 1>();
132 auto stdev_accessor = stdev.accessor<Real, 1>();
133 unsigned int n = mean.size(0);
134 ::dataStore(stream, n, context);
135 for (unsigned int ii = 0; ii < n; ++ii)
136 ::dataStore(stream, mean_accessor[ii], context);
137 for (unsigned int ii = 0; ii < n; ++ii)
138 ::dataStore(stream, stdev_accessor[ii], context);
139}
140
141} // StochasticTools namespace
142
143template <>
144void
145dataStore(std::ostream & stream, StochasticTools::Standardizer & standardizer, void * context)
146{
147 standardizer.dataStore(stream, context);
148}
149
150template <>
151void
152dataLoad(std::istream & stream, StochasticTools::Standardizer & standardizer, void * context)
153{
154 bool defined = false;
155 dataLoad(stream, defined, nullptr);
156 if (!defined)
157 return;
158
159 unsigned int n;
160 dataLoad(stream, n, context);
161 std::vector<Real> mean(n);
162 std::vector<Real> stdev(n);
163 for (unsigned int ii = 0; ii < n; ++ii)
164 dataLoad(stream, mean[ii], context);
165 for (unsigned int ii = 0; ii < n; ++ii)
166 dataLoad(stream, stdev[ii], context);
167 standardizer.set(mean, stdev);
168}
169
170#endif
void mooseError(Args &&... args)
void dataLoad(std::istream &stream, StochasticTools::Standardizer &standardizer, void *context)
void dataStore(std::ostream &stream, StochasticTools::Standardizer &standardizer, void *context)
Class for standardizing data (centering and scaling)
void set(const Real &n)
Methods for setting mean and standard deviation directly Sets mean=0, std=1 for n variables.
void getDescaled(torch::Tensor &input) const
De-scales the assumed scaled input.
void getDestandardized(torch::Tensor &input) const
De-standardizes (de-centered and de-scaled) the assumed standardized input.
void getStandardized(torch::Tensor &input) const
Returns the standardized (centered and scaled) of the provided input.
void getScaled(torch::Tensor &input) const
Scales the assumed de-scaled input.
void computeSet(const torch::Tensor &input)
Methods for computing and setting mean and standard deviation.
void dataStore(std::ostream &stream, void *context) const
Helper for dataStore.
torch::Tensor toCPUContiguous(const torch::Tensor &tensor)
torch::Tensor vectorToTensorCopy(const std::vector< DataType > &vector, c10::IntArrayRef sizes)
Enum for batch type in stochastic tools MultiApp.