https://mooseframework.inl.gov
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 
13 namespace StochasticTools
14 {
15 
16 namespace
17 {
18 
19 void
20 checkInputCompatibility(const torch::Tensor & input, const torch::Tensor & reference)
21 {
22  if (input.dim() != 2)
23  mooseError("Standardizer input must be a rank-2 tensor.");
24  if (reference.dim() != 1)
25  mooseError("Standardizer moments must be stored as feature vectors.");
26  if (input.size(1) != reference.size(0))
27  mooseError("Standardizer input dimension mismatch.");
28 }
29 
30 torch::Tensor
31 toStandardizerOptions(const torch::Tensor & tensor, const torch::TensorOptions & options)
32 {
33  auto result = tensor.to(options.device());
34  if (result.scalar_type() != at::kDouble)
35  result = result.to(at::kDouble);
36  return result;
37 }
38 
39 torch::Tensor
40 asFeatureVector(const torch::Tensor & feature_vector, const torch::Tensor & input)
41 {
42  return toStandardizerOptions(feature_vector, input.options().dtype(at::kDouble));
43 }
44 
45 } // namespace
46 
47 void
48 Standardizer::set(const Real & n)
49 {
50  _mean = torch::zeros({long(n)}, at::kDouble);
51  _stdev = torch::ones({long(n)}, at::kDouble);
52 }
53 
54 void
55 Standardizer::set(const Real & mean, const Real & stdev)
56 {
57  _mean = torch::full({1}, mean, at::kDouble);
58  _stdev = torch::full({1}, stdev, at::kDouble);
59 }
60 
61 void
62 Standardizer::set(const Real & mean, const Real & stdev, const Real & n)
63 {
64  auto options = torch::TensorOptions().dtype(at::kDouble);
65  _mean = torch::full({long(n)}, mean, options);
66  _stdev = torch::full({long(n)}, stdev, options);
67 }
68 
69 void
70 Standardizer::set(const std::vector<Real> & mean, const std::vector<Real> & stdev)
71 {
72  mooseAssert(mean.size() == stdev.size(),
73  "Provided mean and standard deviation vectors are of differing size.");
74  _mean = LibtorchUtils::vectorToTensorCopy(mean, {long(mean.size())});
75  _stdev = LibtorchUtils::vectorToTensorCopy(stdev, {long(stdev.size())});
76 }
77 
78 void
79 Standardizer::computeSet(const torch::Tensor & input)
80 {
81  if (input.dim() != 2)
82  mooseError("Standardizer input must be a rank-2 tensor.");
83  // Compute mean and standard deviation
84  _mean = torch::mean(input, 0, false);
85  _stdev = torch::std(input, 0, 0, false);
86 }
87 
88 void
89 Standardizer::getStandardized(torch::Tensor & input) const
90 {
91  checkInputCompatibility(input, _mean);
92  input.sub_(asFeatureVector(_mean, input)).div_(asFeatureVector(_stdev, input));
93 }
94 
95 void
96 Standardizer::getDestandardized(torch::Tensor & input) const
97 {
98  checkInputCompatibility(input, _mean);
99  input.mul_(asFeatureVector(_stdev, input)).add_(asFeatureVector(_mean, input));
100 }
101 
102 void
103 Standardizer::getDescaled(torch::Tensor & input) const
104 {
105  checkInputCompatibility(input, _stdev);
106  input.mul_(asFeatureVector(_stdev, input));
107 }
108 
109 void
110 Standardizer::getScaled(torch::Tensor & input) const
111 {
112  checkInputCompatibility(input, _stdev);
113  input.div_(asFeatureVector(_stdev, input));
114 }
115 
117 void
118 Standardizer::storeHelper(std::ostream & stream, void * context) const
119 {
120  const auto mean = LibtorchUtils::toCPUContiguous(_mean);
121  const auto stdev = LibtorchUtils::toCPUContiguous(_stdev);
122  auto mean_accessor = mean.accessor<Real, 1>();
123  auto stdev_accessor = stdev.accessor<Real, 1>();
124  unsigned int n = mean.size(0);
125  dataStore(stream, n, context);
126  for (unsigned int ii = 0; ii < n; ++ii)
127  dataStore(stream, mean_accessor[ii], context);
128  for (unsigned int ii = 0; ii < n; ++ii)
129  dataStore(stream, stdev_accessor[ii], context);
130 }
131 
132 } // StochasticTools namespace
133 
134 template <>
135 void
136 dataStore(std::ostream & stream, StochasticTools::Standardizer & standardizer, void * context)
137 {
138  standardizer.storeHelper(stream, context);
139 }
140 
141 template <>
142 void
143 dataLoad(std::istream & stream, StochasticTools::Standardizer & standardizer, void * context)
144 {
145  unsigned int n;
146  dataLoad(stream, n, context);
147  std::vector<Real> mean(n);
148  std::vector<Real> stdev(n);
149  for (unsigned int ii = 0; ii < n; ++ii)
150  dataLoad(stream, mean[ii], context);
151  for (unsigned int ii = 0; ii < n; ++ii)
152  dataLoad(stream, stdev[ii], context);
153  standardizer.set(mean, stdev);
154 }
155 
156 #endif
void storeHelper(std::ostream &stream, void *context) const
Helper for dataStore.
Definition: Standardizer.C:118
void dataLoad(std::istream &stream, StochasticTools::Standardizer &standardizer, void *context)
Definition: Standardizer.C:143
void mooseError(Args &&... args)
torch::Tensor vectorToTensorCopy(const std::vector< DataType > &vector, c10::IntArrayRef sizes)
void getScaled(torch::Tensor &input) const
Scales the assumed de-scaled input.
Definition: Standardizer.C:110
torch::Tensor toCPUContiguous(const torch::Tensor &tensor)
Enum for batch type in stochastic tools MultiApp.
void getDescaled(torch::Tensor &input) const
De-scales the assumed scaled input.
Definition: Standardizer.C:103
void getDestandardized(torch::Tensor &input) const
De-standardizes (de-centered and de-scaled) the assumed standardized input.
Definition: Standardizer.C:96
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void set(const Real &n)
Methods for setting mean and standard deviation directly Sets mean=0, std=1 for n variables...
Definition: Standardizer.C:48
Class for standardizing data (centering and scaling)
Definition: Standardizer.h:24
void dataStore(std::ostream &stream, StochasticTools::Standardizer &standardizer, void *context)
Definition: Standardizer.C:136
void getStandardized(torch::Tensor &input) const
Returns the standardized (centered and scaled) of the provided input.
Definition: Standardizer.C:89
void computeSet(const torch::Tensor &input)
Methods for computing and setting mean and standard deviation.
Definition: Standardizer.C:79