From 0b4b4744e8fad1cbf97aab7e8c15b001be1f87fc Mon Sep 17 00:00:00 2001 From: fractalmanifold Date: Mon, 3 Jun 2024 14:01:14 +0200 Subject: [PATCH 1/7] initial commit in new repository --- CMakeLists_files.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 6f5ebfbd5f7..85a790dfb2c 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -62,6 +62,7 @@ list (APPEND MAIN_SOURCE_FILES opm/material/fluidsystems/blackoilpvt/SolventPvt.cpp opm/material/fluidsystems/blackoilpvt/WetGasPvt.cpp opm/material/fluidsystems/blackoilpvt/WetHumidGasPvt.cpp + opm/ml/keras_model.cpp ) if(ENABLE_ECL_INPUT) list(APPEND MAIN_SOURCE_FILES @@ -474,6 +475,7 @@ list (APPEND TEST_SOURCE_FILES tests/material/test_spline.cpp tests/material/test_tabulation.cpp tests/test_Visitor.cpp + opm/ml/keras_model_test.cpp ) # tests that need to be linked to dune-common @@ -1052,6 +1054,7 @@ list( APPEND PUBLIC_HEADER_FILES opm/material/thermal/SomertonThermalConductionLaw.hpp opm/material/thermal/EclSpecrockLaw.hpp opm/material/thermal/NullSolidEnergyLaw.hpp + opm/ml/keras_model.hpp ) if(ENABLE_ECL_INPUT) From ded92512e11a5cd1d7581143ed73177062ead33a Mon Sep 17 00:00:00 2001 From: fractalmanifold Date: Mon, 3 Jun 2024 14:19:39 +0200 Subject: [PATCH 2/7] Add missing files --- opm/ml/keras_model.cpp | 769 ++++++++++++++++++ opm/ml/keras_model.hpp | 530 ++++++++++++ opm/ml/keras_model_test.cpp | 227 ++++++ opm/ml/ml_tools/generateunittests.py | 294 +++++++ opm/ml/ml_tools/include/test_conv_2x2.h | 43 + opm/ml/ml_tools/include/test_conv_3x3.h | 44 + opm/ml/ml_tools/include/test_conv_3x3x3.h | 47 ++ .../include/test_conv_hard_sigmoid_2x2.h | 43 + .../ml_tools/include/test_conv_sigmoid_2x2.h | 43 + .../ml_tools/include/test_conv_softplus_2x2.h | 43 + opm/ml/ml_tools/include/test_dense_10x1.h | 44 + opm/ml/ml_tools/include/test_dense_10x10.h | 44 + opm/ml/ml_tools/include/test_dense_10x10x10.h | 45 + opm/ml/ml_tools/include/test_dense_1x1.h | 43 + opm/ml/ml_tools/include/test_dense_2x2.h | 43 + opm/ml/ml_tools/include/test_dense_relu_10.h | 45 + opm/ml/ml_tools/include/test_dense_tanh_10.h | 45 + opm/ml/ml_tools/include/test_elu_10.h | 44 + opm/ml/ml_tools/include/test_maxpool2d_1x1.h | 59 ++ opm/ml/ml_tools/include/test_relu_10.h | 45 + .../ml_tools/include/test_scalingdense_1x1.h | 44 + opm/ml/ml_tools/kerasify.py | 323 ++++++++ opm/ml/ml_tools/make_model_BCkrn.py | 104 +++ opm/ml/ml_tools/make_model_BCkrw.py | 103 +++ opm/ml/ml_tools/make_model_VGkrn.py | 90 ++ opm/ml/ml_tools/make_model_VGkrw.py | 87 ++ opm/ml/ml_tools/model_with_scaler_layers.opm | Bin 0 -> 24 bytes opm/ml/ml_tools/models/test_conv_2x2.model | Bin 0 -> 84 bytes opm/ml/ml_tools/models/test_conv_3x3.model | Bin 0 -> 104 bytes opm/ml/ml_tools/models/test_conv_3x3x3.model | Bin 0 -> 408 bytes .../models/test_conv_hard_sigmoid_2x2.model | Bin 0 -> 84 bytes .../models/test_conv_sigmoid_2x2.model | Bin 0 -> 84 bytes .../models/test_conv_softplus_2x2.model | Bin 0 -> 84 bytes opm/ml/ml_tools/models/test_dense_10x1.model | Bin 0 -> 68 bytes opm/ml/ml_tools/models/test_dense_10x10.model | Bin 0 -> 528 bytes .../ml_tools/models/test_dense_10x10x10.model | Bin 0 -> 924 bytes opm/ml/ml_tools/models/test_dense_1x1.model | Bin 0 -> 32 bytes opm/ml/ml_tools/models/test_dense_2x2.model | Bin 0 -> 80 bytes .../ml_tools/models/test_dense_relu_10.model | Bin 0 -> 1384 bytes .../ml_tools/models/test_dense_tanh_10.model | Bin 0 -> 1384 bytes opm/ml/ml_tools/models/test_elu_10.model | Bin 0 -> 536 bytes .../ml_tools/models/test_maxpool2d_1x1.model | Bin 0 -> 444 bytes opm/ml/ml_tools/models/test_relu_10.model | Bin 0 -> 472 bytes .../models/test_scalingdense_1x1.model | Bin 0 -> 604 bytes opm/ml/ml_tools/peaceman.py | 371 +++++++++ opm/ml/ml_tools/scaler_layers.py | 192 +++++ opm/ml/ml_tools/scalertest.py | 74 ++ 47 files changed, 3928 insertions(+) create mode 100644 opm/ml/keras_model.cpp create mode 100644 opm/ml/keras_model.hpp create mode 100644 opm/ml/keras_model_test.cpp create mode 100644 opm/ml/ml_tools/generateunittests.py create mode 100644 opm/ml/ml_tools/include/test_conv_2x2.h create mode 100644 opm/ml/ml_tools/include/test_conv_3x3.h create mode 100644 opm/ml/ml_tools/include/test_conv_3x3x3.h create mode 100644 opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h create mode 100644 opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h create mode 100644 opm/ml/ml_tools/include/test_conv_softplus_2x2.h create mode 100644 opm/ml/ml_tools/include/test_dense_10x1.h create mode 100644 opm/ml/ml_tools/include/test_dense_10x10.h create mode 100644 opm/ml/ml_tools/include/test_dense_10x10x10.h create mode 100644 opm/ml/ml_tools/include/test_dense_1x1.h create mode 100644 opm/ml/ml_tools/include/test_dense_2x2.h create mode 100644 opm/ml/ml_tools/include/test_dense_relu_10.h create mode 100644 opm/ml/ml_tools/include/test_dense_tanh_10.h create mode 100644 opm/ml/ml_tools/include/test_elu_10.h create mode 100644 opm/ml/ml_tools/include/test_maxpool2d_1x1.h create mode 100644 opm/ml/ml_tools/include/test_relu_10.h create mode 100644 opm/ml/ml_tools/include/test_scalingdense_1x1.h create mode 100644 opm/ml/ml_tools/kerasify.py create mode 100644 opm/ml/ml_tools/make_model_BCkrn.py create mode 100644 opm/ml/ml_tools/make_model_BCkrw.py create mode 100644 opm/ml/ml_tools/make_model_VGkrn.py create mode 100644 opm/ml/ml_tools/make_model_VGkrw.py create mode 100644 opm/ml/ml_tools/model_with_scaler_layers.opm create mode 100644 opm/ml/ml_tools/models/test_conv_2x2.model create mode 100644 opm/ml/ml_tools/models/test_conv_3x3.model create mode 100644 opm/ml/ml_tools/models/test_conv_3x3x3.model create mode 100644 opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model create mode 100644 opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model create mode 100644 opm/ml/ml_tools/models/test_conv_softplus_2x2.model create mode 100644 opm/ml/ml_tools/models/test_dense_10x1.model create mode 100644 opm/ml/ml_tools/models/test_dense_10x10.model create mode 100644 opm/ml/ml_tools/models/test_dense_10x10x10.model create mode 100644 opm/ml/ml_tools/models/test_dense_1x1.model create mode 100644 opm/ml/ml_tools/models/test_dense_2x2.model create mode 100644 opm/ml/ml_tools/models/test_dense_relu_10.model create mode 100644 opm/ml/ml_tools/models/test_dense_tanh_10.model create mode 100644 opm/ml/ml_tools/models/test_elu_10.model create mode 100644 opm/ml/ml_tools/models/test_maxpool2d_1x1.model create mode 100644 opm/ml/ml_tools/models/test_relu_10.model create mode 100644 opm/ml/ml_tools/models/test_scalingdense_1x1.model create mode 100644 opm/ml/ml_tools/peaceman.py create mode 100644 opm/ml/ml_tools/scaler_layers.py create mode 100644 opm/ml/ml_tools/scalertest.py diff --git a/opm/ml/keras_model.cpp b/opm/ml/keras_model.cpp new file mode 100644 index 00000000000..538044cd9c7 --- /dev/null +++ b/opm/ml/keras_model.cpp @@ -0,0 +1,769 @@ + +#include "keras_model.hpp" + +#include +#include +#include +#include +#include + +#include + +namespace Opm { + +#pragma once + + +bool ReadUnsignedInt(std::ifstream* file, unsigned int* i) { + KASSERT(file, "Invalid file stream"); + KASSERT(i, "Invalid pointer"); + + file->read((char*)i, sizeof(unsigned int)); + KASSERT(file->gcount() == sizeof(unsigned int), "Expected unsigned int"); + + return true; +} + +bool ReadFloat(std::ifstream* file, float* f) { + KASSERT(file, "Invalid file stream"); + KASSERT(f, "Invalid pointer"); + + file->read((char*)f, sizeof(float)); + KASSERT(file->gcount() == sizeof(float), "Expected Evaluation"); + + return true; +} + +bool ReadFloats(std::ifstream* file, float* f, size_t n) { + KASSERT(file, "Invalid file stream"); + KASSERT(f, "Invalid pointer"); + + file->read((char*)f, sizeof(float) * n); + KASSERT(((unsigned int)file->gcount()) == sizeof(float) * n, + "Expected Evaluations"); + + return true; +} + +template +bool KerasLayerActivation::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + + unsigned int activation = 0; + KASSERT(ReadUnsignedInt(file, &activation), + "Failed to read activation type"); + + switch (activation) { + case kLinear: + activation_type_ = kLinear; + break; + case kRelu: + activation_type_ = kRelu; + break; + case kSoftPlus: + activation_type_ = kSoftPlus; + break; + case kHardSigmoid: + activation_type_ = kHardSigmoid; + break; + case kSigmoid: + activation_type_ = kSigmoid; + break; + case kTanh: + activation_type_ = kTanh; + break; + default: + KASSERT(false, "Unsupported activation type %d", activation); + } + + return true; +} + +template +bool KerasLayerActivation::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + + *out = *in; + + switch (activation_type_) { + case kLinear: + break; + case kRelu: + for (size_t i = 0; i < out->data_.size(); i++) { + if (out->data_[i] < 0.0) { + out->data_[i] = 0.0; + } + } + break; + case kSoftPlus: + for (size_t i = 0; i < out->data_.size(); i++) { + out->data_[i] = log(1.0 + exp(out->data_[i])); + } + break; + case kHardSigmoid: + for (size_t i = 0; i < out->data_.size(); i++) { + Evaluation x = (out->data_[i] * 0.2) + 0.5; + + if (x <= 0) { + out->data_[i] = 0.0; + } else if (x >= 1) { + out->data_[i] = 1.0; + } else { + out->data_[i] = x; + } + } + break; + case kSigmoid: + for (size_t i = 0; i < out->data_.size(); i++) { + Evaluation& x = out->data_[i]; + + if (x >= 0) { + out->data_[i] = 1.0 / (1.0 + exp(-x)); + } else { + Evaluation z = exp(x); + out->data_[i] = z / (1.0 + z); + } + } + break; + case kTanh: + for (size_t i = 0; i < out->data_.size(); i++) { + out->data_[i] = sinh(out->data_[i])/cosh(out->data_[i]); + } + break; + default: + break; + } + + return true; +} + + +template +bool KerasLayerScaling::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + + KASSERT(ReadFloat(file, &data_min), "Failed to read max"); + + return true; +} + +template +bool KerasLayerScaling::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + + *out = *in; + // out->Flatten(); + std::cout<data_[0]<data_[1]< +bool KerasLayerUnScaling::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + return true; +} + +template +bool KerasLayerUnScaling::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + + *out = *in; + // out->Flatten(); + + return true; +} + + +template +bool KerasLayerDense::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + + unsigned int weights_rows = 0; + KASSERT(ReadUnsignedInt(file, &weights_rows), "Expected weight rows"); + KASSERT(weights_rows > 0, "Invalid weights # rows"); + + unsigned int weights_cols = 0; + KASSERT(ReadUnsignedInt(file, &weights_cols), "Expected weight cols"); + KASSERT(weights_cols > 0, "Invalid weights shape"); + + unsigned int biases_shape = 0; + KASSERT(ReadUnsignedInt(file, &biases_shape), "Expected biases shape"); + KASSERT(biases_shape > 0, "Invalid biases shape"); + + weights_.Resize(weights_rows, weights_cols); + KASSERT( + ReadFloats(file, weights_.data_.data(), weights_rows * weights_cols), + "Expected weights"); + + biases_.Resize(biases_shape); + KASSERT(ReadFloats(file, biases_.data_.data(), biases_shape), + "Expected biases"); + + KASSERT(activation_.LoadLayer(file), "Failed to load activation"); + + return true; +} + +template +bool KerasLayerDense::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + KASSERT(in->dims_.size() <= 2, "Invalid input dimensions"); + + if (in->dims_.size() == 2) { + KASSERT(in->dims_[1] == weights_.dims_[0], "Dimension mismatch %d %d", + in->dims_[1], weights_.dims_[0]); + } + + Tensor tmp(weights_.dims_[1]); + + for (int i = 0; i < weights_.dims_[0]; i++) { + for (int j = 0; j < weights_.dims_[1]; j++) { + tmp(j) += (*in)(i)*weights_(i, j); + } + } + + for (int i = 0; i < biases_.dims_[0]; i++) { + tmp(i) += biases_(i); + } + + KASSERT(activation_.Apply(&tmp, out), "Failed to apply activation"); + + return true; +} + +template +bool KerasLayerConvolution2d::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + + unsigned int weights_i = 0; + KASSERT(ReadUnsignedInt(file, &weights_i), "Expected weights_i"); + KASSERT(weights_i > 0, "Invalid weights # i"); + + unsigned int weights_j = 0; + KASSERT(ReadUnsignedInt(file, &weights_j), "Expected weights_j"); + KASSERT(weights_j > 0, "Invalid weights # j"); + + unsigned int weights_k = 0; + KASSERT(ReadUnsignedInt(file, &weights_k), "Expected weights_k"); + KASSERT(weights_k > 0, "Invalid weights # k"); + + unsigned int weights_l = 0; + KASSERT(ReadUnsignedInt(file, &weights_l), "Expected weights_l"); + KASSERT(weights_l > 0, "Invalid weights # l"); + + unsigned int biases_shape = 0; + KASSERT(ReadUnsignedInt(file, &biases_shape), "Expected biases shape"); + KASSERT(biases_shape > 0, "Invalid biases shape"); + + weights_.Resize(weights_i, weights_j, weights_k, weights_l); + KASSERT(ReadFloats(file, weights_.data_.data(), + weights_i * weights_j * weights_k * weights_l), + "Expected weights"); + + biases_.Resize(biases_shape); + KASSERT(ReadFloats(file, biases_.data_.data(), biases_shape), + "Expected biases"); + + KASSERT(activation_.LoadLayer(file), "Failed to load activation"); + + return true; +} + +template +bool KerasLayerConvolution2d::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + + KASSERT(in->dims_[0] == weights_.dims_[1], + "Input 'depth' doesn't match kernel 'depth'"); + + int st_nj = (weights_.dims_[2] - 1) / 2; + int st_pj = (weights_.dims_[2]) / 2; + int st_nk = (weights_.dims_[3] - 1) / 2; + int st_pk = (weights_.dims_[3]) / 2; + + Tensor tmp(weights_.dims_[0], in->dims_[1] - st_nj - st_pj, + in->dims_[2] - st_nk - st_pk); + + // Iterate over each kernel. + for (int i = 0; i < weights_.dims_[0]; i++) { + // Iterate over each 'depth'. + for (int j = 0; j < weights_.dims_[1]; j++) { + // 2D convolution in x and y (k and l in Tensor dimensions). + for (int tj = st_nj; tj < in->dims_[1] - st_pj; tj++) { + for (int tk = st_nk; tk < in->dims_[2] - st_pk; tk++) { + // Iterate over kernel. + for (int k = 0; k < weights_.dims_[2]; k++) { + for (int l = 0; l < weights_.dims_[3]; l++) { + const float& weight = weights_(i, j, k, l); + const Evaluation& value = + (*in)(j, tj - st_nj + k, tk - st_nk + l); + + tmp(i, tj - st_nj, tk - st_nk) += weight * value; + } + } + } + } + } + + // Apply kernel bias to all points in output. + for (int j = 0; j < tmp.dims_[1]; j++) { + for (int k = 0; k < tmp.dims_[2]; k++) { + tmp(i, j, k) += biases_(i); + } + } + } + + KASSERT(activation_.Apply(&tmp, out), "Failed to apply activation"); + + return true; +} + +template +bool KerasLayerFlatten::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + return true; +} + +template +bool KerasLayerFlatten::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + + *out = *in; + out->Flatten(); + + return true; +} + +template +bool KerasLayerElu::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + + KASSERT(ReadFloat(file, &alpha_), "Failed to read alpha"); + + return true; +} + +template +bool KerasLayerElu::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + + *out = *in; + + for (size_t i = 0; i < out->data_.size(); i++) { + if (out->data_[i] < 0.0) { + out->data_[i] = alpha_ * (exp(out->data_[i]) - 1.0); + } + } + + return true; +} + +template +bool KerasLayerMaxPooling2d::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + + KASSERT(ReadUnsignedInt(file, &pool_size_j_), "Expected pool size j"); + KASSERT(ReadUnsignedInt(file, &pool_size_k_), "Expected pool size k"); + + return true; +} + +template +bool KerasLayerMaxPooling2d::Apply(Tensor* in, Tensor* out) { + KASSERT(in, "Invalid input"); + KASSERT(out, "Invalid output"); + + KASSERT(in->dims_.size() == 3, "Input must have 3 dimensions"); + + Tensor tmp(in->dims_[0], in->dims_[1] / pool_size_j_, + in->dims_[2] / pool_size_k_); + + for (int i = 0; i < tmp.dims_[0]; i++) { + for (int j = 0; j < tmp.dims_[1]; j++) { + const int tj = j * pool_size_j_; + + for (int k = 0; k < tmp.dims_[2]; k++) { + const int tk = k * pool_size_k_; + + // Find maximum value over patch starting at tj, tk. + Evaluation max_val = -std::numeric_limits::infinity(); + + for (unsigned int pj = 0; pj < pool_size_j_; pj++) { + for (unsigned int pk = 0; pk < pool_size_k_; pk++) { + const Evaluation& pool_val = (*in)(i, tj + pj, tk + pk); + if (pool_val > max_val) { + max_val = pool_val; + } + } + } + + tmp(i, j, k) = max_val; + } + } + } + + *out = tmp; + + return true; +} + + + +template +bool KerasLayerEmbedding::LoadLayer(std::ifstream* file) { + KASSERT(file, "Invalid file stream"); + + unsigned int weights_rows = 0; + KASSERT(ReadUnsignedInt(file, &weights_rows), "Expected weight rows"); + KASSERT(weights_rows > 0, "Invalid weights # rows"); + + unsigned int weights_cols = 0; + KASSERT(ReadUnsignedInt(file, &weights_cols), "Expected weight cols"); + KASSERT(weights_cols > 0, "Invalid weights shape"); + + weights_.Resize(weights_rows, weights_cols); + KASSERT( + ReadFloats(file, weights_.data_.data(), weights_rows * weights_cols), + "Expected weights"); + + return true; +} + +template +bool KerasLayerEmbedding::Apply(Tensor* in, Tensor* out) { + int output_rows = in->dims_[1]; + int output_cols = weights_.dims_[1]; + out->dims_ = {output_rows, output_cols}; + out->data_.reserve(output_rows * output_cols); + + std::for_each(in->data_.begin(), in->data_.end(), [=](Evaluation i) { + typename std::vector::const_iterator first = + this->weights_.data_.begin() + (getValue(i) * output_cols); + typename std::vector::const_iterator last = + this->weights_.data_.begin() + (getValue(i) + 1) * output_cols; + + out->data_.insert(out->data_.end(), first, last); + }); + + return true; +} + +// template +// bool KerasLayerLSTM::LoadLayer(std::ifstream* file) { +// KASSERT(file, "Invalid file stream"); +// +// unsigned int wi_rows = 0; +// KASSERT(ReadUnsignedInt(file, &wi_rows), "Expected Wi rows"); +// KASSERT(wi_rows > 0, "Invalid Wi # rows"); +// +// unsigned int wi_cols = 0; +// KASSERT(ReadUnsignedInt(file, &wi_cols), "Expected Wi cols"); +// KASSERT(wi_cols > 0, "Invalid Wi shape"); +// +// unsigned int ui_rows = 0; +// KASSERT(ReadUnsignedInt(file, &ui_rows), "Expected Ui rows"); +// KASSERT(ui_rows > 0, "Invalid Ui # rows"); +// +// unsigned int ui_cols = 0; +// KASSERT(ReadUnsignedInt(file, &ui_cols), "Expected Ui cols"); +// KASSERT(ui_cols > 0, "Invalid Ui shape"); +// +// unsigned int bi_shape = 0; +// KASSERT(ReadUnsignedInt(file, &bi_shape), "Expected bi shape"); +// KASSERT(bi_shape > 0, "Invalid bi shape"); +// +// unsigned int wf_rows = 0; +// KASSERT(ReadUnsignedInt(file, &wf_rows), "Expected Wf rows"); +// KASSERT(wf_rows > 0, "Invalid Wf # rows"); +// +// unsigned int wf_cols = 0; +// KASSERT(ReadUnsignedInt(file, &wf_cols), "Expected Wf cols"); +// KASSERT(wf_cols > 0, "Invalid Wf shape"); +// +// unsigned int uf_rows = 0; +// KASSERT(ReadUnsignedInt(file, &uf_rows), "Expected Uf rows"); +// KASSERT(uf_rows > 0, "Invalid Uf # rows"); +// +// unsigned int uf_cols = 0; +// KASSERT(ReadUnsignedInt(file, &uf_cols), "Expected Uf cols"); +// KASSERT(uf_cols > 0, "Invalid Uf shape"); +// +// unsigned int bf_shape = 0; +// KASSERT(ReadUnsignedInt(file, &bf_shape), "Expected bf shape"); +// KASSERT(bf_shape > 0, "Invalid bf shape"); +// +// unsigned int wc_rows = 0; +// KASSERT(ReadUnsignedInt(file, &wc_rows), "Expected Wc rows"); +// KASSERT(wc_rows > 0, "Invalid Wc # rows"); +// +// unsigned int wc_cols = 0; +// KASSERT(ReadUnsignedInt(file, &wc_cols), "Expected Wc cols"); +// KASSERT(wc_cols > 0, "Invalid Wc shape"); +// +// unsigned int uc_rows = 0; +// KASSERT(ReadUnsignedInt(file, &uc_rows), "Expected Uc rows"); +// KASSERT(uc_rows > 0, "Invalid Uc # rows"); +// +// unsigned int uc_cols = 0; +// KASSERT(ReadUnsignedInt(file, &uc_cols), "Expected Uc cols"); +// KASSERT(uc_cols > 0, "Invalid Uc shape"); +// +// unsigned int bc_shape = 0; +// KASSERT(ReadUnsignedInt(file, &bc_shape), "Expected bc shape"); +// KASSERT(bc_shape > 0, "Invalid bc shape"); +// +// unsigned int wo_rows = 0; +// KASSERT(ReadUnsignedInt(file, &wo_rows), "Expected Wo rows"); +// KASSERT(wo_rows > 0, "Invalid Wo # rows"); +// +// unsigned int wo_cols = 0; +// KASSERT(ReadUnsignedInt(file, &wo_cols), "Expected Wo cols"); +// KASSERT(wo_cols > 0, "Invalid Wo shape"); +// +// unsigned int uo_rows = 0; +// KASSERT(ReadUnsignedInt(file, &uo_rows), "Expected Uo rows"); +// KASSERT(uo_rows > 0, "Invalid Uo # rows"); +// +// unsigned int uo_cols = 0; +// KASSERT(ReadUnsignedInt(file, &uo_cols), "Expected Uo cols"); +// KASSERT(uo_cols > 0, "Invalid Uo shape"); +// +// unsigned int bo_shape = 0; +// KASSERT(ReadUnsignedInt(file, &bo_shape), "Expected bo shape"); +// KASSERT(bo_shape > 0, "Invalid bo shape"); +// +// // Load Input Weights and Biases +// Wi_.Resize(wi_rows, wi_cols); +// KASSERT(ReadFloats(file, Wi_.data_.data(), wi_rows * wi_cols), +// "Expected Wi weights"); +// +// Ui_.Resize(ui_rows, ui_cols); +// KASSERT(ReadFloats(file, Ui_.data_.data(), ui_rows * ui_cols), +// "Expected Ui weights"); +// +// bi_.Resize(1, bi_shape); +// KASSERT(ReadFloats(file, bi_.data_.data(), bi_shape), "Expected bi biases"); +// +// // Load Forget Weights and Biases +// Wf_.Resize(wf_rows, wf_cols); +// KASSERT(ReadFloats(file, Wf_.data_.data(), wf_rows * wf_cols), +// "Expected Wf weights"); +// +// Uf_.Resize(uf_rows, uf_cols); +// KASSERT(ReadFloats(file, Uf_.data_.data(), uf_rows * uf_cols), +// "Expected Uf weights"); +// +// bf_.Resize(1, bf_shape); +// KASSERT(ReadFloats(file, bf_.data_.data(), bf_shape), "Expected bf biases"); +// +// // Load State Weights and Biases +// Wc_.Resize(wc_rows, wc_cols); +// KASSERT(ReadFloats(file, Wc_.data_.data(), wc_rows * wc_cols), +// "Expected Wc weights"); +// +// Uc_.Resize(uc_rows, uc_cols); +// KASSERT(ReadFloats(file, Uc_.data_.data(), uc_rows * uc_cols), +// "Expected Uc weights"); +// +// bc_.Resize(1, bc_shape); +// KASSERT(ReadFloats(file, bc_.data_.data(), bc_shape), "Expected bc biases"); +// +// // Load Output Weights and Biases +// Wo_.Resize(wo_rows, wo_cols); +// KASSERT(ReadFloats(file, Wo_.data_.data(), wo_rows * wo_cols), +// "Expected Wo weights"); +// +// Uo_.Resize(uo_rows, uo_cols); +// KASSERT(ReadFloats(file, Uo_.data_.data(), uo_rows * uo_cols), +// "Expected Uo weights"); +// +// bo_.Resize(1, bo_shape); +// KASSERT(ReadFloats(file, bo_.data_.data(), bo_shape), "Expected bo biases"); +// +// KASSERT(innerActivation_.LoadLayer(file), +// "Failed to load inner activation"); +// KASSERT(activation_.LoadLayer(file), "Failed to load activation"); +// +// unsigned int return_sequences = 0; +// KASSERT(ReadUnsignedInt(file, &return_sequences), +// "Expected return_sequences param"); +// return_sequences_ = (bool)return_sequences; +// +// return true; +// } +// +// template +// bool KerasLayerLSTM::Apply(Tensor* in, Tensor* out) { +// // Assume bo always keeps the output shape and we will always receive one +// // single sample. +// int outputDim = bo_.dims_[1]; +// Tensor ht_1 = Tensor(1, outputDim); +// Tensor ct_1 = Tensor(1, outputDim); +// +// ht_1.Fill(0.0f); +// ct_1.Fill(0.0f); +// +// int steps = in->dims_[0]; +// +// Tensor outputs, lastOutput; +// +// if (return_sequences_) { +// outputs.dims_ = {steps, outputDim}; +// outputs.data_.reserve(steps * outputDim); +// } +// +// for (int s = 0; s < steps; s++) { +// Tensor x = in->Select(s); +// +// KASSERT(Step(&x, &lastOutput, &ht_1, &ct_1), "Failed to execute step"); +// +// if (return_sequences_) { +// outputs.data_.insert(outputs.data_.end(), lastOutput.data_.begin(), +// lastOutput.data_.end()); +// } +// } +// +// if (return_sequences_) { +// *out = outputs; +// } else { +// *out = lastOutput; +// } +// +// return true; +// } +// +// template +// bool KerasLayerLSTM::Step(Tensor * x, Tensor * out, Tensor * ht_1, Tensor * ct_1) { +// Tensor xi = x->Dot(Wi_) + bi_; +// Tensor xf = x->Dot(Wf_) + bf_; +// Tensor xc = x->Dot(Wc_) + bc_; +// Tensor xo = x->Dot(Wo_) + bo_; +// +// Tensor i_ = xi + ht_1->Dot(Ui_); +// Tensor f_ = xf + ht_1->Dot(Uf_); +// Tensor c_ = xc + ht_1->Dot(Uc_); +// Tensor o_ = xo + ht_1->Dot(Uo_); +// +// Tensor i, f, cc, o; +// +// KASSERT(innerActivation_.Apply(&i_, &i), +// "Failed to apply inner activation on i"); +// KASSERT(innerActivation_.Apply(&f_, &f), +// "Failed to apply inner activation on f"); +// KASSERT(activation_.Apply(&c_, &cc), "Failed to apply activation on c_"); +// KASSERT(innerActivation_.Apply(&o_, &o), +// "Failed to apply inner activation on o"); +// +// *ct_1 = f.Multiply(*ct_1) + i.Multiply(cc); +// +// KASSERT(activation_.Apply(ct_1, &cc), "Failed to apply activation on c"); +// *out = *ht_1 = o.Multiply(cc); +// +// return true; +// } + +template +bool KerasModel::LoadModel(const std::string& filename) { + std::ifstream file(filename.c_str(), std::ios::binary); + KASSERT(file.is_open(), "Unable to open file %s", filename.c_str()); + + unsigned int num_layers = 0; + KASSERT(ReadUnsignedInt(&file, &num_layers), "Expected number of layers"); + + for (unsigned int i = 0; i < num_layers; i++) { + unsigned int layer_type = 0; + KASSERT(ReadUnsignedInt(&file, &layer_type), "Expected layer type"); + + KerasLayer* layer = NULL; + + switch (layer_type) { + // case kConvolution2d: + // layer = new KerasLayerConvolution2d(); + // break; + case kFlatten: + layer = new KerasLayerFlatten(); + break; + case kScaling: + layer = new KerasLayerScaling(); + break; + case kUnScaling: + layer = new KerasLayerUnScaling(); + break; + case kDense: + layer = new KerasLayerDense(); + break; + // case kElu: + // layer = new KerasLayerElu(); + // break; + case kActivation: + layer = new KerasLayerActivation(); + break; + // case kMaxPooling2D: + // // layer = new KerasLayerMaxPooling2d(); + // break; + // case kLSTM: + // // layer = new KerasLayerLSTM(); + // break; + // case kEmbedding: + // // layer = new KerasLayerEmbedding(); + // break; + default: + break; + } + + KASSERT(layer, "Unknown layer type %d", layer_type); + + bool result = layer->LoadLayer(&file); + if (!result) { + printf("Failed to load layer %d", i); + delete layer; + return false; + } + + layers_.push_back(layer); + } + + return true; +} + +template +bool KerasModel::Apply(Tensor* in, Tensor* out) { + Tensor temp_in, temp_out; + + for (unsigned int i = 0; i < layers_.size(); i++) { + if (i == 0) { + temp_in = *in; + } + + KASSERT(layers_[i]->Apply(&temp_in, &temp_out), + "Failed to apply layer %d", i); + + temp_in = temp_out; + } + + *out = temp_out; + + return true; +} + +template class KerasModel; + +template class KerasModel; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; + +} // namespace Opm diff --git a/opm/ml/keras_model.hpp b/opm/ml/keras_model.hpp new file mode 100644 index 00000000000..1a401ef4758 --- /dev/null +++ b/opm/ml/keras_model.hpp @@ -0,0 +1,530 @@ +#ifndef KERAS_MODEL_H_ +#define KERAS_MODEL_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include + +// typedef double Scalar; + +//typedef Opm::DenseAd::Evaluation Evaluation; +//typedef float Evaluation; +//typedef double Evaluation; +namespace Opm { + +#define KASSERT(x, ...) \ + if (!(x)) { \ + printf("KASSERT: %s(%d): ", __FILE__, __LINE__); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + return false; \ + } + +#define KASSERT_EQ(x, y, eps) \ + if (fabs(x.value() - y.value()) > eps) { \ + printf("KASSERT: Expected %f, got %f\n", y.value(), x.value()); \ + return false; \ + } + +#ifdef DEBUG +#define KDEBUG(x, ...) \ + if (!(x)) { \ + printf("%s(%d): ", __FILE__, __LINE__); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + exit(-1); \ + } +#else +#define KDEBUG(x, ...) ; +#endif + +template +class Tensor { + public: + Tensor() {} + + Tensor(int i) { Resize(i); } + + Tensor(int i, int j) { Resize(i, j); } + + Tensor(int i, int j, int k) { Resize(i, j, k); } + + Tensor(int i, int j, int k, int l) { Resize(i, j, k, l); } + + void Resize(int i) { + dims_ = {i}; + data_.resize(i); + } + + void Resize(int i, int j) { + dims_ = {i, j}; + data_.resize(i * j); + } + + void Resize(int i, int j, int k) { + dims_ = {i, j, k}; + data_.resize(i * j * k); + } + + void Resize(int i, int j, int k, int l) { + dims_ = {i, j, k, l}; + data_.resize(i * j * k * l); + } + + inline void Flatten() { + KDEBUG(dims_.size() > 0, "Invalid tensor"); + + int elements = dims_[0]; + for (unsigned int i = 1; i < dims_.size(); i++) { + elements *= dims_[i]; + } + dims_ = {elements}; + } + + inline Foo& operator()(int i) { + KDEBUG(dims_.size() == 1, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + + return data_[i]; + } + + inline Foo& operator()(int i, int j) { + KDEBUG(dims_.size() == 2, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + + return data_[dims_[1] * i + j]; + } + + inline Foo operator()(int i, int j) const { + KDEBUG(dims_.size() == 2, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + + return data_[dims_[1] * i + j]; + } + + inline Foo& operator()(int i, int j, int k) { + KDEBUG(dims_.size() == 3, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]); + + return data_[dims_[2] * (dims_[1] * i + j) + k]; + } + + inline Foo& operator()(int i, int j, int k, int l) { + KDEBUG(dims_.size() == 4, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]); + KDEBUG(l < dims_[3] && l >= 0, "Invalid l: %d (max %d)", l, dims_[3]); + + return data_[dims_[3] * (dims_[2] * (dims_[1] * i + j) + k) + l]; + } + + inline void Fill(Foo value) { + std::fill(data_.begin(), data_.end(), value); + } + + Tensor Unpack(int row) const { + KASSERT(dims_.size() >= 2, "Invalid tensor"); + std::vector pack_dims = + std::vector(dims_.begin() + 1, dims_.end()); + int pack_size = std::accumulate(pack_dims.begin(), pack_dims.end(), 0); + + typename std::vector::const_iterator first = + data_.begin() + (row * pack_size); + typename std::vector::const_iterator last = + data_.begin() + (row + 1) * pack_size; + + Tensor x = Tensor(); + x.dims_ = pack_dims; + x.data_ = std::vector(first, last); + + return x; + } + + Tensor Select(int row) const { + Tensor x = Unpack(row); + x.dims_.insert(x.dims_.begin(), 1); + + return x; + } + + Tensor operator+(const Tensor& other) { + KASSERT(dims_ == other.dims_, + "Cannot add tensors with different dimensions"); + + Tensor result; + result.dims_ = dims_; + result.data_.reserve(data_.size()); + + std::transform(data_.begin(), data_.end(), other.data_.begin(), + std::back_inserter(result.data_), + [](Foo x, Foo y) { return x + y; }); + + return result; + } + + Tensor Multiply(const Tensor& other) { + KASSERT(dims_ == other.dims_, + "Cannot multiply elements with different dimensions"); + + Tensor result; + result.dims_ = dims_; + result.data_.reserve(data_.size()); + + std::transform(data_.begin(), data_.end(), other.data_.begin(), + std::back_inserter(result.data_), + [](Foo x, Foo y) { return x * y; }); + + return result; + } + + Tensor Dot(const Tensor& other) { + KDEBUG(dims_.size() == 2, "Invalid tensor dimensions"); + KDEBUG(other.dims_.size() == 2, "Invalid tensor dimensions"); + KASSERT(dims_[1] == other.dims_[0], + "Cannot multiply with different inner dimensions"); + + Tensor tmp(dims_[0], other.dims_[1]); + + for (int i = 0; i < dims_[0]; i++) { + for (int j = 0; j < other.dims_[1]; j++) { + for (int k = 0; k < dims_[1]; k++) { + tmp(i, j) += (*this)(i, k) * other(k, j); + } + } + } + + return tmp; + } + + // void Print() { + // if (dims_.size() == 1) { + // printf("[ "); + // for (int i = 0; i < dims_[0]; i++) { + // printf("%f ", (*this)(i)); + // } + // printf("]\n"); + // } else if (dims_.size() == 2) { + // printf("[\n"); + // for (int i = 0; i < dims_[0]; i++) { + // printf(" [ "); + // for (int j = 0; j < dims_[1]; j++) { + // printf("%f ", (*this)(i, j)); + // } + // printf("]\n"); + // } + // printf("]\n"); + // } else if (dims_.size() == 3) { + // printf("[\n"); + // for (int i = 0; i < dims_[0]; i++) { + // printf(" [\n"); + // for (int j = 0; j < dims_[1]; j++) { + // printf(" [ "); + // for (int k = 0; k < dims_[2]; k++) { + // printf("%f ", (*this)(i, j, k)); + // } + // printf(" ]\n"); + // } + // printf(" ]\n"); + // } + // printf("]\n"); + // } else if (dims_.size() == 4) { + // printf("[\n"); + // for (int i = 0; i < dims_[0]; i++) { + // printf(" [\n"); + // for (int j = 0; j < dims_[1]; j++) { + // printf(" [\n"); + // for (int k = 0; k < dims_[2]; k++) { + // printf(" ["); + // for (int l = 0; l < dims_[3]; l++) { + // printf("%f ", (*this)(i, j, k, l)); + // } + // printf("]\n"); + // } + // printf(" ]\n"); + // } + // printf(" ]\n"); + // } + // printf("]\n"); + // } + // } + + // void PrintShape() { + // printf("("); + // for (unsigned int i = 0; i < dims_.size(); i++) { + // printf("%d ", dims_[i]); + // } + // printf(")\n"); + // } + + std::vector dims_; + std::vector data_; +}; + +template +class KerasLayer { + public: + KerasLayer() {} + + virtual ~KerasLayer() {} + + virtual bool LoadLayer(std::ifstream* file) = 0; + + virtual bool Apply(Tensor* in, Tensor* out) = 0; +}; + +template +class KerasLayerActivation : public KerasLayer { + public: + enum ActivationType { + kLinear = 1, + kRelu = 2, + kSoftPlus = 3, + kSigmoid = 4, + kTanh = 5, + kHardSigmoid = 6 + }; + + KerasLayerActivation() : activation_type_(ActivationType::kLinear) {} + + virtual ~KerasLayerActivation() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + ActivationType activation_type_; +}; + +template +class KerasLayerScaling : public KerasLayer { + public: + KerasLayerScaling(): data_min(1.0f) {} + + virtual ~KerasLayerScaling() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + Tensor weights_; + Tensor biases_; + float data_min; + + // KerasLayerActivation activation_; +}; + +template +class KerasLayerUnScaling : public KerasLayer { + public: + KerasLayerUnScaling() {} + + virtual ~KerasLayerUnScaling() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + Tensor weights_; + Tensor biases_; + + // KerasLayerActivation activation_; +}; + + +template +class KerasLayerDense : public KerasLayer { + public: + KerasLayerDense() {} + + virtual ~KerasLayerDense() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + Tensor weights_; + Tensor biases_; + + KerasLayerActivation activation_; +}; + +template +class KerasLayerConvolution2d: public KerasLayer { + public: + KerasLayerConvolution2d() {} + + virtual ~KerasLayerConvolution2d() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + Tensor weights_; + Tensor biases_; + + KerasLayerActivation activation_; +}; + +template +class KerasLayerFlatten : public KerasLayer { + public: + KerasLayerFlatten() {} + + virtual ~KerasLayerFlatten() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: +}; + +template +class KerasLayerElu : public KerasLayer { + public: + KerasLayerElu() : alpha_(1.0f) {} + + virtual ~KerasLayerElu() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + float alpha_; +}; + +template +class KerasLayerMaxPooling2d : public KerasLayer { + public: + KerasLayerMaxPooling2d() : pool_size_j_(0), pool_size_k_(0) {} + + virtual ~KerasLayerMaxPooling2d() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + unsigned int pool_size_j_; + unsigned int pool_size_k_; +}; + +// template +// class KerasLayerLSTM : public KerasLayer { +// public: +// KerasLayerLSTM() : return_sequences_(false) {} +// +// virtual ~KerasLayerLSTM() {} +// +// virtual bool LoadLayer(std::ifstream* file); +// +// virtual bool Apply(Tensor* in, Tensor* out); +// +// private: +// bool Step(Tensor* x, Tensor* out, Tensor* ht_1, Tensor* ct_1); +// +// Tensor Wi_; +// Tensor Ui_; +// Tensor bi_; +// Tensor Wf_; +// Tensor Uf_; +// Tensor bf_; +// Tensor Wc_; +// Tensor Uc_; +// Tensor bc_; +// Tensor Wo_; +// Tensor Uo_; +// Tensor bo_; +// +// KerasLayerActivation innerActivation_; +// KerasLayerActivation activation_; +// bool return_sequences_; +// }; + + +template +class KerasLayerEmbedding : public KerasLayer { + public: + KerasLayerEmbedding() {} + + virtual ~KerasLayerEmbedding() {} + + virtual bool LoadLayer(std::ifstream* file); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + Tensor weights_; +}; + +template +class KerasModel { + public: + enum LayerType { + // kConvolution2d = 2, + kFlatten = 1, + // kElu = 4, + // kMaxPooling2D = 6, + // kLSTM = 7, + // kEmbedding = 8, + kScaling = 2, + kUnScaling = 3, + kDense = 4, + kActivation = 5 + }; + + KerasModel() {} + + virtual ~KerasModel() { + for (unsigned int i = 0; i < layers_.size(); i++) { + delete layers_[i]; + } + } + + virtual bool LoadModel(const std::string& filename); + + virtual bool Apply(Tensor* in, Tensor* out); + + private: + std::vector*> layers_; +}; + +class KerasTimer { + public: + KerasTimer() {} + + void Start() { start_ = std::chrono::high_resolution_clock::now(); } + + float Stop() { + std::chrono::time_point now = + std::chrono::high_resolution_clock::now(); + + std::chrono::duration diff = now - start_; + + return diff.count(); + } + + private: + std::chrono::time_point start_; +}; + +} // namespace Opm + +#endif // KERAS_MODEL_H_ diff --git a/opm/ml/keras_model_test.cpp b/opm/ml/keras_model_test.cpp new file mode 100644 index 00000000000..a26744fc2a9 --- /dev/null +++ b/opm/ml/keras_model_test.cpp @@ -0,0 +1,227 @@ +#include "keras_model.hpp" + +#include +#include + +#include "ml_tools/include/test_conv_2x2.h" +#include "ml_tools/include/test_conv_3x3.h" +#include "ml_tools/include/test_conv_3x3x3.h" +#include "ml_tools/include/test_conv_hard_sigmoid_2x2.h" +#include "ml_tools/include/test_conv_sigmoid_2x2.h" +#include "ml_tools/include/test_conv_softplus_2x2.h" +#include "ml_tools/include/test_dense_10x1.h" +#include "ml_tools/include/test_dense_10x10.h" +#include "ml_tools/include/test_dense_10x10x10.h" +#include "ml_tools/include/test_dense_1x1.h" +#include "ml_tools/include/test_dense_2x2.h" +#include "ml_tools/include/test_dense_relu_10.h" +#include "ml_tools/include/test_dense_tanh_10.h" +#include "ml_tools/include/test_elu_10.h" +#include "ml_tools/include/test_relu_10.h" + + +#include "ml_tools/include/test_scalingdense_1x1.h" + + +namespace Opm { + +template +bool tensor_test() { + printf("TEST tensor_test\n"); + + { + const int i = 3; + const int j = 5; + const int k = 10; + Tensor t(i, j, k); + + Evaluation c = 1.f; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + t(ii, jj, kk) = c; + c += 1.f; + } + } + } + + c = 1.f; + int cc = 0; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + KASSERT_EQ(t(ii, jj, kk), c, 1e-9); + KASSERT_EQ(t.data_[cc], c, 1e-9); + c += 1.f; + cc++; + } + } + } + } + + { + const int i = 2; + const int j = 3; + const int k = 4; + const int l = 5; + Tensor t(i, j, k, l); + + Evaluation c = 1.f; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + for (int ll = 0; ll < l; ll++) { + t(ii, jj, kk, ll) = c; + c += 1.f; + } + } + } + } + + c = 1.f; + int cc = 0; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + for (int ll = 0; ll < l; ll++) { + KASSERT_EQ(t(ii, jj, kk, ll), c, 1e-9); + KASSERT_EQ(t.data_[cc], c, 1e-9); + c += 1.f; + cc++; + } + } + } + } + } + + { + Tensor a(2, 2); + Tensor b(2, 2); + + a.data_ = {1.0, 2.0, 3.0, 5.0}; + b.data_ = {2.0, 5.0, 4.0, 1.0}; + + Tensor result = a + b; + KASSERT(result.data_ == std::vector({3.0, 7.0, 7.0, 6.0}), + "Vector add failed"); + } + + { + Tensor a(2, 2); + Tensor b(2, 2); + + a.data_ = {1.0, 2.0, 3.0, 5.0}; + b.data_ = {2.0, 5.0, 4.0, 1.0}; + + Tensor result = a.Multiply(b); + KASSERT(result.data_ == std::vector({2.0, 10.0, 12.0, 5.0}), + "Vector multiply failed"); + } + + { + Tensor a(2, 1); + Tensor b(1, 2); + + a.data_ = {1.0, 2.0}; + b.data_ = {2.0, 5.0}; + + Tensor result = a.Dot(b); + KASSERT(result.data_ == std::vector({2.0, 5.0, 4.0, 10.0}), + "Vector dot failed"); + } + + return true; +} + + +} + +int main() { + typedef Opm::DenseAd::Evaluation Evaluation; + + Evaluation load_time = 0.0; + Evaluation apply_time = 0.0; + + // if (!tensor_test()) { + // return 1; + // } + // + // if (!test_dense_1x1(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_dense_10x1(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_dense_2x2(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_dense_10x10(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_dense_10x10x10(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_conv_2x2(&load_time, &apply_time)) { + // return 1; + // } + // // + // if (!test_conv_3x3(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_conv_3x3x3(&load_time, &apply_time)) { + // return 1; + // } + // // + // if (!test_elu_10(&load_time, &apply_time)) { + // return 1; + // } + // // + // if (!test_relu_10(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_dense_relu_10(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_dense_tanh_10(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_conv_softplus_2x2(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_conv_hard_sigmoid_2x2(&load_time, &apply_time)) { + // return 1; + // } + // + // if (!test_conv_sigmoid_2x2(&load_time, &apply_time)) { + // return 1; + // } + + if (!test_scalingdense_1x1(&load_time, &apply_time)) { + return 1; + } + + // Run benchmark 5 times and report duration. + Evaluation total_load_time = 0.0; + Evaluation total_apply_time = 0.0; + + for (int i = 0; i < 5; i++) { + total_load_time += load_time; + total_apply_time += apply_time; + } + + printf("Benchmark network loads in %fs\n", total_load_time / 5); + printf("Benchmark network runs in %fs\n", total_apply_time / 5); + + return 0; +} +// } diff --git a/opm/ml/ml_tools/generateunittests.py b/opm/ml/ml_tools/generateunittests.py new file mode 100644 index 00000000000..f8e7fb00ab3 --- /dev/null +++ b/opm/ml/ml_tools/generateunittests.py @@ -0,0 +1,294 @@ +import numpy as np +import pprint +import os +from tensorflow import keras + +from keras.models import Sequential +from keras.layers import Conv2D, Dense, Flatten, Activation, MaxPooling2D, Dropout, BatchNormalization, ELU, Embedding, LSTM +from kerasify import export_model +from scaler_layers import MinMaxScalerLayer, MinMaxUnScalerLayer + +np.set_printoptions(precision=25, threshold=10000000) + + +def c_array(a): + def to_cpp(ndarray): + text = np.array2string(ndarray, separator=',', threshold=np.inf, + floatmode='unique') + return text.replace('[', '{').replace(']', '}').replace(' ', '') + + s = to_cpp(a.ravel()) + shape = to_cpp(np.asarray(a.shape)) if a.shape else '{1}' + return shape, s + + +TEST_CASE = ''' +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_%s(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST %s\\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in%s; + in.data_ = %s; + + Opm::Tensor out%s; + out.data_ = %s; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("%s"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), %s); + } + + return true; +} +''' + + +directory = os.getcwd() +directory1 = "models" +directory2 = "include" + +# path1=os.path.abspath(directory) +if os.path.isdir(directory1): + print(f"{directory1} exists.") +else: + print(f"{directory1} does not exist.") + path1 = os.path.join(directory, directory1) + os.makedirs(path1) + + +if os.path.isdir(directory2): + print(f"{directory2} exists.") +else: + path2 = os.path.join(directory, directory2) + os.makedirs(path2) + + +def output_testcase(model, test_x, test_y, name, eps): + print("Processing %s" % name) + model.compile(loss='mean_squared_error', optimizer='adamax') + model.fit(test_x, test_y, epochs=1, verbose=False) + predict_y = model.predict(test_x).astype('f') + print(model.summary()) + + export_model(model, 'models/test_%s.model' % name) + path = os.path.abspath(f'models/test_{name}.model') + with open('include/test_%s.h' % name, 'w') as f: + x_shape, x_data = c_array(test_x[0]) + y_shape, y_data = c_array(predict_y[0]) + + f.write(TEST_CASE % (name, name, x_shape, x_data, y_shape, y_data, path, eps)) + + + +# scaling 1x1 +data: np.ndarray = np.random.uniform(-500, 500, (5, 1)) +feature_ranges: list[tuple[float, float]] = [(0.0, 1.0), (-3.7, 0.0)] +test_x = np.random.rand(1).astype('f') +test_y = np.random.rand(1).astype('f') +data_min = 10.0 +model = Sequential() +model.add(keras.layers.Input([1])) +# model.add(Flatten()) +# model.add(Flatten()) +model.add(MinMaxScalerLayer(data_min=0.1,feature_range=(0.0, 1.0))) +model.add(Dense(1,activation='tanh')) +model.add(Dense(10,activation='tanh')) +model.add(Dense(10,activation='tanh')) +model.add(MinMaxUnScalerLayer(feature_range=(0.0, 1.0))) +# model.add(Dense(10)) +# model.add(Dense(10)) +# model.add(Dense(10)) +# model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) +# model.add(Flatten()) +# model.add(MinMaxUnScalerLayer()) +# # +# # model.get_layer(model.layers[0].name).adapt(data=data) +# model.get_layer(model.layers[-1].name).adapt(data=data) + +# model.add(Dense(1, input_dim=1)) + +# model: keras.Model = keras.Sequential( +# +# [ +# +# keras.layers.Input([1]), +# +# MinMaxScalerLayer(feature_range=(0.0, 1.0)), +# +# # keras.layers.Dense(1, input_dim=1), +# +# # MinMaxUnScalerLayer(feature_range=(0.0, 1.0)), +# +# ] +# +# ) +output_testcase(model, test_x, test_y, 'scalingdense_1x1', '1e-6') + +# Dense 1x1 +test_x = np.arange(10) +test_y = test_x * 10 + 1 +model = Sequential() +model.add(Dense(1, input_dim=1)) +output_testcase(model, test_x, test_y, 'dense_1x1', '1e-6') + +# Dense 10x1 +test_x = np.random.rand(10, 10).astype('f') +test_y = np.random.rand(10).astype('f') +model = Sequential() +model.add(Dense(1, input_dim=10)) +output_testcase(model, test_x, test_y, 'dense_10x1', '1e-6') + +# Dense 2x2 +test_x = np.random.rand(10, 2).astype('f') +test_y = np.random.rand(10).astype('f') +model = Sequential() +model.add(Dense(2, input_dim=2)) +model.add(Dense(1)) +output_testcase(model, test_x, test_y, 'dense_2x2', '1e-6') + +# Dense 10x10 +test_x = np.random.rand(10, 10).astype('f') +test_y = np.random.rand(10).astype('f') +model = Sequential() +model.add(Dense(10, input_dim=10)) +model.add(Dense(1)) +output_testcase(model, test_x, test_y, 'dense_10x10', '1e-6') + +# Dense 10x10x10 +test_x = np.random.rand(10, 10).astype('f') +test_y = np.random.rand(10, 10).astype('f') +model = Sequential() +model.add(Dense(10, input_dim=10)) +model.add(Dense(10)) +output_testcase(model, test_x, test_y, 'dense_10x10x10', '1e-6') + +# Conv 2x2 +test_x = np.random.rand(10, 2, 2,1).astype('f') +test_y = np.random.rand(10, 1).astype('f') +model = Sequential() +model.add(Conv2D(1,(2, 2), padding='valid', input_shape=(2, 2, 1))) +model.add(Flatten()) +model.add(Dense(1)) +output_testcase(model, test_x, test_y, 'conv_2x2', '1e-6') + +# Conv 3x3 +test_x = np.random.rand(10, 3, 3, 1).astype('f').astype('f') +test_y = np.random.rand(10, 1).astype('f') +model = Sequential([ + Conv2D(1, (3, 3), input_shape=(3, 3, 1)), + Flatten(), + Dense(1) +]) +output_testcase(model, test_x, test_y, 'conv_3x3', '1e-6') + +# Conv 3x3x3 +test_x = np.random.rand(10, 3, 3, 3).astype('f') +test_y = np.random.rand(10, 1).astype('f') +model = Sequential([ + Conv2D(3, (3, 3), input_shape=(3, 3, 3)), + Flatten(), + # BatchNormalization(), + Dense(1) +]) +output_testcase(model, test_x, test_y, 'conv_3x3x3', '1e-6') + +# Activation ELU +test_x = np.random.rand(1, 10).astype('f') +test_y = np.random.rand(1, 1).astype('f') +model = Sequential([ + Dense(10, input_dim=10), + ELU(alpha=0.5), + Dense(1) +]) +output_testcase(model, test_x, test_y, 'elu_10', '1e-6') + +# Activation relu +test_x = np.random.rand(1, 10).astype('f') +test_y = np.random.rand(1, 10).astype('f') +model = Sequential() +model.add(Dense(10, input_dim=10)) +model.add(Activation('relu')) +output_testcase(model, test_x, test_y, 'relu_10', '1e-6') + +# Dense relu +test_x = np.random.rand(1, 10).astype('f') +test_y = np.random.rand(1, 10).astype('f') +model = Sequential() +model.add(Dense(10, input_dim=10, activation='relu')) +model.add(Dense(10, input_dim=10, activation='relu')) +model.add(Dense(10, input_dim=10, activation='relu')) +output_testcase(model, test_x, test_y, 'dense_relu_10', '1e-6') + +# Dense tanh +test_x = np.random.rand(1, 10).astype('f') +test_y = np.random.rand(1, 10).astype('f') +model = Sequential() +model.add(Dense(10, input_dim=10, activation='tanh')) +model.add(Dense(10, input_dim=10, activation='tanh')) +model.add(Dense(10, input_dim=10, activation='tanh')) +output_testcase(model, test_x, test_y, 'dense_tanh_10', '1e-6') + +# Conv softplus +test_x = np.random.rand(10, 2, 2, 1).astype('f') +test_y = np.random.rand(10, 1).astype('f') +model = Sequential([ + Conv2D(1, (2, 2), input_shape=(2, 2, 1), activation='softplus'), + Flatten(), + Dense(1) +]) +output_testcase(model, test_x, test_y, 'conv_softplus_2x2', '1e-6') + +# Conv hardsigmoid +test_x = np.random.rand(10, 2, 2, 1).astype('f') +test_y = np.random.rand(10, 1).astype('f') +model = Sequential([ + Conv2D(1, (2, 2), input_shape=(2, 2, 1), activation='hard_sigmoid'), + Flatten(), + Dense(1) +]) +output_testcase(model, test_x, test_y, 'conv_hard_sigmoid_2x2', '1e-6') + +# Conv sigmoid +test_x = np.random.rand(10, 2, 2, 1).astype('f') +test_y = np.random.rand(10, 1).astype('f') +model = Sequential([ + Conv2D(1, (2, 2), input_shape=(2, 2, 1), activation='sigmoid'), + Flatten(), + Dense(1) +]) +output_testcase(model, test_x, test_y, 'conv_sigmoid_2x2', '1e-6') + +# Maxpooling2D 1x1 +test_x = np.random.rand(10, 10, 10, 1).astype('f') +test_y = np.random.rand(10, 1).astype('f') +model = Sequential([ + MaxPooling2D(pool_size=(1, 1), input_shape=(10, 10, 1)), + Flatten(), + Dense(1) +]) +output_testcase(model, test_x, test_y, 'maxpool2d_1x1', '1e-6') diff --git a/opm/ml/ml_tools/include/test_conv_2x2.h b/opm/ml/ml_tools/include/test_conv_2x2.h new file mode 100644 index 00000000000..18602b770d5 --- /dev/null +++ b/opm/ml/ml_tools/include/test_conv_2x2.h @@ -0,0 +1,43 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_conv_2x2(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST conv_2x2\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{2,2,1}; + in.data_ = {0.750075,0.10270854,0.21013065,0.29597324}; + + Opm::Tensor out{1}; + out.data_ = {0.027571658}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_2x2.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_conv_3x3.h b/opm/ml/ml_tools/include/test_conv_3x3.h new file mode 100644 index 00000000000..338b8471abb --- /dev/null +++ b/opm/ml/ml_tools/include/test_conv_3x3.h @@ -0,0 +1,44 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_conv_3x3(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST conv_3x3\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{3,3,1}; + in.data_ = {0.8302591,0.7126048,0.049354695,0.065839484,0.022077054,0.8151628, +0.8770473,0.93242997,0.5808531}; + + Opm::Tensor out{1}; + out.data_ = {0.1281208}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_3x3.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_conv_3x3x3.h b/opm/ml/ml_tools/include/test_conv_3x3x3.h new file mode 100644 index 00000000000..155e50872a8 --- /dev/null +++ b/opm/ml/ml_tools/include/test_conv_3x3x3.h @@ -0,0 +1,47 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_conv_3x3x3(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST conv_3x3x3\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{3,3,3}; + in.data_ = {0.87271255,0.93225205,0.454738,0.7743667,0.07311473,0.43917352, +0.06562502,0.10534243,0.84919333,0.05485726,0.26453573,0.43184462, +0.31198752,0.3685557,0.33569786,0.5550908,0.30508468,0.5998162, +0.5240912,0.084725335,0.68967754,0.99210244,0.99117345,0.9305709, +0.9118958,0.84186167,0.566753}; + + Opm::Tensor out{1}; + out.data_ = {0.26097965}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_3x3x3.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h new file mode 100644 index 00000000000..a3c1486c83e --- /dev/null +++ b/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h @@ -0,0 +1,43 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_conv_hard_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST conv_hard_sigmoid_2x2\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{2,2,1}; + in.data_ = {0.33098492,0.7765142,0.73701227,0.107884906}; + + Opm::Tensor out{1}; + out.data_ = {-0.8017725}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h new file mode 100644 index 00000000000..a0c026f9c74 --- /dev/null +++ b/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h @@ -0,0 +1,43 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_conv_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST conv_sigmoid_2x2\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{2,2,1}; + in.data_ = {0.57643723,0.7119069,0.902389,0.65012866}; + + Opm::Tensor out{1}; + out.data_ = {-0.42353362}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_conv_softplus_2x2.h b/opm/ml/ml_tools/include/test_conv_softplus_2x2.h new file mode 100644 index 00000000000..278233463b9 --- /dev/null +++ b/opm/ml/ml_tools/include/test_conv_softplus_2x2.h @@ -0,0 +1,43 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_conv_softplus_2x2(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST conv_softplus_2x2\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{2,2,1}; + in.data_ = {0.96513563,0.36131543,0.77126974,0.21065006}; + + Opm::Tensor out{1}; + out.data_ = {-0.33121806}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_softplus_2x2.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_dense_10x1.h b/opm/ml/ml_tools/include/test_dense_10x1.h new file mode 100644 index 00000000000..a7b75f5a30d --- /dev/null +++ b/opm/ml/ml_tools/include/test_dense_10x1.h @@ -0,0 +1,44 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_dense_10x1(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST dense_10x1\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10}; + in.data_ = {0.0659136,0.28923303,0.694333,0.37173527,0.9247947,0.5618971, +0.57161736,0.7481847,0.9059089,0.062005263}; + + Opm::Tensor out{1}; + out.data_ = {0.5485782}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_10x1.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_dense_10x10.h b/opm/ml/ml_tools/include/test_dense_10x10.h new file mode 100644 index 00000000000..04f628fdd65 --- /dev/null +++ b/opm/ml/ml_tools/include/test_dense_10x10.h @@ -0,0 +1,44 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_dense_10x10(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST dense_10x10\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10}; + in.data_ = {0.24637328,0.32497618,0.1574523,0.17820616,0.17318362, +0.59771574,0.4205037,0.0142282825,0.42604983,0.976568}; + + Opm::Tensor out{1}; + out.data_ = {-0.17698397}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_10x10.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_dense_10x10x10.h b/opm/ml/ml_tools/include/test_dense_10x10x10.h new file mode 100644 index 00000000000..7facd125022 --- /dev/null +++ b/opm/ml/ml_tools/include/test_dense_10x10x10.h @@ -0,0 +1,45 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_dense_10x10x10(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST dense_10x10x10\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10}; + in.data_ = {0.8998526,0.42643917,0.2649691,0.101825155,0.4860865,0.35637248, +0.7880747,0.5331231,0.90746176,0.3913051}; + + Opm::Tensor out{10}; + out.data_ = {0.097687565,0.30221617,-0.24571078,-0.051162135,-0.24975275, +-0.3039312,-0.14934357,-0.62535065,-0.34585848,-1.3160709}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_10x10x10.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_dense_1x1.h b/opm/ml/ml_tools/include/test_dense_1x1.h new file mode 100644 index 00000000000..2e369789957 --- /dev/null +++ b/opm/ml/ml_tools/include/test_dense_1x1.h @@ -0,0 +1,43 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_dense_1x1(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST dense_1x1\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{1}; + in.data_ = {0}; + + Opm::Tensor out{1}; + out.data_ = {0.001}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_1x1.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_dense_2x2.h b/opm/ml/ml_tools/include/test_dense_2x2.h new file mode 100644 index 00000000000..8ef29843184 --- /dev/null +++ b/opm/ml/ml_tools/include/test_dense_2x2.h @@ -0,0 +1,43 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_dense_2x2(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST dense_2x2\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{2}; + in.data_ = {0.6887023,0.58510196}; + + Opm::Tensor out{1}; + out.data_ = {0.30864304}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_2x2.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_dense_relu_10.h b/opm/ml/ml_tools/include/test_dense_relu_10.h new file mode 100644 index 00000000000..f1ff6cdeb2e --- /dev/null +++ b/opm/ml/ml_tools/include/test_dense_relu_10.h @@ -0,0 +1,45 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_dense_relu_10(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST dense_relu_10\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10}; + in.data_ = {0.44567293,0.21984123,0.8783762,0.877416,0.6290802,0.5274514, +0.028554708,0.69272816,0.3010707,0.3224137}; + + Opm::Tensor out{10}; + out.data_ = {0.07524448,0.1483022,0.,0.07073106,0.,0., +0.012321308,0.,0.025917793,0.}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_relu_10.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_dense_tanh_10.h b/opm/ml/ml_tools/include/test_dense_tanh_10.h new file mode 100644 index 00000000000..faec85d7145 --- /dev/null +++ b/opm/ml/ml_tools/include/test_dense_tanh_10.h @@ -0,0 +1,45 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_dense_tanh_10(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST dense_tanh_10\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10}; + in.data_ = {0.03345425,0.78990555,0.33485138,0.09934332,0.74528086,0.6406323, +0.78257537,0.17336933,0.06393018,0.94946647}; + + Opm::Tensor out{10}; + out.data_ = {-0.10979327,0.31542704,0.3152341,0.42501545,0.31062323,-0.18132454, +-0.763928,0.15322652,0.73196095,-0.19889684}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_tanh_10.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_elu_10.h b/opm/ml/ml_tools/include/test_elu_10.h new file mode 100644 index 00000000000..6fb641853ea --- /dev/null +++ b/opm/ml/ml_tools/include/test_elu_10.h @@ -0,0 +1,44 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_elu_10(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST elu_10\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10}; + in.data_ = {0.3842556,0.91849715,0.74334174,0.3313295,0.34599218,0.48829415, +0.80283946,0.58847773,0.5926601,0.9469626}; + + Opm::Tensor out{1}; + out.data_ = {0.021793796}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_elu_10.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_maxpool2d_1x1.h b/opm/ml/ml_tools/include/test_maxpool2d_1x1.h new file mode 100644 index 00000000000..f834dffd8a7 --- /dev/null +++ b/opm/ml/ml_tools/include/test_maxpool2d_1x1.h @@ -0,0 +1,59 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_maxpool2d_1x1(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST maxpool2d_1x1\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10,10,1}; + in.data_ = {0.25518134,0.04741953,0.30579203,0.155573,0.49132094,0.07164798, +0.6618191,0.95539516,0.60500616,0.27978984,0.5592694,0.10625745, +0.35216096,0.15352608,0.38916105,0.47961122,0.13570014,0.5139465, +0.60992926,0.48152757,0.45213497,0.74926835,0.893273,0.49284345, +0.13199767,0.40807652,0.32890376,0.92184955,0.8276756,0.4514926, +0.8575906,0.22574344,0.5647829,0.6564582,0.83293825,0.81201965, +0.16786863,0.64626974,0.73370457,0.75692856,0.056844383,0.48827544, +0.4257299,0.6403209,0.556078,0.5105229,0.3147873,0.72197866, +0.25018466,0.25356695,0.6093809,0.5989881,0.2952787,0.7309936, +0.91963696,0.03639153,0.67082775,0.74602616,0.007854396,0.35555983, +0.85999966,0.8637354,0.5419423,0.51870966,0.15975554,0.31114286, +0.2895706,0.6567837,0.49693534,0.8106974,0.3142659,0.004674668, +0.7890345,0.6929022,0.43730104,0.76309645,0.48623887,0.8451051, +0.2559583,0.8858542,0.43520355,0.5545106,0.78928936,0.19655785, +0.9229729,0.6828728,0.77383405,0.98197556,0.8564043,0.25713357, +0.46030727,0.71827936,0.34024438,0.18788093,0.8874286,0.64397246, +0.04353716,0.7736121,0.429076,0.20847954}; + + Opm::Tensor out{1}; + out.data_ = {-0.25252247}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_maxpool2d_1x1.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_relu_10.h b/opm/ml/ml_tools/include/test_relu_10.h new file mode 100644 index 00000000000..f0b0d894d20 --- /dev/null +++ b/opm/ml/ml_tools/include/test_relu_10.h @@ -0,0 +1,45 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_relu_10(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST relu_10\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{10}; + in.data_ = {0.75668657,0.43547645,0.2684515,0.40864667,0.7540064,0.8699675, +0.9615154,0.21117006,0.2840515,0.6931818}; + + Opm::Tensor out{10}; + out.data_ = {0.41057152,0.,0.,0.3421311,1.0349326,1.9920036, +0.,0.,0.,0.}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_relu_10.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/include/test_scalingdense_1x1.h b/opm/ml/ml_tools/include/test_scalingdense_1x1.h new file mode 100644 index 00000000000..64f1c8660e7 --- /dev/null +++ b/opm/ml/ml_tools/include/test_scalingdense_1x1.h @@ -0,0 +1,44 @@ + +#include +#include +namespace fs = std::filesystem; + +using namespace Opm; +template +bool test_scalingdense_1x1(Evaluation* load_time, Evaluation* apply_time) +{ + printf("TEST scalingdense_1x1\n"); + + KASSERT(load_time, "Invalid Evaluation"); + KASSERT(apply_time, "Invalid Evaluation"); + + Opm::Tensor in{1}; + in.data_ = {0.38420224}; + + Opm::Tensor out{10}; + out.data_ = {-0.05173513,0.040830124,-0.031732455,-0.16009168,0.012040144, +-0.07901504,0.08811069,-0.04247553,-0.06113547,-0.1637011}; + + KerasTimer load_timer; + load_timer.Start(); + + KerasModel model; + KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_scalingdense_1x1.model"), "Failed to load model"); + + *load_time = load_timer.Stop(); + + KerasTimer apply_timer; + apply_timer.Start(); + + Opm::Tensor predict = out; + KASSERT(model.Apply(&in, &out), "Failed to apply"); + + *apply_time = apply_timer.Stop(); + + for (int i = 0; i < out.dims_[0]; i++) + { + KASSERT_EQ(out(i), predict(i), 1e-6); + } + + return true; +} diff --git a/opm/ml/ml_tools/kerasify.py b/opm/ml/ml_tools/kerasify.py new file mode 100644 index 00000000000..ac123e2019b --- /dev/null +++ b/opm/ml/ml_tools/kerasify.py @@ -0,0 +1,323 @@ +import numpy as np +import struct + +LAYER_FLATTEN = 1 +LAYER_SCALING = 2 +LAYER_UNSCALING = 3 +LAYER_DENSE = 4 +LAYER_ACTIVATION = 5 +LAYER_MAXPOOLING2D = 6 +LAYER_LSTM = 7 +LAYER_EMBEDDING = 8 +LAYER_ELU = 9 +LAYER_CONV2D = 10 + +ACTIVATION_LINEAR = 1 +ACTIVATION_RELU = 2 +ACTIVATION_SOFTPLUS = 3 +ACTIVATION_SIGMOID = 4 +ACTIVATION_TANH = 5 +ACTIVATION_HARD_SIGMOID = 6 + +def write_scaling(f): + # weights = layer.get_weights()[0] + # biases = layer.get_weights()[1] + + # print(weights) + # activation = layer.get_config()['activation'] + f.write(struct.pack('I', LAYER_SCALING)) + # f.write(struct.pack('I', weights.shape[0])) + # # f.write(struct.pack('I', weights.shape[1])) + # f.write(struct.pack('I', biases.shape[0])) + # + # # weights = weights.flatten() + # # biases = biases.flatten() + # write_floats(f, weights) + # write_floats(f, biases) + # write_activation(activation) + +def write_unscaling(f): + # weights = layer.get_weights()[0] + # biases = layer.get_weights()[1] + + # activation = layer.get_config()['activation'] + f.write(struct.pack('I', LAYER_UNSCALING)) + # f.write(struct.pack('I', weights.shape[0])) + # # f.write(struct.pack('I', weights.shape[1])) + # f.write(struct.pack('I', biases.shape[0])) + # + # # weights = weights.flatten() + # # biases = biases.flatten() + # write_floats(f, weights) + # write_floats(f, biases) + # write_activation(activation) + + +def write_tensor(f, data, dims=1): + """ + Writes tensor as flat array of floats to file in 1024 chunks, + prevents memory explosion writing very large arrays to disk + when calling struct.pack(). + """ + f.write(struct.pack('I', dims)) + + for stride in data.shape[:dims]: + f.write(struct.pack('I', stride)) + + data = data.ravel() + step = 1024 + written = 0 + + for i in np.arange(0, len(data), step): + remaining = min(len(data) - i, step) + written += remaining + f.write(struct.pack(f'={remaining}f', *data[i: i + remaining])) + + assert written == len(data) + + +def write_floats(file, floats): + ''' + Writes floats to file in 1024 chunks.. prevents memory explosion + writing very large arrays to disk when calling struct.pack(). + ''' + step = 1024 + written = 0 + + for i in np.arange(0, len(floats), step): + remaining = min(len(floats) - i, step) + written += remaining + file.write(struct.pack('=%sf' % remaining, *floats[i:i+remaining])) + # file.write(struct.pack(f'={remaining}f', *floats[i: i + remaining])) + + assert written == len(floats) + +def export_model(model, filename): + with open(filename, 'wb') as f: + + def write_activation(activation): + if activation == 'linear': + f.write(struct.pack('I', ACTIVATION_LINEAR)) + elif activation == 'relu': + f.write(struct.pack('I', ACTIVATION_RELU)) + elif activation == 'softplus': + f.write(struct.pack('I', ACTIVATION_SOFTPLUS)) + elif activation == 'tanh': + f.write(struct.pack('I', ACTIVATION_TANH)) + elif activation == 'sigmoid': + f.write(struct.pack('I', ACTIVATION_SIGMOID)) + elif activation == 'hard_sigmoid': + f.write(struct.pack('I', ACTIVATION_HARD_SIGMOID)) + else: + assert False, "Unsupported activation type: %s" % activation + + model_layers = [l for l in model.layers if type(l).__name__ not in ['Dropout']] + num_layers = len(model_layers) + f.write(struct.pack('I', num_layers)) + + for layer in model_layers: + layer_type = type(layer).__name__ + + if layer_type == 'MinMaxScalerLayer': + write_scaling(f) + f.write(struct.pack('f', layer.data_min)) + # write_floats(f, weights) + + + elif layer_type == 'MinMaxUnScalerLayer': + write_unscaling(f) + + elif layer_type == 'Dense': + weights = layer.get_weights()[0] + biases = layer.get_weights()[1] + activation = layer.get_config()['activation'] + + f.write(struct.pack('I', LAYER_DENSE)) + f.write(struct.pack('I', weights.shape[0])) + f.write(struct.pack('I', weights.shape[1])) + f.write(struct.pack('I', biases.shape[0])) + + weights = weights.flatten() + biases = biases.flatten() + + write_floats(f, weights) + write_floats(f, biases) + + write_activation(activation) + + elif layer_type == 'Conv2D': + assert layer.padding == 'valid', "Only border_mode=valid is implemented" + + + # shape: (outputs, rows, cols, depth) + weights = layer.get_weights()[0].transpose(3, 0, 1, 2) + # biases = layer.get_weights()[1] + # activation = layer.get_config()['activation'] + + # weights = layer.get_weights()[0] + biases = layer.get_weights()[1] + activation = layer.get_config()['activation'] + + # weights = weights.flatten() + # biases = biases.flatten() + # write_tensor(f, weights, 4) + # write_tensor(f, biases) + + # # + # weights = layer.get_weights()[0] + # biases = layer.get_weights()[1] + # activation = layer.get_config()['activation'] + # + # The kernel is accessed in reverse order. To simplify the C side we'll + # flip the weight matrix for each kernel. + # weights = weights[:,:,::-1,::-1] + + f.write(struct.pack('I', LAYER_CONV2D)) + f.write(struct.pack('I', weights.shape[0])) + f.write(struct.pack('I', weights.shape[1])) + f.write(struct.pack('I', weights.shape[2])) + f.write(struct.pack('I', weights.shape[3])) + f.write(struct.pack('I', biases.shape[0])) + + weights = weights.flatten() + biases = biases.flatten() + + write_floats(f, weights) + write_floats(f, biases) + + write_activation(activation) + + elif layer_type == 'Flatten': + f.write(struct.pack('I', LAYER_FLATTEN)) + + elif layer_type == 'ELU': + f.write(struct.pack('I', LAYER_ELU)) + f.write(struct.pack('f', layer.alpha)) + + elif layer_type == 'Activation': + activation = layer.get_config()['activation'] + + f.write(struct.pack('I', LAYER_ACTIVATION)) + write_activation(activation) + + elif layer_type == 'MaxPooling2D': + assert layer.padding == 'valid', "Only border_mode=valid is implemented" + + pool_size = layer.get_config()['pool_size'] + f.write(struct.pack('I', LAYER_MAXPOOLING2D)) + f.write(struct.pack('I', pool_size[0])) + f.write(struct.pack('I', pool_size[1])) + + + elif layer_type == 'LSTM': + + inner_activation = layer.get_config()['recurrent_activation'] + activation = layer.get_config()['activation'] + return_sequences = int(layer.get_config()['return_sequences']) + + weights = layer.get_weights() + units = layer.units + + kernel, rkernel, bias = ([x[i: i+units] for i in range(0, 4*units, units)] + for x in (weights[0].transpose(), + weights[1].transpose(), + weights[2])) + bias = [x.reshape(1, -1) for x in bias] + for tensors in zip(kernel, rkernel, bias): + for tensor in tensors: + write_tensor(f, tensor, 2) + + # export_activation(inner_activation, f) + # export_activation(activation, f) + # f.write(struct.pack('I', return_sequences)) + + + # inner_activation = layer.get_config()['recurrent_activation'] + # activation = layer.get_config()['activation'] + # return_sequences = int(layer.get_config()['return_sequences']) + # + # weights = layer.get_weights() + # W_i = weights[0] + # U_i = weights[1] + # b_i = weights[2] + # + # W_c = weights[3] + # U_c = weights[4] + # b_c = weights[5] + # + # W_f = weights[6] + # U_f = weights[7] + # b_f = weights[8] + # + # W_o = weights[9] + # U_o = weights[10] + # b_o = weights[11] + # + # f.write(struct.pack('I', LAYER_LSTM)) + # f.write(struct.pack('I', W_i.shape[0])) + # f.write(struct.pack('I', W_i.shape[1])) + # f.write(struct.pack('I', U_i.shape[0])) + # f.write(struct.pack('I', U_i.shape[1])) + # f.write(struct.pack('I', b_i.shape[0])) + # + # f.write(struct.pack('I', W_f.shape[0])) + # f.write(struct.pack('I', W_f.shape[1])) + # f.write(struct.pack('I', U_f.shape[0])) + # f.write(struct.pack('I', U_f.shape[1])) + # f.write(struct.pack('I', b_f.shape[0])) + # + # f.write(struct.pack('I', W_c.shape[0])) + # f.write(struct.pack('I', W_c.shape[1])) + # f.write(struct.pack('I', U_c.shape[0])) + # f.write(struct.pack('I', U_c.shape[1])) + # f.write(struct.pack('I', b_c.shape[0])) + # + # f.write(struct.pack('I', W_o.shape[0])) + # f.write(struct.pack('I', W_o.shape[1])) + # f.write(struct.pack('I', U_o.shape[0])) + # f.write(struct.pack('I', U_o.shape[1])) + # f.write(struct.pack('I', b_o.shape[0])) + # + # W_i = W_i.flatten() + # U_i = U_i.flatten() + # b_i = b_i.flatten() + # W_f = W_f.flatten() + # U_f = U_f.flatten() + # b_f = b_f.flatten() + # W_c = W_c.flatten() + # U_c = U_c.flatten() + # b_c = b_c.flatten() + # W_o = W_o.flatten() + # U_o = U_o.flatten() + # b_o = b_o.flatten() + # + # write_floats(f, W_i) + # write_floats(f, U_i) + # write_floats(f, b_i) + # write_floats(f, W_f) + # write_floats(f, U_f) + # write_floats(f, b_f) + # write_floats(f, W_c) + # write_floats(f, U_c) + # write_floats(f, b_c) + # write_floats(f, W_o) + # write_floats(f, U_o) + # write_floats(f, b_o) + + write_activation(inner_activation) + write_activation(activation) + f.write(struct.pack('I', return_sequences)) + + elif layer_type == 'Embedding': + weights = layer.get_weights()[0] + + f.write(struct.pack('I', LAYER_EMBEDDING)) + f.write(struct.pack('I', weights.shape[0])) + f.write(struct.pack('I', weights.shape[1])) + + weights = weights.flatten() + + write_floats(f, weights) + + else: + assert False, "Unsupported layer type: %s" % layer_type diff --git a/opm/ml/ml_tools/make_model_BCkrn.py b/opm/ml/ml_tools/make_model_BCkrn.py new file mode 100644 index 00000000000..a66ecb62f53 --- /dev/null +++ b/opm/ml/ml_tools/make_model_BCkrn.py @@ -0,0 +1,104 @@ +from sklearn.preprocessing import MinMaxScaler +from sklearn.metrics import mean_squared_error +from keras.models import Sequential +from keras.layers import Dense +from numpy import asarray +from matplotlib import pyplot +import numpy as np +import pandas as pd + + +#def computeBCKrw(satW, lambdaparam): +# kr = pow(satW, 2.0/lambdaparam + 3.0) +# return kr + +def computeBCKrn(satW, lambdaparam): + Sn = 1.0 - satW; + exponent = 2.0/lambdaparam + 1.0 + kr = Sn*Sn*(1. - pow(satW, exponent)) + return kr + + +# sw = np.linspace(0, 1, num=1001, endpoint=True) +sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) + + +lambdaparam = 2 + +#BCKrw = computeBCKrw(sw, lambdaparam) +BCKrn = computeBCKrn(sw, lambdaparam) + + +# define the dataset +x = sw +y = np.array([BCKrn]) + +print(x.min(), x.max(), y.min(), y.max()) +# reshape arrays into into rows and cols +x = x.reshape((len(x), 1)) +y = y.reshape((10001, 1)) +# separately scale the input and output variables +scale_x = MinMaxScaler() +x = scale_x.fit_transform(x) +scale_y = MinMaxScaler() +y = scale_y.fit_transform(y) +print(x.min(), x.max(), y.min(), y.max()) + +# design the neural network model +model = Sequential() +model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(1)) + +# define the loss function and optimization algorithm +model.compile(loss='mse', optimizer='adam') + +# ft the model on the training dataset +model.fit(x, y, epochs=1000, batch_size=100, verbose=0) + +# make predictions for the input data +yhat = model.predict(x) +# inverse transforms +x_plot = scale_x.inverse_transform(x) +y_plot = scale_y.inverse_transform(y) +yhat_plot = scale_y.inverse_transform(yhat) +# report model error +print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) +print(yhat_plot) +print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) + + +df = pd.DataFrame({'Id': x_plot[:, 0], 'Amount': yhat_plot[:, 0].astype(float)}) + +def f(a): + a = df.loc[df['Id'] == a, 'Amount'] + #for no match + if a.empty: + return 'no match' + #for multiple match + elif len(a) > 1: + return a + else: + #for match one value only + return a.item() + +# plot x vs y +pyplot.plot(x_plot,y_plot, label='Actual') +# plot x vs yhat +pyplot.plot(x_plot,yhat_plot, label='Predicted') +pyplot.title('Input (x) versus Output (y)') +pyplot.xlabel('Input Variable (x)') +pyplot.ylabel('Output Variable (y)') +pyplot.legend() +pyplot.savefig('filename.png', dpi=1200) +pyplot.show() + +#save model +from kerasify import export_model +export_model(model, 'example.modelBCkrn') diff --git a/opm/ml/ml_tools/make_model_BCkrw.py b/opm/ml/ml_tools/make_model_BCkrw.py new file mode 100644 index 00000000000..59627c3e329 --- /dev/null +++ b/opm/ml/ml_tools/make_model_BCkrw.py @@ -0,0 +1,103 @@ +from sklearn.preprocessing import MinMaxScaler +from sklearn.metrics import mean_squared_error +from keras.models import Sequential +from keras.layers import Dense +from numpy import asarray +from matplotlib import pyplot +import numpy as np +import pandas as pd + + +def computeBCKrw(satW, lambdaparam): + kr = pow(satW, 2.0/lambdaparam + 3.0) + return kr + +#def computeBCKrn(satW, lambdaparam): +# Sn = 1.0 - satW; +# exponent = 2.0/lambdaparam + 1.0 +# kr = Sn*Sn*(1. - pow(satW, exponent)) +# return kr + + +# sw = np.linspace(0, 1, num=1001, endpoint=True) +sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) + + +lambdaparam = 2 + +BCKrw = computeBCKrw(sw, lambdaparam) +#BCKrn = computeBCKrn(sw, lambdaparam) + + +# define the dataset +x = sw +y = np.array([BCKrw]) + +print(x.min(), x.max(), y.min(), y.max()) +# reshape arrays into into rows and cols +x = x.reshape((len(x), 1)) +y = y.reshape((10001, 1)) +# separately scale the input and output variables +scale_x = MinMaxScaler() +x = scale_x.fit_transform(x) +scale_y = MinMaxScaler() +y = scale_y.fit_transform(y) +print(x.min(), x.max(), y.min(), y.max()) + +# design the neural network model +model = Sequential() +model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(1)) + +# define the loss function and optimization algorithm +model.compile(loss='mse', optimizer='adam') +# ft the model on the training dataset +model.fit(x, y, epochs=1000, batch_size=100, verbose=0) +# make predictions for the input data +yhat = model.predict(x) +# inverse transforms +x_plot = scale_x.inverse_transform(x) +y_plot = scale_y.inverse_transform(y) +yhat_plot = scale_y.inverse_transform(yhat) +# report model error +print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) +print(yhat_plot) +print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) + + +df = pd.DataFrame({'Id': x_plot[:, 0], 'Amount': yhat_plot[:, 0].astype(float)}) + + +def f(a): + a = df.loc[df['Id'] == a, 'Amount'] + #for no match + if a.empty: + return 'no match' + #for multiple match + elif len(a) > 1: + return a + else: + #for match one value only + return a.item() + +# plot x vs y +pyplot.plot(x_plot,y_plot, label='Actual') +# plot x vs yhat +pyplot.plot(x_plot,yhat_plot, label='Predicted') +pyplot.title('Input (x) versus Output (y)') +pyplot.xlabel('Input Variable (x)') +pyplot.ylabel('Output Variable (y)') +pyplot.legend() +pyplot.savefig('filename.png', dpi=1200) +pyplot.show() + +#save model +from kerasify import export_model +export_model(model, 'example.modelBCkrw') diff --git a/opm/ml/ml_tools/make_model_VGkrn.py b/opm/ml/ml_tools/make_model_VGkrn.py new file mode 100644 index 00000000000..bb26731a6d9 --- /dev/null +++ b/opm/ml/ml_tools/make_model_VGkrn.py @@ -0,0 +1,90 @@ +from sklearn.preprocessing import MinMaxScaler +from sklearn.metrics import mean_squared_error +from keras.models import Sequential +from keras.layers import Dense +from numpy import asarray +from matplotlib import pyplot +import numpy as np +import pandas as pd + + +#def computeVGKrw(satW, lambdaparam): +# kr = pow(satW, 2.0/lambdaparam + 3.0) +# return kr + +def computeVGKrn(satW, lambdaparam): + Sn = 1.0 - satW; + kr = pow(1 - satW, 1.0/3) * pow(1 - pow(satW, 1/lambdaparam), 2*lambdaparam); + return kr + + + + +# sw = np.linspace(0, 1, num=1001, endpoint=True) +sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) + + +lambdaparam = 0.78 + +#VGKrw = computeVGKrw(sw, lambdaparam) +VGKrn = computeVGKrn(sw, lambdaparam) + + +# define the dataset +x = sw +y = np.array([VGKrn]) + +print(x.min(), x.max(), y.min(), y.max()) +# reshape arrays into into rows and cols +x = x.reshape((len(x), 1)) +y = y.reshape((10001, 1)) +# separately scale the input and output variables +scale_x = MinMaxScaler() +x = scale_x.fit_transform(x) +scale_y = MinMaxScaler() +y = scale_y.fit_transform(y) +print(x.min(), x.max(), y.min(), y.max()) + +# design the neural network model +model = Sequential() +model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(1)) + +# define the loss function and optimization algorithm +model.compile(loss='mse', optimizer='adam') +# ft the model on the training dataset +model.fit(x, y, epochs=1000, batch_size=100, verbose=0) +# make predictions for the input data +yhat = model.predict(x) +# inverse transforms +x_plot = scale_x.inverse_transform(x) +y_plot = scale_y.inverse_transform(y) +yhat_plot = scale_y.inverse_transform(yhat) +# report model error +print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) +print(yhat_plot) +print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) + + +# plot x vs y +pyplot.plot(x_plot,y_plot, label='Actual') +# plot x vs yhat +pyplot.plot(x_plot,yhat_plot, label='Predicted') +pyplot.title('Input (x) versus Output (y)') +pyplot.xlabel('Input Variable (x)') +pyplot.ylabel('Output Variable (y)') +pyplot.legend() +pyplot.savefig('filenamekrn.png', dpi=1200) +pyplot.show() +#save model +from kerasify import export_model +# lazy hack to be changed + +export_model(model, 'example.modelVGkrn') diff --git a/opm/ml/ml_tools/make_model_VGkrw.py b/opm/ml/ml_tools/make_model_VGkrw.py new file mode 100644 index 00000000000..53888a7bb15 --- /dev/null +++ b/opm/ml/ml_tools/make_model_VGkrw.py @@ -0,0 +1,87 @@ +from sklearn.preprocessing import MinMaxScaler +from sklearn.metrics import mean_squared_error +from keras.models import Sequential +from keras.layers import Dense +from numpy import asarray +from matplotlib import pyplot +import numpy as np +import pandas as pd + + +def computeVGKrw(satW, lambdaparam): + r = 1.0 - pow(1.0 - pow(satW, 1/lambdaparam), lambdaparam); + return pow(satW,0.5)*r*r; + +#def computeVGKrn(satW, lambdaparam): +# Sn = 1.0 - satW; +# exponent = 2.0/lambdaparam + 1.0 +# kr = Sn*Sn*(1. - pow(satW, exponent)) +# return kr + + +# sw = np.linspace(0, 1, num=1001, endpoint=True) +sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) + + +lambdaparam = 0.78 + +VGKrw = computeVGKrw(sw, lambdaparam) +#VGKrn = computeVGKrn(sw, lambdaparam) + + +# define the dataset +x = sw +y = np.array([VGKrw]) + +print(x.min(), x.max(), y.min(), y.max()) +# reshape arrays into into rows and cols +x = x.reshape((len(x), 1)) +y = y.reshape((10001, 1)) +# separately scale the input and output variables +scale_x = MinMaxScaler() +x = scale_x.fit_transform(x) +scale_y = MinMaxScaler() +y = scale_y.fit_transform(y) +print(x.min(), x.max(), y.min(), y.max()) + +# design the neural network model +model = Sequential() +model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) +# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) +model.add(Dense(1)) + +# define the loss function and optimization algorithm +model.compile(loss='mse', optimizer='adam') +# ft the model on the training dataset +model.fit(x, y, epochs=1000, batch_size=100, verbose=0) +# make predictions for the input data +yhat = model.predict(x) +# inverse transforms +x_plot = scale_x.inverse_transform(x) +y_plot = scale_y.inverse_transform(y) +yhat_plot = scale_y.inverse_transform(yhat) +# report model error +print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) +print(yhat_plot) +print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) + + +# plot x vs y +pyplot.plot(x_plot,y_plot, label='Actual') +# plot x vs yhat +pyplot.plot(x_plot,yhat_plot, label='Predicted') +pyplot.title('Input (x) versus Output (y)') +pyplot.xlabel('Input Variable (x)') +pyplot.ylabel('Output Variable (y)') +pyplot.legend() +pyplot.savefig('filenamekrw.png', dpi=1200) +pyplot.show() +#save model +from kerasify import export_model +export_model(model, 'example.modelVGkrw') diff --git a/opm/ml/ml_tools/model_with_scaler_layers.opm b/opm/ml/ml_tools/model_with_scaler_layers.opm new file mode 100644 index 0000000000000000000000000000000000000000..86755ff952fcedc81881e63c7d6c505441c00012 GIT binary patch literal 24 VcmZQ%U|?VZVn!$iQb5pP4*&tP0L1_R literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_conv_2x2.model b/opm/ml/ml_tools/models/test_conv_2x2.model new file mode 100644 index 0000000000000000000000000000000000000000..58ff65d4c8d870671c14b5b7998f7087ad02c7bb GIT binary patch literal 84 zcmZQ(U|`?^Vn!flf?^OGgggE|w2QeCxc|t^n|5klmiu#rnyp}REKoHt{^=93c6m^F E01)^M#Q*>R literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_conv_3x3.model b/opm/ml/ml_tools/models/test_conv_3x3.model new file mode 100644 index 0000000000000000000000000000000000000000..bbfd9fb546797a5a6514b0146f5ebfaa3ba3bd5b GIT binary patch literal 104 zcmZQ(U|`?^Vn!flhGGyKgrjcXwG&L0-nUyXZ{PK%ef#cjQs3vE)oOE+_0qnRZ4tZe Z9zV6q6Kb}Csb_)egYj>CY_f;R0|3Tb7@7b8 literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_conv_3x3x3.model b/opm/ml/ml_tools/models/test_conv_3x3x3.model new file mode 100644 index 0000000000000000000000000000000000000000..a691f539562411acf1f4dab5f02c1413e2cd3c69 GIT binary patch literal 408 zcmZQ(U|`?^VrDG3tN4=5{i4Zsx6Qll>J?Vn9Wt0}>p8K<&e~y)-D_9Rz2fg@*iAJx z+GqVVa-T0(ft@JtiM`s_OZVx{n7z+uwZxt*58)w*wN;26gEqZTz!MSW-?237N z*Say-UOU{dr(FG?tu$lQzVg$HY`4AD-M2b_vfb+M*0#}3K6bCy`0Qis7TKpOFTD5v zTt_?ZZljT>~Ek9Oj_cLbUzHir;*tXp;-uIiK z&en^!ZST_;bM1DsbMEu$nYgd(&<)%A)#Y~a_wDSISU>EoRPNk2@5WDC`^AEGon9;V zaqsB03+1=m`*5%EzB21ed$&!Pu5 I*$Tu50HwwZ6aWAK literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model b/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model new file mode 100644 index 0000000000000000000000000000000000000000..061f71d224d90e5129d17017648c8ed3f998fb42 GIT binary patch literal 84 zcmZQ(U|`?^Vn!flf?^OGgddeF*+0^Lx3}b8yPe6}Np?9x&AV8jaxfaEcCoe6{(PZk HD-a(5_4o}G literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_conv_softplus_2x2.model b/opm/ml/ml_tools/models/test_conv_softplus_2x2.model new file mode 100644 index 0000000000000000000000000000000000000000..e68fe91c0162ccbea684d9808e55421ec11a741d GIT binary patch literal 84 zcmZQ(U|`?^Vn!flf?^OGgoPVq_y1fUvEO8-?taUvoPBvh&AXVPax739ruO^Ov-^Sa HRv=iY<1{wsLzv=}xwN5XiPKIHhc#)YeWL-%BC3 zD_yhpnSFU~+izC4Pm*c+o@0^c_V#sf?_YOq*}h!~OYQ6grrBMd8EUtD!|gq;VJ!AL zpC#-w{v@<#b4v3*-9}qGOVy@*3Vdt!&3m$HU+?sH`_9Tb*}CkQZ8!I{(Z1R1S?n8c zDD1oU^84O5%?tJ|ia2FEd#9qEEc5w&T&HL4<7IxgFCt>yKEYg8yEh3>_kB>mWM{a& zW8baC&-d*5bYP#6&n7#$ya#q$3bxtJdepk_&4JB!lP>(Vn^4KT|0XAg{bx?*J%|1* zvfDnF*SIzpS<0(rro=D6rSG4yT{%}lXb&%PT1d+qksHrYO25Vdb_Y_9Err)TX# zQ<(M#%KX}=*8AD+z=LAD*35Y}IYQ05@{n+@P_q>j?*htM`2poJfHWggT!PpjJXs;h v&TW#l{fSgf`v@s9`!I%U`@GDr?#p6lv0v_6x9|Ae<2J`1u}+W(3}zT^=u-)zB{cn!|km1Ny7 z77{*gf;(0V$HOXUOQzVP=3pW3T_u_2`)I3S5d8^SqRS?7&e=&e-o*kHQ*{5VdYG4tQ`58%{^W_8kskMl;EpY$mnw$xUL=*SU- zC!Rp@U<`^{-Pk4XROcMMMCrBN$VvGD2d|5TGTkg$HwJT)^9?NDc#k@qPS~Cr!{+ca zOf$0wo~c&S=UrvLymAhmQ@vF0I*TTEsGukg5u!ec!!3)SUer~wd*w;2{fS)Y+qWU} z$!oO1f14l9QlZ6CgVAn|e50G_z_M!keZN(8SW=FjwNYf8tfZ@z$#gVv7{^aHP*FsM za!*8svv6^D{=3R|0=JUI+wQ-J%&>|>K5Xz#lJlaQiozRdf*rv?mP9Bpr=yH@(9P$Z*k{=a zm-G%+_l(e>?jY6ol=8k_JKJncMDB$@C~b5(O5c|V&*nUh_4<>1uIfJRl^C#N_Gd&N zuA(7}RLDpcaf-|?{=vXJc^f@+aXJ>Ab5?wxoeB5#2;3PjAjLH^t@}WRK82QYTF#R= zWJq1xp(j6IPcN(-qb<>WIP`iyrLCJ|qp8PmUK9Aw%4vEj%Yh>%4uh(6_C}u$HCTm- z-U_&uZ^5m|hkR}IJn6m+qNavAq_{&lvGD=i6O@r5<&JZ4o!#-};AiJxZ?EKC8#z|A%7Z^;tFeA43_Iu)wfV~En>DS} m_OghVE%_R+WsA980jIYX{Q{=Sfn+a literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_dense_relu_10.model b/opm/ml/ml_tools/models/test_dense_relu_10.model new file mode 100644 index 0000000000000000000000000000000000000000..9563cb5288cf6c3ac61a7573785f809b37e4ffd8 GIT binary patch literal 1384 zcmZwGdrXsO6bA4jlp+u;iYTsjC@Li&iq{Ezr(`fN8#BmoC=$UtL#MbIL}#Gbbt#Bi zPz0oEQK3j7P^47o_nr?G+=AjNFc1~3AlNA=sKt8SN=6p5>?BXlllT1j%WKVIv1}}{ z|0sU3M~IlKBNKS(RFJa{y~AvU6=`gYYrTUbAz}D-HoF#&lCl6Rkm2A{|Qf(?SNz1!=z#lTe#_q z7f3Jbra!OMK%*~*DM-6PX@~VVGJXQWTx+JGe=)6F?13(GZ;<;vdYa5|i*@+?jI+C;P3@)gt$628g5O?20?r|xwa=UaQK23AURdg(^g0n&P z%z@*-qxr!W2p4gH_bM2MnkPd<3!7<Qo#iB+Qx#{m9LG%yZOt)G@(w+i2-Ami>R0IlJ_jvDZqt z+}{hL>z`0dJbs0QqHl42VH;&$xewiPi(r0I7gj}ciCOCd@0`wqpdk_U-W=h@@UKz8 zErW*{CX5-X2lp&CigXt!kw_lMVteWmrV3!-k37gSEdp6sEoIo;6_|_z_=_L`b7%a9 zl{tqo#WowPsfhANQIwmcH`rb+m-`WAITOWZmJ{spg zswOT406g;wNb!D1Ue;L&Z!XzEX|8!v9?65K{`4-&Uvxr4Y6(?-|1}zn3n`ar%V9`< zl2Z8H!&U=>Rb@`3MAZ+pZV^oDt^;wC5&5n(7|PaB?W$JD56*$Y*LK1aqD}b0^ag65 zW#jFAU09%X1CjAuK-VT)P`K@+${k(c{TVeW-D3kk+_|L_eDV?+du@eNcGV$-nJ~5V zJo@ITP*$RZtUqNany#cnbqyfOt<`P6_5@O^t7)I5&E%_?LwK=105@Ble8)U3hX4M@ M@5XxE*dDd~8^0uevH$=8 literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_dense_tanh_10.model b/opm/ml/ml_tools/models/test_dense_tanh_10.model new file mode 100644 index 0000000000000000000000000000000000000000..82a4d5788f9023508a91e55248209573bfa84834 GIT binary patch literal 1384 zcmZvcYc!O37{Hk@u4%^RSVqFo}`slsjTd*Y1~req*TYU$)(vgrKvc} z;E)nYA#A0F_j$F-TDmxdGsx8F6d-<>*`tUoy^E_XF=XvI6X=&-O82*od zb>D)ut^p;tuZ5N_2f8l86_@xVy5@iDvXI*ii)R3XhU;w zf){`uUvR0V9X242F`zUI1Du~*A=33VzH93Nv8;xKx9Kp$A2tzQ=}Ii@=|id20nB`p zL7s$9&_UZyD$BD@p>@+R7;nx%64i@SCdQ1RrjqCzHRF|49I7HqkFs-#AUU#5bjq8i zkM_sVA+{M*ejVTvd*?GmpVsZw7~cOopjA5elLo;aJ&Gy6co5Y;P|nr@wK4%C)+9 zqTv?wrD}-p_;vcS`Y!Di3O}9!7VL3jK;U zqIou#DjCSauIuf1+b$jEnWw?!OD{2bQUEt=xXitMzXR7a104DDB?s1_x`^_#~q zB6t?1JNDB#^8syRQqjwi#_!uW)cyPJpvVlsg%)W<_mUH6jl^PbV;A{hT?#t4w83d{ z13JcR#zj%NP#-^7v*U&qW9%L$iV*r>-o-{tU7UzJ<=wE{TZ_`O z8p~=Y;p}7zG;OiKC<`NI^j_pOTTrdnv+RouG%RU8OvOcx7y#s}*B{hv3N>E@R!DZoU)Sp$s zLFW?SWDa78l>+a6LStCa02rBQV_+Df)8gf{A?FM8)uleEga0c4XBY9z3}X@`Fa%CK}csvx!M%c z+LG+WiWW+YIo-YII+mbo-PYI?vkHeR$P$-lVY5&pm zwgGLedfKr#4oBnxb1@~sm*)9_$4)4m?J%!X2%Fd6#)WPhu6x6XSid4TFw57u{nRw6 z77WzQCCxz;mX1r|8DXqI(oK zT8Q?HFnwFHsimufUoC1d_GlTa*^3H|gf(4p!YAC07jcnvykW4m@K%iEo%={^zJ&X(_Jz&CpqCmr2z8(~3|1xur-QswJdh w|8^>CGIw8kQQo6suX#pjV}>3-JPb2x{(zpwSvd4XZ2j?z^^r!`{oEcYH z=_$1L_L(%h%)rZgHbg$Od{;5uc9YL@TUSv9yGueBZQI=M+8z}zwR`WVvX7}ZdEc8W zSN2Z*k+zqs^o8x^i~`&357*hGYx~+A|Y2eJ2&; z?4q7@+InBIwwrFGYj?S})b^hLDO>(0x^|PT1nt<{9PBE&WbM96%k0avj59$B|t+P?RDXvMzEHs!Y6f#J5iai8|8ZV|U*eOkG9b*B2hS?kX4^)i#% z_w+fJop|;to7sn4_bpL(*yp=i(az!Lti8|tcG$+IJM7aedAG+aVCvquytlT}d`@;n zZV&c4bT8Yh#Q$<{+OD6rp<4|09*ADI_b!vCo!-lHwl!Ic_P*buzVEejgx$t%(RL4l i1@~>T?zf$K#b__LftuZVGroQEB~13^2{l`R;tK%fdc%MK literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_relu_10.model b/opm/ml/ml_tools/models/test_relu_10.model new file mode 100644 index 0000000000000000000000000000000000000000..0115b3923653b5bcf0cec57548670ac73c879368 GIT binary patch literal 472 zcmZQ#U|?VYVlE_Xy4P=C#JL>1nW3-ueeyeD_uGQY-v2*?eTznpU2Ns6eJ6gt*lTsP zecvawUc0D-wtb6kS?zo7`+aZyjlz9hTld;2H0Il_6I^1)GAYyUPV*l--aV)H87=&> z@1o+veKluX_bpBf-uum?*LKA*hkaklj_zH+Cu3`6_IBU22NUcx9x>TV9hz--v@+Ii z#_|TcwQ>Bm4jVf5C9zzy6L6hno8y1hPWVolt<2}regBku_w}T&+h;AGZr9ElW@pZK zecy+e7q&;lIrlB|G~c)B{tG*Y^<{Porg_<|n%TE+-t+Hvi{`$!ONqH)*W>HP~52f3YcJ{%*HTo^8L42HSpyH)Xp%SDoCqRCvBk z;eob&3rv*lj=8njolVo<=bR#9w_)>j+rDkJ`)uNs?Yfg$_CK8bbKixo-L@a9588dI zyka*sR(c=X`}cMaPRrXee3iBSv*yjd=}Is6B`j&%=b&l4r!wx%zL%52?A#}c*ztug zv)dIn$xdwBHoFhoJ8Ts;_w36MYPJGK4;Ul^*_lGkyK;aSCI+J!fecn4W&&aW*LBYT literal 0 HcmV?d00001 diff --git a/opm/ml/ml_tools/models/test_scalingdense_1x1.model b/opm/ml/ml_tools/models/test_scalingdense_1x1.model new file mode 100644 index 0000000000000000000000000000000000000000..621a21efa0fb1b2cea661f1277b3ccc1e2110f2d GIT binary patch literal 604 zcmYk3Ur1A77{)hiF_w)SxdewXSQl0j1(FT-o`H;}n029D#4-t+OOH`GNU{;zGzuyu z8^)q-Z62qwuKcqc=e$RPwMDXA!*3v#!K?U32kqAhO{&hspsFoUgWTGM=8K=|Zs;4D2rkh_c6k%zzV0TrgTPxrFj z^C=`{_7K+*y2SNxUVV=9rvF*0$gXbZvQF-v|0Cbe>&6Qjq)!Uik{LgeRu5Wl*zvR8 zjIE917!`}zePmWMI-O)qy0QLC^6*q#Qbk>C4vB#8cin4k~614~3id{mJT zT|W%z3niMqhB=(w9|P)+o4GnT&HOy00Ow4gI@kIgD#Bq*Clz?`@>gu5R9NSI22*=X z^m*PrHfNq-m%+IfPM#4Ggh4bhP+zbwa>0$}&s@ZZpA*i+Pn0vW&}wT|p~$ zFJGkB{BNP$VngMv)5vVrpmeDQ3gvM$P?Nyi9n)yv7Z6F`PL??D#n float: + r"""Compute the well productivity index (adjusted for density and viscosity) from the + Peaceman well model. + + .. math:: + WI\cdot\frac{\mu}{\rho} = \frac{2\pi hk}{\ln (r_e/r_w)} + + Parameters: + h: Thickness of the well block. + k: Permeability. + r_e: Equivalent well-block radius. + r_w: Wellbore radius. + + Returns: + :math:`WI\cdot\frac{\mu}{\rho}` + + """ + WI = (2 * math.pi * h * k) / (math.log(r_e / r_w)) + return WI + + +computePeaceman_np = np.vectorize(computePeaceman) + +logger.info("Prepare dataset") + +# scale h +h_plot = np.linspace(1, 20, 20) +h3 = 6.096 +k3 = 9.86923e-14 +#h_plot = np.array([h3]) +scale_h = MinMaxScaler() +# h = scale_h.fit_transform(h_plot.reshape(-1, 1)).squeeze(axis=0) +h = scale_h.fit_transform(h_plot.reshape(-1, 1)).squeeze() +#param_h = scale_h.get_params() +#print(scale_h.data_max_) +# scale k +k_plot = np.linspace(1e-13, 1e-11, 20) +#k_plot = np.array([k3]) +scale_k = MinMaxScaler() +k = scale_k.fit_transform(k_plot.reshape(-1, 1)).squeeze() +#param_k = scale_k.get_params() +#print(param_k) +# # scale r_e +# r_e_plot = np.logspace(math.log(10), math.log(400), 300) +r_e_plot = np.linspace(10, 300, 600) +#scale_r_e = MinMaxScaler((0.02, 0.5)) +scale_r_e = MinMaxScaler() +r_e = scale_r_e.fit_transform(r_e_plot.reshape(-1, 1)).squeeze() +#param_r_e = scale_r_e.get_params() +r_w = np.array([0.0762]) +h_v, k_v, r_e_v, r_w_v = np.meshgrid(h, k, r_e, r_w) +h_plot_v, k_plot_v, r_e_plot_v, r_w_v = np.meshgrid(h_plot, k_plot, r_e_plot, r_w) + +x = np.stack([h_v.flatten(), k_v.flatten(), r_e_v.flatten(), r_w_v.flatten()], axis=-1) + +y = computePeaceman_np( + h_plot_v.flatten()[..., None], + k_plot_v.flatten()[..., None], + r_e_plot_v.flatten()[..., None], + r_w_v.flatten()[..., None], +) +scale_y = MinMaxScaler() +y_scaled = scale_y.fit_transform(y) + +logger.info("Done") + +# Write scaling info to file +with open("scales.csv", "w", newline="") as csvfile: + writer = csv.DictWriter(csvfile, fieldnames=["variable", "min", "max"]) + writer.writeheader() + writer.writerow( + {"variable": "h", "min": f"{h_plot.min()}", "max": f"{h_plot.max()}"} + ) + writer.writerow( + {"variable": "k", "min": f"{k_plot.min()}", "max": f"{k_plot.max()}"} + ) + writer.writerow( + {"variable": "r_e", "min": f"{r_e_plot.min()}", "max": f"{r_e_plot.max()}"} + ) + writer.writerow({"variable": "r_w", "min": f"{r_w.min()}", "max": f"{r_w.max()}"}) + writer.writerow({"variable": "y", "min": f"{y.min()}", "max": f"{y.max()}"}) + + +# design the neural network model +model = Sequential( + [ + tf.keras.Input(shape=(4,)), + # tf.keras.layers.BatchNormalization(), + Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), + Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), + Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), + Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), + Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), + Dense(1), + ] +) + +# define the loss function and optimization algorithm +# lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( +# 0.1, decay_steps=1000, decay_rate=0.96, staircase=False +# ) +# model.compile(loss="mse", optimizer=tf.keras.optimizers.Adam(learning_rate=lr_schedule)) + +reduce_lr = tf.keras.callbacks.ReduceLROnPlateau( + monitor="loss", factor=0.1, patience=10, verbose=1, min_delta=1e-10 +) +model.compile(loss="mse", optimizer=tf.keras.optimizers.Adam(learning_rate=0.1)) + + +# ft the model on the training dataset +logger.info("Train model") +model.fit(x, y_scaled, epochs=5, batch_size=100, verbose=1, callbacks=reduce_lr) + +# make predictions for the input data +yhat = model.predict(x) +# inverse transforms +# r_e_plot = scale_r_e.inverse_transform(r_e.reshape(-1, 1)).squeeze() +# y_plot = scale_y.inverse_transform(y) +# yhat_plot = scale_y.inverse_transform(yhat) +# report model error +mse = tf.keras.losses.MeanSquaredError() +logger.info(f"MSE: {mse(y, yhat).numpy():.3f}") + + +re3 = 60.3473 +rw3 = 0.0762 +h3 = 15.24 +k3 = 1.97385e-13 + +#60.3473 0.0762 15.24 1.97385e-13 + + +wi = computePeaceman(h3 , k3 , re3, rw3) + +# scale h +h_plot2 = np.array(h3) +# h_plot = np.array([1e-12]) +#scale_h = MinMaxScaler() +#scale_h.set_params(param_h) +# h = scale_h.fit_transform(h_plot.reshape(-1, 1)).squeeze(axis=0) +h2 = scale_h.transform(h_plot2.reshape(-1, 1)).squeeze() + +# scale k +k_plot2 = np.array(k3) +#scale_k = MinMaxScaler() +#scale_k.set_params(param_k) +k2 = scale_k.transform(k_plot2.reshape(-1, 1)).squeeze() + +# # scale r_e +# r_e_plot = np.logspace(math.log(10), math.log(400), 300) +r_e_plot2 = np.array(re3) +#scale_r_e = MinMaxScaler((0.02, 0.5)) +#scale_r_e.set_params(param_r_e) +r_e2 = scale_r_e.transform(r_e_plot2.reshape(-1, 1)).squeeze() +r_w2 = np.array(rw3) +h_v2, k_v2, r_e_v2, r_w_v2 = np.meshgrid(h2, k2, r_e2, r_w2) +h_plot_v2, k_plot_v2, r_e_plot_v2, r_w_v2 = np.meshgrid(h_plot2, k_plot2, r_e_plot2, r_w2) +x2 = np.stack([h_v2.flatten(), k_v2.flatten(), r_e_v2.flatten(), r_w_v2.flatten()], axis=-1) +yhat2 = model.predict(x2) +print(r_e2, r_w2, h2, k2) +print(wi, yhat2, scale_y.inverse_transform(yhat2)) +# df = pd.DataFrame({"Id": x_plot[:, 0], "Amount": yhat_plot[:, 0].astype(float)}) + + +# def f(a): +# a = df.loc[df["Id"] == a, "Amount"] +# # for no match +# if a.empty: +# return "no match" +# # for multiple match +# elif len(a) > 1: +# return a +# else: +# # for match one value only +# return a.item() + + +# Plot w.r.t. r_e +# plot x vs y +for i in [0, 5, 10, 15]: + try: + pyplot.figure() + pyplot.plot( + r_e_plot, + computePeaceman_np( + np.full_like(r_e, h_plot[i]), + np.full_like(r_e, k_plot[i]), + r_e_plot, + np.full_like(r_e, r_w[0]), + ), + label="Actual", + ) + # plot x vs yhat + pyplot.plot( + r_e_plot, + scale_y.inverse_transform( + model( + np.stack( + [ + np.full_like(r_e, h[i]), + np.full_like(r_e, k[i]), + r_e, + np.full_like(r_e, r_w[0]), + ], + axis=-1, + ) + ) + ), + label="Predicted", + ) + pyplot.title("Input (x) versus Output (y)") + pyplot.xlabel("$r_e$") + pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") + pyplot.legend() + pyplot.savefig(f"plt_r_e_vs_WI_{i}.png", dpi=1200) + pyplot.show() + pyplot.close() + except Exception as e: + print(e) + pass + +# Plot w.r.t. h +# plot x vs y +try: + pyplot.figure() + pyplot.plot( + h_plot, + computePeaceman_np( + h_plot, + np.full_like(h, k_plot[0]), + np.full_like(h, r_e_plot[0]), + np.full_like(h, r_w[0]), + ), + label="Actual", + ) + # plot x vs yhat + pyplot.plot( + h_plot, + scale_y.inverse_transform( + model( + np.stack( + [ + h, + np.full_like(h, k[0]), + np.full_like(h, r_e[0]), + np.full_like(h, r_w[0]), + ], + axis=-1, + ) + ) + ), + label="Predicted", + ) + pyplot.title("Input (x) versus Output (y)") + pyplot.xlabel("$h$") + pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") + pyplot.legend() + pyplot.savefig("plt_h_vs_WI.png", dpi=1200) + pyplot.show() + pyplot.close() +except Exception as e: + pass + +# Plot w.r.t. k +# plot x vs y +try: + pyplot.figure() + pyplot.plot( + k_plot, + computePeaceman_np( + np.full_like(k, h_plot[0]), + k_plot, + np.full_like(k, r_e_plot[0]), + np.full_like(k, r_w[0]), + ), + label="Actual", + ) + # plot x vs yhat + pyplot.plot( + k_plot, + scale_y.inverse_transform( + model( + np.stack( + [ + np.full_like(k, h[0]), + k, + np.full_like(k, r_e[0]), + np.full_like(k, r_w[0]), + ], + axis=-1, + ) + ) + ), + label="Predicted", + ) + pyplot.title("Input (x) versus Output (y)") + pyplot.xlabel("$k$") + pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") + pyplot.legend() + pyplot.savefig("plt_k_vs_WI.png", dpi=1200) + pyplot.show() + pyplot.close() +except Exception as e: + pass + +# Plot w.r.t. r_w +# plot x vs y +try: + pyplot.figure() + pyplot.plot( + r_w, + computePeaceman_np( + np.full_like(r_w, h_plot[0]), + np.full_like(r_w, k_plot[0]), + np.full_like(r_w, r_e_plot[0]), + r_w, + ), + label="Actual", + ) + # plot x vs yhat + pyplot.plot( + r_w, + scale_y.inverse_transform( + model( + np.stack( + [ + np.full_like(r_w, h[0]), + np.full_like(r_w, k[0]), + np.full_like(r_w, r_e[0]), + r_w, + ], + axis=-1, + ) + ) + ), + label="Predicted", + ) + pyplot.title("Input (x) versus Output (y)") + pyplot.xlabel("$r_w$") + pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") + pyplot.legend() + pyplot.savefig("plt_r_w_vs_WI.png", dpi=1200) + pyplot.show() + pyplot.close() +except Exception as e: + pass + +# save model +#model.save_weights("modelPeaceman.tf") + +from kerasify import export_model + +export_model(model, "example.modelPeaceman") \ No newline at end of file diff --git a/opm/ml/ml_tools/scaler_layers.py b/opm/ml/ml_tools/scaler_layers.py new file mode 100644 index 00000000000..ca4593d4f74 --- /dev/null +++ b/opm/ml/ml_tools/scaler_layers.py @@ -0,0 +1,192 @@ +"""Provide MinMax scaler layers for tensorflow.keras.""" + +from __future__ import annotations + +from typing import Optional, Sequence + +import numpy as np +import tensorflow as tf +from numpy.typing import ArrayLike +from tensorflow import keras +from tensorflow.python.keras.engine.base_preprocessing_layer import ( # pylint: disable=E0611 + PreprocessingLayer, +) + + +class ScalerLayer(keras.layers.Layer): + """MixIn to provide functionality for the Scaler Layer.""" + + data_min: tf.Tensor + data_max: tf.Tensor + min: tf.Tensor + scalar: tf.Tensor + + def __init__( + self, + data_min: Optional[float | ArrayLike] = None, + data_max: Optional[float | ArrayLike] = None, + feature_range: Sequence[float] | np.ndarray | tf.Tensor = (0, 1), + **kwargs, # pylint: disable=W0613 + ) -> None: + super().__init__(**kwargs) + if feature_range[0] >= feature_range[1]: + raise ValueError("Feature range must be strictly increasing.") + self.feature_range: tf.Tensor = tf.convert_to_tensor( + feature_range, dtype=tf.float32 + ) + self._is_adapted: bool = False + if data_min is not None and data_max is not None: + self.data_min = tf.convert_to_tensor(data_min, dtype=tf.float32) + self.data_max = tf.convert_to_tensor(data_max, dtype=tf.float32) + self._adapt() + + def build(self, input_shape: tuple[int, ...]) -> None: + """Initialize ``data_min`` and ``data_max`` with the default values if they have + not been initialized yet. + + Args: + input_shape (tuple[int, ...]): _description_ + + """ + if not self._is_adapted: + # ``data_min`` and ``data_max`` have the same shape as one input tensor. + self.data_min = tf.zeros(input_shape[1:]) + self.data_max = tf.ones(input_shape[1:]) + self._adapt() + + def get_weights(self) -> list[ArrayLike]: + """Return parameters of the scaling. + + Returns: + list[ArrayLike]: List with three elements in the following order: + ``self.data_min``, ``self.data_max``, ``self.feature_range`` + + """ + return [self.data_min, self.data_max, self.feature_range] + + def set_weights(self, weights: list[ArrayLike]) -> None: + """Set parameters of the scaling. + + Args: + weights (list[ArrayLike]): List with three elements in the following order: + ``data_min``, ``data_max``, ``feature_range`` + + Raises: + ValueError: If ``feature_range[0] >= feature_range[1]``. + + """ + self.feature_range = tf.convert_to_tensor(weights[2], dtype=tf.float32) + if self.feature_range[0] >= self.feature_range[1]: + raise ValueError("Feature range must be strictly increasing.") + self.data_min = tf.convert_to_tensor(weights[0], dtype=tf.float32) + self.data_max = tf.convert_to_tensor(weights[1], dtype=tf.float32) + + def adapt(self, data: ArrayLike) -> None: + """Fit the layer to the min and max of the data. This is done individually for + each input feature. + + Note: + So far, this is only tested for 1 dimensional input and output. For higher + dimensional input and output some functionality might need to be added. + + Args: + data: _description_ + + """ + data = tf.convert_to_tensor(data, dtype=tf.float32) + self.data_min = tf.math.reduce_min(data, axis=0) + self.data_max = tf.math.reduce_max(data, axis=0) + self._adapt() + + def _adapt(self) -> None: + if tf.math.reduce_any(self.data_min > self.data_max): + raise RuntimeError( + f"""self.data_min {self.data_min} cannot be larger than self.data_max + {self.data_max} for any element.""" + ) + self.scalar = tf.where( + self.data_max > self.data_min, + self.data_max - self.data_min, + tf.ones_like(self.data_min), + ) + self.min = tf.where( + self.data_max > self.data_min, + self.data_min, + tf.zeros_like(self.data_min), + ) + self._is_adapted = True + + +class MinMaxScalerLayer(ScalerLayer, PreprocessingLayer): # pylint: disable=W0223,R0901 + """Scales the input according to MinMaxScaling. + + See + https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html + for an explanation of the transform. + + """ + + def __init__( + self, + data_min: Optional[float | ArrayLike] = None, + data_max: Optional[float | ArrayLike] = None, + feature_range: Sequence[float] | np.ndarray | tf.Tensor = (0, 1), + **kwargs, # pylint: disable=W0613 + ) -> None: + super().__init__(data_min, data_max, feature_range, **kwargs) + self._name: str = "MinMaxScalerLayer" + + # Ignore pylint complaining about a missing docstring. Also ignore + # "variadics removed ...". + def call(self, inputs: tf.Tensor) -> tf.Tensor: # pylint: disable=C0116, W0221 + if not self.is_adapted: + print(np.greater_equal(self.data_min, self.data_max)) + raise RuntimeError( + """The layer has not been adapted correctly. Call ``adapt`` before using + the layer or set the ``data_min`` and ``data_max`` values manually. + """ + ) + + # Ensure the dtype is correct. + inputs = tf.convert_to_tensor(inputs, dtype=tf.float32) + scaled_data = (inputs - self.min) / self.scalar + return ( + scaled_data * (self.feature_range[1] - self.feature_range[0]) + ) + self.feature_range[0] + # return inputs + + +class MinMaxUnScalerLayer(ScalerLayer, tf.keras.layers.Layer): + """Unscales the input by applying the inverse transform of ``MinMaxScalerLayer``. + + See + https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html + for an explanation of the transformation. + + """ + + def __init__( + self, + data_min: Optional[float | ArrayLike] = None, + data_max: Optional[float | ArrayLike] = None, + feature_range: Sequence[float] | np.ndarray | tf.Tensor = (0, 1), + **kwargs, # pylint: disable=W0613 + ) -> None: + super().__init__(data_min, data_max, feature_range, **kwargs) + self._name: str = "MinMaxUnScalerLayer" + + # Ignore pylint complaining about a missing docstring and something else. + def call(self, inputs: tf.Tensor) -> tf.Tensor: # pylint: disable=W0221 + if not self._is_adapted: + raise RuntimeError( + """The layer has not been adapted correctly. Call ``adapt`` before using + the layer or set the ``data_min`` and ``data_max`` values manually.""" + ) + + # Ensure the dtype is correct. + inputs = tf.convert_to_tensor(inputs, dtype=tf.float32) + unscaled_data = (inputs - self.feature_range[0]) / ( + self.feature_range[1] - self.feature_range[0] + ) + return unscaled_data * self.scalar + self.min + # return inputs diff --git a/opm/ml/ml_tools/scalertest.py b/opm/ml/ml_tools/scalertest.py new file mode 100644 index 00000000000..282d8db5650 --- /dev/null +++ b/opm/ml/ml_tools/scalertest.py @@ -0,0 +1,74 @@ +# + +from __future__ import annotations + +import pathlib + +import numpy as np + +from tensorflow import keras + +from kerasify import export_model + +from scaler_layers import MinMaxScalerLayer, MinMaxUnScalerLayer + +from keras.models import Sequential + + +savepath = pathlib.Path(__file__).parent / "model_with_scaler_layers.opm" + +feature_ranges: list[tuple[float, float]] = [(0.0, 1.0), (-3.7, 0.0)] + +data: np.ndarray = np.random.uniform(-500, 500, (5, 1)) + +# model: keras.Model = keras.Sequential( +# +# [ +# +# keras.layers.Input([10]), +# +# MinMaxScalerLayer(feature_range=feature_ranges[0]), +# +# keras.layers.Dense(units=10), +# +# MinMaxUnScalerLayer(feature_range=feature_ranges[1]), +# +# ] +# +# ) + +model = Sequential() +model.add(keras.layers.Input([1])) +model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) +# model.add(Flatten()) +# model.add(Dense(1, input_dim=1)) +model.add(MinMaxUnScalerLayer(feature_range=(-3.7, 0.0))) +# +# model.get_layer(model.layers[0].name).adapt(data=data) +# model.get_layer(model.layers[-1].name).adapt(data=data) + +# model.add(Dense(1, input_dim=1)) + +# model: keras.Model = keras.Sequential( +# +# [ +# +# keras.layers.Input([1]), +# +# MinMaxScalerLayer(feature_range=(0.0, 1.0)), +# +# # keras.layers.Dense(1, input_dim=1), +# +# # MinMaxUnScalerLayer(feature_range=(0.0, 1.0)), +# +# ] +# +# ) + + +# +# model.get_layer(model.layers[0].name).adapt(data=data) +# # +# model.get_layer(model.layers[-1].name).adapt(data=data) + +export_model(model, str(savepath)) From fe515cc93ed8923aa532d71665fc26098d9c24ec Mon Sep 17 00:00:00 2001 From: fractalmanifold Date: Thu, 6 Jun 2024 13:57:58 +0200 Subject: [PATCH 3/7] adding basic scaling layers --- opm/ml/keras_model.cpp | 35 +++++++++++-- opm/ml/keras_model.hpp | 14 +++++- opm/ml/ml_tools/generateunittests.py | 12 ++--- opm/ml/ml_tools/include/test_conv_2x2.h | 6 +-- opm/ml/ml_tools/include/test_conv_3x3.h | 8 +-- opm/ml/ml_tools/include/test_conv_3x3x3.h | 14 +++--- .../include/test_conv_hard_sigmoid_2x2.h | 6 +-- .../ml_tools/include/test_conv_sigmoid_2x2.h | 6 +-- .../ml_tools/include/test_conv_softplus_2x2.h | 6 +-- opm/ml/ml_tools/include/test_dense_10x1.h | 8 +-- opm/ml/ml_tools/include/test_dense_10x10.h | 8 +-- opm/ml/ml_tools/include/test_dense_10x10x10.h | 10 ++-- opm/ml/ml_tools/include/test_dense_1x1.h | 2 +- opm/ml/ml_tools/include/test_dense_2x2.h | 6 +-- opm/ml/ml_tools/include/test_dense_relu_10.h | 10 ++-- opm/ml/ml_tools/include/test_dense_tanh_10.h | 10 ++-- opm/ml/ml_tools/include/test_elu_10.h | 8 +-- opm/ml/ml_tools/include/test_maxpool2d_1x1.h | 46 ++++++++++-------- opm/ml/ml_tools/include/test_relu_10.h | 10 ++-- .../ml_tools/include/test_scalingdense_1x1.h | 11 ++--- opm/ml/ml_tools/kerasify.py | 42 ++++++---------- opm/ml/ml_tools/model_with_scaler_layers.opm | Bin 24 -> 128 bytes opm/ml/ml_tools/models/test_conv_2x2.model | Bin 84 -> 84 bytes opm/ml/ml_tools/models/test_conv_3x3.model | Bin 104 -> 104 bytes opm/ml/ml_tools/models/test_conv_3x3x3.model | Bin 408 -> 408 bytes .../models/test_conv_hard_sigmoid_2x2.model | Bin 84 -> 84 bytes .../models/test_conv_sigmoid_2x2.model | Bin 84 -> 84 bytes .../models/test_conv_softplus_2x2.model | Bin 84 -> 84 bytes opm/ml/ml_tools/models/test_dense_10x1.model | Bin 68 -> 68 bytes opm/ml/ml_tools/models/test_dense_10x10.model | Bin 528 -> 528 bytes .../ml_tools/models/test_dense_10x10x10.model | Bin 924 -> 924 bytes opm/ml/ml_tools/models/test_dense_1x1.model | Bin 32 -> 32 bytes opm/ml/ml_tools/models/test_dense_2x2.model | Bin 80 -> 80 bytes .../ml_tools/models/test_dense_relu_10.model | Bin 1384 -> 1384 bytes .../ml_tools/models/test_dense_tanh_10.model | Bin 1384 -> 1384 bytes opm/ml/ml_tools/models/test_elu_10.model | Bin 536 -> 536 bytes .../ml_tools/models/test_maxpool2d_1x1.model | Bin 444 -> 444 bytes opm/ml/ml_tools/models/test_relu_10.model | Bin 472 -> 472 bytes .../models/test_scalingdense_1x1.model | Bin 604 -> 236 bytes opm/ml/ml_tools/scaler_layers.py | 2 +- opm/ml/ml_tools/scalertest.py | 10 ++-- 41 files changed, 161 insertions(+), 129 deletions(-) diff --git a/opm/ml/keras_model.cpp b/opm/ml/keras_model.cpp index 538044cd9c7..8553cda9f98 100644 --- a/opm/ml/keras_model.cpp +++ b/opm/ml/keras_model.cpp @@ -143,8 +143,12 @@ template bool KerasLayerScaling::LoadLayer(std::ifstream* file) { KASSERT(file, "Invalid file stream"); - KASSERT(ReadFloat(file, &data_min), "Failed to read max"); + KASSERT(ReadFloat(file, &data_min), "Failed to read min"); + KASSERT(ReadFloat(file, &data_max), "Failed to read max"); + KASSERT(ReadFloat(file, &feat_inf), "Failed to read max"); + KASSERT(ReadFloat(file, &feat_sup), "Failed to read max"); + // KASSERT(ReadFloat(file, &feat), "Failed to read max"); return true; } @@ -153,11 +157,16 @@ bool KerasLayerScaling::Apply(Tensor* in, Tensor temp_in, temp_out; + *out = *in; - // out->Flatten(); - std::cout<data_[0]<data_[1]<data_.size(); i++) { + std::cout<<"out->data_[i]"<data_[i]<data_[i] - data_min)/(data_max - data_min); + out->data_[i] = tempscale * (feat_sup - feat_inf) + feat_inf; + } return true; } @@ -165,6 +174,12 @@ bool KerasLayerScaling::Apply(Tensor* in, Tensor bool KerasLayerUnScaling::LoadLayer(std::ifstream* file) { KASSERT(file, "Invalid file stream"); + + KASSERT(ReadFloat(file, &data_min), "Failed to read min"); + KASSERT(ReadFloat(file, &data_max), "Failed to read max"); + KASSERT(ReadFloat(file, &feat_inf), "Failed to read inf"); + KASSERT(ReadFloat(file, &feat_sup), "Failed to read sup"); + return true; } @@ -173,9 +188,19 @@ bool KerasLayerUnScaling::Apply(Tensor* in, TensorFlatten(); + for (size_t i = 0; i < out->data_.size(); i++) { + std::cout<<"out->data_[i]"<data_[i]<data_[i] - feat_inf)/(feat_sup - feat_inf); + + out->data_[i] = tempscale * (data_max - data_min) + data_min; + } + + return true; } diff --git a/opm/ml/keras_model.hpp b/opm/ml/keras_model.hpp index 1a401ef4758..41299eb8215 100644 --- a/opm/ml/keras_model.hpp +++ b/opm/ml/keras_model.hpp @@ -310,7 +310,7 @@ class KerasLayerActivation : public KerasLayer { template class KerasLayerScaling : public KerasLayer { public: - KerasLayerScaling(): data_min(1.0f) {} + KerasLayerScaling(): data_min(1.0f), data_max(1.0f), feat_inf(1.0f), feat_sup(1.0f) {} virtual ~KerasLayerScaling() {} @@ -322,6 +322,12 @@ class KerasLayerScaling : public KerasLayer { Tensor weights_; Tensor biases_; float data_min; + float data_max; + float feat_inf; + float feat_sup; + + // float feat; + // float feature_range; // KerasLayerActivation activation_; }; @@ -329,7 +335,7 @@ class KerasLayerScaling : public KerasLayer { template class KerasLayerUnScaling : public KerasLayer { public: - KerasLayerUnScaling() {} + KerasLayerUnScaling(): data_min(1.0f), data_max(1.0f), feat_inf(1.0f), feat_sup(1.0f) {} virtual ~KerasLayerUnScaling() {} @@ -340,6 +346,10 @@ class KerasLayerUnScaling : public KerasLayer { private: Tensor weights_; Tensor biases_; + float data_min; + float data_max; + float feat_inf; + float feat_sup; // KerasLayerActivation activation_; }; diff --git a/opm/ml/ml_tools/generateunittests.py b/opm/ml/ml_tools/generateunittests.py index f8e7fb00ab3..b409c5cec93 100644 --- a/opm/ml/ml_tools/generateunittests.py +++ b/opm/ml/ml_tools/generateunittests.py @@ -115,11 +115,11 @@ def output_testcase(model, test_x, test_y, name, eps): model.add(keras.layers.Input([1])) # model.add(Flatten()) # model.add(Flatten()) -model.add(MinMaxScalerLayer(data_min=0.1,feature_range=(0.0, 1.0))) +model.add(MinMaxScalerLayer(data_min=10,feature_range=(0.0, 1.0))) model.add(Dense(1,activation='tanh')) model.add(Dense(10,activation='tanh')) -model.add(Dense(10,activation='tanh')) -model.add(MinMaxUnScalerLayer(feature_range=(0.0, 1.0))) +model.add(Dense(1,activation='tanh')) +model.add(MinMaxUnScalerLayer(feature_range=(1.0, 5.0))) # model.add(Dense(10)) # model.add(Dense(10)) # model.add(Dense(10)) @@ -127,8 +127,8 @@ def output_testcase(model, test_x, test_y, name, eps): # model.add(Flatten()) # model.add(MinMaxUnScalerLayer()) # # -# # model.get_layer(model.layers[0].name).adapt(data=data) -# model.get_layer(model.layers[-1].name).adapt(data=data) +model.get_layer(model.layers[0].name).adapt(data=data) +model.get_layer(model.layers[-1].name).adapt(data=data) # model.add(Dense(1, input_dim=1)) @@ -147,7 +147,7 @@ def output_testcase(model, test_x, test_y, name, eps): # ] # # ) -output_testcase(model, test_x, test_y, 'scalingdense_1x1', '1e-6') +output_testcase(model, test_x, test_y, 'scalingdense_1x1', '1e-3') # Dense 1x1 test_x = np.arange(10) diff --git a/opm/ml/ml_tools/include/test_conv_2x2.h b/opm/ml/ml_tools/include/test_conv_2x2.h index 18602b770d5..b006f78cfa4 100644 --- a/opm/ml/ml_tools/include/test_conv_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_2x2.h @@ -13,16 +13,16 @@ bool test_conv_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.750075,0.10270854,0.21013065,0.29597324}; + in.data_ = {0.062906526,0.34327188,0.7227239,0.17407319}; Opm::Tensor out{1}; - out.data_ = {0.027571658}; + out.data_ = {-0.05085864}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_2x2.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_2x2.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_conv_3x3.h b/opm/ml/ml_tools/include/test_conv_3x3.h index 338b8471abb..5f90cff2dc5 100644 --- a/opm/ml/ml_tools/include/test_conv_3x3.h +++ b/opm/ml/ml_tools/include/test_conv_3x3.h @@ -13,17 +13,17 @@ bool test_conv_3x3(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{3,3,1}; - in.data_ = {0.8302591,0.7126048,0.049354695,0.065839484,0.022077054,0.8151628, -0.8770473,0.93242997,0.5808531}; + in.data_ = {0.31915146,0.46648613,0.713153,0.7186029,0.4189023,0.93898046, +0.21495701,0.22672214,0.6468133}; Opm::Tensor out{1}; - out.data_ = {0.1281208}; + out.data_ = {0.012564741}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_3x3.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_3x3.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_conv_3x3x3.h b/opm/ml/ml_tools/include/test_conv_3x3x3.h index 155e50872a8..1568e050726 100644 --- a/opm/ml/ml_tools/include/test_conv_3x3x3.h +++ b/opm/ml/ml_tools/include/test_conv_3x3x3.h @@ -13,20 +13,20 @@ bool test_conv_3x3x3(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{3,3,3}; - in.data_ = {0.87271255,0.93225205,0.454738,0.7743667,0.07311473,0.43917352, -0.06562502,0.10534243,0.84919333,0.05485726,0.26453573,0.43184462, -0.31198752,0.3685557,0.33569786,0.5550908,0.30508468,0.5998162, -0.5240912,0.084725335,0.68967754,0.99210244,0.99117345,0.9305709, -0.9118958,0.84186167,0.566753}; + in.data_ = {0.99366415,0.8214218,0.78640515,0.2603204,0.16119346,0.33790612, +0.003531503,0.8499332,0.45968544,0.4627597,0.13754487,0.10913391, +0.14221385,0.6451374,0.84302205,0.4868773,0.083437696,0.27630988, +0.22067706,0.11169723,0.3520237,0.58716524,0.05329963,0.26573667, +0.4124315,0.18437439,0.74106956}; Opm::Tensor out{1}; - out.data_ = {0.26097965}; + out.data_ = {-0.32770187}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_3x3x3.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_3x3x3.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h index a3c1486c83e..04e8c6c5b0d 100644 --- a/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h @@ -13,16 +13,16 @@ bool test_conv_hard_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.33098492,0.7765142,0.73701227,0.107884906}; + in.data_ = {0.50463355,0.9183773,0.38787946,0.43078265}; Opm::Tensor out{1}; - out.data_ = {-0.8017725}; + out.data_ = {0.32929042}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h index a0c026f9c74..ba2366d204e 100644 --- a/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h @@ -13,16 +13,16 @@ bool test_conv_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.57643723,0.7119069,0.902389,0.65012866}; + in.data_ = {0.91240454,0.20470788,0.9951741,0.7569204}; Opm::Tensor out{1}; - out.data_ = {-0.42353362}; + out.data_ = {0.0065397182}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_conv_softplus_2x2.h b/opm/ml/ml_tools/include/test_conv_softplus_2x2.h index 278233463b9..6549daacdc7 100644 --- a/opm/ml/ml_tools/include/test_conv_softplus_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_softplus_2x2.h @@ -13,16 +13,16 @@ bool test_conv_softplus_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.96513563,0.36131543,0.77126974,0.21065006}; + in.data_ = {0.9781388,0.69906306,0.73934394,0.07835838}; Opm::Tensor out{1}; - out.data_ = {-0.33121806}; + out.data_ = {0.6921864}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_conv_softplus_2x2.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_softplus_2x2.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_10x1.h b/opm/ml/ml_tools/include/test_dense_10x1.h index a7b75f5a30d..beba5165363 100644 --- a/opm/ml/ml_tools/include/test_dense_10x1.h +++ b/opm/ml/ml_tools/include/test_dense_10x1.h @@ -13,17 +13,17 @@ bool test_dense_10x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.0659136,0.28923303,0.694333,0.37173527,0.9247947,0.5618971, -0.57161736,0.7481847,0.9059089,0.062005263}; + in.data_ = {0.62656444,0.8955544,0.97843874,0.3737466,0.2596527,0.53862107, +0.0325291,0.7202331,0.9628396,0.22615331}; Opm::Tensor out{1}; - out.data_ = {0.5485782}; + out.data_ = {-0.47586796}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_10x1.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x1.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10.h b/opm/ml/ml_tools/include/test_dense_10x10.h index 04f628fdd65..1b6ecc675aa 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10.h +++ b/opm/ml/ml_tools/include/test_dense_10x10.h @@ -13,17 +13,17 @@ bool test_dense_10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.24637328,0.32497618,0.1574523,0.17820616,0.17318362, -0.59771574,0.4205037,0.0142282825,0.42604983,0.976568}; + in.data_ = {0.6189273,0.92638606,0.5629345,0.66560996,0.8742824,0.49490887, +0.6071822,0.51056105,0.012800761,0.45888036}; Opm::Tensor out{1}; - out.data_ = {-0.17698397}; + out.data_ = {-1.2550222}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_10x10.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10x10.h b/opm/ml/ml_tools/include/test_dense_10x10x10.h index 7facd125022..1860f70bfb3 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10x10.h +++ b/opm/ml/ml_tools/include/test_dense_10x10x10.h @@ -13,18 +13,18 @@ bool test_dense_10x10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.8998526,0.42643917,0.2649691,0.101825155,0.4860865,0.35637248, -0.7880747,0.5331231,0.90746176,0.3913051}; + in.data_ = {0.7104989,0.4149288,0.71831465,0.5625794,0.7118615,0.8625888, +0.35311338,0.70555335,0.19741295,0.6377552}; Opm::Tensor out{10}; - out.data_ = {0.097687565,0.30221617,-0.24571078,-0.051162135,-0.24975275, --0.3039312,-0.14934357,-0.62535065,-0.34585848,-1.3160709}; + out.data_ = {-0.047795724,0.55596924,-0.08081586,-0.5206654,0.17288932, +-0.5772272,0.45383403,-0.38085136,-0.5176138,0.2733392}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_10x10x10.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x10x10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_1x1.h b/opm/ml/ml_tools/include/test_dense_1x1.h index 2e369789957..3dda009b122 100644 --- a/opm/ml/ml_tools/include/test_dense_1x1.h +++ b/opm/ml/ml_tools/include/test_dense_1x1.h @@ -22,7 +22,7 @@ bool test_dense_1x1(Evaluation* load_time, Evaluation* apply_time) load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_1x1.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_1x1.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_2x2.h b/opm/ml/ml_tools/include/test_dense_2x2.h index 8ef29843184..374c424e89f 100644 --- a/opm/ml/ml_tools/include/test_dense_2x2.h +++ b/opm/ml/ml_tools/include/test_dense_2x2.h @@ -13,16 +13,16 @@ bool test_dense_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2}; - in.data_ = {0.6887023,0.58510196}; + in.data_ = {0.9365942,0.34521446}; Opm::Tensor out{1}; - out.data_ = {0.30864304}; + out.data_ = {0.086802945}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_2x2.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_2x2.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_relu_10.h b/opm/ml/ml_tools/include/test_dense_relu_10.h index f1ff6cdeb2e..e8858570810 100644 --- a/opm/ml/ml_tools/include/test_dense_relu_10.h +++ b/opm/ml/ml_tools/include/test_dense_relu_10.h @@ -13,18 +13,18 @@ bool test_dense_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.44567293,0.21984123,0.8783762,0.877416,0.6290802,0.5274514, -0.028554708,0.69272816,0.3010707,0.3224137}; + in.data_ = {0.64364296,0.36075893,0.28376237,0.41895798,0.6025532,0.035710134, +0.95477134,0.51287717,0.78825593,0.5268354}; Opm::Tensor out{10}; - out.data_ = {0.07524448,0.1483022,0.,0.07073106,0.,0., -0.012321308,0.,0.025917793,0.}; + out.data_ = {0.124458,0.,0.,0.,0.,0., +0.062164858,0.24708469,0.31542313,0.059695993}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_relu_10.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_relu_10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_tanh_10.h b/opm/ml/ml_tools/include/test_dense_tanh_10.h index faec85d7145..d1c895469d4 100644 --- a/opm/ml/ml_tools/include/test_dense_tanh_10.h +++ b/opm/ml/ml_tools/include/test_dense_tanh_10.h @@ -13,18 +13,18 @@ bool test_dense_tanh_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.03345425,0.78990555,0.33485138,0.09934332,0.74528086,0.6406323, -0.78257537,0.17336933,0.06393018,0.94946647}; + in.data_ = {0.26271367,0.57310253,0.4322339,0.018163363,0.42448965,0.6118086, +0.20635886,0.38553724,0.97148365,0.2353917}; Opm::Tensor out{10}; - out.data_ = {-0.10979327,0.31542704,0.3152341,0.42501545,0.31062323,-0.18132454, --0.763928,0.15322652,0.73196095,-0.19889684}; + out.data_ = {-0.5350144,-0.36773947,-0.015882624,0.020122323,0.11873825, +0.42103818,-0.27925694,0.060885787,0.5043703,0.029599192}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_dense_tanh_10.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_tanh_10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_elu_10.h b/opm/ml/ml_tools/include/test_elu_10.h index 6fb641853ea..5597d0483c5 100644 --- a/opm/ml/ml_tools/include/test_elu_10.h +++ b/opm/ml/ml_tools/include/test_elu_10.h @@ -13,17 +13,17 @@ bool test_elu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.3842556,0.91849715,0.74334174,0.3313295,0.34599218,0.48829415, -0.80283946,0.58847773,0.5926601,0.9469626}; + in.data_ = {0.9834945,0.5741797,0.027460653,0.07063913,0.7403407,0.72907645, +0.009775176,0.309714,0.5252622,0.090779774}; Opm::Tensor out{1}; - out.data_ = {0.021793796}; + out.data_ = {0.50609195}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_elu_10.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_elu_10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_maxpool2d_1x1.h b/opm/ml/ml_tools/include/test_maxpool2d_1x1.h index f834dffd8a7..856ecc50537 100644 --- a/opm/ml/ml_tools/include/test_maxpool2d_1x1.h +++ b/opm/ml/ml_tools/include/test_maxpool2d_1x1.h @@ -13,32 +13,40 @@ bool test_maxpool2d_1x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10,10,1}; - in.data_ = {0.25518134,0.04741953,0.30579203,0.155573,0.49132094,0.07164798, -0.6618191,0.95539516,0.60500616,0.27978984,0.5592694,0.10625745, -0.35216096,0.15352608,0.38916105,0.47961122,0.13570014,0.5139465, -0.60992926,0.48152757,0.45213497,0.74926835,0.893273,0.49284345, -0.13199767,0.40807652,0.32890376,0.92184955,0.8276756,0.4514926, -0.8575906,0.22574344,0.5647829,0.6564582,0.83293825,0.81201965, -0.16786863,0.64626974,0.73370457,0.75692856,0.056844383,0.48827544, -0.4257299,0.6403209,0.556078,0.5105229,0.3147873,0.72197866, -0.25018466,0.25356695,0.6093809,0.5989881,0.2952787,0.7309936, -0.91963696,0.03639153,0.67082775,0.74602616,0.007854396,0.35555983, -0.85999966,0.8637354,0.5419423,0.51870966,0.15975554,0.31114286, -0.2895706,0.6567837,0.49693534,0.8106974,0.3142659,0.004674668, -0.7890345,0.6929022,0.43730104,0.76309645,0.48623887,0.8451051, -0.2559583,0.8858542,0.43520355,0.5545106,0.78928936,0.19655785, -0.9229729,0.6828728,0.77383405,0.98197556,0.8564043,0.25713357, -0.46030727,0.71827936,0.34024438,0.18788093,0.8874286,0.64397246, -0.04353716,0.7736121,0.429076,0.20847954}; + in.data_ = {8.05891514e-01,4.24958289e-01,9.78650153e-01,8.33032012e-01, +6.98836505e-01,5.28312251e-02,9.86697435e-01,1.75924480e-01, +5.77136397e-01,8.90503943e-01,3.50836873e-01,8.51357281e-02, +3.52928936e-01,3.79992664e-01,4.45006251e-01,9.93837059e-01, +5.55398285e-01,8.62534046e-01,1.73030049e-01,4.98871028e-01, +5.99020064e-01,2.93842643e-01,4.75706041e-01,3.08726907e-01, +6.87034428e-01,9.52807069e-01,3.84712100e-01,5.96658170e-01, +3.96235764e-01,1.40618477e-02,1.94596589e-01,6.25770569e-01, +5.62299132e-01,5.34520566e-01,1.95316955e-01,9.29202616e-01, +8.59472275e-01,2.36784384e-01,1.90333515e-01,5.04570246e-01, +4.75366235e-01,9.33640420e-01,9.12167579e-02,7.26325393e-01, +6.58039212e-01,9.39130664e-01,3.68637234e-01,7.78640509e-02, +5.77523530e-01,3.63632172e-01,4.44532394e-01,8.23739767e-02, +3.01169813e-01,9.15617108e-01,4.01109338e-01,6.52816117e-01, +3.36535722e-01,1.83367670e-01,9.86048639e-01,2.11613506e-01, +9.39686358e-01,2.76162028e-01,8.99377912e-02,5.59440315e-01, +6.95002973e-01,6.85773134e-01,6.95965350e-01,9.38641310e-01, +3.02985966e-01,7.37742484e-01,4.92526293e-01,3.16089630e-01, +1.87618837e-01,6.22452796e-02,9.46086943e-01,2.13588208e-01, +6.07565165e-01,6.22669816e-01,6.42262280e-01,1.74358606e-01, +7.60361373e-01,6.07401252e-01,3.88030050e-04,1.06557794e-01, +5.73728263e-01,2.31160838e-02,9.74358380e-01,3.07875097e-01, +1.41230553e-01,2.09358424e-01,7.70691752e-01,8.38017046e-01, +1.21261969e-01,5.75457394e-01,6.84708729e-02,5.65244675e-01, +3.90781015e-01,5.39179444e-01,8.40706050e-01,6.09158993e-01}; Opm::Tensor out{1}; - out.data_ = {-0.25252247}; + out.data_ = {0.82167464}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_maxpool2d_1x1.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_maxpool2d_1x1.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_relu_10.h b/opm/ml/ml_tools/include/test_relu_10.h index f0b0d894d20..d2694135d46 100644 --- a/opm/ml/ml_tools/include/test_relu_10.h +++ b/opm/ml/ml_tools/include/test_relu_10.h @@ -13,18 +13,18 @@ bool test_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.75668657,0.43547645,0.2684515,0.40864667,0.7540064,0.8699675, -0.9615154,0.21117006,0.2840515,0.6931818}; + in.data_ = {0.34561083,0.045264732,0.75015557,0.8151314,0.2287286,0.7522012, +0.01585116,0.17131925,0.4055651,0.35491937}; Opm::Tensor out{10}; - out.data_ = {0.41057152,0.,0.,0.3421311,1.0349326,1.9920036, -0.,0.,0.,0.}; + out.data_ = {1.0254096,0.043472286,0.,0.39489448,0.,0., +0.,0.,0.,0.026771469}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_relu_10.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_relu_10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_scalingdense_1x1.h b/opm/ml/ml_tools/include/test_scalingdense_1x1.h index 64f1c8660e7..f3b7d93d9c0 100644 --- a/opm/ml/ml_tools/include/test_scalingdense_1x1.h +++ b/opm/ml/ml_tools/include/test_scalingdense_1x1.h @@ -13,17 +13,16 @@ bool test_scalingdense_1x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{1}; - in.data_ = {0.38420224}; + in.data_ = {0.5439535}; - Opm::Tensor out{10}; - out.data_ = {-0.05173513,0.040830124,-0.031732455,-0.16009168,0.012040144, --0.07901504,0.08811069,-0.04247553,-0.06113547,-0.1637011}; + Opm::Tensor out{1}; + out.data_ = {-633.0674}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/bikagit/opm-common/opm/ml/ml_tools/models/test_scalingdense_1x1.model"), "Failed to load model"); + KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_scalingdense_1x1.model"), "Failed to load model"); *load_time = load_timer.Stop(); @@ -37,7 +36,7 @@ bool test_scalingdense_1x1(Evaluation* load_time, Evaluation* apply_time) for (int i = 0; i < out.dims_[0]; i++) { - KASSERT_EQ(out(i), predict(i), 1e-6); + KASSERT_EQ(out(i), predict(i), 1e-3); } return true; diff --git a/opm/ml/ml_tools/kerasify.py b/opm/ml/ml_tools/kerasify.py index ac123e2019b..0ce8ef392c2 100644 --- a/opm/ml/ml_tools/kerasify.py +++ b/opm/ml/ml_tools/kerasify.py @@ -20,37 +20,11 @@ ACTIVATION_HARD_SIGMOID = 6 def write_scaling(f): - # weights = layer.get_weights()[0] - # biases = layer.get_weights()[1] - - # print(weights) - # activation = layer.get_config()['activation'] f.write(struct.pack('I', LAYER_SCALING)) - # f.write(struct.pack('I', weights.shape[0])) - # # f.write(struct.pack('I', weights.shape[1])) - # f.write(struct.pack('I', biases.shape[0])) - # - # # weights = weights.flatten() - # # biases = biases.flatten() - # write_floats(f, weights) - # write_floats(f, biases) - # write_activation(activation) -def write_unscaling(f): - # weights = layer.get_weights()[0] - # biases = layer.get_weights()[1] - # activation = layer.get_config()['activation'] +def write_unscaling(f): f.write(struct.pack('I', LAYER_UNSCALING)) - # f.write(struct.pack('I', weights.shape[0])) - # # f.write(struct.pack('I', weights.shape[1])) - # f.write(struct.pack('I', biases.shape[0])) - # - # # weights = weights.flatten() - # # biases = biases.flatten() - # write_floats(f, weights) - # write_floats(f, biases) - # write_activation(activation) def write_tensor(f, data, dims=1): @@ -120,12 +94,24 @@ def write_activation(activation): if layer_type == 'MinMaxScalerLayer': write_scaling(f) + feat_inf = layer.get_weights()[0] + feat_sup = layer.get_weights()[1] f.write(struct.pack('f', layer.data_min)) - # write_floats(f, weights) + f.write(struct.pack('f', layer.data_max)) + f.write(struct.pack('f', feat_inf)) + f.write(struct.pack('f', feat_sup)) elif layer_type == 'MinMaxUnScalerLayer': write_unscaling(f) + feat_inf = layer.get_weights()[0] + feat_sup = layer.get_weights()[1] + # feat = layer.get_weights()[2][0] + f.write(struct.pack('f', layer.data_min)) + f.write(struct.pack('f', layer.data_max)) + f.write(struct.pack('f', feat_inf)) + f.write(struct.pack('f', feat_sup)) + elif layer_type == 'Dense': weights = layer.get_weights()[0] diff --git a/opm/ml/ml_tools/model_with_scaler_layers.opm b/opm/ml/ml_tools/model_with_scaler_layers.opm index 86755ff952fcedc81881e63c7d6c505441c00012..eb518437d3b8bc31f382f88a54e0784612057553 100644 GIT binary patch literal 128 zcmZQ$U|?VZVh~^fVn!sal09)hNE{@FF4wr_wmmMn3lDGX!zH)r+a0)>%s@o|A~Oo) literal 24 VcmZQ%U|?VZVn!$iQb5pP4*&tP0L1_R diff --git a/opm/ml/ml_tools/models/test_conv_2x2.model b/opm/ml/ml_tools/models/test_conv_2x2.model index 58ff65d4c8d870671c14b5b7998f7087ad02c7bb..d8335c5287e8e33164791ff7d81dcf1f742198d8 100644 GIT binary patch delta 41 xcmWFunII#QzMs?XTttX{f$IEy5=js3a)p|AO*D|;Ii diff --git a/opm/ml/ml_tools/models/test_conv_3x3.model b/opm/ml/ml_tools/models/test_conv_3x3.model index bbfd9fb546797a5a6514b0146f5ebfaa3ba3bd5b..9d51d3d542a1aa614f0faff441aea4e342ba3d55 100644 GIT binary patch delta 57 zcmV-90LK4lXpkHv0?L;@(s1@ZE-4Ye+0!#VsQLW9MqBzm3Iv@!76_ES0%*Iwkw6>_ PXgjh$ZW4n!0RR91&Epm} delta 57 zcmV-90LK4lXpkHvTHD<|5oH^`yDo0N*Mh#j-?AsZM{0#U$pzBB$%a_FKI7#+kw6>_ P*ztltZW4n!0RR91BU>5Q diff --git a/opm/ml/ml_tools/models/test_conv_3x3x3.model b/opm/ml/ml_tools/models/test_conv_3x3x3.model index a691f539562411acf1f4dab5f02c1413e2cd3c69..b8d18359f90c197b2b17852a2d5963585f9bda35 100644 GIT binary patch delta 367 zcmV-#0g(Qf1DFGl9DnUG5qpgzid?>*XXs=i6# z9Xl{te!iWORz7utLcYsLGQNG|Y(Ax6dA`BQc0Ta;G`^8sjDJ4C%4$C6G>txEqmw>a zP=!1@&2YWSRr$S3370-nO^?1ce<(h+haEnEST?@k4P?I8vFE(lah<-?+)2H{wu`WR5MiX*~3erA}yW)G;oKBJkw9~-DXm7Y4i z`wE0U6j_(P1uX-;(f3xRWO7;ZW4pKZW4pKZO8x%T%gTFH@YrpwV NcRy|tgE|2K004v(vJ3zK delta 367 zcmV-#0g(Qf1DFGl9Dj;)(mdaClRn!wi#~rKsXoFmojpmBj6OR+oIdMCNxc{Em_C&? zGQK*2%cD`Mxp1rL` z06o^jfV_7n{yiH3TE2J7qCK|lExxO7lRm5WJ3U)MOg`(ZOn<%sixj>s9}~U*ok2be zrw6{<)t@_$XCpo*hS@w~WBR>M+cZ9tAE-X3#&tgVT%o@9*Q7m$*fYNS0De764Tint z=$$^h2MNARjFG;I!q`23t9L$M-#$Jf1@OIjBZ`Tz zy)(XcJJP+jkWY}l>(vv!K{Y(SHydj{)&lyy)MRry)>-bo5zK_X3wk@gCQRD9iRXvD zHao1nv)OOF({rOf1}i1LH*rTkTw9#JmaMRWME(b08GvevH$=8 delta 41 xcmWFunII!laK_kvhw3f6oW7v_3W8epc|y&*CK^caJh4B$KVPWXijjeV0RTet4nF_@ diff --git a/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model b/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model index 061f71d224d90e5129d17017648c8ed3f998fb42..81a4410cafb90dd8dac45e1dbff153e3d596e031 100644 GIT binary patch delta 41 xcmWFunII$5cI1s+b48ThpO|F3)U-hRK>lW{i3SopvsXQ{&J$|3Vq{=o0032U4r%}Z delta 41 xcmWFunII$bs9eeZk@ma2CHLCxOx8}a%MohcHPJwVXR)=?{(PZkD@Fze1^{fW4?zF` diff --git a/opm/ml/ml_tools/models/test_conv_softplus_2x2.model b/opm/ml/ml_tools/models/test_conv_softplus_2x2.model index e68fe91c0162ccbea684d9808e55421ec11a741d..a029dd7ab4cf4a0dc971ccff5b8edc6bc2b41f5b 100644 GIT binary patch delta 37 scmWFunII#;ox!(EP2$R+Jc|y&*7#SEC0LA19@Bjb+ delta 37 tcmWFunIIz|+#tLE=lY2KCNp*STUO=lo2Vnh^Zn`B{dq#oR*Vb`3;-v?4zvIO diff --git a/opm/ml/ml_tools/models/test_dense_10x1.model b/opm/ml/ml_tools/models/test_dense_10x1.model index 5ee01fbe92e170f93891227952a8e6300512e89e..b74ad18c2f379e71247d1f13e22664e64d9996dc 100644 GIT binary patch delta 53 zcmV-50LuSFM359PEMb7Y&PNVE-7s=KqbgNBIHt@#2A2Rth;{xx9S9e_ LY!ZVy0RR91S&$J`}$r!+G|rXZC~v}2U~@{6?PVE zjQe|S#O>m5-nZ4(XWG9m`^>%*`m^_??Rj9waPY8Q!l8CMWo>RdjoL$YvU}77O**D#6;=W94_I>k@*zfD+d9lx?bCzB7?)&@J zdIZ?bh`nStJA&IT!eHXQO&vXZpXjjL9ou`%uIuq_Tejriw)gKa?0?C{ZYR-oZTCYD zF8k;LS36^wXxrlcllu;>+Gv->KE>|DnI(3ycXRhLRjt@Jt+dZBAb-I=h9wK_il+tJ zHtx*ZmpH9!Uuy}2{mmGbeTN;3Z1;TFX~%Z4X-{6tecN|BTlQ`&WZGY%ddcp=iY<1{wsLzv=}xwN5XiPKIHhc#)YeWL-%BC3 zD_yhpnSFU~+izC4Pm*c+o@0^c_V#sf?_YOq*}h!~OYQ6grrBMd8EUtD!|gq;VJ!AL zpC#-w{v@<#b4v3*-9}qGOVy@*3Vdt!&3m$HU+?sH`_9Tb*}CkQZ8!I{(Z1R1S?n8c zDD1oU^84O5%?tJ|ia2FEd#9qEEc5w&T&HL4<7IxgFCt>yKEYg8yEh3>_kB>mWM{a& zW8baC&-d*5bYP#6&n7#$ya#q$3bxtJdepk_&4JB!lP>(Vn^4KT|0XAg{bx?*J%|1* zvfDnF*SIzpS<0(rro=D6rSG4yT{%}lXb&%PT1d+qksHrYO25Vdb_Y_9Err)TX# zQ<(M#%KX}=*8AD+z=LAD*35Y}IYQ05@{n+@P_q>j?*htM`2poJfHWggT!PpjJXs;h v&TW#l{fSgf`v@s9`!I%U`@GDr?#p6lv0v_6x9|Ae<2J`1u;!`jR_YnszVF{rcv2@tT^y1;blyB@0+ngq;pB>y zNKsDXVIq3eWT$gFAMlW|-)BU|8S2WzL7pWIVpGH5c)GFKYBT@nkN$Yw>;1XUpRe$+ zurOhesQ(~-Vl(uAw$Pr=0G61QRPb6UUWylT8xE`JK)WBRF+Hj`H!+cdAilmDy@h6Y zYBXR{F?%-JNbBG5lFw_Qh!PvlPHHJ&^x(1lG`L-VD-6#2^ufXi>&|+b8bxNL_SW(G z;UC$~#VM!?3}U!A%06#A#QXs_#kkyHmJ#Z|NVXYYrc&ZKg|*T7R4i06!I+PlduEXN zOeA-q;|2oldof+`7rvRDLTRaxGrj*6oA>_AjEYZfHFr+%WuIlx;{A8YDmjms!+k75 zZe%4MC3SjqXsGHyqjMPU=${l^!}FB2Af#nicGH>;p*?lqBvennN9kv-^4zrxWXf_; zx_k=arf}}dW1sM9!vJ=Ba@pu~Jvwh~LoUk%?YWNR)_OD_yo5C|y$}TA>Fq8Jx@1{c z-sXkx^gg`#_+^%87-hSv6EO7aZN6ql2PW(0s9_zUltoe9U@GOkrAK{QB~`>~t?D3^ z4;|XuVzu&+Lu?H0&@K3%mLH}Kk-GUdzEw9<_ttoFO`W5<$SBHlL~=d9h`6fpS(3is zU}dcnEXF^Df|hcq&Hbb{^^&gbE^V4wg=yU}jQlR9nx__EU3Y@7eeoXV_LuR}1fhLn z;XDn=+NtrHy0%-^LAc_q(_HKgEsW* zjw7W)%TMMA$Z8rvkh2eXi^EXh!Ngv|UPeO7{Z_8*J ok07Klg4FCWD literal 924 zcmZwFe^AqP9LMnqv=PG}}+W(3}zT^=u-)zB{cn!|km1Ny7 z77{*gf;(0V$HOXUOQzVP=3pW3T_u_2`)I3S5d8^SqRS?7&e=&e-o*kHQ*{5VdYG4tQ`58%{^W_8kskMl;EpY$mnw$xUL=*SU- zC!Rp@U<`^{-Pk4XROcMMMCrBN$VvGD2d|5TGTkg$HwJT)^9?NDc#k@qPS~Cr!{+ca zOf$0wo~c&S=UrvLymAhmQ@vF0I*TTEsGukg5u!ec!!3)SUer~wd*w;2{fS)Y+qWU} z$!oO1f14l9QlZ6CgVAn|e50G_z_M!keZN(8SW=FjwNYf8tfZ@z$#gVv7{^aHP*FsM za!*8svv6^D{=3R|0=JUI+wQ-J%&>|>K5Xz#lJlaQiozRdf*rv?mP9Bpr=yH@(9P$Z*k{=a zm-G%+_l(e>?jY6ol=8k_JKJncMDB$@C~b5(O5c|V&*nUh_4<>1uIfJRl^C#N_Gd&N zuA(7}RLDpcaf-|?{=vXJc^f@+aXJ>Ab5?wxoeB5#2;3PjAjLH^t@}WRK82QYTF#R= zWJq1xp(j6IPcN(-qb<>WIP`iyrLCJ|qp8PmUK9Aw%4vEj%Yh>%4uh(6_C}u$HCTm- z-U_&uZ^5m|hkR}IJn6m+qNavAq_{&lvGD=i6O@r5<&JZ4o!#-};AiJxZ?EKC8#z|A%7Z^;tFeA43_Iu)wfV~En>DS} m_OghVE%_R+WsA980jIYX{Q{=Sf|NlLjA`6e4%D5Mg|53053NLmH+?% delta 17 YcmY#Tm>|NlJiK*(zEHCjBLf2i04@ClasU7T diff --git a/opm/ml/ml_tools/models/test_dense_2x2.model b/opm/ml/ml_tools/models/test_dense_2x2.model index 41e038d7a4f2fdab58bf89f19623557893c4afd3..a4ae64789d0ec6cd20669bd691206ebeb3ca65c6 100644 GIT binary patch literal 80 zcmZQ#U|?VYVkRVfZ1*j@zlVeOFF$=?Pu#cJ`}2gFcjW*vBa&JW8-(Y7t=|7AVV03nzaasU7T literal 80 zcmZQ#U|?VYVkRWKwoTNQpYNRAV)j1!qzfwhQ-zwXl7*UgF(Ro2u|fFq-1Bx~+-vq_ I1J!`|0QZv)c>n+a diff --git a/opm/ml/ml_tools/models/test_dense_relu_10.model b/opm/ml/ml_tools/models/test_dense_relu_10.model index 9563cb5288cf6c3ac61a7573785f809b37e4ffd8..1621a7bfac620056023718493e358706ef29d2c4 100644 GIT binary patch literal 1384 zcmZwHe^AqP7zgk%2I7W4Kv2ZRuQ1Fc@VDW<&lgWmMx_!eDj=jHXreANBN!eDDQcpT z$puK{O@agjjh#~gbsVGa2!Vl}hM02tt!Pz**{R+@;= zrWxW&Mkt4Q)wr~#0KJBJbkAa6JS`qZ755^BjP;{w(QjDR*a+&U-zI zV}Cv^E?k3DKn{iqU!hm66??*$%O-{Tklea$=)30?BzL=G!cikG%IZgF04!g^W2+C@ z;8-V@{z%%4oSAWuet7_o*;iB2wH^3vW*W7)E)xA4~Bng%iJR5c-M-Y^<^*0>q9*j?ix~5~!#-KQ)BJMH^M5UAyIy#%JB2Mfo>K4E@joO~Q% zo3D^J-TDT4rE3QD;3?ALSFbm@Bs*s`Dh&b4W{UQ1ewJC29B!(;^*`Ed~ zzc#YHSWMQ$>)^**AAsALbY@X)0B}>LQciQOk&yEZD6{$u&o`9fvo9V%{JHb-HB zC>gl-X+BZJ*g|x4Dn_XV%*#%ePFh{Xfg>fDD+vy9dPEkvg^X z517}ahg|R`NBqQSZCHjawIjHMrXga125l>^kOj)`Feu|5$@7+B`prsk?X1VJU6)WX z{5j+g=0T^D0oQG6Y!AMHU#-?*j3fgeJYg_XF$@6%9Qut!FX&NigpC`DNV4m5JZJWD zF`h(8^fJmVX$vHI)?!!tB{Fxf1x?1@L7|HZ{@U9D#ufSIo6rTQvSOQZcpxmU#Bg;c zsN6FkVIhw-1+=15;3(uSZ$?|^NZ54WnvM0_0HU?);nKasIK8KrXd_jW{B0WBe|d?T zNeviYWQ})=`D|ch1ZPvSF92d~1*H7ij(q@%hX5!^GuYuxnT+H2mA|Lrp86LZEb{|0!s BfPnx2 literal 1384 zcmZwGdrXsO6bA4jlp+u;iYTsjC@Li&iq{Ezr(`fN8#BmoC=$UtL#MbIL}#Gbbt#Bi zPz0oEQK3j7P^47o_nr?G+=AjNFc1~3AlNA=sKt8SN=6p5>?BXlllT1j%WKVIv1}}{ z|0sU3M~IlKBNKS(RFJa{y~AvU6=`gYYrTUbAz}D-HoF#&lCl6Rkm2A{|Qf(?SNz1!=z#lTe#_q z7f3Jbra!OMK%*~*DM-6PX@~VVGJXQWTx+JGe=)6F?13(GZ;<;vdYa5|i*@+?jI+C;P3@)gt$628g5O?20?r|xwa=UaQK23AURdg(^g0n&P z%z@*-qxr!W2p4gH_bM2MnkPd<3!7<Qo#iB+Qx#{m9LG%yZOt)G@(w+i2-Ami>R0IlJ_jvDZqt z+}{hL>z`0dJbs0QqHl42VH;&$xewiPi(r0I7gj}ciCOCd@0`wqpdk_U-W=h@@UKz8 zErW*{CX5-X2lp&CigXt!kw_lMVteWmrV3!-k37gSEdp6sEoIo;6_|_z_=_L`b7%a9 zl{tqo#WowPsfhANQIwmcH`rb+m-`WAITOWZmJ{spg zswOT406g;wNb!D1Ue;L&Z!XzEX|8!v9?65K{`4-&Uvxr4Y6(?-|1}zn3n`ar%V9`< zl2Z8H!&U=>Rb@`3MAZ+pZV^oDt^;wC5&5n(7|PaB?W$JD56*$Y*LK1aqD}b0^ag65 zW#jFAU09%X1CjAuK-VT)P`K@+${k(c{TVeW-D3kk+_|L_eDV?+du@eNcGV$-nJ~5V zJo@ITP*$RZtUqNany#cnbqyfOt<`P6_5@O^t7)I5&E%_?LwK=105@Ble8)U3hX4M@ M@5XxE*dDd~8^0uevH$=8 diff --git a/opm/ml/ml_tools/models/test_dense_tanh_10.model b/opm/ml/ml_tools/models/test_dense_tanh_10.model index 82a4d5788f9023508a91e55248209573bfa84834..a621821157fe85de3e0e1c270450472afb9af8d7 100644 GIT binary patch literal 1384 zcmZwEe^kwP9LMqM-rG;Vq8}qmD%mKscB$)r-rwX$M@DSJnzQB>-HFOf)^u*J?xdsK zRx?RiNzynK8HekB-`|+qZ-uU|>gM)SRI1>xs7nf9wx`JkRU%{`~vk7#SIH*)0E; z_oQlw6G)-!`+nr{ILxM5S}-7o3iMK9O*fBO`ap$y6&>j3=Yr8n4prv;7+3WtB5OyTu4!DFF53wQ#aCE=v_-`+_=9F zPYYcjG;|bKMxKCnyL8xa)(;lgYRK7Z4}kxm9u6N|TXFnz(XW7ve}Kru+dzf#y`#moG8sa~n8md<1$<8NgJU z0EX2EkvQ68@tjAnGbR$&j`q?`6Ei_Hwt`5tJ3*~QVdr{lq^twM;)Oe8shUA|el_?E z3}R5UCFR`L3C>lY(w`*#3ab-d&?QgInde>>%*RLcMBY9M*!(jY&XSS(bPA5B=XfD>bB>Rk{%IOwW{b3W-o-OVsr9E;a$*{Su)H>EAb4Q1N^Bn zfq1G+v7K!fTL^mxvupqEFPz=)*gxKTER*^_0(Dp_`o^T=m7u-2B;Q8)mD5F#D7j3z zM+G@Ja0*4@vl#mgm$FkOLv6(!^qOFUKSkKXKJ^Gp=^j9_i7_R&GmuReUZdQi6x0oR zEGvJD37JpmBzHeZ^7Mgyxi85@c`@Yvt_A*017>HsVPt?m<}Me*231-yq-qB``*>z@lB)G`A_C1U$M@g*qJV(<8Fd+&+*$} Q{ok_Af(dLQwsFgU09=!fLjV8( literal 1384 zcmZvcYc!O37{Hk@u4%^RSVqFo}`slsjTd*Y1~req*TYU$)(vgrKvc} z;E)nYA#A0F_j$F-TDmxdGsx8F6d-<>*`tUoy^E_XF=XvI6X=&-O82*od zb>D)ut^p;tuZ5N_2f8l86_@xVy5@iDvXI*ii)R3XhU;w zf){`uUvR0V9X242F`zUI1Du~*A=33VzH93Nv8;xKx9Kp$A2tzQ=}Ii@=|id20nB`p zL7s$9&_UZyD$BD@p>@+R7;nx%64i@SCdQ1RrjqCzHRF|49I7HqkFs-#AUU#5bjq8i zkM_sVA+{M*ejVTvd*?GmpVsZw7~cOopjA5elLo;aJ&Gy6co5Y;P|nr@wK4%C)+9 zqTv?wrD}-p_;vcS`Y!Di3O}9!7VL3jK;U zqIou#DjCSauIuf1+b$jEnWw?!OD{2bQUEt=xXitMzXR7a104DDB?s1_x`^_#~q zB6t?1JNDB#^8syRQqjwi#_!uW)cyPJpvVlsg%)W<_mUH6jl^PbV;A{hT?#t4w83d{ z13JcR#zj%NP#-^7v*U&qW9%L$iV*r>-o-{tU7UzJ<=wE{TZ_`O z8p~=Y;p}7zG;OiKC<`NI^j_pOTTrdnv+RouG%RU8OvOcx7y#s}*B{hv3N>E@R!DZoU)Sp$s zLFW?SWDa78l>+a6LStCa02rBQV_+Df)8gf{A?FM8)uleEga0c4XBY9z3}X@`F1egSn6n|s_SiWM60KOFa#Xe|189vpZw?5+asXo_(guW6Q{XQC8VZ6b1 z_B}62&pjZ|SUv4a6Fm%(1HbfPS-#Hd@4lrC6+YEd2ERYi%{`zcu{@&A@4ovk)4tr? znm+E1F*{hl@IKE+%|41y!#xqs>%IiL^1dp5EI!dCsy?fexPQJpKk~d}-k(0w)`Y&7 z<@r4W<^n%!$^5)ZHGaG)7I{9Vq{KcfTw6Y(r4znd*ZID#Qlz_=K#e_GI9$HQQR6l7>z%$&9&Ej>V35AS$N4;=OoP68 z7U;gW;~G9S1%KH-Mxv1_urVR_fZSXt1 zob|sxI`Eu6cejZ?C)6oE5!0}~FYgFH4Z4B8EG(BkOSDG4>(Mg4Zic45yQ%3uzzF}o zzIUa*jBw<>GHdoeHr9{6mv=wD&CLS8`zD9J;*jV&;yd`GK7N4tK5+iZJ?n%UzMbIA zyA=|HIx7-`I{y)aI^Ge3Ix7)_x@QoBI#v;bIyVx7I^zz5x-1fdI+M%+95BqQs6H_3 t-abdb6+a?=DL>KxTfPD&Z9V*)&pwiO2S4o69=>Q@;yzIlgE|2K0061)`Jw;- delta 503 zcmYL^T}V>_9L2Y~t1Pi@EtBYj@?rVnM`fgT&rOYzsKp?yxf&Gpur!M(Bte$WkaD$Y zq-#sE7cE*SG1heV{;y*Ry4G4_Q_voSs8n=OF#4cYNI`-RUaowoFpu$~_v5MzHzgbz0-E6pzF*D8zij zj{G>y)ERq`5;Sw=x_WA2z2LN4Md6kg>Bj_OCcaX?x=m1~3V2hz6U!^c=t9^*BFbpI z`5~+oPSU+S4)?)`7@ZoVpt=wHGZ`uPL4aAZB0JDRq1eKy-Dp>tkhpshfzlW^v%OEW zTYf-)%0bDZRsAAcybg{27u=W7JMM(m z-Mpv3uRM6bkiGjkYCfT)Ouji?2fpp5Za$@BFuemyKRt$7>wi5101iE$j~zb6(*nK` z5{tYC@-jZvZB0Jh<=MT2){nh7m-D^iO4qy^>a4x`(}q3mpRc_xZR~C4a`5iFaJM29k@z9PiYlC_Dn!K z`n2Rddtnv6*+mV$mG0TPO*3meI@t6*bDeKJAwe-drW+H9J%2?(zH@>QydI6FJ>w-s MK5Y_%IspIx00hFsPXGV_ delta 418 zcmV;T0bTyQ1H1!}B!A%(~6uz7HV7@*(lfC{K7=OOWAznUOv}M7i+3Ko5DrDq$fbW zO{*b3K>3=z=1#ahU1vbPDRl0G)(UT*C@8xBG~az^02K#QimA`j`kX1e)3RkSd@ zz+0}p-2zEIF6quad}^Y-@3ber>qA&Rv9?=2;8PL4vKu>(J(bily$diVKCd^|JyyszPFsqLM# z);+U?586$1WZipU@gh5a4+T3F(b@Y9dZhLi1b*1t#&v&RjPPE&iuqsnMc=Ws3w8>$ z(_neHFOf0DZpw{k`vM}<_dVn4-#0IGg>V+?oLCv@eN-JS5~b`H~y+4OAPv(HeJVSj+gOxqMu z1G~77?fWv1uHN@V{Gy%Gqz88A?`hekO!{GW;Z(a_n$UK;S?W9Y$)vQ~Wec_J`?i1f zzO~uh_7fhxwhO3a-|xZrdY|sJTl+4sUE3$W=HI?I6Bq8|sxjX8!tI%DmweAY?HZQ- z#f|CvI_4bT7q|Q3z7TT;`wi|=b{0Guc2DB^_G$@n*o&~e*t>tG;J);QyY@9)7O{D_ ziEH1prSkjgCfe-FiJ!1{ivAJ1pxlG|E}D1R_RiURPeSmO-B%`ey9Vc1w$F6g z_Af1G+keG<`QAI+A^YYUFz-(nYTm^w&};>aA_gEEOoQ0SAO1nW3-ueeyeD_uGQY-v2*?eTznpU2Ns6eJ6gt*lTsP zecvawUc0D-wtb6kS?zo7`+aZyjlz9hTld;2H0Il_6I^1)GAYyUPV*l--aV)H87=&> z@1o+veKluX_bpBf-uum?*LKA*hkaklj_zH+Cu3`6_IBU22NUcx9x>TV9hz--v@+Ii z#_|TcwQ>Bm4jVf5C9zzy6L6hno8y1hPWVolt<2}regBku_w}T&+h;AGZr9ElW@pZK zecy+e7q&;lIrlB|G~c)B{tG*Y^<{Porg_<|n%TE+-t+Hvi{`$!ONqH)*W>HP~52f3YcJ{%*HTo^8L42HSpyH)Xp%SDoCqRCvBk z;eob&3rv*lj=8njolVo<=bR#9w_)>j+rDkJ`)uNs?Yfg$_CK8bbKixo-L@a9588dI zyka*sR(c=X`}cMaPRrXee3iBSv*yjd=}Is6B`j&%=b&l4r!wx%zL%52?A#}c*ztug zv)dIn$xdwBHoFhoJ8Ts;_w36MYPJGK4;Ul^*_lGkyK;aSCI+J!fecn4W&&aW*LBYT diff --git a/opm/ml/ml_tools/models/test_scalingdense_1x1.model b/opm/ml/ml_tools/models/test_scalingdense_1x1.model index 621a21efa0fb1b2cea661f1277b3ccc1e2110f2d..5906a8626157a24f060f33a3e6a36e66e9ba1d30 100644 GIT binary patch literal 236 zcmZQ&U|?VZ;@RKNAKsS!%o)f8f(CmQAjyb?)7~wz%NJ_4Vg-u9b)V~V}TY=2O!iU=dG8^WG zo9cD@mY*}&?|eyU@2uXhwsU{!+WEC@*;kw=vcDkkshyu^rOmgSg7zRYL2hIQVuYU> K>=_sqH~;{~-$&s9 literal 604 zcmYk3Ur1A77{)hiF_w)SxdewXSQl0j1(FT-o`H;}n029D#4-t+OOH`GNU{;zGzuyu z8^)q-Z62qwuKcqc=e$RPwMDXA!*3v#!K?U32kqAhO{&hspsFoUgWTGM=8K=|Zs;4D2rkh_c6k%zzV0TrgTPxrFj z^C=`{_7K+*y2SNxUVV=9rvF*0$gXbZvQF-v|0Cbe>&6Qjq)!Uik{LgeRu5Wl*zvR8 zjIE917!`}zePmWMI-O)qy0QLC^6*q#Qbk>C4vB#8cin4k~614~3id{mJT zT|W%z3niMqhB=(w9|P)+o4GnT&HOy00Ow4gI@kIgD#Bq*Clz?`@>gu5R9NSI22*=X z^m*PrHfNq-m%+IfPM#4Ggh4bhP+zbwa>0$}&s@ZZpA*i+Pn0vW&}wT|p~$ zFJGkB{BNP$VngMv)5vVrpmeDQ3gvM$P?Nyi9n)yv7Z6F`PL??D#n list[ArrayLike]: ``self.data_min``, ``self.data_max``, ``self.feature_range`` """ - return [self.data_min, self.data_max, self.feature_range] + return [self.feature_range[0], self.feature_range[1], self.data_min, self.data_max, self.feature_range] def set_weights(self, weights: list[ArrayLike]) -> None: """Set parameters of the scaling. diff --git a/opm/ml/ml_tools/scalertest.py b/opm/ml/ml_tools/scalertest.py index 282d8db5650..c9b195edd02 100644 --- a/opm/ml/ml_tools/scalertest.py +++ b/opm/ml/ml_tools/scalertest.py @@ -13,7 +13,7 @@ from scaler_layers import MinMaxScalerLayer, MinMaxUnScalerLayer from keras.models import Sequential - +from keras.layers import Conv2D, Dense, Flatten, Activation, MaxPooling2D, Dropout, BatchNormalization, ELU, Embedding, LSTM savepath = pathlib.Path(__file__).parent / "model_with_scaler_layers.opm" @@ -41,8 +41,12 @@ model.add(keras.layers.Input([1])) model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) # model.add(Flatten()) -# model.add(Dense(1, input_dim=1)) -model.add(MinMaxUnScalerLayer(feature_range=(-3.7, 0.0))) +model.add(Dense(1, input_dim=1)) +model.add(Dense(1, input_dim=1)) +model.add(Dense(1, input_dim=1)) +model.add(Dense(1, input_dim=1)) + +model.add(MinMaxUnScalerLayer(feature_range=(-3.7, -1.0))) # # model.get_layer(model.layers[0].name).adapt(data=data) # model.get_layer(model.layers[-1].name).adapt(data=data) From 5aedd89bf34f7068e23ccce3f35ddb0f8be3206c Mon Sep 17 00:00:00 2001 From: fractalmanifold Date: Mon, 17 Jun 2024 05:24:18 +0200 Subject: [PATCH 4/7] scaling test --- opm/ml/keras_model.cpp | 15 +++- opm/ml/keras_model_test.cpp | 73 +++++++++--------- opm/ml/ml_tools/generateunittests.py | 26 +++---- opm/ml/ml_tools/include/test_conv_2x2.h | 4 +- opm/ml/ml_tools/include/test_conv_3x3.h | 6 +- opm/ml/ml_tools/include/test_conv_3x3x3.h | 12 +-- .../include/test_conv_hard_sigmoid_2x2.h | 4 +- .../ml_tools/include/test_conv_sigmoid_2x2.h | 4 +- .../ml_tools/include/test_conv_softplus_2x2.h | 4 +- opm/ml/ml_tools/include/test_dense_10x1.h | 6 +- opm/ml/ml_tools/include/test_dense_10x10.h | 6 +- opm/ml/ml_tools/include/test_dense_10x10x10.h | 11 ++- opm/ml/ml_tools/include/test_dense_2x2.h | 4 +- opm/ml/ml_tools/include/test_dense_relu_10.h | 8 +- opm/ml/ml_tools/include/test_dense_tanh_10.h | 8 +- opm/ml/ml_tools/include/test_elu_10.h | 6 +- opm/ml/ml_tools/include/test_maxpool2d_1x1.h | 47 +++++------ opm/ml/ml_tools/include/test_relu_10.h | 8 +- .../ml_tools/include/test_scalingdense_1x1.h | 10 ++- opm/ml/ml_tools/model_with_scaler_layers.opm | Bin 128 -> 0 bytes opm/ml/ml_tools/models/test_conv_2x2.model | Bin 84 -> 84 bytes opm/ml/ml_tools/models/test_conv_3x3.model | Bin 104 -> 104 bytes opm/ml/ml_tools/models/test_conv_3x3x3.model | Bin 408 -> 408 bytes .../models/test_conv_hard_sigmoid_2x2.model | Bin 84 -> 84 bytes .../models/test_conv_sigmoid_2x2.model | Bin 84 -> 84 bytes .../models/test_conv_softplus_2x2.model | Bin 84 -> 84 bytes opm/ml/ml_tools/models/test_dense_10x1.model | Bin 68 -> 68 bytes opm/ml/ml_tools/models/test_dense_10x10.model | Bin 528 -> 528 bytes .../ml_tools/models/test_dense_10x10x10.model | Bin 924 -> 924 bytes opm/ml/ml_tools/models/test_dense_1x1.model | Bin 32 -> 32 bytes opm/ml/ml_tools/models/test_dense_2x2.model | Bin 80 -> 80 bytes .../ml_tools/models/test_dense_relu_10.model | Bin 1384 -> 1384 bytes .../ml_tools/models/test_dense_tanh_10.model | Bin 1384 -> 1384 bytes opm/ml/ml_tools/models/test_elu_10.model | Bin 536 -> 536 bytes .../ml_tools/models/test_maxpool2d_1x1.model | Bin 444 -> 444 bytes opm/ml/ml_tools/models/test_relu_10.model | Bin 472 -> 472 bytes .../models/test_scalingdense_1x1.model | Bin 236 -> 1884 bytes 37 files changed, 134 insertions(+), 128 deletions(-) delete mode 100644 opm/ml/ml_tools/model_with_scaler_layers.opm diff --git a/opm/ml/keras_model.cpp b/opm/ml/keras_model.cpp index 8553cda9f98..da365b068e9 100644 --- a/opm/ml/keras_model.cpp +++ b/opm/ml/keras_model.cpp @@ -162,8 +162,8 @@ bool KerasLayerScaling::Apply(Tensor* in, Tensordata_.size(); i++) { - std::cout<<"out->data_[i]"<data_[i]<data_[i]"<data_[i]<data_[i] - data_min)/(data_max - data_min); out->data_[i] = tempscale * (feat_sup - feat_inf) + feat_inf; } @@ -193,8 +193,8 @@ bool KerasLayerUnScaling::Apply(Tensor* in, TensorFlatten(); for (size_t i = 0; i < out->data_.size(); i++) { - std::cout<<"out->data_[i]"<data_[i]<data_[i]"<data_[i]<data_[i] - feat_inf)/(feat_sup - feat_inf); out->data_[i] = tempscale * (data_max - data_min) + data_min; @@ -241,6 +241,13 @@ bool KerasLayerDense::Apply(Tensor* in, Tensordims_.size() <= 2, "Invalid input dimensions"); + + // if (in->dims_.size() == 1) { + // KASSERT(in->dims_[0] == weights_.dims_[0], "Dimension mismatch %d %d", + // in->dims_[0], weights_.dims_[0]); + // } + + if (in->dims_.size() == 2) { KASSERT(in->dims_[1] == weights_.dims_[0], "Dimension mismatch %d %d", in->dims_[1], weights_.dims_[0]); diff --git a/opm/ml/keras_model_test.cpp b/opm/ml/keras_model_test.cpp index a26744fc2a9..0b3991d98b0 100644 --- a/opm/ml/keras_model_test.cpp +++ b/opm/ml/keras_model_test.cpp @@ -138,34 +138,35 @@ bool tensor_test() { int main() { typedef Opm::DenseAd::Evaluation Evaluation; - + // typedef float Evaluation; + Evaluation load_time = 0.0; Evaluation apply_time = 0.0; - // if (!tensor_test()) { - // return 1; - // } - // - // if (!test_dense_1x1(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_dense_10x1(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_dense_2x2(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_dense_10x10(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_dense_10x10x10(&load_time, &apply_time)) { - // return 1; - // } - // + if (!tensor_test()) { + return 1; + } + + if (!test_dense_1x1(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_10x1(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_2x2(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_10x10(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_10x10x10(&load_time, &apply_time)) { + return 1; + } + // if (!test_conv_2x2(&load_time, &apply_time)) { // return 1; // } @@ -173,7 +174,7 @@ int main() { // if (!test_conv_3x3(&load_time, &apply_time)) { // return 1; // } - // + // if (!test_conv_3x3x3(&load_time, &apply_time)) { // return 1; // } @@ -185,7 +186,7 @@ int main() { // if (!test_relu_10(&load_time, &apply_time)) { // return 1; // } - // + // if (!test_dense_relu_10(&load_time, &apply_time)) { // return 1; // } @@ -210,17 +211,17 @@ int main() { return 1; } - // Run benchmark 5 times and report duration. - Evaluation total_load_time = 0.0; - Evaluation total_apply_time = 0.0; + // // Run benchmark 5 times and report duration. + // Evaluation total_load_time = 0.0; + // Evaluation total_apply_time = 0.0; - for (int i = 0; i < 5; i++) { - total_load_time += load_time; - total_apply_time += apply_time; - } + // for (int i = 0; i < 5; i++) { + // total_load_time += load_time; + // total_apply_time += apply_time; + // } - printf("Benchmark network loads in %fs\n", total_load_time / 5); - printf("Benchmark network runs in %fs\n", total_apply_time / 5); + // printf("Benchmark network loads in %fs\n", total_load_time / 5); + // printf("Benchmark network runs in %fs\n", total_apply_time / 5); return 0; } diff --git a/opm/ml/ml_tools/generateunittests.py b/opm/ml/ml_tools/generateunittests.py index b409c5cec93..dc19b53e6b4 100644 --- a/opm/ml/ml_tools/generateunittests.py +++ b/opm/ml/ml_tools/generateunittests.py @@ -108,24 +108,22 @@ def output_testcase(model, test_x, test_y, name, eps): # scaling 1x1 data: np.ndarray = np.random.uniform(-500, 500, (5, 1)) feature_ranges: list[tuple[float, float]] = [(0.0, 1.0), (-3.7, 0.0)] -test_x = np.random.rand(1).astype('f') -test_y = np.random.rand(1).astype('f') +test_x = np.random.rand(10, 10).astype('f') +test_y = np.random.rand(10).astype('f') data_min = 10.0 model = Sequential() -model.add(keras.layers.Input([1])) -# model.add(Flatten()) -# model.add(Flatten()) -model.add(MinMaxScalerLayer(data_min=10,feature_range=(0.0, 1.0))) -model.add(Dense(1,activation='tanh')) +model.add(keras.layers.Input([10])) +# model.add(Dense(1, input_dim=10)) +model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) + +# model.add(Dense(1,activation='tanh')) +model.add(Dense(10,activation='tanh')) +model.add(Dense(10,activation='tanh')) +model.add(Dense(10,activation='tanh')) model.add(Dense(10,activation='tanh')) -model.add(Dense(1,activation='tanh')) -model.add(MinMaxUnScalerLayer(feature_range=(1.0, 5.0))) -# model.add(Dense(10)) -# model.add(Dense(10)) -# model.add(Dense(10)) -# model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) # model.add(Flatten()) -# model.add(MinMaxUnScalerLayer()) +model.add(MinMaxUnScalerLayer(feature_range=(-3.7, -1.0))) + # # model.get_layer(model.layers[0].name).adapt(data=data) model.get_layer(model.layers[-1].name).adapt(data=data) diff --git a/opm/ml/ml_tools/include/test_conv_2x2.h b/opm/ml/ml_tools/include/test_conv_2x2.h index b006f78cfa4..4289b617f41 100644 --- a/opm/ml/ml_tools/include/test_conv_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_2x2.h @@ -13,10 +13,10 @@ bool test_conv_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.062906526,0.34327188,0.7227239,0.17407319}; + in.data_ = {0.6796515,0.68067896,0.46129513,0.96068424}; Opm::Tensor out{1}; - out.data_ = {-0.05085864}; + out.data_ = {0.7798276}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_conv_3x3.h b/opm/ml/ml_tools/include/test_conv_3x3.h index 5f90cff2dc5..dc1430bdb30 100644 --- a/opm/ml/ml_tools/include/test_conv_3x3.h +++ b/opm/ml/ml_tools/include/test_conv_3x3.h @@ -13,11 +13,11 @@ bool test_conv_3x3(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{3,3,1}; - in.data_ = {0.31915146,0.46648613,0.713153,0.7186029,0.4189023,0.93898046, -0.21495701,0.22672214,0.6468133}; + in.data_ = {0.88527423,0.8638909,0.86746955,0.42614478,0.031315308,0.84676105, +0.8503915,0.3592089,0.098730415}; Opm::Tensor out{1}; - out.data_ = {0.012564741}; + out.data_ = {0.891428}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_conv_3x3x3.h b/opm/ml/ml_tools/include/test_conv_3x3x3.h index 1568e050726..3b75cefd5f9 100644 --- a/opm/ml/ml_tools/include/test_conv_3x3x3.h +++ b/opm/ml/ml_tools/include/test_conv_3x3x3.h @@ -13,14 +13,14 @@ bool test_conv_3x3x3(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{3,3,3}; - in.data_ = {0.99366415,0.8214218,0.78640515,0.2603204,0.16119346,0.33790612, -0.003531503,0.8499332,0.45968544,0.4627597,0.13754487,0.10913391, -0.14221385,0.6451374,0.84302205,0.4868773,0.083437696,0.27630988, -0.22067706,0.11169723,0.3520237,0.58716524,0.05329963,0.26573667, -0.4124315,0.18437439,0.74106956}; + in.data_ = {0.32681695,0.88247293,0.9610101,0.7766642,0.90783143,0.95788574, +0.25465804,0.14405063,0.30747658,0.29391462,0.88617074,0.7574131, +0.7840184,0.13056566,0.17718191,0.51664996,0.68511343,0.2752934, +0.3730155,0.7273659,0.070773244,0.6111477,0.55316126,0.14030892, +0.9425838,0.78347766,0.7334307}; Opm::Tensor out{1}; - out.data_ = {-0.32770187}; + out.data_ = {0.34363604}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h index 04e8c6c5b0d..c05e401eb39 100644 --- a/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h @@ -13,10 +13,10 @@ bool test_conv_hard_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.50463355,0.9183773,0.38787946,0.43078265}; + in.data_ = {0.86426544,0.8477615,0.5583865,0.5447023}; Opm::Tensor out{1}; - out.data_ = {0.32929042}; + out.data_ = {-0.8503885}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h index ba2366d204e..c72807478ae 100644 --- a/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h @@ -13,10 +13,10 @@ bool test_conv_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.91240454,0.20470788,0.9951741,0.7569204}; + in.data_ = {0.29207453,0.290471,0.13317004,0.9632514}; Opm::Tensor out{1}; - out.data_ = {0.0065397182}; + out.data_ = {-0.5019707}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_conv_softplus_2x2.h b/opm/ml/ml_tools/include/test_conv_softplus_2x2.h index 6549daacdc7..79767295fa1 100644 --- a/opm/ml/ml_tools/include/test_conv_softplus_2x2.h +++ b/opm/ml/ml_tools/include/test_conv_softplus_2x2.h @@ -13,10 +13,10 @@ bool test_conv_softplus_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2,2,1}; - in.data_ = {0.9781388,0.69906306,0.73934394,0.07835838}; + in.data_ = {0.96259403,0.20030555,0.8772307,0.76010585}; Opm::Tensor out{1}; - out.data_ = {0.6921864}; + out.data_ = {-0.5558099}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_10x1.h b/opm/ml/ml_tools/include/test_dense_10x1.h index beba5165363..d9a5a89fd72 100644 --- a/opm/ml/ml_tools/include/test_dense_10x1.h +++ b/opm/ml/ml_tools/include/test_dense_10x1.h @@ -13,11 +13,11 @@ bool test_dense_10x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.62656444,0.8955544,0.97843874,0.3737466,0.2596527,0.53862107, -0.0325291,0.7202331,0.9628396,0.22615331}; + in.data_ = {0.6118447,0.770052,0.16679357,0.8346833,0.7955753,0.25932008, +0.3465901,0.13505514,0.35986346,0.716514}; Opm::Tensor out{1}; - out.data_ = {-0.47586796}; + out.data_ = {0.91411453}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10.h b/opm/ml/ml_tools/include/test_dense_10x10.h index 1b6ecc675aa..48cd20f6409 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10.h +++ b/opm/ml/ml_tools/include/test_dense_10x10.h @@ -13,11 +13,11 @@ bool test_dense_10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.6189273,0.92638606,0.5629345,0.66560996,0.8742824,0.49490887, -0.6071822,0.51056105,0.012800761,0.45888036}; + in.data_ = {0.28370148,0.6116727,0.123164214,0.86745644,0.5565164,0.5560578, +0.56472105,0.34990314,0.8911647,0.41991234}; Opm::Tensor out{1}; - out.data_ = {-1.2550222}; + out.data_ = {1.1963887}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10x10.h b/opm/ml/ml_tools/include/test_dense_10x10x10.h index 1860f70bfb3..e4472dc69c0 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10x10.h +++ b/opm/ml/ml_tools/include/test_dense_10x10x10.h @@ -13,15 +13,18 @@ bool test_dense_10x10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.7104989,0.4149288,0.71831465,0.5625794,0.7118615,0.8625888, -0.35311338,0.70555335,0.19741295,0.6377552}; + in.data_ = {0.9307595,0.623219,0.26583958,0.58003414,0.030215342,0.06587499, +0.9004415,0.03221161,0.4206354,0.8563274}; + Opm::Tensor out{10}; - out.data_ = {-0.047795724,0.55596924,-0.08081586,-0.5206654,0.17288932, --0.5772272,0.45383403,-0.38085136,-0.5176138,0.2733392}; + out.data_ = {0.068457894,0.03991737,-0.30497518,-0.19265954,-0.32966894, +-0.6756333,0.4275365,1.121752,0.14004697,0.30182698}; KerasTimer load_timer; load_timer.Start(); + std::cout<<"in->dims_.size() "< model; KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x10x10.model"), "Failed to load model"); diff --git a/opm/ml/ml_tools/include/test_dense_2x2.h b/opm/ml/ml_tools/include/test_dense_2x2.h index 374c424e89f..b111553a215 100644 --- a/opm/ml/ml_tools/include/test_dense_2x2.h +++ b/opm/ml/ml_tools/include/test_dense_2x2.h @@ -13,10 +13,10 @@ bool test_dense_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2}; - in.data_ = {0.9365942,0.34521446}; + in.data_ = {0.89572245,0.11905332}; Opm::Tensor out{1}; - out.data_ = {0.086802945}; + out.data_ = {-0.94843066}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_relu_10.h b/opm/ml/ml_tools/include/test_dense_relu_10.h index e8858570810..52a4b8952cd 100644 --- a/opm/ml/ml_tools/include/test_dense_relu_10.h +++ b/opm/ml/ml_tools/include/test_dense_relu_10.h @@ -13,12 +13,12 @@ bool test_dense_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.64364296,0.36075893,0.28376237,0.41895798,0.6025532,0.035710134, -0.95477134,0.51287717,0.78825593,0.5268354}; + in.data_ = {0.17480424,0.53673047,0.9696888,0.86909395,0.7807599,0.45374545, +0.85382074,0.6236224,0.20212452,0.46260563}; Opm::Tensor out{10}; - out.data_ = {0.124458,0.,0.,0.,0.,0., -0.062164858,0.24708469,0.31542313,0.059695993}; + out.data_ = {0.16656388,0.018555019,0.027130837,0.,0.,0., +0.,0.027509432,0.03260679,0.039918847}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_tanh_10.h b/opm/ml/ml_tools/include/test_dense_tanh_10.h index d1c895469d4..0913b0fdef5 100644 --- a/opm/ml/ml_tools/include/test_dense_tanh_10.h +++ b/opm/ml/ml_tools/include/test_dense_tanh_10.h @@ -13,12 +13,12 @@ bool test_dense_tanh_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.26271367,0.57310253,0.4322339,0.018163363,0.42448965,0.6118086, -0.20635886,0.38553724,0.97148365,0.2353917}; + in.data_ = {0.1899011,0.3590567,0.284928,0.8981879,0.8274132,0.8743853, +0.025491558,0.18069586,0.19910076,0.5135733}; Opm::Tensor out{10}; - out.data_ = {-0.5350144,-0.36773947,-0.015882624,0.020122323,0.11873825, -0.42103818,-0.27925694,0.060885787,0.5043703,0.029599192}; + out.data_ = {0.49924585,0.54542077,-0.60667866,-0.34529728,0.15064734,-0.26957473, +0.05453661,-0.5642658,0.4621192,-0.19287723}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_elu_10.h b/opm/ml/ml_tools/include/test_elu_10.h index 5597d0483c5..87159a230cc 100644 --- a/opm/ml/ml_tools/include/test_elu_10.h +++ b/opm/ml/ml_tools/include/test_elu_10.h @@ -13,11 +13,11 @@ bool test_elu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.9834945,0.5741797,0.027460653,0.07063913,0.7403407,0.72907645, -0.009775176,0.309714,0.5252622,0.090779774}; + in.data_ = {0.18739146,0.70936984,0.9280732,0.62002677,0.40296188,0.1884241, +0.84437937,0.023707515,0.09143902,0.5966835}; Opm::Tensor out{1}; - out.data_ = {0.50609195}; + out.data_ = {0.589676}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_maxpool2d_1x1.h b/opm/ml/ml_tools/include/test_maxpool2d_1x1.h index 856ecc50537..510252f99e7 100644 --- a/opm/ml/ml_tools/include/test_maxpool2d_1x1.h +++ b/opm/ml/ml_tools/include/test_maxpool2d_1x1.h @@ -13,34 +13,29 @@ bool test_maxpool2d_1x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10,10,1}; - in.data_ = {8.05891514e-01,4.24958289e-01,9.78650153e-01,8.33032012e-01, -6.98836505e-01,5.28312251e-02,9.86697435e-01,1.75924480e-01, -5.77136397e-01,8.90503943e-01,3.50836873e-01,8.51357281e-02, -3.52928936e-01,3.79992664e-01,4.45006251e-01,9.93837059e-01, -5.55398285e-01,8.62534046e-01,1.73030049e-01,4.98871028e-01, -5.99020064e-01,2.93842643e-01,4.75706041e-01,3.08726907e-01, -6.87034428e-01,9.52807069e-01,3.84712100e-01,5.96658170e-01, -3.96235764e-01,1.40618477e-02,1.94596589e-01,6.25770569e-01, -5.62299132e-01,5.34520566e-01,1.95316955e-01,9.29202616e-01, -8.59472275e-01,2.36784384e-01,1.90333515e-01,5.04570246e-01, -4.75366235e-01,9.33640420e-01,9.12167579e-02,7.26325393e-01, -6.58039212e-01,9.39130664e-01,3.68637234e-01,7.78640509e-02, -5.77523530e-01,3.63632172e-01,4.44532394e-01,8.23739767e-02, -3.01169813e-01,9.15617108e-01,4.01109338e-01,6.52816117e-01, -3.36535722e-01,1.83367670e-01,9.86048639e-01,2.11613506e-01, -9.39686358e-01,2.76162028e-01,8.99377912e-02,5.59440315e-01, -6.95002973e-01,6.85773134e-01,6.95965350e-01,9.38641310e-01, -3.02985966e-01,7.37742484e-01,4.92526293e-01,3.16089630e-01, -1.87618837e-01,6.22452796e-02,9.46086943e-01,2.13588208e-01, -6.07565165e-01,6.22669816e-01,6.42262280e-01,1.74358606e-01, -7.60361373e-01,6.07401252e-01,3.88030050e-04,1.06557794e-01, -5.73728263e-01,2.31160838e-02,9.74358380e-01,3.07875097e-01, -1.41230553e-01,2.09358424e-01,7.70691752e-01,8.38017046e-01, -1.21261969e-01,5.75457394e-01,6.84708729e-02,5.65244675e-01, -3.90781015e-01,5.39179444e-01,8.40706050e-01,6.09158993e-01}; + in.data_ = {0.3584981,0.2958925,0.7605831,0.53394246,0.61106086, +0.0044219894,0.5463487,0.25235063,0.18157023,0.06756325, +0.8124267,0.8730054,0.0947123,0.80920976,0.8023841, +0.18305726,0.1803083,0.044107396,0.8450164,0.5707187, +0.627845,0.49776414,0.7567636,0.22644873,0.17683746, +0.09286818,0.16009343,0.5313456,0.95800453,0.32112077, +0.91887784,0.57785136,0.38100433,0.30305266,0.4294771, +0.74898136,0.24068417,0.24434112,0.4277804,0.66749835, +0.2807149,0.5275129,0.64340687,0.2915763,0.032093775, +0.7258795,0.5505952,0.68428564,0.41406462,0.91326606, +0.22276446,0.8068874,0.80964404,0.26798266,0.96306396, +0.18655908,0.91054565,0.005801419,0.9993052,0.51641726, +0.8414052,0.45861587,0.9145516,0.51948214,0.88117427, +0.22991507,0.053036828,0.6385797,0.68001044,0.739364, +0.56692076,0.36897555,0.39697468,0.5334803,0.19781172, +0.7582431,0.1215363,0.1281851,0.5813795,0.98001736, +0.84356993,0.70857924,0.6370623,0.54709303,0.9008569, +0.73727363,0.53235346,0.7178515,0.8857483,0.80863845, +0.26460695,0.19305061,0.3812545,0.018899608,0.7839583, +0.9368291,0.87295556,0.17056823,0.46442586,0.91270417}; Opm::Tensor out{1}; - out.data_ = {0.82167464}; + out.data_ = {0.79461604}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_relu_10.h b/opm/ml/ml_tools/include/test_relu_10.h index d2694135d46..2f60bbac2ca 100644 --- a/opm/ml/ml_tools/include/test_relu_10.h +++ b/opm/ml/ml_tools/include/test_relu_10.h @@ -13,12 +13,12 @@ bool test_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.34561083,0.045264732,0.75015557,0.8151314,0.2287286,0.7522012, -0.01585116,0.17131925,0.4055651,0.35491937}; + in.data_ = {0.37697044,0.6427236,0.89172053,0.73344576,0.11428697,0.40963235, +0.81641096,0.6176922,0.6046866,0.9238176}; Opm::Tensor out{10}; - out.data_ = {1.0254096,0.043472286,0.,0.39489448,0.,0., -0.,0.,0.,0.026771469}; + out.data_ = {0.44721743,0.,0.61811334,0.5108469,0.73356915,0., +0.,0.,0.5264998,0.026750417}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_scalingdense_1x1.h b/opm/ml/ml_tools/include/test_scalingdense_1x1.h index f3b7d93d9c0..2b0c69a7716 100644 --- a/opm/ml/ml_tools/include/test_scalingdense_1x1.h +++ b/opm/ml/ml_tools/include/test_scalingdense_1x1.h @@ -12,11 +12,13 @@ bool test_scalingdense_1x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(load_time, "Invalid Evaluation"); KASSERT(apply_time, "Invalid Evaluation"); - Opm::Tensor in{1}; - in.data_ = {0.5439535}; + Opm::Tensor in{10}; + in.data_ = {0.35745713,0.5183338,0.43530357,0.7207405,0.96301425,0.47163334, +0.10632531,0.49405062,0.48787624,0.23182626}; - Opm::Tensor out{1}; - out.data_ = {-633.0674}; + Opm::Tensor out{10}; + out.data_ = {80.98062,133.76828,113.56729,180.86313,126.80325,148.15707, +111.01114,41.78473,51.552124,153.05319}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/model_with_scaler_layers.opm b/opm/ml/ml_tools/model_with_scaler_layers.opm deleted file mode 100644 index eb518437d3b8bc31f382f88a54e0784612057553..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128 zcmZQ$U|?VZVh~^fVn!sal09)hNE{@FF4wr_wmmMn3lDGX!zH)r+a0)>%s@o|A~Oo) diff --git a/opm/ml/ml_tools/models/test_conv_2x2.model b/opm/ml/ml_tools/models/test_conv_2x2.model index d8335c5287e8e33164791ff7d81dcf1f742198d8..2427ebe5545682e4d632f5fe1eb97d9d2b5679b9 100644 GIT binary patch delta 41 xcmWFunII#wJ}hcqF}MCcueD3}MKAW=mn+n4HPJwV=V<1#{dq#oyBHZ57yw{@55xcf delta 41 xcmWFunII#QzMs?XTttX{f$IEy5=js3a)p|AO*D|;Iisy)x@ zHa@L4AH6#c2tEsr8NRy$IzFl>48EVOnmz~km_BTDj6LIc+kZXi38}u{u*SWW0B$}% z^4YzZVxhj5D5pNj5b3>Ns@%O$5SYG;3Culea9h1SO_RR5voXGUa#Ou!`l!CEAjUn{ zqv1V>^?|ioG>g6v%u;E-083%M1@sv`;a5&RZ&sK->gA0+VoTyZRr*~$BGr>U6K^)XV$GU8 zvDySa4V5fD?U_$KCVj-b1qpgzid?>*XXs=i6# z9Xl{te!iWORz7utLcYsLGQNG|Y(Ax6dA`BQc0Ta;G`^8sjDJ4C%4$C6G>txEqmw>a zP=!1@&2YWSRr$S3370-nO^?1ce<(h+haEnEST?@k4P?I8vFE(lah<-?+)2H{wu`WR5MiX*~3erA}yW)G;oKBJkw9~-DXm7Y4i z`wE0U6j_(P1uX-;(f3xRWO7;ZW4pKZW4pKZxVw#lWYMP6gq-~zcVar QzxhvhKW-9(IspIx0GWWY-T(jq diff --git a/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model b/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model index 540e853cdab52f11dd176b150dbbff156d6cf7c5..fc82dd1aa73946c35fa83cd408e8001eb28e7553 100644 GIT binary patch delta 41 xcmWFunII#wD7SgvvnCCD$wP7bIHM2l%M)teHPJwVr_kx<{(PZkD@Fze1^{UE4~_r; delta 41 wcmWFunII#wz4y*O2Fs;;WxDU#DU@m0*$XvWO*D|;c|KL!J_E>RWME(b08GvevH$=8 diff --git a/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model b/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model index 81a4410cafb90dd8dac45e1dbff153e3d596e031..69057aa2371eda0c9adc92bf1154066fa24667e3 100644 GIT binary patch delta 41 xcmWFunII#wMYGwiu5tH1kAMkwJFMT^lW{i3SopvsXQ{&J$|3Vq{=o0032U4r%}Z diff --git a/opm/ml/ml_tools/models/test_conv_softplus_2x2.model b/opm/ml/ml_tools/models/test_conv_softplus_2x2.model index a029dd7ab4cf4a0dc971ccff5b8edc6bc2b41f5b..61f0218aedcb4479959e0324bd03af1e46bf18a1 100644 GIT binary patch delta 38 ucmWFunII#0*du$d#p^};DoW4UaVc}#=T6j>=2>0Ax<5~-*@}^YfdK#|XAJ`Y delta 38 tcmWFunII#`ox!Tbke$0e3ijN-BxTn=nMRg84kY9rsCt=zzD|KjRayN-S5_Puf6v5&b`dtZ$IQ@a-p z^Y+Cayt(gH+}3>;E7?y#rE@DW_#{dUc2%LjeQMI=GeWT7H+pRq+#E43-@5%$xSwI@Z&H=JPe2^MOq__mJ zL0Dz3%6{ckC)-0c)Au@L?zj6b{dnKXAO3b$J`}$r!+G|rXZC~v}2U~@{6?PVE zjQe|S#O>m5-nZ4(XWG9m`^>%*`m^_??Rj9waPY8Q!l8CMWo>RdjoL$YvU}77O**D#6;=W94_I>k@*zfD+d9lx?bCzB7?)&@J zdIZ?bh`nStJA&IT!eHXQO&vXZpXjjL9ou`%uIuq_Tejriw)gKa?0?C{ZYR-oZTCYD zF8k;LS36^wXxrlcllu;>+Gv->KE>|DnI(3ycXRhLRjt@Jt+dZBAb-I=h9wK_il+tJ zHtx*ZmpH9!Uuy}2{mmGbeTN;3Z1;TFX~%Z4X-{6tecN|BTlQ`&WZGY%ddcpjJ)EFWm>Fi|@@kswe=qf4Yh~_a}=uL}`9@@B&2Y0~?4sP~mYp>M9?Q;)n@&jqiqlYY}7^+d3 zxt)zgXo|SYT*CG2aDJWYK(L%X7nk9*z8RX5M#@@u72(tE>{g>#E&cO1@;h{&8Y{;k z|I!l{MH_C+zk=#Vd$FV9EL;hXu&8gL$e}0XD|(MB|3Qn8qb*cxF6W-RJW9s?E-cJl z!dHK-RI49OF}KA|1L@!3nrwt?^a{Y+pDnPeu#?@kTnjb~I;d0=z!iKe!3N`9d{owo zJ^fSERAEzj&cxHtJF}p;DOP{&@1WIo2jw#dLPks^`81SLN)-GJqs$==>pG9HjHnwd zvFQSNNBE$5>lyNI-$j2WP%U`P^R#i!S`f7mv_SdaXI>G2T3|QP?K;91<~>NV7eT}$U;@* z`c_h9TIoo|elD|jD_LXHs4JqEf`olI@NzE#4@N_yv%}RnMtuzvkm*9X+lH0)=(KJ0 zjO#m`pW95%iFssSJVCjapJf5PzvIWbzo}?ehmh1Uym3ivkFRjig@9qzJLv-~B{iJn zrsMEcu23&&Vp&#U0i{X);IuDwb%$3DsAT+K5AFU5a=v1wq?Bw?TBDAk@et}qliH1z2R1)lEciJw}NTe3C zl|)8!C7msj+KbIji1cge6$`F^~sNEQ|Td6 zgdL_gZ@aPY@qXO%m}DZ4TFRcd#gcYeN#6PdF{xox)-cFLJxJ=_kyAz6t#5HhOJg|M zhi05lJVTy_cQJflV*e@nS2T>wp#JnEw7jo$o_##oJj;!`jR_YnszVF{rcv2@tT^y1;blyB@0+ngq;pB>y zNKsDXVIq3eWT$gFAMlW|-)BU|8S2WzL7pWIVpGH5c)GFKYBT@nkN$Yw>;1XUpRe$+ zurOhesQ(~-Vl(uAw$Pr=0G61QRPb6UUWylT8xE`JK)WBRF+Hj`H!+cdAilmDy@h6Y zYBXR{F?%-JNbBG5lFw_Qh!PvlPHHJ&^x(1lG`L-VD-6#2^ufXi>&|+b8bxNL_SW(G z;UC$~#VM!?3}U!A%06#A#QXs_#kkyHmJ#Z|NVXYYrc&ZKg|*T7R4i06!I+PlduEXN zOeA-q;|2oldof+`7rvRDLTRaxGrj*6oA>_AjEYZfHFr+%WuIlx;{A8YDmjms!+k75 zZe%4MC3SjqXsGHyqjMPU=${l^!}FB2Af#nicGH>;p*?lqBvennN9kv-^4zrxWXf_; zx_k=arf}}dW1sM9!vJ=Ba@pu~Jvwh~LoUk%?YWNR)_OD_yo5C|y$}TA>Fq8Jx@1{c z-sXkx^gg`#_+^%87-hSv6EO7aZN6ql2PW(0s9_zUltoe9U@GOkrAK{QB~`>~t?D3^ z4;|XuVzu&+Lu?H0&@K3%mLH}Kk-GUdzEw9<_ttoFO`W5<$SBHlL~=d9h`6fpS(3is zU}dcnEXF^Df|hcq&Hbb{^^&gbE^V4wg=yU}jQlR9nx__EU3Y@7eeoXV_LuR}1fhLn z;XDn=+NtrHy0%-^LAc_q(_HKgEsW* zjw7W)%TMMA$Z8rvkh2eXi^EXh!Ngv|UPeO7{Z_8*J ok07Klg4FCWD diff --git a/opm/ml/ml_tools/models/test_dense_1x1.model b/opm/ml/ml_tools/models/test_dense_1x1.model index f87b9ded7d54af3ba26cdf5f06fd2743536c030c..4d9f017f6f1da30ac79c9d6927501319b84a8ab9 100644 GIT binary patch delta 17 YcmY#Tm>|N#vnY3ezEHCjBLf2i04V|l3IG5A delta 17 YcmY#Tm>|NlLjA`6e4%D5Mg|53053NLmH+?% diff --git a/opm/ml/ml_tools/models/test_dense_2x2.model b/opm/ml/ml_tools/models/test_dense_2x2.model index a4ae64789d0ec6cd20669bd691206ebeb3ca65c6..0ee9163a62d7f0c777b6628b5fd0374d6bd75a7b 100644 GIT binary patch literal 80 zcmZQ#U|?VYVkRUkBNDN{BCT(K=prGz<%dM<^MsnMK$sCpEr<=mcax&+lT6p!!Q=t% C+zp@r literal 80 zcmZQ#U|?VYVkRVfZ1*j@zlVeOFF$=?Pu#cJ`}2gFcjW*vBa&JW8-(Y7t=|7AVV03nzaasU7T diff --git a/opm/ml/ml_tools/models/test_dense_relu_10.model b/opm/ml/ml_tools/models/test_dense_relu_10.model index 1621a7bfac620056023718493e358706ef29d2c4..dac1b5be1ceb0771c30b271926e1614e555bc6b2 100644 GIT binary patch literal 1384 zcmZwGeNfDK90%}U+oshMr6JX^da~y#t%=zBel{eXFmWq+UX3H2oGV;I?s|}051|!m zBcUrB*Ta@8{C=O`Pu=X*PCB+MDSEibP%0{M-MP9uGsfI^<~`rfeBOV)=3`7z6n{8o zA7rwB4z_GS=v3UrbN$6&yR!_Q*$!f~a1Q3h{Dl$E>mV>A1*5eBmY+El+taLI!VEKZ z+Tm4r!2CSgy0-v7qZu{s=29oCgK#SNFiy+82I-T^iNRVAYn+YP+fnhPr^AfINs%-QM%r|~zEi3Q%RSnX;eJrfML zwg#{wqmvF2)uCDGRID;MfPH5!EDzGala(q6@hXCxVk4>DU@0lns_E<|3E24uFKVc`3EzRffx)xK)F_{%qTi09r0KkV#=Wi^VkO-odrzLL=&JQ0wuNad<+OkA+@|? zxVIn`W4{>-SL`RF{8l@;?Qe-~A$eF;c#&-9He=fFz34Nu0K0rmS$zTxaf_8W=B6nt zPt2yXiW;%5P>J>HCcyoZ6r24v(~lB9A(5}D(XMs?% z;|6RJRpNllQCwtE29ocRP_Mm#ZvIQLV8DRwx3;2U86RXnakwq~HQIiw0De~#_-ENO z7Ge(wzwinpXSag)PB&OS>=*H$VTbjt*gX2iq;80Pv1 z+T}NcjbjST^JoJ@{slO?f-mJZ&jLrC9i&H9km*jNSn!Ufw=q~L|2W&w=T2MXG$X$sfAe3pabTPnm+GgEZsOTm9+SJkf$)34en0B zKHbky?l^=!+g1^;uoa~A{y})zR)Aq!t>IK-Fg9hi!D9z=)w1N4gQq FzX959WK#eD literal 1384 zcmZwHe^AqP7zgk%2I7W4Kv2ZRuQ1Fc@VDW<&lgWmMx_!eDj=jHXreANBN!eDDQcpT z$puK{O@agjjh#~gbsVGa2!Vl}hM02tt!Pz**{R+@;= zrWxW&Mkt4Q)wr~#0KJBJbkAa6JS`qZ755^BjP;{w(QjDR*a+&U-zI zV}Cv^E?k3DKn{iqU!hm66??*$%O-{Tklea$=)30?BzL=G!cikG%IZgF04!g^W2+C@ z;8-V@{z%%4oSAWuet7_o*;iB2wH^3vW*W7)E)xA4~Bng%iJR5c-M-Y^<^*0>q9*j?ix~5~!#-KQ)BJMH^M5UAyIy#%JB2Mfo>K4E@joO~Q% zo3D^J-TDT4rE3QD;3?ALSFbm@Bs*s`Dh&b4W{UQ1ewJC29B!(;^*`Ed~ zzc#YHSWMQ$>)^**AAsALbY@X)0B}>LQciQOk&yEZD6{$u&o`9fvo9V%{JHb-HB zC>gl-X+BZJ*g|x4Dn_XV%*#%ePFh{Xfg>fDD+vy9dPEkvg^X z517}ahg|R`NBqQSZCHjawIjHMrXga125l>^kOj)`Feu|5$@7+B`prsk?X1VJU6)WX z{5j+g=0T^D0oQG6Y!AMHU#-?*j3fgeJYg_XF$@6%9Qut!FX&NigpC`DNV4m5JZJWD zF`h(8^fJmVX$vHI)?!!tB{Fxf1x?1@L7|HZ{@U9D#ufSIo6rTQvSOQZcpxmU#Bg;c zsN6FkVIhw-1+=15;3(uSZ$?|^NZ54WnvM0_0HU?);nKasIK8KrXd_jW{B0WBe|d?T zNeviYWQ})=`D|ch1ZPvSF92d~1*H7ij(q@%hX5!^GuYuxnT+H2mA|Lrp86LZEb{|0!s BfPnx2 diff --git a/opm/ml/ml_tools/models/test_dense_tanh_10.model b/opm/ml/ml_tools/models/test_dense_tanh_10.model index a621821157fe85de3e0e1c270450472afb9af8d7..c2c9808ebc0833c1dcdbfb4ea56a206df527b904 100644 GIT binary patch literal 1384 zcmZ{jX;9P!7{(Vth(!~{6orwju@F-v)Is3?t~P?ETq`OJ5Goop93iMkGm7K_aSI}% z$u$teH6bDcvh4p^4ihvvb`fx45t2jhI6Oc@`s4JW5B1?U&-1=tfAgsFcsw-@{=blS zJtv2%caZDZu);%p!IihKXuP+(L}F*IFa8gg;?4|9r80|(4BN=5UP#$?UC1BJLwX>7+0 z312#J5E8NbD7|RkicT{v!NYCguzBt%@#>wX+3^N+OEd(<6>ji;CPPk;rr^Q7Q5;g} zq1+>zag?hH+%xjAYgG$PJdrU~$?ZV$2%RX?6z~VV$l0}=)E{NjRLxCt(hg%|O;r%% zUX8RMCp7w`Qe8wdbA+Eu`$D`a&vhP0bmK8*f1U~Z*bJ3JdQeU#A=pa+8+92q?~146 z?a!g7IEs3kT$tuv!9->#T)K-S293eAcY`0bnrKMJRkEo*s+8opO0o{mm0Y?UN_JmG zQplf)l-0L~WIFzA>e9o=%m_xSl|Q*%7h9h7tz>om*3bv%ZXj9}q?V*E4X%9%cuwLb zZ!Z<_`e<$XtmNA14z}Ah5$EA%q5xFD1e+@eIsre~=^w zIi9KY*vcrIYUujUv1Dc&Mc<~U<7S=?QkWvvjdOOGbH%xPzr}^* Ryqa@+eV+?kUHC2R@^5$}rRM+u literal 1384 zcmZwEe^kwP9LMqM-rG;Vq8}qmD%mKscB$)r-rwX$M@DSJnzQB>-HFOf)^u*J?xdsK zRx?RiNzynK8HekB-`|+qZ-uU|>gM)SRI1>xs7nf9wx`JkRU%{`~vk7#SIH*)0E; z_oQlw6G)-!`+nr{ILxM5S}-7o3iMK9O*fBO`ap$y6&>j3=Yr8n4prv;7+3WtB5OyTu4!DFF53wQ#aCE=v_-`+_=9F zPYYcjG;|bKMxKCnyL8xa)(;lgYRK7Z4}kxm9u6N|TXFnz(XW7ve}Kru+dzf#y`#moG8sa~n8md<1$<8NgJU z0EX2EkvQ68@tjAnGbR$&j`q?`6Ei_Hwt`5tJ3*~QVdr{lq^twM;)Oe8shUA|el_?E z3}R5UCFR`L3C>lY(w`*#3ab-d&?QgInde>>%*RLcMBY9M*!(jY&XSS(bPA5B=XfD>bB>Rk{%IOwW{b3W-o-OVsr9E;a$*{Su)H>EAb4Q1N^Bn zfq1G+v7K!fTL^mxvupqEFPz=)*gxKTER*^_0(Dp_`o^T=m7u-2B;Q8)mD5F#D7j3z zM+G@Ja0*4@vl#mgm$FkOLv6(!^qOFUKSkKXKJ^Gp=^j9_i7_R&GmuReUZdQi6x0oR zEGvJD37JpmBzHeZ^7Mgyxi85@c`@Yvt_A*017>HsVPt?m<}Me*231-yq-qB``*>z@lB)G`A_C1U$M@g*qJV(<8Fd+&+*$} Q{ok_Af(dLQwsFgU09=!fLjV8( diff --git a/opm/ml/ml_tools/models/test_elu_10.model b/opm/ml/ml_tools/models/test_elu_10.model index aa8c862bc224b25c5ec24056cbbacea9f4b22e77..8a506a707e0c0293894e78218bcecfd6c2e118ea 100644 GIT binary patch delta 503 zcmV1egSn6o2#zzdbgLs=g!d1-`rw*SwfeG(Gw-cfRSP06yp+9X_SGFh0h- zx;}qrSv+om&pzQ23BSgP#6DS^3BQ`_sXhl|0zXmE`@P=|e7;iwLB5oD!#)sKQ9VdV z`n_V)=)U}~1-xns?>@e&y*`Ex2EWKKkiPY6M!v`ysl7zn;(tCKS53a|;oiPTbLYLC zUmZPab^pC{!;ZeDJifhzVDr971NJ?G>=8axx}-i|UIf14F9^RXAJabCHQ_#}R0F?}{ms6B_XEEV!rHzP zHwV8qG>yJG!hi8TJ{#P=4xqWcmLU2*?#-M&x@AfLgsh^DBD37Dwzpx<1%G0uP-&!#h0{zQPNdzE>RPJ(GQxKFTN} zye1NZx&;!0IvWy$x@QuDIw%r@I%5)px@QuDI#&{dy4Vqex>^#0x|7TS95A3PgT3{p twmngoIKKKa2|ptTXFe};%)XGk4nNVdF~8YLoDE5B+IgE|2K004pZ>u&%6 delta 503 zcmV1egSn6n|s_SiWM60KOFa#Xe|189vpZw?5+asXo_(guW6Q{XQC8VZ6b1 z_B}62&pjZ|SUv4a6Fm%(1HbfPS-#Hd@4lrC6+YEd2ERYi%{`zcu{@&A@4ovk)4tr? znm+E1F*{hl@IKE+%|41y!#xqs>%IiL^1dp5EI!dCsy?fexPQJpKk~d}-k(0w)`Y&7 z<@r4W<^n%!$^5)ZHGaG)7I{9Vq{KcfTw6Y(r4znd*ZID#Qlz_=K#e_GI9$HQQR6l7>z%$&9&Ej>V35AS$N4;=OoP68 z7U;gW;~G9S1%KH-Mxv1_urVR_fZSXt1 zob|sxI`Eu6cejZ?C)6oE5!0}~FYgFH4Z4B8EG(BkOSDG4>(Mg4Zic45yQ%3uzzF}o zzIUa*jBw<>GHdoeHr9{6mv=wD&CLS8`zD9J;*jV&;yd`GK7N4tK5+iZJ?n%UzMbIA zyA=|HIx7-`I{y)aI^Ge3Ix7)_x@QoBI#v;bIyVx7I^zz5x-1fdI+M%+95BqQs6H_3 t-abdb6+a?=DL>KxTfPD&Z9V*)&pwiO2S4o69=>Q@;yzIlgE|2K0061)`Jw;- diff --git a/opm/ml/ml_tools/models/test_maxpool2d_1x1.model b/opm/ml/ml_tools/models/test_maxpool2d_1x1.model index 3458c4caf3edd8142cf3abed8a2e2659d1a5bb5d..0773beb5a1eba05463ef600b3065bc97e6a5fbb7 100644 GIT binary patch delta 418 zcmV;T0bTyQ1H1!}B!2^dRXzA%cfR|HPQETx+dW!Wi9J`U4L&(2H@FKt4rh6+YD4TD~DS0=-R47Cw@Z z=e;hDL%OKojJ+bQjy*PPLpyg31-_FrXFa2|Ilg*McD{FH9)CUx95lPSKE%C^ELc9; zUdTO>Pg1=O#Zta^24BANQO3P7fH1xaHn}~8QyV@n#z#JX>+!w9nn1p$eUCj~P+dN) zuP{7zcj6)x5mP&knu%J^DR8HUU1`q%yu<^u9fYhflsc6Dd9=tua0wF;YI| zO9s6GpE5peC4Xx^n!VjUeHv!IHgKA~sa!0*O%h7IBF`7Rw)t1SzYa;h6@@&$SJO+r zTr0FYA}NnO7TMxGcR55pE#GIpOPxSIv^Utj-MltFO1~DnA4o^Oj&8}lp)XuMhdrJ= zeqgyh-nfjtfbw;|kt1(Dd%;>hSt~QX2DOttZFvGdZyPs5KGGB}ys0}UzBwB1yaHjd MJ#G?%IspIx09zBcod5s; delta 418 zcmV;T0bTyQ1H1!}B!6@GM?Ks{89sPrv%ORb&%N1+h`d?w_q|4-{XJC;Xg=b??!CDY zGro2cKfbZpHoi;weLW4@F+NLzWWFu@UOaLXqP^X`HNFX7b3U2qF+REAUA`6~t38>m z-Mpv3uRM6bkiGjkYCfT)Ouji?2fpp5Za$@BFuemyKRt$7>wi5101iE$j~zb6(*nK` z5{tYC@-jZvZB0Jh<=MT2){nh7m-D^iO4qy^>a4x`(}q3mpRc_xZR~C4a`5iFaJM29k@z9PiYlC_Dn!K z`n2Rddtnv6*+mV$mG0TPO*3meI@t6*bDeKJAwe-drW+H9J%2?(zH@>QydI6FJ>w-s MK5Y_%IspIx00hFsPXGV_ diff --git a/opm/ml/ml_tools/models/test_relu_10.model b/opm/ml/ml_tools/models/test_relu_10.model index f31f58d2689164e4d8bbe577dcd1e1f82adf5e78..e5eea91cb471817bc062c2aa38c7ccd6ccd12a4a 100644 GIT binary patch delta 462 zcmV;<0WtpA1K0zQ6o0>k;yvPLrM|X?tv(&|!Mt=%%|cBac1j1K>R(1Sh^zkSIPtZGOH)X{5c0?4!QG z;RU~lEZaRr6tleKfX}|7KS?M=S%!MZ+jvEn{94~D+m zMf1L`#I(NCC4U0HB)n<9Frj)qj^|Cjf8eUVX6rD%8PIP&tb(0B^a|@fRcs!<>ScgF z{tU4`=mDv{urUC?Sj<{JBA&87{^W!{qhAU?8DEjU(MYE~Mtbl*gg;Kah)}RTtij8@ zI9G|j$2CYk-{6J4d+BFB3g*f_DLWQEsgnsm5XWggK}Rh8zAS5my~ywgzLb_4zOvBF zJ!KMux&QzG09z7+I${!ox)>6JIsgCw00000000000PzunI%5)pIspIx00jU500IC2 E0DPX@>Hq)$ literal 472 zcmZQ#U|?VYVlE{7`;NR_^|JyyszPFsqLM# z);+U?586$1WZipU@gh5a4+T3F(b@Y9dZhLi1b*1t#&v&RjPPE&iuqsnMc=Ws3w8>$ z(_neHFOf0DZpw{k`vM}<_dVn4-#0IGg>V+?oLCv@eN-JS5~b`H~y+4OAPv(HeJVSj+gOxqMu z1G~77?fWv1uHN@V{Gy%Gqz88A?`hekO!{GW;Z(a_n$UK;S?W9Y$)vQ~Wec_J`?i1f zzO~uh_7fhxwhO3a-|xZrdY|sJTl+4sUE3$W=HI?I6Bq8|sxjX8!tI%DmweAY?HZQ- z#f|CvI_4bT7q|Q3z7TT;`wi|=b{0Guc2DB^_G$@n*o&~e*t>tG;J);QyY@9)7O{D_ ziEH1prSkjgCfe-FiJ!1{ivAJ1pxlG|E}D1R_RiURPeSmO-B%`ey9Vc1w$F6g z_Af1G+keG<`QAI+A^YYUFz-(nYTm^w&};>aA_gEEOoQ0SAOd#_6>0%=4b#IUmpS;TY=Z z=;&$rNByvhF?Fm4uwtf;86i+|>GzGUGGX|fV z;eZ(wi$n%&tH&^^vMTAtXc^Y7P(h^404===v?MB;c&fMr?N~ULJ_K#zOW<`wpA}8S z!!BQn)3fejYNS0LuXBfnmK}I1%Mu#-<+PQ{VO&c+@oUZ~4wVR?@JA87n39Q&%Io;? z_gtpz7YMW7}|j_V}Lrfyu>AmJ3--~MkiS|7^{R>8oq^o z7WE&HyiBH{re5e*qRWJ~aPjMz;wq6AZFQMKo8Q!_`R`2iRUECuKf3H&ucpoC7C__L zVMxt7K>W9*(#pCP*tmQLoEZ89*GSKhWwvv$qpBKKT{U99+1-vED?1@@-apZ6##u;M zyceIWyZ|2*$ie;N5)AHr4sKa@!RH$h9Zp?@ulpa8wP$BT|JGm8#PJ8n)m;VB@&Ukf zDG^?iV(3+Cu-aQd0+U40JR(L-$}6Z_bsM(tUIaCl^2nxF;V6~l)6}p?>hrHJ;KX`= z99tuiAFwXP4Ye1*Vni2b#mcGbR0DB2^@Pq!Zl_|tK9l-<5rm{fPy_x=kW5Ph`}%Qs zT=@db42w{_(+30dBFL6$HmI;^1ZndRV6d(mD!f03<4lEogS z;J9Z1glz*LQ6|8~fNuPJP9H{Ct)L+e=IEWyVPZ<+p(REPk?%jEx!h%R%q&AtQgIS) zAE7Xr_=qfsJB%~UuMoH0wJ>K}Jr3O`;A78Y=I#on=QRfG2xmVm_K>`BIpy#jZ-2~F zz004uG&vs)lT|;%oKK$6)&V~1rbL0Cxg#X}*NCx=Z313w4lxpPnHc?i%=xSfo6@I) zD6j>T_GRR8q6Yqb{VcD&58CvnqZyhIH;DDpxtx9PNaRmMC&AN{KOFH9~F}hi&gP zrKkNn!N+1gIO=DBwb&diy2LoRmd|Ed$Y7JN4pTK)3vmr!qOCoTb(JlJn87hHwKigV z&;1XDnsKl+RMWvT!B}~=mKb&9%kM<1ah=OWGIZYo*DdYF$-xrr+a`m+NfX>MoQc0$ zQ#@Mh1`i696jLUka^eQ$FO0>HGR9CyT5w~76NDdoj(T?YNKlp(E(Zm|P4Aa-FXj<6 z1sSvNIIManzx6padz1gnrCU-R1boP4G`>%PePIS|eF#N^nerF5`_MLBfr?2MHbk6- z?*3RXE4>Mt5jEWzX2ANACYbGZ7(WPph<}?Wfts@0L|ie0>~TE|dgH%A(uoInS;K*e zaXaE)UWQNI?vN)DW#H#{5Vz$N!NHj~1Y!B(kmHvIJ;fZxL|Ossw#(>SYcaX}?PkLJLPb)V~V}TY=2O!iU=dG8^WG zo9cD@mY*}&?|eyU@2uXhwsU{!+WEC@*;kw=vcDkkshyu^rOmgSg7zRYL2hIQVuYU> K>=_sqH~;{~-$&s9 From 7ffe97c331ae6b48af94bc78b7f8b4c773f8e60d Mon Sep 17 00:00:00 2001 From: fractalmanifold Date: Tue, 13 Aug 2024 18:43:15 +0200 Subject: [PATCH 5/7] Licensing --- opm/ml/keras_model.cpp | 416 ++---------------- opm/ml/keras_model.hpp | 189 ++------ opm/ml/keras_model_test.cpp | 104 ++--- opm/ml/ml_tools/generateunittests.py | 127 ++---- opm/ml/ml_tools/include/test_conv_2x2.h | 43 -- opm/ml/ml_tools/include/test_conv_3x3.h | 44 -- opm/ml/ml_tools/include/test_conv_3x3x3.h | 47 -- .../include/test_conv_hard_sigmoid_2x2.h | 43 -- .../ml_tools/include/test_conv_sigmoid_2x2.h | 43 -- .../ml_tools/include/test_conv_softplus_2x2.h | 43 -- opm/ml/ml_tools/include/test_dense_10x1.h | 32 +- opm/ml/ml_tools/include/test_dense_10x10.h | 32 +- opm/ml/ml_tools/include/test_dense_10x10x10.h | 37 +- opm/ml/ml_tools/include/test_dense_1x1.h | 26 ++ opm/ml/ml_tools/include/test_dense_2x2.h | 30 +- opm/ml/ml_tools/include/test_dense_relu_10.h | 34 +- opm/ml/ml_tools/include/test_dense_tanh_10.h | 34 +- opm/ml/ml_tools/include/test_elu_10.h | 44 -- opm/ml/ml_tools/include/test_maxpool2d_1x1.h | 62 --- opm/ml/ml_tools/include/test_relu_10.h | 34 +- .../ml_tools/include/test_scalingdense_1x1.h | 34 +- opm/ml/ml_tools/kerasify.py | 190 +------- opm/ml/ml_tools/make_model_BCkrn.py | 104 ----- opm/ml/ml_tools/make_model_BCkrw.py | 103 ----- opm/ml/ml_tools/make_model_VGkrn.py | 90 ---- opm/ml/ml_tools/make_model_VGkrw.py | 87 ---- opm/ml/ml_tools/models/test_conv_2x2.model | Bin 84 -> 0 bytes opm/ml/ml_tools/models/test_conv_3x3.model | Bin 104 -> 0 bytes opm/ml/ml_tools/models/test_conv_3x3x3.model | Bin 408 -> 0 bytes .../models/test_conv_hard_sigmoid_2x2.model | Bin 84 -> 0 bytes .../models/test_conv_sigmoid_2x2.model | Bin 84 -> 0 bytes .../models/test_conv_softplus_2x2.model | Bin 84 -> 0 bytes opm/ml/ml_tools/models/test_dense_10x1.model | Bin 68 -> 68 bytes opm/ml/ml_tools/models/test_dense_10x10.model | Bin 528 -> 528 bytes .../ml_tools/models/test_dense_10x10x10.model | Bin 924 -> 924 bytes opm/ml/ml_tools/models/test_dense_1x1.model | Bin 32 -> 32 bytes opm/ml/ml_tools/models/test_dense_2x2.model | Bin 80 -> 80 bytes .../ml_tools/models/test_dense_relu_10.model | Bin 1384 -> 1384 bytes .../ml_tools/models/test_dense_tanh_10.model | Bin 1384 -> 1384 bytes opm/ml/ml_tools/models/test_elu_10.model | Bin 536 -> 0 bytes .../ml_tools/models/test_maxpool2d_1x1.model | Bin 444 -> 0 bytes opm/ml/ml_tools/models/test_relu_10.model | Bin 472 -> 472 bytes .../models/test_scalingdense_1x1.model | Bin 1884 -> 1884 bytes opm/ml/ml_tools/peaceman.py | 371 ---------------- opm/ml/ml_tools/scaler_layers.py | 19 + opm/ml/ml_tools/scalertest.py | 21 +- 46 files changed, 459 insertions(+), 2024 deletions(-) delete mode 100644 opm/ml/ml_tools/include/test_conv_2x2.h delete mode 100644 opm/ml/ml_tools/include/test_conv_3x3.h delete mode 100644 opm/ml/ml_tools/include/test_conv_3x3x3.h delete mode 100644 opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h delete mode 100644 opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h delete mode 100644 opm/ml/ml_tools/include/test_conv_softplus_2x2.h delete mode 100644 opm/ml/ml_tools/include/test_elu_10.h delete mode 100644 opm/ml/ml_tools/include/test_maxpool2d_1x1.h delete mode 100644 opm/ml/ml_tools/make_model_BCkrn.py delete mode 100644 opm/ml/ml_tools/make_model_BCkrw.py delete mode 100644 opm/ml/ml_tools/make_model_VGkrn.py delete mode 100644 opm/ml/ml_tools/make_model_VGkrw.py delete mode 100644 opm/ml/ml_tools/models/test_conv_2x2.model delete mode 100644 opm/ml/ml_tools/models/test_conv_3x3.model delete mode 100644 opm/ml/ml_tools/models/test_conv_3x3x3.model delete mode 100644 opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model delete mode 100644 opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model delete mode 100644 opm/ml/ml_tools/models/test_conv_softplus_2x2.model delete mode 100644 opm/ml/ml_tools/models/test_elu_10.model delete mode 100644 opm/ml/ml_tools/models/test_maxpool2d_1x1.model delete mode 100644 opm/ml/ml_tools/peaceman.py diff --git a/opm/ml/keras_model.cpp b/opm/ml/keras_model.cpp index da365b068e9..46a191c9e22 100644 --- a/opm/ml/keras_model.cpp +++ b/opm/ml/keras_model.cpp @@ -1,3 +1,29 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include "keras_model.hpp" @@ -270,94 +296,6 @@ bool KerasLayerDense::Apply(Tensor* in, Tensor -bool KerasLayerConvolution2d::LoadLayer(std::ifstream* file) { - KASSERT(file, "Invalid file stream"); - - unsigned int weights_i = 0; - KASSERT(ReadUnsignedInt(file, &weights_i), "Expected weights_i"); - KASSERT(weights_i > 0, "Invalid weights # i"); - - unsigned int weights_j = 0; - KASSERT(ReadUnsignedInt(file, &weights_j), "Expected weights_j"); - KASSERT(weights_j > 0, "Invalid weights # j"); - - unsigned int weights_k = 0; - KASSERT(ReadUnsignedInt(file, &weights_k), "Expected weights_k"); - KASSERT(weights_k > 0, "Invalid weights # k"); - - unsigned int weights_l = 0; - KASSERT(ReadUnsignedInt(file, &weights_l), "Expected weights_l"); - KASSERT(weights_l > 0, "Invalid weights # l"); - - unsigned int biases_shape = 0; - KASSERT(ReadUnsignedInt(file, &biases_shape), "Expected biases shape"); - KASSERT(biases_shape > 0, "Invalid biases shape"); - - weights_.Resize(weights_i, weights_j, weights_k, weights_l); - KASSERT(ReadFloats(file, weights_.data_.data(), - weights_i * weights_j * weights_k * weights_l), - "Expected weights"); - - biases_.Resize(biases_shape); - KASSERT(ReadFloats(file, biases_.data_.data(), biases_shape), - "Expected biases"); - - KASSERT(activation_.LoadLayer(file), "Failed to load activation"); - - return true; -} - -template -bool KerasLayerConvolution2d::Apply(Tensor* in, Tensor* out) { - KASSERT(in, "Invalid input"); - KASSERT(out, "Invalid output"); - - KASSERT(in->dims_[0] == weights_.dims_[1], - "Input 'depth' doesn't match kernel 'depth'"); - - int st_nj = (weights_.dims_[2] - 1) / 2; - int st_pj = (weights_.dims_[2]) / 2; - int st_nk = (weights_.dims_[3] - 1) / 2; - int st_pk = (weights_.dims_[3]) / 2; - - Tensor tmp(weights_.dims_[0], in->dims_[1] - st_nj - st_pj, - in->dims_[2] - st_nk - st_pk); - - // Iterate over each kernel. - for (int i = 0; i < weights_.dims_[0]; i++) { - // Iterate over each 'depth'. - for (int j = 0; j < weights_.dims_[1]; j++) { - // 2D convolution in x and y (k and l in Tensor dimensions). - for (int tj = st_nj; tj < in->dims_[1] - st_pj; tj++) { - for (int tk = st_nk; tk < in->dims_[2] - st_pk; tk++) { - // Iterate over kernel. - for (int k = 0; k < weights_.dims_[2]; k++) { - for (int l = 0; l < weights_.dims_[3]; l++) { - const float& weight = weights_(i, j, k, l); - const Evaluation& value = - (*in)(j, tj - st_nj + k, tk - st_nk + l); - - tmp(i, tj - st_nj, tk - st_nk) += weight * value; - } - } - } - } - } - - // Apply kernel bias to all points in output. - for (int j = 0; j < tmp.dims_[1]; j++) { - for (int k = 0; k < tmp.dims_[2]; k++) { - tmp(i, j, k) += biases_(i); - } - } - } - - KASSERT(activation_.Apply(&tmp, out), "Failed to apply activation"); - - return true; -} - template bool KerasLayerFlatten::LoadLayer(std::ifstream* file) { KASSERT(file, "Invalid file stream"); @@ -375,80 +313,6 @@ bool KerasLayerFlatten::Apply(Tensor* in, Tensor -bool KerasLayerElu::LoadLayer(std::ifstream* file) { - KASSERT(file, "Invalid file stream"); - - KASSERT(ReadFloat(file, &alpha_), "Failed to read alpha"); - - return true; -} - -template -bool KerasLayerElu::Apply(Tensor* in, Tensor* out) { - KASSERT(in, "Invalid input"); - KASSERT(out, "Invalid output"); - - *out = *in; - - for (size_t i = 0; i < out->data_.size(); i++) { - if (out->data_[i] < 0.0) { - out->data_[i] = alpha_ * (exp(out->data_[i]) - 1.0); - } - } - - return true; -} - -template -bool KerasLayerMaxPooling2d::LoadLayer(std::ifstream* file) { - KASSERT(file, "Invalid file stream"); - - KASSERT(ReadUnsignedInt(file, &pool_size_j_), "Expected pool size j"); - KASSERT(ReadUnsignedInt(file, &pool_size_k_), "Expected pool size k"); - - return true; -} - -template -bool KerasLayerMaxPooling2d::Apply(Tensor* in, Tensor* out) { - KASSERT(in, "Invalid input"); - KASSERT(out, "Invalid output"); - - KASSERT(in->dims_.size() == 3, "Input must have 3 dimensions"); - - Tensor tmp(in->dims_[0], in->dims_[1] / pool_size_j_, - in->dims_[2] / pool_size_k_); - - for (int i = 0; i < tmp.dims_[0]; i++) { - for (int j = 0; j < tmp.dims_[1]; j++) { - const int tj = j * pool_size_j_; - - for (int k = 0; k < tmp.dims_[2]; k++) { - const int tk = k * pool_size_k_; - - // Find maximum value over patch starting at tj, tk. - Evaluation max_val = -std::numeric_limits::infinity(); - - for (unsigned int pj = 0; pj < pool_size_j_; pj++) { - for (unsigned int pk = 0; pk < pool_size_k_; pk++) { - const Evaluation& pool_val = (*in)(i, tj + pj, tk + pk); - if (pool_val > max_val) { - max_val = pool_val; - } - } - } - - tmp(i, j, k) = max_val; - } - } - } - - *out = tmp; - - return true; -} - template @@ -490,219 +354,6 @@ bool KerasLayerEmbedding::Apply(Tensor* in, Tensor -// bool KerasLayerLSTM::LoadLayer(std::ifstream* file) { -// KASSERT(file, "Invalid file stream"); -// -// unsigned int wi_rows = 0; -// KASSERT(ReadUnsignedInt(file, &wi_rows), "Expected Wi rows"); -// KASSERT(wi_rows > 0, "Invalid Wi # rows"); -// -// unsigned int wi_cols = 0; -// KASSERT(ReadUnsignedInt(file, &wi_cols), "Expected Wi cols"); -// KASSERT(wi_cols > 0, "Invalid Wi shape"); -// -// unsigned int ui_rows = 0; -// KASSERT(ReadUnsignedInt(file, &ui_rows), "Expected Ui rows"); -// KASSERT(ui_rows > 0, "Invalid Ui # rows"); -// -// unsigned int ui_cols = 0; -// KASSERT(ReadUnsignedInt(file, &ui_cols), "Expected Ui cols"); -// KASSERT(ui_cols > 0, "Invalid Ui shape"); -// -// unsigned int bi_shape = 0; -// KASSERT(ReadUnsignedInt(file, &bi_shape), "Expected bi shape"); -// KASSERT(bi_shape > 0, "Invalid bi shape"); -// -// unsigned int wf_rows = 0; -// KASSERT(ReadUnsignedInt(file, &wf_rows), "Expected Wf rows"); -// KASSERT(wf_rows > 0, "Invalid Wf # rows"); -// -// unsigned int wf_cols = 0; -// KASSERT(ReadUnsignedInt(file, &wf_cols), "Expected Wf cols"); -// KASSERT(wf_cols > 0, "Invalid Wf shape"); -// -// unsigned int uf_rows = 0; -// KASSERT(ReadUnsignedInt(file, &uf_rows), "Expected Uf rows"); -// KASSERT(uf_rows > 0, "Invalid Uf # rows"); -// -// unsigned int uf_cols = 0; -// KASSERT(ReadUnsignedInt(file, &uf_cols), "Expected Uf cols"); -// KASSERT(uf_cols > 0, "Invalid Uf shape"); -// -// unsigned int bf_shape = 0; -// KASSERT(ReadUnsignedInt(file, &bf_shape), "Expected bf shape"); -// KASSERT(bf_shape > 0, "Invalid bf shape"); -// -// unsigned int wc_rows = 0; -// KASSERT(ReadUnsignedInt(file, &wc_rows), "Expected Wc rows"); -// KASSERT(wc_rows > 0, "Invalid Wc # rows"); -// -// unsigned int wc_cols = 0; -// KASSERT(ReadUnsignedInt(file, &wc_cols), "Expected Wc cols"); -// KASSERT(wc_cols > 0, "Invalid Wc shape"); -// -// unsigned int uc_rows = 0; -// KASSERT(ReadUnsignedInt(file, &uc_rows), "Expected Uc rows"); -// KASSERT(uc_rows > 0, "Invalid Uc # rows"); -// -// unsigned int uc_cols = 0; -// KASSERT(ReadUnsignedInt(file, &uc_cols), "Expected Uc cols"); -// KASSERT(uc_cols > 0, "Invalid Uc shape"); -// -// unsigned int bc_shape = 0; -// KASSERT(ReadUnsignedInt(file, &bc_shape), "Expected bc shape"); -// KASSERT(bc_shape > 0, "Invalid bc shape"); -// -// unsigned int wo_rows = 0; -// KASSERT(ReadUnsignedInt(file, &wo_rows), "Expected Wo rows"); -// KASSERT(wo_rows > 0, "Invalid Wo # rows"); -// -// unsigned int wo_cols = 0; -// KASSERT(ReadUnsignedInt(file, &wo_cols), "Expected Wo cols"); -// KASSERT(wo_cols > 0, "Invalid Wo shape"); -// -// unsigned int uo_rows = 0; -// KASSERT(ReadUnsignedInt(file, &uo_rows), "Expected Uo rows"); -// KASSERT(uo_rows > 0, "Invalid Uo # rows"); -// -// unsigned int uo_cols = 0; -// KASSERT(ReadUnsignedInt(file, &uo_cols), "Expected Uo cols"); -// KASSERT(uo_cols > 0, "Invalid Uo shape"); -// -// unsigned int bo_shape = 0; -// KASSERT(ReadUnsignedInt(file, &bo_shape), "Expected bo shape"); -// KASSERT(bo_shape > 0, "Invalid bo shape"); -// -// // Load Input Weights and Biases -// Wi_.Resize(wi_rows, wi_cols); -// KASSERT(ReadFloats(file, Wi_.data_.data(), wi_rows * wi_cols), -// "Expected Wi weights"); -// -// Ui_.Resize(ui_rows, ui_cols); -// KASSERT(ReadFloats(file, Ui_.data_.data(), ui_rows * ui_cols), -// "Expected Ui weights"); -// -// bi_.Resize(1, bi_shape); -// KASSERT(ReadFloats(file, bi_.data_.data(), bi_shape), "Expected bi biases"); -// -// // Load Forget Weights and Biases -// Wf_.Resize(wf_rows, wf_cols); -// KASSERT(ReadFloats(file, Wf_.data_.data(), wf_rows * wf_cols), -// "Expected Wf weights"); -// -// Uf_.Resize(uf_rows, uf_cols); -// KASSERT(ReadFloats(file, Uf_.data_.data(), uf_rows * uf_cols), -// "Expected Uf weights"); -// -// bf_.Resize(1, bf_shape); -// KASSERT(ReadFloats(file, bf_.data_.data(), bf_shape), "Expected bf biases"); -// -// // Load State Weights and Biases -// Wc_.Resize(wc_rows, wc_cols); -// KASSERT(ReadFloats(file, Wc_.data_.data(), wc_rows * wc_cols), -// "Expected Wc weights"); -// -// Uc_.Resize(uc_rows, uc_cols); -// KASSERT(ReadFloats(file, Uc_.data_.data(), uc_rows * uc_cols), -// "Expected Uc weights"); -// -// bc_.Resize(1, bc_shape); -// KASSERT(ReadFloats(file, bc_.data_.data(), bc_shape), "Expected bc biases"); -// -// // Load Output Weights and Biases -// Wo_.Resize(wo_rows, wo_cols); -// KASSERT(ReadFloats(file, Wo_.data_.data(), wo_rows * wo_cols), -// "Expected Wo weights"); -// -// Uo_.Resize(uo_rows, uo_cols); -// KASSERT(ReadFloats(file, Uo_.data_.data(), uo_rows * uo_cols), -// "Expected Uo weights"); -// -// bo_.Resize(1, bo_shape); -// KASSERT(ReadFloats(file, bo_.data_.data(), bo_shape), "Expected bo biases"); -// -// KASSERT(innerActivation_.LoadLayer(file), -// "Failed to load inner activation"); -// KASSERT(activation_.LoadLayer(file), "Failed to load activation"); -// -// unsigned int return_sequences = 0; -// KASSERT(ReadUnsignedInt(file, &return_sequences), -// "Expected return_sequences param"); -// return_sequences_ = (bool)return_sequences; -// -// return true; -// } -// -// template -// bool KerasLayerLSTM::Apply(Tensor* in, Tensor* out) { -// // Assume bo always keeps the output shape and we will always receive one -// // single sample. -// int outputDim = bo_.dims_[1]; -// Tensor ht_1 = Tensor(1, outputDim); -// Tensor ct_1 = Tensor(1, outputDim); -// -// ht_1.Fill(0.0f); -// ct_1.Fill(0.0f); -// -// int steps = in->dims_[0]; -// -// Tensor outputs, lastOutput; -// -// if (return_sequences_) { -// outputs.dims_ = {steps, outputDim}; -// outputs.data_.reserve(steps * outputDim); -// } -// -// for (int s = 0; s < steps; s++) { -// Tensor x = in->Select(s); -// -// KASSERT(Step(&x, &lastOutput, &ht_1, &ct_1), "Failed to execute step"); -// -// if (return_sequences_) { -// outputs.data_.insert(outputs.data_.end(), lastOutput.data_.begin(), -// lastOutput.data_.end()); -// } -// } -// -// if (return_sequences_) { -// *out = outputs; -// } else { -// *out = lastOutput; -// } -// -// return true; -// } -// -// template -// bool KerasLayerLSTM::Step(Tensor * x, Tensor * out, Tensor * ht_1, Tensor * ct_1) { -// Tensor xi = x->Dot(Wi_) + bi_; -// Tensor xf = x->Dot(Wf_) + bf_; -// Tensor xc = x->Dot(Wc_) + bc_; -// Tensor xo = x->Dot(Wo_) + bo_; -// -// Tensor i_ = xi + ht_1->Dot(Ui_); -// Tensor f_ = xf + ht_1->Dot(Uf_); -// Tensor c_ = xc + ht_1->Dot(Uc_); -// Tensor o_ = xo + ht_1->Dot(Uo_); -// -// Tensor i, f, cc, o; -// -// KASSERT(innerActivation_.Apply(&i_, &i), -// "Failed to apply inner activation on i"); -// KASSERT(innerActivation_.Apply(&f_, &f), -// "Failed to apply inner activation on f"); -// KASSERT(activation_.Apply(&c_, &cc), "Failed to apply activation on c_"); -// KASSERT(innerActivation_.Apply(&o_, &o), -// "Failed to apply inner activation on o"); -// -// *ct_1 = f.Multiply(*ct_1) + i.Multiply(cc); -// -// KASSERT(activation_.Apply(ct_1, &cc), "Failed to apply activation on c"); -// *out = *ht_1 = o.Multiply(cc); -// -// return true; -// } template bool KerasModel::LoadModel(const std::string& filename) { @@ -719,9 +370,6 @@ bool KerasModel::LoadModel(const std::string& filename) { KerasLayer* layer = NULL; switch (layer_type) { - // case kConvolution2d: - // layer = new KerasLayerConvolution2d(); - // break; case kFlatten: layer = new KerasLayerFlatten(); break; @@ -734,21 +382,9 @@ bool KerasModel::LoadModel(const std::string& filename) { case kDense: layer = new KerasLayerDense(); break; - // case kElu: - // layer = new KerasLayerElu(); - // break; case kActivation: layer = new KerasLayerActivation(); break; - // case kMaxPooling2D: - // // layer = new KerasLayerMaxPooling2d(); - // break; - // case kLSTM: - // // layer = new KerasLayerLSTM(); - // break; - // case kEmbedding: - // // layer = new KerasLayerEmbedding(); - // break; default: break; } diff --git a/opm/ml/keras_model.hpp b/opm/ml/keras_model.hpp index 41299eb8215..f84ea106bbf 100644 --- a/opm/ml/keras_model.hpp +++ b/opm/ml/keras_model.hpp @@ -1,3 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + #ifndef KERAS_MODEL_H_ #define KERAS_MODEL_H_ @@ -11,11 +38,6 @@ #include #include -// typedef double Scalar; - -//typedef Opm::DenseAd::Evaluation Evaluation; -//typedef float Evaluation; -//typedef double Evaluation; namespace Opm { #define KASSERT(x, ...) \ @@ -27,8 +49,8 @@ namespace Opm { } #define KASSERT_EQ(x, y, eps) \ - if (fabs(x.value() - y.value()) > eps) { \ - printf("KASSERT: Expected %f, got %f\n", y.value(), x.value()); \ + if (fabs(x.value() - y.value()) > eps) { \ + printf("KASSERT: Expected %f, got %f\n", y.value(), x.value()); \ return false; \ } @@ -207,66 +229,6 @@ class Tensor { return tmp; } - // void Print() { - // if (dims_.size() == 1) { - // printf("[ "); - // for (int i = 0; i < dims_[0]; i++) { - // printf("%f ", (*this)(i)); - // } - // printf("]\n"); - // } else if (dims_.size() == 2) { - // printf("[\n"); - // for (int i = 0; i < dims_[0]; i++) { - // printf(" [ "); - // for (int j = 0; j < dims_[1]; j++) { - // printf("%f ", (*this)(i, j)); - // } - // printf("]\n"); - // } - // printf("]\n"); - // } else if (dims_.size() == 3) { - // printf("[\n"); - // for (int i = 0; i < dims_[0]; i++) { - // printf(" [\n"); - // for (int j = 0; j < dims_[1]; j++) { - // printf(" [ "); - // for (int k = 0; k < dims_[2]; k++) { - // printf("%f ", (*this)(i, j, k)); - // } - // printf(" ]\n"); - // } - // printf(" ]\n"); - // } - // printf("]\n"); - // } else if (dims_.size() == 4) { - // printf("[\n"); - // for (int i = 0; i < dims_[0]; i++) { - // printf(" [\n"); - // for (int j = 0; j < dims_[1]; j++) { - // printf(" [\n"); - // for (int k = 0; k < dims_[2]; k++) { - // printf(" ["); - // for (int l = 0; l < dims_[3]; l++) { - // printf("%f ", (*this)(i, j, k, l)); - // } - // printf("]\n"); - // } - // printf(" ]\n"); - // } - // printf(" ]\n"); - // } - // printf("]\n"); - // } - // } - - // void PrintShape() { - // printf("("); - // for (unsigned int i = 0; i < dims_.size(); i++) { - // printf("%d ", dims_[i]); - // } - // printf(")\n"); - // } - std::vector dims_; std::vector data_; }; @@ -325,11 +287,6 @@ class KerasLayerScaling : public KerasLayer { float data_max; float feat_inf; float feat_sup; - - // float feat; - // float feature_range; - - // KerasLayerActivation activation_; }; template @@ -350,8 +307,6 @@ class KerasLayerUnScaling : public KerasLayer { float data_max; float feat_inf; float feat_sup; - - // KerasLayerActivation activation_; }; @@ -373,24 +328,6 @@ class KerasLayerDense : public KerasLayer { KerasLayerActivation activation_; }; -template -class KerasLayerConvolution2d: public KerasLayer { - public: - KerasLayerConvolution2d() {} - - virtual ~KerasLayerConvolution2d() {} - - virtual bool LoadLayer(std::ifstream* file); - - virtual bool Apply(Tensor* in, Tensor* out); - - private: - Tensor weights_; - Tensor biases_; - - KerasLayerActivation activation_; -}; - template class KerasLayerFlatten : public KerasLayer { public: @@ -405,69 +342,6 @@ class KerasLayerFlatten : public KerasLayer { private: }; -template -class KerasLayerElu : public KerasLayer { - public: - KerasLayerElu() : alpha_(1.0f) {} - - virtual ~KerasLayerElu() {} - - virtual bool LoadLayer(std::ifstream* file); - - virtual bool Apply(Tensor* in, Tensor* out); - - private: - float alpha_; -}; - -template -class KerasLayerMaxPooling2d : public KerasLayer { - public: - KerasLayerMaxPooling2d() : pool_size_j_(0), pool_size_k_(0) {} - - virtual ~KerasLayerMaxPooling2d() {} - - virtual bool LoadLayer(std::ifstream* file); - - virtual bool Apply(Tensor* in, Tensor* out); - - private: - unsigned int pool_size_j_; - unsigned int pool_size_k_; -}; - -// template -// class KerasLayerLSTM : public KerasLayer { -// public: -// KerasLayerLSTM() : return_sequences_(false) {} -// -// virtual ~KerasLayerLSTM() {} -// -// virtual bool LoadLayer(std::ifstream* file); -// -// virtual bool Apply(Tensor* in, Tensor* out); -// -// private: -// bool Step(Tensor* x, Tensor* out, Tensor* ht_1, Tensor* ct_1); -// -// Tensor Wi_; -// Tensor Ui_; -// Tensor bi_; -// Tensor Wf_; -// Tensor Uf_; -// Tensor bf_; -// Tensor Wc_; -// Tensor Uc_; -// Tensor bc_; -// Tensor Wo_; -// Tensor Uo_; -// Tensor bo_; -// -// KerasLayerActivation innerActivation_; -// KerasLayerActivation activation_; -// bool return_sequences_; -// }; - template class KerasLayerEmbedding : public KerasLayer { @@ -488,12 +362,7 @@ template class KerasModel { public: enum LayerType { - // kConvolution2d = 2, kFlatten = 1, - // kElu = 4, - // kMaxPooling2D = 6, - // kLSTM = 7, - // kEmbedding = 8, kScaling = 2, kUnScaling = 3, kDense = 4, diff --git a/opm/ml/keras_model_test.cpp b/opm/ml/keras_model_test.cpp index 0b3991d98b0..354e744e950 100644 --- a/opm/ml/keras_model_test.cpp +++ b/opm/ml/keras_model_test.cpp @@ -1,25 +1,41 @@ -#include "keras_model.hpp" +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ +#include "keras_model.hpp" #include #include - -#include "ml_tools/include/test_conv_2x2.h" -#include "ml_tools/include/test_conv_3x3.h" -#include "ml_tools/include/test_conv_3x3x3.h" -#include "ml_tools/include/test_conv_hard_sigmoid_2x2.h" -#include "ml_tools/include/test_conv_sigmoid_2x2.h" -#include "ml_tools/include/test_conv_softplus_2x2.h" #include "ml_tools/include/test_dense_10x1.h" #include "ml_tools/include/test_dense_10x10.h" #include "ml_tools/include/test_dense_10x10x10.h" #include "ml_tools/include/test_dense_1x1.h" #include "ml_tools/include/test_dense_2x2.h" +#include "ml_tools/include/test_relu_10.h" #include "ml_tools/include/test_dense_relu_10.h" #include "ml_tools/include/test_dense_tanh_10.h" -#include "ml_tools/include/test_elu_10.h" -#include "ml_tools/include/test_relu_10.h" - - #include "ml_tools/include/test_scalingdense_1x1.h" @@ -138,7 +154,6 @@ bool tensor_test() { int main() { typedef Opm::DenseAd::Evaluation Evaluation; - // typedef float Evaluation; Evaluation load_time = 0.0; Evaluation apply_time = 0.0; @@ -166,63 +181,22 @@ int main() { if (!test_dense_10x10x10(&load_time, &apply_time)) { return 1; } + + if (!test_relu_10(&load_time, &apply_time)) { + return 1; + } - // if (!test_conv_2x2(&load_time, &apply_time)) { - // return 1; - // } - // // - // if (!test_conv_3x3(&load_time, &apply_time)) { - // return 1; - // } - - // if (!test_conv_3x3x3(&load_time, &apply_time)) { - // return 1; - // } - // // - // if (!test_elu_10(&load_time, &apply_time)) { - // return 1; - // } - // // - // if (!test_relu_10(&load_time, &apply_time)) { - // return 1; - // } + if (!test_dense_relu_10(&load_time, &apply_time)) { + return 1; + } - // if (!test_dense_relu_10(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_dense_tanh_10(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_conv_softplus_2x2(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_conv_hard_sigmoid_2x2(&load_time, &apply_time)) { - // return 1; - // } - // - // if (!test_conv_sigmoid_2x2(&load_time, &apply_time)) { - // return 1; - // } + if (!test_dense_tanh_10(&load_time, &apply_time)) { + return 1; + } if (!test_scalingdense_1x1(&load_time, &apply_time)) { return 1; } - // // Run benchmark 5 times and report duration. - // Evaluation total_load_time = 0.0; - // Evaluation total_apply_time = 0.0; - - // for (int i = 0; i < 5; i++) { - // total_load_time += load_time; - // total_apply_time += apply_time; - // } - - // printf("Benchmark network loads in %fs\n", total_load_time / 5); - // printf("Benchmark network runs in %fs\n", total_apply_time / 5); - return 0; -} -// } +} \ No newline at end of file diff --git a/opm/ml/ml_tools/generateunittests.py b/opm/ml/ml_tools/generateunittests.py index dc19b53e6b4..fa36a0681b5 100644 --- a/opm/ml/ml_tools/generateunittests.py +++ b/opm/ml/ml_tools/generateunittests.py @@ -1,3 +1,22 @@ +# Copyright (c) 2024 Birane Kane +# Copyright (c) 2024 Tor Harald Sandve + +# This file is part of the Open Porous Media project (OPM). + +# OPM is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# OPM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with OPM. If not, see . + + import numpy as np import pprint import os @@ -23,6 +42,33 @@ def to_cpp(ndarray): TEST_CASE = ''' +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + #include #include namespace fs = std::filesystem; @@ -115,7 +161,6 @@ def output_testcase(model, test_x, test_y, name, eps): model.add(keras.layers.Input([10])) # model.add(Dense(1, input_dim=10)) model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) - # model.add(Dense(1,activation='tanh')) model.add(Dense(10,activation='tanh')) model.add(Dense(10,activation='tanh')) @@ -123,7 +168,6 @@ def output_testcase(model, test_x, test_y, name, eps): model.add(Dense(10,activation='tanh')) # model.add(Flatten()) model.add(MinMaxUnScalerLayer(feature_range=(-3.7, -1.0))) - # # model.get_layer(model.layers[0].name).adapt(data=data) model.get_layer(model.layers[-1].name).adapt(data=data) @@ -185,46 +229,6 @@ def output_testcase(model, test_x, test_y, name, eps): model.add(Dense(10)) output_testcase(model, test_x, test_y, 'dense_10x10x10', '1e-6') -# Conv 2x2 -test_x = np.random.rand(10, 2, 2,1).astype('f') -test_y = np.random.rand(10, 1).astype('f') -model = Sequential() -model.add(Conv2D(1,(2, 2), padding='valid', input_shape=(2, 2, 1))) -model.add(Flatten()) -model.add(Dense(1)) -output_testcase(model, test_x, test_y, 'conv_2x2', '1e-6') - -# Conv 3x3 -test_x = np.random.rand(10, 3, 3, 1).astype('f').astype('f') -test_y = np.random.rand(10, 1).astype('f') -model = Sequential([ - Conv2D(1, (3, 3), input_shape=(3, 3, 1)), - Flatten(), - Dense(1) -]) -output_testcase(model, test_x, test_y, 'conv_3x3', '1e-6') - -# Conv 3x3x3 -test_x = np.random.rand(10, 3, 3, 3).astype('f') -test_y = np.random.rand(10, 1).astype('f') -model = Sequential([ - Conv2D(3, (3, 3), input_shape=(3, 3, 3)), - Flatten(), - # BatchNormalization(), - Dense(1) -]) -output_testcase(model, test_x, test_y, 'conv_3x3x3', '1e-6') - -# Activation ELU -test_x = np.random.rand(1, 10).astype('f') -test_y = np.random.rand(1, 1).astype('f') -model = Sequential([ - Dense(10, input_dim=10), - ELU(alpha=0.5), - Dense(1) -]) -output_testcase(model, test_x, test_y, 'elu_10', '1e-6') - # Activation relu test_x = np.random.rand(1, 10).astype('f') test_y = np.random.rand(1, 10).astype('f') @@ -251,42 +255,3 @@ def output_testcase(model, test_x, test_y, name, eps): model.add(Dense(10, input_dim=10, activation='tanh')) output_testcase(model, test_x, test_y, 'dense_tanh_10', '1e-6') -# Conv softplus -test_x = np.random.rand(10, 2, 2, 1).astype('f') -test_y = np.random.rand(10, 1).astype('f') -model = Sequential([ - Conv2D(1, (2, 2), input_shape=(2, 2, 1), activation='softplus'), - Flatten(), - Dense(1) -]) -output_testcase(model, test_x, test_y, 'conv_softplus_2x2', '1e-6') - -# Conv hardsigmoid -test_x = np.random.rand(10, 2, 2, 1).astype('f') -test_y = np.random.rand(10, 1).astype('f') -model = Sequential([ - Conv2D(1, (2, 2), input_shape=(2, 2, 1), activation='hard_sigmoid'), - Flatten(), - Dense(1) -]) -output_testcase(model, test_x, test_y, 'conv_hard_sigmoid_2x2', '1e-6') - -# Conv sigmoid -test_x = np.random.rand(10, 2, 2, 1).astype('f') -test_y = np.random.rand(10, 1).astype('f') -model = Sequential([ - Conv2D(1, (2, 2), input_shape=(2, 2, 1), activation='sigmoid'), - Flatten(), - Dense(1) -]) -output_testcase(model, test_x, test_y, 'conv_sigmoid_2x2', '1e-6') - -# Maxpooling2D 1x1 -test_x = np.random.rand(10, 10, 10, 1).astype('f') -test_y = np.random.rand(10, 1).astype('f') -model = Sequential([ - MaxPooling2D(pool_size=(1, 1), input_shape=(10, 10, 1)), - Flatten(), - Dense(1) -]) -output_testcase(model, test_x, test_y, 'maxpool2d_1x1', '1e-6') diff --git a/opm/ml/ml_tools/include/test_conv_2x2.h b/opm/ml/ml_tools/include/test_conv_2x2.h deleted file mode 100644 index 4289b617f41..00000000000 --- a/opm/ml/ml_tools/include/test_conv_2x2.h +++ /dev/null @@ -1,43 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_conv_2x2(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST conv_2x2\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{2,2,1}; - in.data_ = {0.6796515,0.68067896,0.46129513,0.96068424}; - - Opm::Tensor out{1}; - out.data_ = {0.7798276}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_2x2.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_conv_3x3.h b/opm/ml/ml_tools/include/test_conv_3x3.h deleted file mode 100644 index dc1430bdb30..00000000000 --- a/opm/ml/ml_tools/include/test_conv_3x3.h +++ /dev/null @@ -1,44 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_conv_3x3(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST conv_3x3\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{3,3,1}; - in.data_ = {0.88527423,0.8638909,0.86746955,0.42614478,0.031315308,0.84676105, -0.8503915,0.3592089,0.098730415}; - - Opm::Tensor out{1}; - out.data_ = {0.891428}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_3x3.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_conv_3x3x3.h b/opm/ml/ml_tools/include/test_conv_3x3x3.h deleted file mode 100644 index 3b75cefd5f9..00000000000 --- a/opm/ml/ml_tools/include/test_conv_3x3x3.h +++ /dev/null @@ -1,47 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_conv_3x3x3(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST conv_3x3x3\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{3,3,3}; - in.data_ = {0.32681695,0.88247293,0.9610101,0.7766642,0.90783143,0.95788574, -0.25465804,0.14405063,0.30747658,0.29391462,0.88617074,0.7574131, -0.7840184,0.13056566,0.17718191,0.51664996,0.68511343,0.2752934, -0.3730155,0.7273659,0.070773244,0.6111477,0.55316126,0.14030892, -0.9425838,0.78347766,0.7334307}; - - Opm::Tensor out{1}; - out.data_ = {0.34363604}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_3x3x3.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h deleted file mode 100644 index c05e401eb39..00000000000 --- a/opm/ml/ml_tools/include/test_conv_hard_sigmoid_2x2.h +++ /dev/null @@ -1,43 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_conv_hard_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST conv_hard_sigmoid_2x2\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{2,2,1}; - in.data_ = {0.86426544,0.8477615,0.5583865,0.5447023}; - - Opm::Tensor out{1}; - out.data_ = {-0.8503885}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h b/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h deleted file mode 100644 index c72807478ae..00000000000 --- a/opm/ml/ml_tools/include/test_conv_sigmoid_2x2.h +++ /dev/null @@ -1,43 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_conv_sigmoid_2x2(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST conv_sigmoid_2x2\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{2,2,1}; - in.data_ = {0.29207453,0.290471,0.13317004,0.9632514}; - - Opm::Tensor out{1}; - out.data_ = {-0.5019707}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_conv_softplus_2x2.h b/opm/ml/ml_tools/include/test_conv_softplus_2x2.h deleted file mode 100644 index 79767295fa1..00000000000 --- a/opm/ml/ml_tools/include/test_conv_softplus_2x2.h +++ /dev/null @@ -1,43 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_conv_softplus_2x2(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST conv_softplus_2x2\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{2,2,1}; - in.data_ = {0.96259403,0.20030555,0.8772307,0.76010585}; - - Opm::Tensor out{1}; - out.data_ = {-0.5558099}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_conv_softplus_2x2.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_dense_10x1.h b/opm/ml/ml_tools/include/test_dense_10x1.h index d9a5a89fd72..7306e3f47c8 100644 --- a/opm/ml/ml_tools/include/test_dense_10x1.h +++ b/opm/ml/ml_tools/include/test_dense_10x1.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,11 +39,11 @@ bool test_dense_10x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.6118447,0.770052,0.16679357,0.8346833,0.7955753,0.25932008, -0.3465901,0.13505514,0.35986346,0.716514}; + in.data_ = {0.07588807,0.46424174,0.2545689,0.24965246,0.48471555,0.9185193, +0.33841145,0.30067867,0.98624486,0.85875916}; Opm::Tensor out{1}; - out.data_ = {0.91411453}; + out.data_ = {-0.6094914}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10.h b/opm/ml/ml_tools/include/test_dense_10x10.h index 48cd20f6409..1f14f6f5739 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10.h +++ b/opm/ml/ml_tools/include/test_dense_10x10.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,11 +39,11 @@ bool test_dense_10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.28370148,0.6116727,0.123164214,0.86745644,0.5565164,0.5560578, -0.56472105,0.34990314,0.8911647,0.41991234}; + in.data_ = {0.74464816,0.063315846,0.2233216,0.3184675,0.017677268,0.24977225, +0.5242765,0.27742663,0.009411842,0.27946305}; Opm::Tensor out{1}; - out.data_ = {1.1963887}; + out.data_ = {0.06583358}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10x10.h b/opm/ml/ml_tools/include/test_dense_10x10x10.h index e4472dc69c0..d373bffc066 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10x10.h +++ b/opm/ml/ml_tools/include/test_dense_10x10x10.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,18 +39,15 @@ bool test_dense_10x10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.9307595,0.623219,0.26583958,0.58003414,0.030215342,0.06587499, -0.9004415,0.03221161,0.4206354,0.8563274}; - + in.data_ = {0.84246427,0.15756324,0.8924635,0.5069177,0.8633376,0.31142905, +0.7651278,0.5454816,0.22917923,0.54828155}; Opm::Tensor out{10}; - out.data_ = {0.068457894,0.03991737,-0.30497518,-0.19265954,-0.32966894, --0.6756333,0.4275365,1.121752,0.14004697,0.30182698}; + out.data_ = {0.767188,0.23175952,0.036515277,-0.2622609,-0.25455678, +0.157909,-0.6259325,-0.6256348,0.4324326,-0.4141315}; KerasTimer load_timer; load_timer.Start(); - std::cout<<"in->dims_.size() "< model; KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x10x10.model"), "Failed to load model"); diff --git a/opm/ml/ml_tools/include/test_dense_1x1.h b/opm/ml/ml_tools/include/test_dense_1x1.h index 3dda009b122..5410cee5d08 100644 --- a/opm/ml/ml_tools/include/test_dense_1x1.h +++ b/opm/ml/ml_tools/include/test_dense_1x1.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; diff --git a/opm/ml/ml_tools/include/test_dense_2x2.h b/opm/ml/ml_tools/include/test_dense_2x2.h index b111553a215..1bbfe040217 100644 --- a/opm/ml/ml_tools/include/test_dense_2x2.h +++ b/opm/ml/ml_tools/include/test_dense_2x2.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,10 +39,10 @@ bool test_dense_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2}; - in.data_ = {0.89572245,0.11905332}; + in.data_ = {0.6440019,0.62654394}; Opm::Tensor out{1}; - out.data_ = {-0.94843066}; + out.data_ = {0.7173992}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_relu_10.h b/opm/ml/ml_tools/include/test_dense_relu_10.h index 52a4b8952cd..2031e90b6f3 100644 --- a/opm/ml/ml_tools/include/test_dense_relu_10.h +++ b/opm/ml/ml_tools/include/test_dense_relu_10.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,12 +39,12 @@ bool test_dense_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.17480424,0.53673047,0.9696888,0.86909395,0.7807599,0.45374545, -0.85382074,0.6236224,0.20212452,0.46260563}; + in.data_ = {0.58381814,0.90178627,0.13896127,0.18618706,0.94524324,0.11974335, +0.88227147,0.09502208,0.71341133,0.53053087}; Opm::Tensor out{10}; - out.data_ = {0.16656388,0.018555019,0.027130837,0.,0.,0., -0.,0.027509432,0.03260679,0.039918847}; + out.data_ = {0.,0.,0.,0.,0.,0.20002396, +0.19065511,0.,0.,0.1995258}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_dense_tanh_10.h b/opm/ml/ml_tools/include/test_dense_tanh_10.h index 0913b0fdef5..9785b41416d 100644 --- a/opm/ml/ml_tools/include/test_dense_tanh_10.h +++ b/opm/ml/ml_tools/include/test_dense_tanh_10.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,12 +39,12 @@ bool test_dense_tanh_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.1899011,0.3590567,0.284928,0.8981879,0.8274132,0.8743853, -0.025491558,0.18069586,0.19910076,0.5135733}; + in.data_ = {0.5133757,0.8992964,0.018602798,0.8300745,0.43004134,0.16437091, +0.13667183,0.7081913,0.39895463,0.53926337}; Opm::Tensor out{10}; - out.data_ = {0.49924585,0.54542077,-0.60667866,-0.34529728,0.15064734,-0.26957473, -0.05453661,-0.5642658,0.4621192,-0.19287723}; + out.data_ = {-0.16390416,-0.11630989,0.37623432,-0.65770155,0.1101914, +-0.097250186,0.5037399,-0.2223558,0.3810121,0.6196858}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_elu_10.h b/opm/ml/ml_tools/include/test_elu_10.h deleted file mode 100644 index 87159a230cc..00000000000 --- a/opm/ml/ml_tools/include/test_elu_10.h +++ /dev/null @@ -1,44 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_elu_10(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST elu_10\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{10}; - in.data_ = {0.18739146,0.70936984,0.9280732,0.62002677,0.40296188,0.1884241, -0.84437937,0.023707515,0.09143902,0.5966835}; - - Opm::Tensor out{1}; - out.data_ = {0.589676}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_elu_10.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_maxpool2d_1x1.h b/opm/ml/ml_tools/include/test_maxpool2d_1x1.h deleted file mode 100644 index 510252f99e7..00000000000 --- a/opm/ml/ml_tools/include/test_maxpool2d_1x1.h +++ /dev/null @@ -1,62 +0,0 @@ - -#include -#include -namespace fs = std::filesystem; - -using namespace Opm; -template -bool test_maxpool2d_1x1(Evaluation* load_time, Evaluation* apply_time) -{ - printf("TEST maxpool2d_1x1\n"); - - KASSERT(load_time, "Invalid Evaluation"); - KASSERT(apply_time, "Invalid Evaluation"); - - Opm::Tensor in{10,10,1}; - in.data_ = {0.3584981,0.2958925,0.7605831,0.53394246,0.61106086, -0.0044219894,0.5463487,0.25235063,0.18157023,0.06756325, -0.8124267,0.8730054,0.0947123,0.80920976,0.8023841, -0.18305726,0.1803083,0.044107396,0.8450164,0.5707187, -0.627845,0.49776414,0.7567636,0.22644873,0.17683746, -0.09286818,0.16009343,0.5313456,0.95800453,0.32112077, -0.91887784,0.57785136,0.38100433,0.30305266,0.4294771, -0.74898136,0.24068417,0.24434112,0.4277804,0.66749835, -0.2807149,0.5275129,0.64340687,0.2915763,0.032093775, -0.7258795,0.5505952,0.68428564,0.41406462,0.91326606, -0.22276446,0.8068874,0.80964404,0.26798266,0.96306396, -0.18655908,0.91054565,0.005801419,0.9993052,0.51641726, -0.8414052,0.45861587,0.9145516,0.51948214,0.88117427, -0.22991507,0.053036828,0.6385797,0.68001044,0.739364, -0.56692076,0.36897555,0.39697468,0.5334803,0.19781172, -0.7582431,0.1215363,0.1281851,0.5813795,0.98001736, -0.84356993,0.70857924,0.6370623,0.54709303,0.9008569, -0.73727363,0.53235346,0.7178515,0.8857483,0.80863845, -0.26460695,0.19305061,0.3812545,0.018899608,0.7839583, -0.9368291,0.87295556,0.17056823,0.46442586,0.91270417}; - - Opm::Tensor out{1}; - out.data_ = {0.79461604}; - - KerasTimer load_timer; - load_timer.Start(); - - KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_maxpool2d_1x1.model"), "Failed to load model"); - - *load_time = load_timer.Stop(); - - KerasTimer apply_timer; - apply_timer.Start(); - - Opm::Tensor predict = out; - KASSERT(model.Apply(&in, &out), "Failed to apply"); - - *apply_time = apply_timer.Stop(); - - for (int i = 0; i < out.dims_[0]; i++) - { - KASSERT_EQ(out(i), predict(i), 1e-6); - } - - return true; -} diff --git a/opm/ml/ml_tools/include/test_relu_10.h b/opm/ml/ml_tools/include/test_relu_10.h index 2f60bbac2ca..86d8e3c9611 100644 --- a/opm/ml/ml_tools/include/test_relu_10.h +++ b/opm/ml/ml_tools/include/test_relu_10.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,12 +39,12 @@ bool test_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.37697044,0.6427236,0.89172053,0.73344576,0.11428697,0.40963235, -0.81641096,0.6176922,0.6046866,0.9238176}; + in.data_ = {0.120741345,0.59726936,0.9251051,0.87210053,0.6669108,0.13732599, +0.3093547,0.77527475,0.3986614,0.943842}; Opm::Tensor out{10}; - out.data_ = {0.44721743,0.,0.61811334,0.5108469,0.73356915,0., -0.,0.,0.5264998,0.026750417}; + out.data_ = {0.,0.,0.48979148,0.,1.1085179,0., +0.,0.33353794,0.7359366,0.8868316}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/include/test_scalingdense_1x1.h b/opm/ml/ml_tools/include/test_scalingdense_1x1.h index 2b0c69a7716..3e16e372023 100644 --- a/opm/ml/ml_tools/include/test_scalingdense_1x1.h +++ b/opm/ml/ml_tools/include/test_scalingdense_1x1.h @@ -1,4 +1,30 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.OLD file. + */ + +/* + * Copyright (c) 2024 Birane Kane + * Copyright (c) 2024 Tor Harald Sandve + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #include #include namespace fs = std::filesystem; @@ -13,12 +39,12 @@ bool test_scalingdense_1x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.35745713,0.5183338,0.43530357,0.7207405,0.96301425,0.47163334, -0.10632531,0.49405062,0.48787624,0.23182626}; + in.data_ = {0.22338921,0.8132339,0.43024784,0.26458433,0.92503846,0.6615654, +0.88089544,0.34508273,0.6916904,0.57852364}; Opm::Tensor out{10}; - out.data_ = {80.98062,133.76828,113.56729,180.86313,126.80325,148.15707, -111.01114,41.78473,51.552124,153.05319}; + out.data_ = {670.77625,672.4989,709.0858,640.06885,827.44714,736.1234,617.30554, +638.03955,629.93115,653.84595}; KerasTimer load_timer; load_timer.Start(); diff --git a/opm/ml/ml_tools/kerasify.py b/opm/ml/ml_tools/kerasify.py index 0ce8ef392c2..a91dc615941 100644 --- a/opm/ml/ml_tools/kerasify.py +++ b/opm/ml/ml_tools/kerasify.py @@ -1,3 +1,21 @@ +# Copyright (c) 2024 Birane Kane +# Copyright (c) 2024 Tor Harald Sandve + +# This file is part of the Open Porous Media project (OPM). + +# OPM is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# OPM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with OPM. If not, see . + import numpy as np import struct @@ -6,11 +24,6 @@ LAYER_UNSCALING = 3 LAYER_DENSE = 4 LAYER_ACTIVATION = 5 -LAYER_MAXPOOLING2D = 6 -LAYER_LSTM = 7 -LAYER_EMBEDDING = 8 -LAYER_ELU = 9 -LAYER_CONV2D = 10 ACTIVATION_LINEAR = 1 ACTIVATION_RELU = 2 @@ -106,13 +119,11 @@ def write_activation(activation): write_unscaling(f) feat_inf = layer.get_weights()[0] feat_sup = layer.get_weights()[1] - # feat = layer.get_weights()[2][0] f.write(struct.pack('f', layer.data_min)) f.write(struct.pack('f', layer.data_max)) f.write(struct.pack('f', feat_inf)) f.write(struct.pack('f', feat_sup)) - elif layer_type == 'Dense': weights = layer.get_weights()[0] biases = layer.get_weights()[1] @@ -131,179 +142,14 @@ def write_activation(activation): write_activation(activation) - elif layer_type == 'Conv2D': - assert layer.padding == 'valid', "Only border_mode=valid is implemented" - - - # shape: (outputs, rows, cols, depth) - weights = layer.get_weights()[0].transpose(3, 0, 1, 2) - # biases = layer.get_weights()[1] - # activation = layer.get_config()['activation'] - - # weights = layer.get_weights()[0] - biases = layer.get_weights()[1] - activation = layer.get_config()['activation'] - - # weights = weights.flatten() - # biases = biases.flatten() - # write_tensor(f, weights, 4) - # write_tensor(f, biases) - - # # - # weights = layer.get_weights()[0] - # biases = layer.get_weights()[1] - # activation = layer.get_config()['activation'] - # - # The kernel is accessed in reverse order. To simplify the C side we'll - # flip the weight matrix for each kernel. - # weights = weights[:,:,::-1,::-1] - - f.write(struct.pack('I', LAYER_CONV2D)) - f.write(struct.pack('I', weights.shape[0])) - f.write(struct.pack('I', weights.shape[1])) - f.write(struct.pack('I', weights.shape[2])) - f.write(struct.pack('I', weights.shape[3])) - f.write(struct.pack('I', biases.shape[0])) - - weights = weights.flatten() - biases = biases.flatten() - - write_floats(f, weights) - write_floats(f, biases) - - write_activation(activation) - elif layer_type == 'Flatten': f.write(struct.pack('I', LAYER_FLATTEN)) - elif layer_type == 'ELU': - f.write(struct.pack('I', LAYER_ELU)) - f.write(struct.pack('f', layer.alpha)) - elif layer_type == 'Activation': activation = layer.get_config()['activation'] f.write(struct.pack('I', LAYER_ACTIVATION)) write_activation(activation) - elif layer_type == 'MaxPooling2D': - assert layer.padding == 'valid', "Only border_mode=valid is implemented" - - pool_size = layer.get_config()['pool_size'] - f.write(struct.pack('I', LAYER_MAXPOOLING2D)) - f.write(struct.pack('I', pool_size[0])) - f.write(struct.pack('I', pool_size[1])) - - - elif layer_type == 'LSTM': - - inner_activation = layer.get_config()['recurrent_activation'] - activation = layer.get_config()['activation'] - return_sequences = int(layer.get_config()['return_sequences']) - - weights = layer.get_weights() - units = layer.units - - kernel, rkernel, bias = ([x[i: i+units] for i in range(0, 4*units, units)] - for x in (weights[0].transpose(), - weights[1].transpose(), - weights[2])) - bias = [x.reshape(1, -1) for x in bias] - for tensors in zip(kernel, rkernel, bias): - for tensor in tensors: - write_tensor(f, tensor, 2) - - # export_activation(inner_activation, f) - # export_activation(activation, f) - # f.write(struct.pack('I', return_sequences)) - - - # inner_activation = layer.get_config()['recurrent_activation'] - # activation = layer.get_config()['activation'] - # return_sequences = int(layer.get_config()['return_sequences']) - # - # weights = layer.get_weights() - # W_i = weights[0] - # U_i = weights[1] - # b_i = weights[2] - # - # W_c = weights[3] - # U_c = weights[4] - # b_c = weights[5] - # - # W_f = weights[6] - # U_f = weights[7] - # b_f = weights[8] - # - # W_o = weights[9] - # U_o = weights[10] - # b_o = weights[11] - # - # f.write(struct.pack('I', LAYER_LSTM)) - # f.write(struct.pack('I', W_i.shape[0])) - # f.write(struct.pack('I', W_i.shape[1])) - # f.write(struct.pack('I', U_i.shape[0])) - # f.write(struct.pack('I', U_i.shape[1])) - # f.write(struct.pack('I', b_i.shape[0])) - # - # f.write(struct.pack('I', W_f.shape[0])) - # f.write(struct.pack('I', W_f.shape[1])) - # f.write(struct.pack('I', U_f.shape[0])) - # f.write(struct.pack('I', U_f.shape[1])) - # f.write(struct.pack('I', b_f.shape[0])) - # - # f.write(struct.pack('I', W_c.shape[0])) - # f.write(struct.pack('I', W_c.shape[1])) - # f.write(struct.pack('I', U_c.shape[0])) - # f.write(struct.pack('I', U_c.shape[1])) - # f.write(struct.pack('I', b_c.shape[0])) - # - # f.write(struct.pack('I', W_o.shape[0])) - # f.write(struct.pack('I', W_o.shape[1])) - # f.write(struct.pack('I', U_o.shape[0])) - # f.write(struct.pack('I', U_o.shape[1])) - # f.write(struct.pack('I', b_o.shape[0])) - # - # W_i = W_i.flatten() - # U_i = U_i.flatten() - # b_i = b_i.flatten() - # W_f = W_f.flatten() - # U_f = U_f.flatten() - # b_f = b_f.flatten() - # W_c = W_c.flatten() - # U_c = U_c.flatten() - # b_c = b_c.flatten() - # W_o = W_o.flatten() - # U_o = U_o.flatten() - # b_o = b_o.flatten() - # - # write_floats(f, W_i) - # write_floats(f, U_i) - # write_floats(f, b_i) - # write_floats(f, W_f) - # write_floats(f, U_f) - # write_floats(f, b_f) - # write_floats(f, W_c) - # write_floats(f, U_c) - # write_floats(f, b_c) - # write_floats(f, W_o) - # write_floats(f, U_o) - # write_floats(f, b_o) - - write_activation(inner_activation) - write_activation(activation) - f.write(struct.pack('I', return_sequences)) - - elif layer_type == 'Embedding': - weights = layer.get_weights()[0] - - f.write(struct.pack('I', LAYER_EMBEDDING)) - f.write(struct.pack('I', weights.shape[0])) - f.write(struct.pack('I', weights.shape[1])) - - weights = weights.flatten() - - write_floats(f, weights) - else: assert False, "Unsupported layer type: %s" % layer_type diff --git a/opm/ml/ml_tools/make_model_BCkrn.py b/opm/ml/ml_tools/make_model_BCkrn.py deleted file mode 100644 index a66ecb62f53..00000000000 --- a/opm/ml/ml_tools/make_model_BCkrn.py +++ /dev/null @@ -1,104 +0,0 @@ -from sklearn.preprocessing import MinMaxScaler -from sklearn.metrics import mean_squared_error -from keras.models import Sequential -from keras.layers import Dense -from numpy import asarray -from matplotlib import pyplot -import numpy as np -import pandas as pd - - -#def computeBCKrw(satW, lambdaparam): -# kr = pow(satW, 2.0/lambdaparam + 3.0) -# return kr - -def computeBCKrn(satW, lambdaparam): - Sn = 1.0 - satW; - exponent = 2.0/lambdaparam + 1.0 - kr = Sn*Sn*(1. - pow(satW, exponent)) - return kr - - -# sw = np.linspace(0, 1, num=1001, endpoint=True) -sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) - - -lambdaparam = 2 - -#BCKrw = computeBCKrw(sw, lambdaparam) -BCKrn = computeBCKrn(sw, lambdaparam) - - -# define the dataset -x = sw -y = np.array([BCKrn]) - -print(x.min(), x.max(), y.min(), y.max()) -# reshape arrays into into rows and cols -x = x.reshape((len(x), 1)) -y = y.reshape((10001, 1)) -# separately scale the input and output variables -scale_x = MinMaxScaler() -x = scale_x.fit_transform(x) -scale_y = MinMaxScaler() -y = scale_y.fit_transform(y) -print(x.min(), x.max(), y.min(), y.max()) - -# design the neural network model -model = Sequential() -model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(1)) - -# define the loss function and optimization algorithm -model.compile(loss='mse', optimizer='adam') - -# ft the model on the training dataset -model.fit(x, y, epochs=1000, batch_size=100, verbose=0) - -# make predictions for the input data -yhat = model.predict(x) -# inverse transforms -x_plot = scale_x.inverse_transform(x) -y_plot = scale_y.inverse_transform(y) -yhat_plot = scale_y.inverse_transform(yhat) -# report model error -print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) -print(yhat_plot) -print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) - - -df = pd.DataFrame({'Id': x_plot[:, 0], 'Amount': yhat_plot[:, 0].astype(float)}) - -def f(a): - a = df.loc[df['Id'] == a, 'Amount'] - #for no match - if a.empty: - return 'no match' - #for multiple match - elif len(a) > 1: - return a - else: - #for match one value only - return a.item() - -# plot x vs y -pyplot.plot(x_plot,y_plot, label='Actual') -# plot x vs yhat -pyplot.plot(x_plot,yhat_plot, label='Predicted') -pyplot.title('Input (x) versus Output (y)') -pyplot.xlabel('Input Variable (x)') -pyplot.ylabel('Output Variable (y)') -pyplot.legend() -pyplot.savefig('filename.png', dpi=1200) -pyplot.show() - -#save model -from kerasify import export_model -export_model(model, 'example.modelBCkrn') diff --git a/opm/ml/ml_tools/make_model_BCkrw.py b/opm/ml/ml_tools/make_model_BCkrw.py deleted file mode 100644 index 59627c3e329..00000000000 --- a/opm/ml/ml_tools/make_model_BCkrw.py +++ /dev/null @@ -1,103 +0,0 @@ -from sklearn.preprocessing import MinMaxScaler -from sklearn.metrics import mean_squared_error -from keras.models import Sequential -from keras.layers import Dense -from numpy import asarray -from matplotlib import pyplot -import numpy as np -import pandas as pd - - -def computeBCKrw(satW, lambdaparam): - kr = pow(satW, 2.0/lambdaparam + 3.0) - return kr - -#def computeBCKrn(satW, lambdaparam): -# Sn = 1.0 - satW; -# exponent = 2.0/lambdaparam + 1.0 -# kr = Sn*Sn*(1. - pow(satW, exponent)) -# return kr - - -# sw = np.linspace(0, 1, num=1001, endpoint=True) -sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) - - -lambdaparam = 2 - -BCKrw = computeBCKrw(sw, lambdaparam) -#BCKrn = computeBCKrn(sw, lambdaparam) - - -# define the dataset -x = sw -y = np.array([BCKrw]) - -print(x.min(), x.max(), y.min(), y.max()) -# reshape arrays into into rows and cols -x = x.reshape((len(x), 1)) -y = y.reshape((10001, 1)) -# separately scale the input and output variables -scale_x = MinMaxScaler() -x = scale_x.fit_transform(x) -scale_y = MinMaxScaler() -y = scale_y.fit_transform(y) -print(x.min(), x.max(), y.min(), y.max()) - -# design the neural network model -model = Sequential() -model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(1)) - -# define the loss function and optimization algorithm -model.compile(loss='mse', optimizer='adam') -# ft the model on the training dataset -model.fit(x, y, epochs=1000, batch_size=100, verbose=0) -# make predictions for the input data -yhat = model.predict(x) -# inverse transforms -x_plot = scale_x.inverse_transform(x) -y_plot = scale_y.inverse_transform(y) -yhat_plot = scale_y.inverse_transform(yhat) -# report model error -print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) -print(yhat_plot) -print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) - - -df = pd.DataFrame({'Id': x_plot[:, 0], 'Amount': yhat_plot[:, 0].astype(float)}) - - -def f(a): - a = df.loc[df['Id'] == a, 'Amount'] - #for no match - if a.empty: - return 'no match' - #for multiple match - elif len(a) > 1: - return a - else: - #for match one value only - return a.item() - -# plot x vs y -pyplot.plot(x_plot,y_plot, label='Actual') -# plot x vs yhat -pyplot.plot(x_plot,yhat_plot, label='Predicted') -pyplot.title('Input (x) versus Output (y)') -pyplot.xlabel('Input Variable (x)') -pyplot.ylabel('Output Variable (y)') -pyplot.legend() -pyplot.savefig('filename.png', dpi=1200) -pyplot.show() - -#save model -from kerasify import export_model -export_model(model, 'example.modelBCkrw') diff --git a/opm/ml/ml_tools/make_model_VGkrn.py b/opm/ml/ml_tools/make_model_VGkrn.py deleted file mode 100644 index bb26731a6d9..00000000000 --- a/opm/ml/ml_tools/make_model_VGkrn.py +++ /dev/null @@ -1,90 +0,0 @@ -from sklearn.preprocessing import MinMaxScaler -from sklearn.metrics import mean_squared_error -from keras.models import Sequential -from keras.layers import Dense -from numpy import asarray -from matplotlib import pyplot -import numpy as np -import pandas as pd - - -#def computeVGKrw(satW, lambdaparam): -# kr = pow(satW, 2.0/lambdaparam + 3.0) -# return kr - -def computeVGKrn(satW, lambdaparam): - Sn = 1.0 - satW; - kr = pow(1 - satW, 1.0/3) * pow(1 - pow(satW, 1/lambdaparam), 2*lambdaparam); - return kr - - - - -# sw = np.linspace(0, 1, num=1001, endpoint=True) -sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) - - -lambdaparam = 0.78 - -#VGKrw = computeVGKrw(sw, lambdaparam) -VGKrn = computeVGKrn(sw, lambdaparam) - - -# define the dataset -x = sw -y = np.array([VGKrn]) - -print(x.min(), x.max(), y.min(), y.max()) -# reshape arrays into into rows and cols -x = x.reshape((len(x), 1)) -y = y.reshape((10001, 1)) -# separately scale the input and output variables -scale_x = MinMaxScaler() -x = scale_x.fit_transform(x) -scale_y = MinMaxScaler() -y = scale_y.fit_transform(y) -print(x.min(), x.max(), y.min(), y.max()) - -# design the neural network model -model = Sequential() -model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(1)) - -# define the loss function and optimization algorithm -model.compile(loss='mse', optimizer='adam') -# ft the model on the training dataset -model.fit(x, y, epochs=1000, batch_size=100, verbose=0) -# make predictions for the input data -yhat = model.predict(x) -# inverse transforms -x_plot = scale_x.inverse_transform(x) -y_plot = scale_y.inverse_transform(y) -yhat_plot = scale_y.inverse_transform(yhat) -# report model error -print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) -print(yhat_plot) -print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) - - -# plot x vs y -pyplot.plot(x_plot,y_plot, label='Actual') -# plot x vs yhat -pyplot.plot(x_plot,yhat_plot, label='Predicted') -pyplot.title('Input (x) versus Output (y)') -pyplot.xlabel('Input Variable (x)') -pyplot.ylabel('Output Variable (y)') -pyplot.legend() -pyplot.savefig('filenamekrn.png', dpi=1200) -pyplot.show() -#save model -from kerasify import export_model -# lazy hack to be changed - -export_model(model, 'example.modelVGkrn') diff --git a/opm/ml/ml_tools/make_model_VGkrw.py b/opm/ml/ml_tools/make_model_VGkrw.py deleted file mode 100644 index 53888a7bb15..00000000000 --- a/opm/ml/ml_tools/make_model_VGkrw.py +++ /dev/null @@ -1,87 +0,0 @@ -from sklearn.preprocessing import MinMaxScaler -from sklearn.metrics import mean_squared_error -from keras.models import Sequential -from keras.layers import Dense -from numpy import asarray -from matplotlib import pyplot -import numpy as np -import pandas as pd - - -def computeVGKrw(satW, lambdaparam): - r = 1.0 - pow(1.0 - pow(satW, 1/lambdaparam), lambdaparam); - return pow(satW,0.5)*r*r; - -#def computeVGKrn(satW, lambdaparam): -# Sn = 1.0 - satW; -# exponent = 2.0/lambdaparam + 1.0 -# kr = Sn*Sn*(1. - pow(satW, exponent)) -# return kr - - -# sw = np.linspace(0, 1, num=1001, endpoint=True) -sw = np.linspace(0, 1, 10001).reshape( (10001, 1) ) - - -lambdaparam = 0.78 - -VGKrw = computeVGKrw(sw, lambdaparam) -#VGKrn = computeVGKrn(sw, lambdaparam) - - -# define the dataset -x = sw -y = np.array([VGKrw]) - -print(x.min(), x.max(), y.min(), y.max()) -# reshape arrays into into rows and cols -x = x.reshape((len(x), 1)) -y = y.reshape((10001, 1)) -# separately scale the input and output variables -scale_x = MinMaxScaler() -x = scale_x.fit_transform(x) -scale_y = MinMaxScaler() -y = scale_y.fit_transform(y) -print(x.min(), x.max(), y.min(), y.max()) - -# design the neural network model -model = Sequential() -model.add(Dense(3, input_dim=1, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(10, activation='relu', kernel_initializer='he_uniform')) -# model.add(Dense(1000, activation='relu', kernel_initializer='he_uniform')) -model.add(Dense(1)) - -# define the loss function and optimization algorithm -model.compile(loss='mse', optimizer='adam') -# ft the model on the training dataset -model.fit(x, y, epochs=1000, batch_size=100, verbose=0) -# make predictions for the input data -yhat = model.predict(x) -# inverse transforms -x_plot = scale_x.inverse_transform(x) -y_plot = scale_y.inverse_transform(y) -yhat_plot = scale_y.inverse_transform(yhat) -# report model error -print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot)) -print(yhat_plot) -print('blah: %.3f' % mean_squared_error(y_plot, yhat_plot)) - - -# plot x vs y -pyplot.plot(x_plot,y_plot, label='Actual') -# plot x vs yhat -pyplot.plot(x_plot,yhat_plot, label='Predicted') -pyplot.title('Input (x) versus Output (y)') -pyplot.xlabel('Input Variable (x)') -pyplot.ylabel('Output Variable (y)') -pyplot.legend() -pyplot.savefig('filenamekrw.png', dpi=1200) -pyplot.show() -#save model -from kerasify import export_model -export_model(model, 'example.modelVGkrw') diff --git a/opm/ml/ml_tools/models/test_conv_2x2.model b/opm/ml/ml_tools/models/test_conv_2x2.model deleted file mode 100644 index 2427ebe5545682e4d632f5fe1eb97d9d2b5679b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmZQ(U|`?^Vn!flf?^OGgx7~f?JMTi-{-Y<>AvX2-urTenyp}REKoHt{?W{3`}2gF HcY*i-*&Yp) diff --git a/opm/ml/ml_tools/models/test_conv_3x3.model b/opm/ml/ml_tools/models/test_conv_3x3.model deleted file mode 100644 index 6794446c19d8e84c566d06e46b74a12cd025ef72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmZQ(U|`?^Vn!flhGGyKg#DL)-^Z?g%!cRF)rV0`1ZH}~fWHSYrP0b)28i2wiq diff --git a/opm/ml/ml_tools/models/test_conv_3x3x3.model b/opm/ml/ml_tools/models/test_conv_3x3x3.model deleted file mode 100644 index 211b8fcf0f83adcb84f8949d68b21d45dda247d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZQ(U|`?^VrDGZ?7r^4nO!aWs!jd(y>?$@cPrrFo@-u3`?~gS+Qag6@jfMq<9okd zT(Yli5$nF0Tr;h|)i&CGv-97VWcp~Y?mfG`G0P|J3;xS*d(&+GJ~Qdxd+nlr+1k~w zvOWLG%xx&=Sc6@EzcP};1?j`doyB#sh_DM2^*;G7Tw(obU{N4{Q1@^5{ZLsZr z!L_f!CwJd_?HP6xFEZJkGU?tYa3*sfgLmRS)-RH_55xWJ^227>y?WYfo8wuj~EoVd?-t3a)Da diff --git a/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model b/opm/ml/ml_tools/models/test_conv_hard_sigmoid_2x2.model deleted file mode 100644 index fc82dd1aa73946c35fa83cd408e8001eb28e7553..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmZQ(U|`?^Vn!flf?^OGgcs#D?|asyVJ~?oZXaj#!F_o`&AZs3ax739rnb=O=Kg%4 IW-AaM0PUL%V*mgE diff --git a/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model b/opm/ml/ml_tools/models/test_conv_sigmoid_2x2.model deleted file mode 100644 index 69057aa2371eda0c9adc92bf1154066fa24667e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmZQ(U|`?^Vn!flf?^OGgturm+toGh-scf8!ET53d%Ikr=3OjMIT#I7TU8XaKToLH H3d9Eh*8L2$ diff --git a/opm/ml/ml_tools/models/test_conv_softplus_2x2.model b/opm/ml/ml_tools/models/test_conv_softplus_2x2.model deleted file mode 100644 index 61f0218aedcb4479959e0324bd03af1e46bf18a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmZQ(U|`?^Vn!flf?^OGgb#aU@3nZnXkSI?IXf<8Zu?xJ=3UHCITk1lQ@gr?b$^~v IvlWOB0LxVjCjbBd diff --git a/opm/ml/ml_tools/models/test_dense_10x1.model b/opm/ml/ml_tools/models/test_dense_10x1.model index 5d3b0bed11bfaf915d77b7f58012436b9c1de2c2..4f3e572a68dca5ba9b426fb9bad49845080f94cf 100644 GIT binary patch delta 53 zcmV-50LuSFM359P2wm4cqm*+!T39^4L^1|HMUU6M(-jQA{U!swO)qXffZ5SL9K77V LZW4n!0RR91FBcSL delta 53 zcmV-50LuSFM359P+pai11Lz(;pl>Tbke$0e3ijN-BxTn=nMRg84kY-Uva z&9%E_H({UeYID0|Ki}`Yd-(6ZIdf0#+tcN2cc|p%-pM(c`!=jxu=Bftj@_H+?fVw! zT-bN0;JCbj0$Mb5gUGqGS{ZBss-4}4^mR;}e zt9yesKDUz>XS6q4e9MmEDEEH3x~u!@vi{gjzsYI;cAMqCrwcsxm0IrID-?ZcuUP(a z+u2;^c2(vRZ6`}V+xJamq8;11*EV4R$L*f=pSLZE-fVX;T6tfJYMY&c_2YeMv!~iH zB`&p_yNt#Dv@o~*-Z-m$n|tE+rU*6f$`xw1$_CO=K%4<&djaVzAPr*Y0ofoqMx?j| zu|e3aeAnI=@i*9rsCt=zzD|KjRayN-S5_Puf6v5&b`dtZ$IQ@a-p z^Y+Cayt(gH+}3>;E7?y#rE@DW_#{dUc2%LjeQMI=GeWT7H+pRq+#E43-@5%$xSwI@Z&H=JPe2^MOq__mJ zL0Dz3%6{ckC)-0c)Au@L?zj6b{dnKXAO3b~@h5ko9eI+?=ud3}XpI%C8Xz0?bTY%0)h2$9H{(APWu=#Tz*-22DBPj4?T zFJFP=Kgt{DslUa6%2aIdc3q$}X;cw9l*AiQYIG02f;~Pw#-V0bCUX28$ z5^qjcM-5j%25E6+5Oe8;}o0?tQFC{}Y8Z zGFt4+$J$@TDr0>cC4IaPGxa5CP&}m?@Y_V?T~n5cwt7q(29ea!&3$QG#2aR-$T^n6 z8IILi-WFYiOH;{C1ncmcc7PfCIxK0^a~KG;k$Z<2PhXE^#!Kl`l~RMRyB{LKtmovJ zBK`$;Kc}ex9k$^o+fsDD1v0_o0c0=2|s@5#nsEhYbisz zyC+Y&dsVm~TJWwQNBDgtOhHeIV56{${-WiJh8c`fF1=cP01_Dsh%_rQ#|! zQIN%s?ww`p((e+M1tDXyRGBAEMe|Y*6|b?O^{uV2q@AY?`Y4i%o@25ODHY#Wqp|26 zc$YkeySZt#xJ}HDTQB3FzQ(+Lt)6lk525ClA7KwYz#QLQ2Yc~*)q8Kh*54yi(`NTJn-3$`xIg_f(*g!@VBCoTU4XU(}e literal 924 zcmZvZeN5DK9LMkAjJ)EFWm>Fi|@@kswe=qf4Yh~_a}=uL}`9@@B&2Y0~?4sP~mYp>M9?Q;)n@&jqiqlYY}7^+d3 zxt)zgXo|SYT*CG2aDJWYK(L%X7nk9*z8RX5M#@@u72(tE>{g>#E&cO1@;h{&8Y{;k z|I!l{MH_C+zk=#Vd$FV9EL;hXu&8gL$e}0XD|(MB|3Qn8qb*cxF6W-RJW9s?E-cJl z!dHK-RI49OF}KA|1L@!3nrwt?^a{Y+pDnPeu#?@kTnjb~I;d0=z!iKe!3N`9d{owo zJ^fSERAEzj&cxHtJF}p;DOP{&@1WIo2jw#dLPks^`81SLN)-GJqs$==>pG9HjHnwd zvFQSNNBE$5>lyNI-$j2WP%U`P^R#i!S`f7mv_SdaXI>G2T3|QP?K;91<~>NV7eT}$U;@* z`c_h9TIoo|elD|jD_LXHs4JqEf`olI@NzE#4@N_yv%}RnMtuzvkm*9X+lH0)=(KJ0 zjO#m`pW95%iFssSJVCjapJf5PzvIWbzo}?ehmh1Uym3ivkFRjig@9qzJLv-~B{iJn zrsMEcu23&&Vp&#U0i{X);IuDwb%$3DsAT+K5AFU5a=v1wq?Bw?TBDAk@et}qliH1z2R1)lEciJw}NTe3C zl|)8!C7msj+KbIji1cge6$`F^~sNEQ|Td6 zgdL_gZ@aPY@qXO%m}DZ4TFRcd#gcYeN#6PdF{xox)-cFLJxJ=_kyAz6t#5HhOJg|M zhi05lJVTy_cQJflV*e@nS2T>wp#JnEw7jo$o_##oJj|Mq@26#-FVt+s$iTn=03fUbCIA2c delta 17 YcmY#Tm>|N#vnY3ezEHCjBLf2i04V|l3IG5A diff --git a/opm/ml/ml_tools/models/test_dense_2x2.model b/opm/ml/ml_tools/models/test_dense_2x2.model index 0ee9163a62d7f0c777b6628b5fd0374d6bd75a7b..7fe8b18bb83716023f08dc05e36ea5b03cbcbe3e 100644 GIT binary patch literal 80 zcmZQ#U|?VYVkRV9942kQ%6Olhx{H~8TEYzb9HC~bc%kN9j7VxhY!E&n+h)I+OJg5M H4Tui_$|ns0 literal 80 zcmZQ#U|?VYVkRUkBNDN{BCT(K=prGz<%dM<^MsnMK$sCpEr<=mcax&+lT6p!!Q=t% C+zp@r diff --git a/opm/ml/ml_tools/models/test_dense_relu_10.model b/opm/ml/ml_tools/models/test_dense_relu_10.model index dac1b5be1ceb0771c30b271926e1614e555bc6b2..41aeed0b4f323232b8612797b9c12ae70e6f7532 100644 GIT binary patch literal 1384 zcmZwEe^AqP7zgk#Z0=<9=cY9X4o-$u{+PNbX>Tzy8NOzlnQ=y%rKpM3{TE8hc+JX=r+4Bd3O zf<6#XK-^TlcqMrW)^-uCHsct$Zea=~W($J%5G19{$CnOvKoza=b#hw@^HN8MkK%XG zvsTcQxL%;A2k8$}J)tpA1tZfD_DsEw-z0K$e=PHWOmQKYegA>x6nmX)(ll+$hBnB3 z6ovd;C0*-1K$xG!f$U2rSccoQ?orj);@kk-rbJx4d^h3FNh3d;X9+zj4x(7q0H2mr zgMnKG{a|q76vxtO|3(Q~rVArZ^=$ z?{nCA^D0ZX#c>G)N^bzWFc~Y`IYPsxqgW!}k3&a$Fm`@9P=hN4GA}8{<{p8nuqL=$ zl7cM_%MY=Y1TyS<=w=NlQW>ek&tf9RyulE3H3!*G?~=6HSaQH`4`hC z-EX5fsu#mPc7}|`1K_-i(#e}U(K*s8P?xU)V@DgFUQqx(;oGoaAQQ~{>TuM|(M@!) zV)5cX;aLM8)EljY#ZW`o-UaYX(Le_CHNclupk#JBi7}eMCx(w@Vs;hxN2?!73^N~wfG4M*nA$PXCJ_XKqH;3xQrQ$P1p()RK%3S zA;ojN6XA#ngLNeFiWx(&lGeN3126l@bV^tqZZ+(IqI@$x?QBGu2a_HNHAA0b2YQ|R z0H#cKf%UCFV|dEE7BqkxW4qN^mU+NZN__ zNFh|Wb1-n-C6F>MqRWZnNL@*X$d_ekN?3+#A6YQIM}Yy6h+?;H;@4jey-yzD#%L?{ zm)xka7AK*EGePLGs}J%Pg+qG02{U?P(5o$#J}}xqPLaLfx4IQYOS_5w1zV`i_zLuW zMo27|0pqBH@Il?*n76wcDi&ElvwjF%TQwNIHx@#Yt#nXiK6dWE1&=>jj-rrsLUpVm z^OQW`$FY^j@39g5I zyu-A2$T-}=9;Y*GD*%DY7bv?V+LdcW$&54FUf~hsmD*uYS~JOr))N=OV;En37_Pey zVP7o=gNA~YWdi^J literal 1384 zcmZwGeNfDK90%}U+oshMr6JX^da~y#t%=zBel{eXFmWq+UX3H2oGV;I?s|}051|!m zBcUrB*Ta@8{C=O`Pu=X*PCB+MDSEibP%0{M-MP9uGsfI^<~`rfeBOV)=3`7z6n{8o zA7rwB4z_GS=v3UrbN$6&yR!_Q*$!f~a1Q3h{Dl$E>mV>A1*5eBmY+El+taLI!VEKZ z+Tm4r!2CSgy0-v7qZu{s=29oCgK#SNFiy+82I-T^iNRVAYn+YP+fnhPr^AfINs%-QM%r|~zEi3Q%RSnX;eJrfML zwg#{wqmvF2)uCDGRID;MfPH5!EDzGala(q6@hXCxVk4>DU@0lns_E<|3E24uFKVc`3EzRffx)xK)F_{%qTi09r0KkV#=Wi^VkO-odrzLL=&JQ0wuNad<+OkA+@|? zxVIn`W4{>-SL`RF{8l@;?Qe-~A$eF;c#&-9He=fFz34Nu0K0rmS$zTxaf_8W=B6nt zPt2yXiW;%5P>J>HCcyoZ6r24v(~lB9A(5}D(XMs?% z;|6RJRpNllQCwtE29ocRP_Mm#ZvIQLV8DRwx3;2U86RXnakwq~HQIiw0De~#_-ENO z7Ge(wzwinpXSag)PB&OS>=*H$VTbjt*gX2iq;80Pv1 z+T}NcjbjST^JoJ@{slO?f-mJZ&jLrC9i&H9km*jNSn!Ufw=q~L|2W&w=T2MXG$X$sfAe3pabTPnm+GgEZsOTm9+SJkf$)34en0B zKHbky?l^=!+g1^;uoa~A{y})zR)Aq!t>IK-Fg9hi!D9z=)w1N4gQq FzX959WK#eD diff --git a/opm/ml/ml_tools/models/test_dense_tanh_10.model b/opm/ml/ml_tools/models/test_dense_tanh_10.model index c2c9808ebc0833c1dcdbfb4ea56a206df527b904..efadda6e44d709064369f25592e18fc616b3b578 100644 GIT binary patch literal 1384 zcmZvbSx}Q_6owOlC{ZiLS{JYoV5qeyB8+WAzVi!?f@rH1h*S_{35%HERz}b=Y9J6x z*rZfwMF@*%StL=11pX7GiXe4us18s-P+S^OQ6nOx{h9Hi7hXK`%y+)aXI?WFi)GHh z{U7eE&5$~q2CuX=P<|u}3dT><9+HDlobnWT9w+emCbsTy+;OZ}T7!N8;}{-1Mi%Yp z$1R82Fei5edzYU?iw+Cy8Y`j~@a@s@;X}`Sk%jJ==p5LU>uFuoY4jc5OQxQw1Yd3+ zJ+C9bR6S^2@)m2) zJVLwFvm{Ntg52-$Mcc(WP`j)M5{v6FPkanJf@-m|l&$+boJE~-eM&#RQGq6(8qCfd zCCXigp>?$kM_rvUV81V1%#OjJb~pF|m9+lVQ8IG87fSh4bf?Q6;~MoiZ0vcBGq2Ut zp-xxf!h=9Cd$tzr+caQwE&+QN73>Hs#h0J0Z_*S^U`Vo2P4E^$fY9{)2Sq@Cgg=2#f55jB2MH`uJv+KxuhL?MK3{SUWxK%M@)V*-ZUCu z4dK>OZ5YEAYbig5vGGHxHkR>b<{ilp&0xmdEZ);HX&;RT9RxVvm#wR>9->7XSHV`$Yy|wGgo3&x4Y^!<7q?l9AY`Ep#{4@?w}xwl zq}&A_T*}7bUMI{Pz7F2z3FOC)WZ2hq4igj#tP#(^J^37vWEr6S%{OTLatQog&8V(+ zHAoM)qT_Gzuv2{tB(YUc`tSv@uXCa!3%p@l@NBZezXK)mD!9*+3)U)sr-LpQW7hUT zunRMz9-C{?l2<}sb>UJ^9DLy9lzbBJ{2crKOn~fuF|^en2vh3u#+?e}?9`J6_sbyX zI-pwe2xF>e;YX{7-~(qPM!nXcmiG&`S9K!OjlY3mvSTRYD8@`%{x*imKgL=Ci5Lm2k?3!^C{c_`Pru8>A@OTLhW!x?mRnHE z8#j0c@*N?dst*>;&xD@zZeYjxfN9q>-7!NI+_qC-LuM#gUh)E`q-s1d&;pZt+|Ix> Vi?{0~m=h6Vrt literal 1384 zcmZ{jX;9P!7{(Vth(!~{6orwju@F-v)Is3?t~P?ETq`OJ5Goop93iMkGm7K_aSI}% z$u$teH6bDcvh4p^4ihvvb`fx45t2jhI6Oc@`s4JW5B1?U&-1=tfAgsFcsw-@{=blS zJtv2%caZDZu);%p!IihKXuP+(L}F*IFa8gg;?4|9r80|(4BN=5UP#$?UC1BJLwX>7+0 z312#J5E8NbD7|RkicT{v!NYCguzBt%@#>wX+3^N+OEd(<6>ji;CPPk;rr^Q7Q5;g} zq1+>zag?hH+%xjAYgG$PJdrU~$?ZV$2%RX?6z~VV$l0}=)E{NjRLxCt(hg%|O;r%% zUX8RMCp7w`Qe8wdbA+Eu`$D`a&vhP0bmK8*f1U~Z*bJ3JdQeU#A=pa+8+92q?~146 z?a!g7IEs3kT$tuv!9->#T)K-S293eAcY`0bnrKMJRkEo*s+8opO0o{mm0Y?UN_JmG zQplf)l-0L~WIFzA>e9o=%m_xSl|Q*%7h9h7tz>om*3bv%ZXj9}q?V*E4X%9%cuwLb zZ!Z<_`e<$XtmNA14z}Ah5$EA%q5xFD1e+@eIsre~=^w zIi9KY*vcrIYUujUv1Dc&Mc<~U<7S=?QkWvvjdOOGbH%xPzr}^* Ryqa@+eV+?kUHC2R@^5$}rRM+u diff --git a/opm/ml/ml_tools/models/test_elu_10.model b/opm/ml/ml_tools/models/test_elu_10.model deleted file mode 100644 index 8a506a707e0c0293894e78218bcecfd6c2e118ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 536 zcmYk3ZAepL6vsF3*4l(E7fGT^O9*k1D|DsoIk!S=MM6VyOrl8!g9&{ZV#OlkO0eEo z^s+TnEKAZaQ97H2?8M z!-)CP7*;MTQPj^5Sx=IF8b0{(cQ6y2I-z%dHvwQJa<$&agDO*mOH zN*j}Nu*u$xOX)Xg^?aZMP6Kgw|E8Yk6&$f3?dw><16-B}nIdQn-v#GU1}zm;QGe@~!@Y>0dUC{3YuXq?`x$idQdKZF~77>PcF;too@gNx)_->{{AUluA-9GmL; z3?a@1Gn-Gr<98}P=_mH@Vy6L93E2V=1$n2sy>h(p8ns03onX!zz=L0o@P&U)J^ zSuvi*;{6#2LjnqP0}v$}Fj5#od)a$(?MwikRc#Ts>V>dUFEo@&c1f<1==_`Qk`qNj zxLvYb>QF5q4gasx{4USXHi52=JR!EgZp`ge^OY(W)Oe=QFKYQ0k9M%v2j{8bj*+>g H-}(DL2oC10 diff --git a/opm/ml/ml_tools/models/test_maxpool2d_1x1.model b/opm/ml/ml_tools/models/test_maxpool2d_1x1.model deleted file mode 100644 index 0773beb5a1eba05463ef600b3065bc97e6a5fbb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 444 zcmZQ(U|?VaVn!s)0%WHk@tGS!ZGR+`@B7{9w@)whwrx~+r)~HuUOP(-^L_b$#OxAX z^!6!x>DzK!O4)9oBVw1~e|Yb+2(CH)-PYy?TAlyH-5t*{ig+&(C#;blb&SEcaFUmF+7}k+b8HG1Iv-Tdmx@XVH^L%@M+5WP%HDk29wZv#&+?Rc}ZSDU1 ztc5l0RM#5X$r=XPJ@sbW%Q)Z2E>|_%Zr0wrwzX1e`^*Yv?Ohq8v)5P1Yp>FI@jcsq zhVR?Y=ebX`)n;G#W$%44+FPuZH2ZDEZa%Utw{)@7y`R3%d#;1s7V{f>@9r_P^V%=A zTi(NcUtiwIy$khY?AmST+0-TMw7s{ZXK%x&(tQ(^^X;k+M%hJb8}DP=I@vb2lF2UL e+}ZAuh~A!+*6RB#rQYpfO5A9hC)8{OiZ1|=L$pZ% diff --git a/opm/ml/ml_tools/models/test_relu_10.model b/opm/ml/ml_tools/models/test_relu_10.model index e5eea91cb471817bc062c2aa38c7ccd6ccd12a4a..d9597021154518edd510455d0d4e12fd443bb5c3 100644 GIT binary patch delta 462 zcmV;<0WtpA1K0zQ6n`v1V?JOEsy^Kb)V^`7_=snJK%RaMeNWL)bqP||} zQNA>x&be;?Y8Jj#n5n+Nx|BYgJAJ+&MHW8Ff2uwpZk;}`^b5U^@rgY$GMqk` z|KU9pACSHP^?xlriyv3LVy@i21+=`rfE6h{QIGe%C3vj76wrFU+GF89f5@f2zxVgP z%ZqkgDmIevG16-gycv-(bCm=~a+k;yvPLrM|X?tv(&|!Mt=%%|cBac1j1K>R(1Sh^zkSIPtZGOH)X{5c0?4!QG z;RU~lEZaRr6tleKfX}|7KS?M=S%!MZ+jvEn{94~D+m zMf1L`#I(NCC4U0HB)n<9Frj)qj^|Cjf8eUVX6rD%8PIP&tb(0B^a|@fRcs!<>ScgF z{tU4`=mDv{urUC?Sj<{JBA&87{^W!{qhAU?8DEjU(MYE~Mtbl*gg;Kah)}RTtij8@ zI9G|j$2CYk-{6J4d+BFB3g*f_DLWQEsgnsm5XWggK}Rh8zAS5my~ywgzLb_4zOvBF zJ!KMux&QzG09z7+I${!ox)>6JIsgCw00000000000PzunI%5)pIspIx00jU500IC2 E0DPX@>Hq)$ diff --git a/opm/ml/ml_tools/models/test_scalingdense_1x1.model b/opm/ml/ml_tools/models/test_scalingdense_1x1.model index f0f8f88bd5f0dc9ed596d13356e3851bb24d0602..7baf2c16f3f6c426c46dc5985b99d3c025e1d859 100644 GIT binary patch literal 1884 zcmaKte>Bwj8pj!95Fslh+0@P5V<`z~%=h`0irup6tg^dFt+A{1BT+YdtJ@+LF@EIN z7z+8Zx0En`wVKcKRjG_hc50_VOk0yhOC|cblRMpWoYURYxu0`hpXYO)&!4aJejbjN zmKIBcf1vDQAWBzjo|+R+vo-gOcPPjk1@r4qFi_tg`A>5QJ2wU9NwjGCSTGnS-NBKX z;~3t=X3%~Tqi5+e0UtJ#IK~uhpZ)<(TtnK(;|MP39HYE92*L0EV@OL$4aTZWgNz5eGKf)wuO7k^_l9hZk*W=iaBRg;B;^+DOoT9zt3*Oo!J~FM)e`>`6TNF7O!yLrZC{N{KRCXIO&QOWg1y$hPJWLt4pM&v$#Mzr4q?^dD!F2hl09?2sF^Zm>4K$;`?ZR;mV7w$u5=RV1>s}+pZT?dDg*YK!G2YjA%mpET&!}J7Q=8DPJ zkeh4+IBx_}+Kq5g+7qdXEyWkjV(BsmW`>kN{BnP5<(R( zsIM;9^Ni=8#&XATqL-lJ9hFKUB<~uM*`HD)_Jb6wnvgFy#UuAp4)E`f!kVH~^vbrPMMaRb`Cpa&fa+KK6H5w0Dc10TG0qn!83acA%@>S?7Pbwj032L^xqKQ7*9B`4qkSpZ$9 z-@rThdpC#Ed3;;{+kc-+cehbU71qM}^{()vbS|`h&tWVNMx*wxB8;$&Mf>ufVO%#I zM)Ln88zQnWZXg5)Ha{kvb_7_g!=x|Y3hO`y^12BO%2|gJpElHc@jdK_Qc1?bkASf{ zN^&D%JCr!JfS^)`35lg(kBPKc&PUw>@#6A6(Ky5eDFCy6oNRR9PIC&L6e30OsygY*KEIv z(frZ#EQ$%i_rPx?BrtfCGD0r?Pfvj!(TlQ8D#0EP(T(c*_;H2KpR#J5~|Kk*fC zM>9|B3Nyh&+6NvkH<5q-G7c%@A$3%SlmG0+C6`55=-URTMTMxWoe5q#49J=bF>4cx gnM!oUf%2wlmv4RjU*5XZ(J;M3uV0I7)9g^@Ki!vak^lez literal 1884 zcmZ{lYf#f?7Kgb7LV}E1uvJEC!B&a|1r-;}d;WE`!XmJX+*~ag1Qn&4T5na6i-en8 zqykbz5eyPo41!u{g}mplhzJ;hqQq9YEi4EkUV=oBLN_>d#_6>0%=4b#IUmpS;TY=Z z=;&$rNByvhF?Fm4uwtf;86i+|>GzGUGGX|fV z;eZ(wi$n%&tH&^^vMTAtXc^Y7P(h^404===v?MB;c&fMr?N~ULJ_K#zOW<`wpA}8S z!!BQn)3fejYNS0LuXBfnmK}I1%Mu#-<+PQ{VO&c+@oUZ~4wVR?@JA87n39Q&%Io;? z_gtpz7YMW7}|j_V}Lrfyu>AmJ3--~MkiS|7^{R>8oq^o z7WE&HyiBH{re5e*qRWJ~aPjMz;wq6AZFQMKo8Q!_`R`2iRUECuKf3H&ucpoC7C__L zVMxt7K>W9*(#pCP*tmQLoEZ89*GSKhWwvv$qpBKKT{U99+1-vED?1@@-apZ6##u;M zyceIWyZ|2*$ie;N5)AHr4sKa@!RH$h9Zp?@ulpa8wP$BT|JGm8#PJ8n)m;VB@&Ukf zDG^?iV(3+Cu-aQd0+U40JR(L-$}6Z_bsM(tUIaCl^2nxF;V6~l)6}p?>hrHJ;KX`= z99tuiAFwXP4Ye1*Vni2b#mcGbR0DB2^@Pq!Zl_|tK9l-<5rm{fPy_x=kW5Ph`}%Qs zT=@db42w{_(+30dBFL6$HmI;^1ZndRV6d(mD!f03<4lEogS z;J9Z1glz*LQ6|8~fNuPJP9H{Ct)L+e=IEWyVPZ<+p(REPk?%jEx!h%R%q&AtQgIS) zAE7Xr_=qfsJB%~UuMoH0wJ>K}Jr3O`;A78Y=I#on=QRfG2xmVm_K>`BIpy#jZ-2~F zz004uG&vs)lT|;%oKK$6)&V~1rbL0Cxg#X}*NCx=Z313w4lxpPnHc?i%=xSfo6@I) zD6j>T_GRR8q6Yqb{VcD&58CvnqZyhIH;DDpxtx9PNaRmMC&AN{KOFH9~F}hi&gP zrKkNn!N+1gIO=DBwb&diy2LoRmd|Ed$Y7JN4pTK)3vmr!qOCoTb(JlJn87hHwKigV z&;1XDnsKl+RMWvT!B}~=mKb&9%kM<1ah=OWGIZYo*DdYF$-xrr+a`m+NfX>MoQc0$ zQ#@Mh1`i696jLUka^eQ$FO0>HGR9CyT5w~76NDdoj(T?YNKlp(E(Zm|P4Aa-FXj<6 z1sSvNIIManzx6padz1gnrCU-R1boP4G`>%PePIS|eF#N^nerF5`_MLBfr?2MHbk6- z?*3RXE4>Mt5jEWzX2ANACYbGZ7(WPph<}?Wfts@0L|ie0>~TE|dgH%A(uoInS;K*e zaXaE)UWQNI?vN)DW#H#{5Vz$N!NHj~1Y!B(kmHvIJ;fZxL|Ossw#(>SYcaX}?PkLJLP float: - r"""Compute the well productivity index (adjusted for density and viscosity) from the - Peaceman well model. - - .. math:: - WI\cdot\frac{\mu}{\rho} = \frac{2\pi hk}{\ln (r_e/r_w)} - - Parameters: - h: Thickness of the well block. - k: Permeability. - r_e: Equivalent well-block radius. - r_w: Wellbore radius. - - Returns: - :math:`WI\cdot\frac{\mu}{\rho}` - - """ - WI = (2 * math.pi * h * k) / (math.log(r_e / r_w)) - return WI - - -computePeaceman_np = np.vectorize(computePeaceman) - -logger.info("Prepare dataset") - -# scale h -h_plot = np.linspace(1, 20, 20) -h3 = 6.096 -k3 = 9.86923e-14 -#h_plot = np.array([h3]) -scale_h = MinMaxScaler() -# h = scale_h.fit_transform(h_plot.reshape(-1, 1)).squeeze(axis=0) -h = scale_h.fit_transform(h_plot.reshape(-1, 1)).squeeze() -#param_h = scale_h.get_params() -#print(scale_h.data_max_) -# scale k -k_plot = np.linspace(1e-13, 1e-11, 20) -#k_plot = np.array([k3]) -scale_k = MinMaxScaler() -k = scale_k.fit_transform(k_plot.reshape(-1, 1)).squeeze() -#param_k = scale_k.get_params() -#print(param_k) -# # scale r_e -# r_e_plot = np.logspace(math.log(10), math.log(400), 300) -r_e_plot = np.linspace(10, 300, 600) -#scale_r_e = MinMaxScaler((0.02, 0.5)) -scale_r_e = MinMaxScaler() -r_e = scale_r_e.fit_transform(r_e_plot.reshape(-1, 1)).squeeze() -#param_r_e = scale_r_e.get_params() -r_w = np.array([0.0762]) -h_v, k_v, r_e_v, r_w_v = np.meshgrid(h, k, r_e, r_w) -h_plot_v, k_plot_v, r_e_plot_v, r_w_v = np.meshgrid(h_plot, k_plot, r_e_plot, r_w) - -x = np.stack([h_v.flatten(), k_v.flatten(), r_e_v.flatten(), r_w_v.flatten()], axis=-1) - -y = computePeaceman_np( - h_plot_v.flatten()[..., None], - k_plot_v.flatten()[..., None], - r_e_plot_v.flatten()[..., None], - r_w_v.flatten()[..., None], -) -scale_y = MinMaxScaler() -y_scaled = scale_y.fit_transform(y) - -logger.info("Done") - -# Write scaling info to file -with open("scales.csv", "w", newline="") as csvfile: - writer = csv.DictWriter(csvfile, fieldnames=["variable", "min", "max"]) - writer.writeheader() - writer.writerow( - {"variable": "h", "min": f"{h_plot.min()}", "max": f"{h_plot.max()}"} - ) - writer.writerow( - {"variable": "k", "min": f"{k_plot.min()}", "max": f"{k_plot.max()}"} - ) - writer.writerow( - {"variable": "r_e", "min": f"{r_e_plot.min()}", "max": f"{r_e_plot.max()}"} - ) - writer.writerow({"variable": "r_w", "min": f"{r_w.min()}", "max": f"{r_w.max()}"}) - writer.writerow({"variable": "y", "min": f"{y.min()}", "max": f"{y.max()}"}) - - -# design the neural network model -model = Sequential( - [ - tf.keras.Input(shape=(4,)), - # tf.keras.layers.BatchNormalization(), - Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), - Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), - Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), - Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), - Dense(10, activation="sigmoid", kernel_initializer="glorot_normal"), - Dense(1), - ] -) - -# define the loss function and optimization algorithm -# lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( -# 0.1, decay_steps=1000, decay_rate=0.96, staircase=False -# ) -# model.compile(loss="mse", optimizer=tf.keras.optimizers.Adam(learning_rate=lr_schedule)) - -reduce_lr = tf.keras.callbacks.ReduceLROnPlateau( - monitor="loss", factor=0.1, patience=10, verbose=1, min_delta=1e-10 -) -model.compile(loss="mse", optimizer=tf.keras.optimizers.Adam(learning_rate=0.1)) - - -# ft the model on the training dataset -logger.info("Train model") -model.fit(x, y_scaled, epochs=5, batch_size=100, verbose=1, callbacks=reduce_lr) - -# make predictions for the input data -yhat = model.predict(x) -# inverse transforms -# r_e_plot = scale_r_e.inverse_transform(r_e.reshape(-1, 1)).squeeze() -# y_plot = scale_y.inverse_transform(y) -# yhat_plot = scale_y.inverse_transform(yhat) -# report model error -mse = tf.keras.losses.MeanSquaredError() -logger.info(f"MSE: {mse(y, yhat).numpy():.3f}") - - -re3 = 60.3473 -rw3 = 0.0762 -h3 = 15.24 -k3 = 1.97385e-13 - -#60.3473 0.0762 15.24 1.97385e-13 - - -wi = computePeaceman(h3 , k3 , re3, rw3) - -# scale h -h_plot2 = np.array(h3) -# h_plot = np.array([1e-12]) -#scale_h = MinMaxScaler() -#scale_h.set_params(param_h) -# h = scale_h.fit_transform(h_plot.reshape(-1, 1)).squeeze(axis=0) -h2 = scale_h.transform(h_plot2.reshape(-1, 1)).squeeze() - -# scale k -k_plot2 = np.array(k3) -#scale_k = MinMaxScaler() -#scale_k.set_params(param_k) -k2 = scale_k.transform(k_plot2.reshape(-1, 1)).squeeze() - -# # scale r_e -# r_e_plot = np.logspace(math.log(10), math.log(400), 300) -r_e_plot2 = np.array(re3) -#scale_r_e = MinMaxScaler((0.02, 0.5)) -#scale_r_e.set_params(param_r_e) -r_e2 = scale_r_e.transform(r_e_plot2.reshape(-1, 1)).squeeze() -r_w2 = np.array(rw3) -h_v2, k_v2, r_e_v2, r_w_v2 = np.meshgrid(h2, k2, r_e2, r_w2) -h_plot_v2, k_plot_v2, r_e_plot_v2, r_w_v2 = np.meshgrid(h_plot2, k_plot2, r_e_plot2, r_w2) -x2 = np.stack([h_v2.flatten(), k_v2.flatten(), r_e_v2.flatten(), r_w_v2.flatten()], axis=-1) -yhat2 = model.predict(x2) -print(r_e2, r_w2, h2, k2) -print(wi, yhat2, scale_y.inverse_transform(yhat2)) -# df = pd.DataFrame({"Id": x_plot[:, 0], "Amount": yhat_plot[:, 0].astype(float)}) - - -# def f(a): -# a = df.loc[df["Id"] == a, "Amount"] -# # for no match -# if a.empty: -# return "no match" -# # for multiple match -# elif len(a) > 1: -# return a -# else: -# # for match one value only -# return a.item() - - -# Plot w.r.t. r_e -# plot x vs y -for i in [0, 5, 10, 15]: - try: - pyplot.figure() - pyplot.plot( - r_e_plot, - computePeaceman_np( - np.full_like(r_e, h_plot[i]), - np.full_like(r_e, k_plot[i]), - r_e_plot, - np.full_like(r_e, r_w[0]), - ), - label="Actual", - ) - # plot x vs yhat - pyplot.plot( - r_e_plot, - scale_y.inverse_transform( - model( - np.stack( - [ - np.full_like(r_e, h[i]), - np.full_like(r_e, k[i]), - r_e, - np.full_like(r_e, r_w[0]), - ], - axis=-1, - ) - ) - ), - label="Predicted", - ) - pyplot.title("Input (x) versus Output (y)") - pyplot.xlabel("$r_e$") - pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") - pyplot.legend() - pyplot.savefig(f"plt_r_e_vs_WI_{i}.png", dpi=1200) - pyplot.show() - pyplot.close() - except Exception as e: - print(e) - pass - -# Plot w.r.t. h -# plot x vs y -try: - pyplot.figure() - pyplot.plot( - h_plot, - computePeaceman_np( - h_plot, - np.full_like(h, k_plot[0]), - np.full_like(h, r_e_plot[0]), - np.full_like(h, r_w[0]), - ), - label="Actual", - ) - # plot x vs yhat - pyplot.plot( - h_plot, - scale_y.inverse_transform( - model( - np.stack( - [ - h, - np.full_like(h, k[0]), - np.full_like(h, r_e[0]), - np.full_like(h, r_w[0]), - ], - axis=-1, - ) - ) - ), - label="Predicted", - ) - pyplot.title("Input (x) versus Output (y)") - pyplot.xlabel("$h$") - pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") - pyplot.legend() - pyplot.savefig("plt_h_vs_WI.png", dpi=1200) - pyplot.show() - pyplot.close() -except Exception as e: - pass - -# Plot w.r.t. k -# plot x vs y -try: - pyplot.figure() - pyplot.plot( - k_plot, - computePeaceman_np( - np.full_like(k, h_plot[0]), - k_plot, - np.full_like(k, r_e_plot[0]), - np.full_like(k, r_w[0]), - ), - label="Actual", - ) - # plot x vs yhat - pyplot.plot( - k_plot, - scale_y.inverse_transform( - model( - np.stack( - [ - np.full_like(k, h[0]), - k, - np.full_like(k, r_e[0]), - np.full_like(k, r_w[0]), - ], - axis=-1, - ) - ) - ), - label="Predicted", - ) - pyplot.title("Input (x) versus Output (y)") - pyplot.xlabel("$k$") - pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") - pyplot.legend() - pyplot.savefig("plt_k_vs_WI.png", dpi=1200) - pyplot.show() - pyplot.close() -except Exception as e: - pass - -# Plot w.r.t. r_w -# plot x vs y -try: - pyplot.figure() - pyplot.plot( - r_w, - computePeaceman_np( - np.full_like(r_w, h_plot[0]), - np.full_like(r_w, k_plot[0]), - np.full_like(r_w, r_e_plot[0]), - r_w, - ), - label="Actual", - ) - # plot x vs yhat - pyplot.plot( - r_w, - scale_y.inverse_transform( - model( - np.stack( - [ - np.full_like(r_w, h[0]), - np.full_like(r_w, k[0]), - np.full_like(r_w, r_e[0]), - r_w, - ], - axis=-1, - ) - ) - ), - label="Predicted", - ) - pyplot.title("Input (x) versus Output (y)") - pyplot.xlabel("$r_w$") - pyplot.ylabel(r"$WI\cdot\frac{\mu}{\rho}$") - pyplot.legend() - pyplot.savefig("plt_r_w_vs_WI.png", dpi=1200) - pyplot.show() - pyplot.close() -except Exception as e: - pass - -# save model -#model.save_weights("modelPeaceman.tf") - -from kerasify import export_model - -export_model(model, "example.modelPeaceman") \ No newline at end of file diff --git a/opm/ml/ml_tools/scaler_layers.py b/opm/ml/ml_tools/scaler_layers.py index 91db738fb61..ca77c60f7e3 100644 --- a/opm/ml/ml_tools/scaler_layers.py +++ b/opm/ml/ml_tools/scaler_layers.py @@ -1,3 +1,22 @@ +# Copyright (c) 2024 Birane Kane +# Copyright (c) 2024 Tor Harald Sandve +# Copyright (c) 2024 Peter Moritz von Schultzendorff + +# This file is part of the Open Porous Media project (OPM). + +# OPM is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# OPM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with OPM. If not, see . + """Provide MinMax scaler layers for tensorflow.keras.""" from __future__ import annotations diff --git a/opm/ml/ml_tools/scalertest.py b/opm/ml/ml_tools/scalertest.py index c9b195edd02..a662bc1da5a 100644 --- a/opm/ml/ml_tools/scalertest.py +++ b/opm/ml/ml_tools/scalertest.py @@ -1,4 +1,23 @@ -# +# Copyright (c) 2024 Birane Kane +# Copyright (c) 2024 Tor Harald Sandve +# Copyright (c) 2024 Peter Moritz von Schultzendorff + +# This file is part of the Open Porous Media project (OPM). + +# OPM is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# OPM is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with OPM. If not, see . + + from __future__ import annotations From e2f0a977c31fed66b6384bd501e54c5efae62d9c Mon Sep 17 00:00:00 2001 From: fractalmanifold Date: Tue, 13 Aug 2024 18:44:43 +0200 Subject: [PATCH 6/7] adding MITLicensing --- CMakeLists_files.cmake | 11 +++- opm/ml/LICENSE.MIT | 19 +++++++ opm/ml/keras_model.cpp | 22 +------- opm/ml/keras_model.hpp | 5 +- opm/ml/ml_tools/__init__.py | 0 opm/ml/ml_tools/kerasify.py | 10 +++- opm/ml/ml_tools/models/test_dense_10x1.model | Bin 68 -> 0 bytes opm/ml/ml_tools/models/test_dense_10x10.model | Bin 528 -> 0 bytes .../ml_tools/models/test_dense_10x10x10.model | Bin 924 -> 0 bytes opm/ml/ml_tools/models/test_dense_1x1.model | Bin 32 -> 0 bytes opm/ml/ml_tools/models/test_dense_2x2.model | Bin 80 -> 0 bytes .../ml_tools/models/test_dense_relu_10.model | Bin 1384 -> 0 bytes .../ml_tools/models/test_dense_tanh_10.model | Bin 1384 -> 0 bytes opm/ml/ml_tools/models/test_relu_10.model | Bin 472 -> 0 bytes .../models/test_scalingdense_1x1.model | Bin 1884 -> 0 bytes opm/ml/ml_tools/scaler_layers.py | 5 +- opm/ml/ml_tools/scalertest.py | 51 +----------------- {opm => tests}/ml/keras_model_test.cpp | 29 +++++----- .../ml/ml_tools/generateunittests.py | 51 +++++------------- .../ml/ml_tools/include/test_dense_10x1.hpp | 14 ++--- .../ml/ml_tools/include/test_dense_10x10.hpp | 14 ++--- .../ml_tools/include/test_dense_10x10x10.hpp | 16 +++--- .../ml/ml_tools/include/test_dense_1x1.hpp | 8 +-- .../ml/ml_tools/include/test_dense_2x2.hpp | 12 ++--- .../ml_tools/include/test_dense_relu_10.hpp | 16 +++--- .../ml_tools/include/test_dense_tanh_10.hpp | 16 +++--- .../ml/ml_tools/include/test_relu_10.hpp | 16 +++--- .../include/test_scalingdense_10x1.hpp | 20 +++---- .../ml/ml_tools/models/test_dense_10x1.model | Bin 0 -> 68 bytes .../ml/ml_tools/models/test_dense_10x10.model | Bin 0 -> 528 bytes .../ml_tools/models/test_dense_10x10x10.model | Bin 0 -> 924 bytes tests/ml/ml_tools/models/test_dense_1x1.model | Bin 0 -> 32 bytes tests/ml/ml_tools/models/test_dense_2x2.model | Bin 0 -> 80 bytes .../ml_tools/models/test_dense_relu_10.model | Bin 0 -> 1384 bytes .../ml_tools/models/test_dense_tanh_10.model | Bin 0 -> 1384 bytes tests/ml/ml_tools/models/test_relu_10.model | Bin 0 -> 472 bytes .../models/test_scalingdense_10x1.model | Bin 0 -> 1884 bytes 37 files changed, 137 insertions(+), 198 deletions(-) create mode 100644 opm/ml/LICENSE.MIT create mode 100644 opm/ml/ml_tools/__init__.py delete mode 100644 opm/ml/ml_tools/models/test_dense_10x1.model delete mode 100644 opm/ml/ml_tools/models/test_dense_10x10.model delete mode 100644 opm/ml/ml_tools/models/test_dense_10x10x10.model delete mode 100644 opm/ml/ml_tools/models/test_dense_1x1.model delete mode 100644 opm/ml/ml_tools/models/test_dense_2x2.model delete mode 100644 opm/ml/ml_tools/models/test_dense_relu_10.model delete mode 100644 opm/ml/ml_tools/models/test_dense_tanh_10.model delete mode 100644 opm/ml/ml_tools/models/test_relu_10.model delete mode 100644 opm/ml/ml_tools/models/test_scalingdense_1x1.model rename {opm => tests}/ml/keras_model_test.cpp (87%) rename {opm => tests}/ml/ml_tools/generateunittests.py (88%) rename opm/ml/ml_tools/include/test_dense_10x1.h => tests/ml/ml_tools/include/test_dense_10x1.hpp (79%) rename opm/ml/ml_tools/include/test_dense_10x10.h => tests/ml/ml_tools/include/test_dense_10x10.hpp (79%) rename opm/ml/ml_tools/include/test_dense_10x10x10.h => tests/ml/ml_tools/include/test_dense_10x10x10.hpp (75%) rename opm/ml/ml_tools/include/test_dense_1x1.h => tests/ml/ml_tools/include/test_dense_1x1.hpp (86%) rename opm/ml/ml_tools/include/test_dense_2x2.h => tests/ml/ml_tools/include/test_dense_2x2.hpp (83%) rename opm/ml/ml_tools/include/test_dense_relu_10.h => tests/ml/ml_tools/include/test_dense_relu_10.hpp (77%) rename opm/ml/ml_tools/include/test_dense_tanh_10.h => tests/ml/ml_tools/include/test_dense_tanh_10.hpp (75%) rename opm/ml/ml_tools/include/test_relu_10.h => tests/ml/ml_tools/include/test_relu_10.hpp (77%) rename opm/ml/ml_tools/include/test_scalingdense_1x1.h => tests/ml/ml_tools/include/test_scalingdense_10x1.hpp (70%) create mode 100644 tests/ml/ml_tools/models/test_dense_10x1.model create mode 100644 tests/ml/ml_tools/models/test_dense_10x10.model create mode 100644 tests/ml/ml_tools/models/test_dense_10x10x10.model create mode 100644 tests/ml/ml_tools/models/test_dense_1x1.model create mode 100644 tests/ml/ml_tools/models/test_dense_2x2.model create mode 100644 tests/ml/ml_tools/models/test_dense_relu_10.model create mode 100644 tests/ml/ml_tools/models/test_dense_tanh_10.model create mode 100644 tests/ml/ml_tools/models/test_relu_10.model create mode 100644 tests/ml/ml_tools/models/test_scalingdense_10x1.model diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 85a790dfb2c..877962a2a76 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -475,7 +475,7 @@ list (APPEND TEST_SOURCE_FILES tests/material/test_spline.cpp tests/material/test_tabulation.cpp tests/test_Visitor.cpp - opm/ml/keras_model_test.cpp + tests/ml/keras_model_test.cpp ) # tests that need to be linked to dune-common @@ -648,6 +648,15 @@ list (APPEND TEST_DATA_FILES tests/material/co2_unittest_below_sat.json tests/material/h2o_unittest.json tests/material/h2_unittest.json + tests/ml/ml_tools/models/test_dense_1x1.model + tests/ml/ml_tools/models/test_dense_2x2.model + tests/ml/ml_tools/models/test_dense_10x1.model + tests/ml/ml_tools/models/test_dense_10x10.model + tests/ml/ml_tools/models/test_dense_10x10x10.model + tests/ml/ml_tools/models/test_dense_relu_10.model + tests/ml/ml_tools/models/test_dense_tanh_10.model + tests/ml/ml_tools/models/test_relu_10.model + tests/ml/ml_tools/models/test_scalingdense_10x1.model ) if(ENABLE_ECL_OUTPUT) list (APPEND TEST_DATA_FILES diff --git a/opm/ml/LICENSE.MIT b/opm/ml/LICENSE.MIT new file mode 100644 index 00000000000..6908c245ebf --- /dev/null +++ b/opm/ml/LICENSE.MIT @@ -0,0 +1,19 @@ +Copyright (c) 2016 Robert W. Rose, 2018 Paul Maevskikh, 2024 NORCE + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/opm/ml/keras_model.cpp b/opm/ml/keras_model.cpp index 46a191c9e22..0aaf3a832ee 100644 --- a/opm/ml/keras_model.cpp +++ b/opm/ml/keras_model.cpp @@ -3,12 +3,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -37,8 +36,6 @@ namespace Opm { -#pragma once - bool ReadUnsignedInt(std::ifstream* file, unsigned int* i) { KASSERT(file, "Invalid file stream"); @@ -173,8 +170,6 @@ bool KerasLayerScaling::LoadLayer(std::ifstream* file) { KASSERT(ReadFloat(file, &data_max), "Failed to read max"); KASSERT(ReadFloat(file, &feat_inf), "Failed to read max"); KASSERT(ReadFloat(file, &feat_sup), "Failed to read max"); - - // KASSERT(ReadFloat(file, &feat), "Failed to read max"); return true; } @@ -188,8 +183,6 @@ bool KerasLayerScaling::Apply(Tensor* in, Tensordata_.size(); i++) { - // std::cout<<"out->data_[i]"<data_[i]<data_[i] - data_min)/(data_max - data_min); out->data_[i] = tempscale * (feat_sup - feat_inf) + feat_inf; } @@ -214,13 +207,9 @@ bool KerasLayerUnScaling::Apply(Tensor* in, TensorFlatten(); for (size_t i = 0; i < out->data_.size(); i++) { - // std::cout<<"out->data_[i]"<data_[i]<data_[i] - feat_inf)/(feat_sup - feat_inf); out->data_[i] = tempscale * (data_max - data_min) + data_min; @@ -267,13 +256,6 @@ bool KerasLayerDense::Apply(Tensor* in, Tensordims_.size() <= 2, "Invalid input dimensions"); - - // if (in->dims_.size() == 1) { - // KASSERT(in->dims_[0] == weights_.dims_[0], "Dimension mismatch %d %d", - // in->dims_[0], weights_.dims_[0]); - // } - - if (in->dims_.size() == 2) { KASSERT(in->dims_[1] == weights_.dims_[0], "Dimension mismatch %d %d", in->dims_[1], weights_.dims_[0]); diff --git a/opm/ml/keras_model.hpp b/opm/ml/keras_model.hpp index f84ea106bbf..40a77ce81f3 100644 --- a/opm/ml/keras_model.hpp +++ b/opm/ml/keras_model.hpp @@ -3,12 +3,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify diff --git a/opm/ml/ml_tools/__init__.py b/opm/ml/ml_tools/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/opm/ml/ml_tools/kerasify.py b/opm/ml/ml_tools/kerasify.py index a91dc615941..8dde9e054bb 100644 --- a/opm/ml/ml_tools/kerasify.py +++ b/opm/ml/ml_tools/kerasify.py @@ -1,6 +1,12 @@ -# Copyright (c) 2024 Birane Kane -# Copyright (c) 2024 Tor Harald Sandve +# /* +# * Copyright (c) 2016 Robert W. Rose +# * Copyright (c) 2018 Paul Maevskikh +# * +# * MIT License, see LICENSE.MIT file. +# */ + +# Copyright (c) 2024 NORCE # This file is part of the Open Porous Media project (OPM). # OPM is free software: you can redistribute it and/or modify diff --git a/opm/ml/ml_tools/models/test_dense_10x1.model b/opm/ml/ml_tools/models/test_dense_10x1.model deleted file mode 100644 index 4f3e572a68dca5ba9b426fb9bad49845080f94cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmZQ%U|?VYVlE(Ngkp}^>voH$6x&8c*z9*PVzYPczrOFXD9`@CYRr3m_4Di+ZeFyL O*>h)Ko=~$DNDlz*a}yc> diff --git a/opm/ml/ml_tools/models/test_dense_10x10.model b/opm/ml/ml_tools/models/test_dense_10x10.model deleted file mode 100644 index 0317b1d6e80047cd79f59aa9b92d59e87b8b44ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 528 zcmZQ#U|?VYVlE`?v%Gbmr0(`T7Oy+()@+<=m$d%F-t`+^?@Ru}WBc%(?!M@^>-Uva z&9%E_H({UeYID0|Ki}`Yd-(6ZIdf0#+tcN2cc|p%-pM(c`!=jxu=Bftj@_H+?fVw! zT-bN0;JCbj0$Mb5gUGqGS{ZBss-4}4^mR;}e zt9yesKDUz>XS6q4e9MmEDEEH3x~u!@vi{gjzsYI;cAMqCrwcsxm0IrID-?ZcuUP(a z+u2;^c2(vRZ6`}V+xJamq8;11*EV4R$L*f=pSLZE-fVX;T6tfJYMY&c_2YeMv!~iH zB`&p_yNt#Dv@o~*-Z-m$n|tE+rU*6f$`xw1$_CO=K%4<&djaVzAPr*Y0ofoqMx?j| zu|e3aeAnI=@i*~@h5ko9eI+?=ud3}XpI%C8Xz0?bTY%0)h2$9H{(APWu=#Tz*-22DBPj4?T zFJFP=Kgt{DslUa6%2aIdc3q$}X;cw9l*AiQYIG02f;~Pw#-V0bCUX28$ z5^qjcM-5j%25E6+5Oe8;}o0?tQFC{}Y8Z zGFt4+$J$@TDr0>cC4IaPGxa5CP&}m?@Y_V?T~n5cwt7q(29ea!&3$QG#2aR-$T^n6 z8IILi-WFYiOH;{C1ncmcc7PfCIxK0^a~KG;k$Z<2PhXE^#!Kl`l~RMRyB{LKtmovJ zBK`$;Kc}ex9k$^o+fsDD1v0_o0c0=2|s@5#nsEhYbisz zyC+Y&dsVm~TJWwQNBDgtOhHeIV56{${-WiJh8c`fF1=cP01_Dsh%_rQ#|! zQIN%s?ww`p((e+M1tDXyRGBAEMe|Y*6|b?O^{uV2q@AY?`Y4i%o@25ODHY#Wqp|26 zc$YkeySZt#xJ}HDTQB3FzQ(+Lt)6lk525ClA7KwYz#QLQ2Yc~*)q8Kh*54yi(`NTJn-3$`xIg_f(*g!@VBCoTU4XU(}e diff --git a/opm/ml/ml_tools/models/test_dense_1x1.model b/opm/ml/ml_tools/models/test_dense_1x1.model deleted file mode 100644 index c512d9dd927289ee946065f9c4b8ba095da799b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 acmZQ%U|?VYVn!rv@26#-FVt)W5(5AeLjpbk diff --git a/opm/ml/ml_tools/models/test_dense_2x2.model b/opm/ml/ml_tools/models/test_dense_2x2.model deleted file mode 100644 index 7fe8b18bb83716023f08dc05e36ea5b03cbcbe3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80 zcmZQ#U|?VYVkRV9942kQ%6Olhx{H~8TEYzb9HC~bc%kN9j7VxhY!E&n+h)I+OJg5M H4Tui_$|ns0 diff --git a/opm/ml/ml_tools/models/test_dense_relu_10.model b/opm/ml/ml_tools/models/test_dense_relu_10.model deleted file mode 100644 index 41aeed0b4f323232b8612797b9c12ae70e6f7532..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1384 zcmZwEe^AqP7zgk#Z0=<9=cY9X4o-$u{+PNbX>Tzy8NOzlnQ=y%rKpM3{TE8hc+JX=r+4Bd3O zf<6#XK-^TlcqMrW)^-uCHsct$Zea=~W($J%5G19{$CnOvKoza=b#hw@^HN8MkK%XG zvsTcQxL%;A2k8$}J)tpA1tZfD_DsEw-z0K$e=PHWOmQKYegA>x6nmX)(ll+$hBnB3 z6ovd;C0*-1K$xG!f$U2rSccoQ?orj);@kk-rbJx4d^h3FNh3d;X9+zj4x(7q0H2mr zgMnKG{a|q76vxtO|3(Q~rVArZ^=$ z?{nCA^D0ZX#c>G)N^bzWFc~Y`IYPsxqgW!}k3&a$Fm`@9P=hN4GA}8{<{p8nuqL=$ zl7cM_%MY=Y1TyS<=w=NlQW>ek&tf9RyulE3H3!*G?~=6HSaQH`4`hC z-EX5fsu#mPc7}|`1K_-i(#e}U(K*s8P?xU)V@DgFUQqx(;oGoaAQQ~{>TuM|(M@!) zV)5cX;aLM8)EljY#ZW`o-UaYX(Le_CHNclupk#JBi7}eMCx(w@Vs;hxN2?!73^N~wfG4M*nA$PXCJ_XKqH;3xQrQ$P1p()RK%3S zA;ojN6XA#ngLNeFiWx(&lGeN3126l@bV^tqZZ+(IqI@$x?QBGu2a_HNHAA0b2YQ|R z0H#cKf%UCFV|dEE7BqkxW4qN^mU+NZN__ zNFh|Wb1-n-C6F>MqRWZnNL@*X$d_ekN?3+#A6YQIM}Yy6h+?;H;@4jey-yzD#%L?{ zm)xka7AK*EGePLGs}J%Pg+qG02{U?P(5o$#J}}xqPLaLfx4IQYOS_5w1zV`i_zLuW zMo27|0pqBH@Il?*n76wcDi&ElvwjF%TQwNIHx@#Yt#nXiK6dWE1&=>jj-rrsLUpVm z^OQW`$FY^j@39g5I zyu-A2$T-}=9;Y*GD*%DY7bv?V+LdcW$&54FUf~hsmD*uYS~JOr))N=OV;En37_Pey zVP7o=gNA~YWdi^J diff --git a/opm/ml/ml_tools/models/test_dense_tanh_10.model b/opm/ml/ml_tools/models/test_dense_tanh_10.model deleted file mode 100644 index efadda6e44d709064369f25592e18fc616b3b578..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1384 zcmZvbSx}Q_6owOlC{ZiLS{JYoV5qeyB8+WAzVi!?f@rH1h*S_{35%HERz}b=Y9J6x z*rZfwMF@*%StL=11pX7GiXe4us18s-P+S^OQ6nOx{h9Hi7hXK`%y+)aXI?WFi)GHh z{U7eE&5$~q2CuX=P<|u}3dT><9+HDlobnWT9w+emCbsTy+;OZ}T7!N8;}{-1Mi%Yp z$1R82Fei5edzYU?iw+Cy8Y`j~@a@s@;X}`Sk%jJ==p5LU>uFuoY4jc5OQxQw1Yd3+ zJ+C9bR6S^2@)m2) zJVLwFvm{Ntg52-$Mcc(WP`j)M5{v6FPkanJf@-m|l&$+boJE~-eM&#RQGq6(8qCfd zCCXigp>?$kM_rvUV81V1%#OjJb~pF|m9+lVQ8IG87fSh4bf?Q6;~MoiZ0vcBGq2Ut zp-xxf!h=9Cd$tzr+caQwE&+QN73>Hs#h0J0Z_*S^U`Vo2P4E^$fY9{)2Sq@Cgg=2#f55jB2MH`uJv+KxuhL?MK3{SUWxK%M@)V*-ZUCu z4dK>OZ5YEAYbig5vGGHxHkR>b<{ilp&0xmdEZ);HX&;RT9RxVvm#wR>9->7XSHV`$Yy|wGgo3&x4Y^!<7q?l9AY`Ep#{4@?w}xwl zq}&A_T*}7bUMI{Pz7F2z3FOC)WZ2hq4igj#tP#(^J^37vWEr6S%{OTLatQog&8V(+ zHAoM)qT_Gzuv2{tB(YUc`tSv@uXCa!3%p@l@NBZezXK)mD!9*+3)U)sr-LpQW7hUT zunRMz9-C{?l2<}sb>UJ^9DLy9lzbBJ{2crKOn~fuF|^en2vh3u#+?e}?9`J6_sbyX zI-pwe2xF>e;YX{7-~(qPM!nXcmiG&`S9K!OjlY3mvSTRYD8@`%{x*imKgL=Ci5Lm2k?3!^C{c_`Pru8>A@OTLhW!x?mRnHE z8#j0c@*N?dst*>;&xD@zZeYjxfN9q>-7!NI+_qC-LuM#gUh)E`q-s1d&;pZt+|Ix> Vi?{0~m=h6Vrt diff --git a/opm/ml/ml_tools/models/test_relu_10.model b/opm/ml/ml_tools/models/test_relu_10.model deleted file mode 100644 index d9597021154518edd510455d0d4e12fd443bb5c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 472 zcmZQ#U|?VYVlE`C@#?~XkXlm zz`oRu z+2?!P+wMcE)7~%hAKS?;-?PtThMZl>ne}#;I4|1WOL}YfL29b4fa5ybD$aj)ZsD=} z;!^(E8XWp;_o1bCAHPKIK2c?6`!b`gb`oh~`+gYP?33JRXJ@d1!!GXkTf0xQ`|Sc= z-P~6Yc7I>WfvI-;D^J_{e4oDWPnOue&>1WD9oRL+ZjN>BJ_T1XyHoY6>=g3m+HLs4 zy?4ULPFo|RId(JtKeQE*pRkYNtFCRgeE8m^b$9l$ZrQW1K~&Q=u>bpB)rvKHL@reA zyOsRVuKvW*efz(E-*>vZ-fl6&mVFEYfwp~epX}J~Z`n8ZwYlxQ&|7xX*f{qy$1Jd^ zh}>_duHb2Rr%GdA?u^Cz9Da)0C7lr7J1c&{KB4P7_WjG6yziR9M!O>mGxx=@pW6Gw zX8%5`&(-?`4otE$dw$qf?bS~^VAOy?xKOhdh>;=GybB`2z~B!QO91jyfS3^|$O^Bwj8pj!95Fslh+0@P5V<`z~%=h`0irup6tg^dFt+A{1BT+YdtJ@+LF@EIN z7z+8Zx0En`wVKcKRjG_hc50_VOk0yhOC|cblRMpWoYURYxu0`hpXYO)&!4aJejbjN zmKIBcf1vDQAWBzjo|+R+vo-gOcPPjk1@r4qFi_tg`A>5QJ2wU9NwjGCSTGnS-NBKX z;~3t=X3%~Tqi5+e0UtJ#IK~uhpZ)<(TtnK(;|MP39HYE92*L0EV@OL$4aTZWgNz5eGKf)wuO7k^_l9hZk*W=iaBRg;B;^+DOoT9zt3*Oo!J~FM)e`>`6TNF7O!yLrZC{N{KRCXIO&QOWg1y$hPJWLt4pM&v$#Mzr4q?^dD!F2hl09?2sF^Zm>4K$;`?ZR;mV7w$u5=RV1>s}+pZT?dDg*YK!G2YjA%mpET&!}J7Q=8DPJ zkeh4+IBx_}+Kq5g+7qdXEyWkjV(BsmW`>kN{BnP5<(R( zsIM;9^Ni=8#&XATqL-lJ9hFKUB<~uM*`HD)_Jb6wnvgFy#UuAp4)E`f!kVH~^vbrPMMaRb`Cpa&fa+KK6H5w0Dc10TG0qn!83acA%@>S?7Pbwj032L^xqKQ7*9B`4qkSpZ$9 z-@rThdpC#Ed3;;{+kc-+cehbU71qM}^{()vbS|`h&tWVNMx*wxB8;$&Mf>ufVO%#I zM)Ln88zQnWZXg5)Ha{kvb_7_g!=x|Y3hO`y^12BO%2|gJpElHc@jdK_Qc1?bkASf{ zN^&D%JCr!JfS^)`35lg(kBPKc&PUw>@#6A6(Ky5eDFCy6oNRR9PIC&L6e30OsygY*KEIv z(frZ#EQ$%i_rPx?BrtfCGD0r?Pfvj!(TlQ8D#0EP(T(c*_;H2KpR#J5~|Kk*fC zM>9|B3Nyh&+6NvkH<5q-G7c%@A$3%SlmG0+C6`55=-URTMTMxWoe5q#49J=bF>4cx gnM!oUf%2wlmv4RjU*5XZ(J;M3uV0I7)9g^@Ki!vak^lez diff --git a/opm/ml/ml_tools/scaler_layers.py b/opm/ml/ml_tools/scaler_layers.py index ca77c60f7e3..553eebc1825 100644 --- a/opm/ml/ml_tools/scaler_layers.py +++ b/opm/ml/ml_tools/scaler_layers.py @@ -1,6 +1,5 @@ -# Copyright (c) 2024 Birane Kane -# Copyright (c) 2024 Tor Harald Sandve -# Copyright (c) 2024 Peter Moritz von Schultzendorff +# Copyright (c) 2024 NORCE +# Copyright (c) 2024 UiB # This file is part of the Open Porous Media project (OPM). diff --git a/opm/ml/ml_tools/scalertest.py b/opm/ml/ml_tools/scalertest.py index a662bc1da5a..ef5a819a686 100644 --- a/opm/ml/ml_tools/scalertest.py +++ b/opm/ml/ml_tools/scalertest.py @@ -1,6 +1,5 @@ -# Copyright (c) 2024 Birane Kane -# Copyright (c) 2024 Tor Harald Sandve -# Copyright (c) 2024 Peter Moritz von Schultzendorff +# Copyright (c) 2024 NORCE +# Copyright (c) 2024 UiB # This file is part of the Open Porous Media project (OPM). @@ -17,8 +16,6 @@ # You should have received a copy of the GNU General Public License # along with OPM. If not, see . - - from __future__ import annotations import pathlib @@ -40,58 +37,14 @@ data: np.ndarray = np.random.uniform(-500, 500, (5, 1)) -# model: keras.Model = keras.Sequential( -# -# [ -# -# keras.layers.Input([10]), -# -# MinMaxScalerLayer(feature_range=feature_ranges[0]), -# -# keras.layers.Dense(units=10), -# -# MinMaxUnScalerLayer(feature_range=feature_ranges[1]), -# -# ] -# -# ) - model = Sequential() model.add(keras.layers.Input([1])) model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) -# model.add(Flatten()) model.add(Dense(1, input_dim=1)) model.add(Dense(1, input_dim=1)) model.add(Dense(1, input_dim=1)) model.add(Dense(1, input_dim=1)) model.add(MinMaxUnScalerLayer(feature_range=(-3.7, -1.0))) -# -# model.get_layer(model.layers[0].name).adapt(data=data) -# model.get_layer(model.layers[-1].name).adapt(data=data) - -# model.add(Dense(1, input_dim=1)) - -# model: keras.Model = keras.Sequential( -# -# [ -# -# keras.layers.Input([1]), -# -# MinMaxScalerLayer(feature_range=(0.0, 1.0)), -# -# # keras.layers.Dense(1, input_dim=1), -# -# # MinMaxUnScalerLayer(feature_range=(0.0, 1.0)), -# -# ] -# -# ) - - -# -# model.get_layer(model.layers[0].name).adapt(data=data) -# # -# model.get_layer(model.layers[-1].name).adapt(data=data) export_model(model, str(savepath)) diff --git a/opm/ml/keras_model_test.cpp b/tests/ml/keras_model_test.cpp similarity index 87% rename from opm/ml/keras_model_test.cpp rename to tests/ml/keras_model_test.cpp index 354e744e950..2eef0a75c01 100644 --- a/opm/ml/keras_model_test.cpp +++ b/tests/ml/keras_model_test.cpp @@ -3,12 +3,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,18 +24,18 @@ along with OPM. If not, see . */ -#include "keras_model.hpp" +#include #include #include -#include "ml_tools/include/test_dense_10x1.h" -#include "ml_tools/include/test_dense_10x10.h" -#include "ml_tools/include/test_dense_10x10x10.h" -#include "ml_tools/include/test_dense_1x1.h" -#include "ml_tools/include/test_dense_2x2.h" -#include "ml_tools/include/test_relu_10.h" -#include "ml_tools/include/test_dense_relu_10.h" -#include "ml_tools/include/test_dense_tanh_10.h" -#include "ml_tools/include/test_scalingdense_1x1.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace Opm { @@ -149,9 +148,9 @@ bool tensor_test() { return true; } - } + int main() { typedef Opm::DenseAd::Evaluation Evaluation; @@ -194,7 +193,7 @@ int main() { return 1; } - if (!test_scalingdense_1x1(&load_time, &apply_time)) { + if (!test_scalingdense_10x1(&load_time, &apply_time)) { return 1; } diff --git a/opm/ml/ml_tools/generateunittests.py b/tests/ml/ml_tools/generateunittests.py similarity index 88% rename from opm/ml/ml_tools/generateunittests.py rename to tests/ml/ml_tools/generateunittests.py index fa36a0681b5..e5f53de578f 100644 --- a/opm/ml/ml_tools/generateunittests.py +++ b/tests/ml/ml_tools/generateunittests.py @@ -1,6 +1,4 @@ -# Copyright (c) 2024 Birane Kane -# Copyright (c) 2024 Tor Harald Sandve - +# Copyright (c) 2024 NORCE # This file is part of the Open Porous Media project (OPM). # OPM is free software: you can redistribute it and/or modify @@ -16,14 +14,16 @@ # You should have received a copy of the GNU General Public License # along with OPM. If not, see . - import numpy as np import pprint -import os +import os, sys from tensorflow import keras from keras.models import Sequential from keras.layers import Conv2D, Dense, Flatten, Activation, MaxPooling2D, Dropout, BatchNormalization, ELU, Embedding, LSTM + +sys.path.append('../../../opm/ml/ml_tools') + from kerasify import export_model from scaler_layers import MinMaxScalerLayer, MinMaxUnScalerLayer @@ -47,12 +47,11 @@ def to_cpp(ndarray): * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -113,12 +112,10 @@ def to_cpp(ndarray): } ''' - directory = os.getcwd() directory1 = "models" directory2 = "include" -# path1=os.path.abspath(directory) if os.path.isdir(directory1): print(f"{directory1} exists.") else: @@ -126,7 +123,6 @@ def to_cpp(ndarray): path1 = os.path.join(directory, directory1) os.makedirs(path1) - if os.path.isdir(directory2): print(f"{directory2} exists.") else: @@ -142,16 +138,15 @@ def output_testcase(model, test_x, test_y, name, eps): print(model.summary()) export_model(model, 'models/test_%s.model' % name) - path = os.path.abspath(f'models/test_{name}.model') - with open('include/test_%s.h' % name, 'w') as f: + path = f'./ml/ml_tools/models/test_{name}.model' + with open('include/test_%s.hpp' % name, 'w') as f: x_shape, x_data = c_array(test_x[0]) y_shape, y_data = c_array(predict_y[0]) f.write(TEST_CASE % (name, name, x_shape, x_data, y_shape, y_data, path, eps)) - -# scaling 1x1 +# scaling 10x1 data: np.ndarray = np.random.uniform(-500, 500, (5, 1)) feature_ranges: list[tuple[float, float]] = [(0.0, 1.0), (-3.7, 0.0)] test_x = np.random.rand(10, 10).astype('f') @@ -159,37 +154,16 @@ def output_testcase(model, test_x, test_y, name, eps): data_min = 10.0 model = Sequential() model.add(keras.layers.Input([10])) -# model.add(Dense(1, input_dim=10)) model.add(MinMaxScalerLayer(feature_range=(0.0, 1.0))) -# model.add(Dense(1,activation='tanh')) model.add(Dense(10,activation='tanh')) model.add(Dense(10,activation='tanh')) model.add(Dense(10,activation='tanh')) model.add(Dense(10,activation='tanh')) -# model.add(Flatten()) model.add(MinMaxUnScalerLayer(feature_range=(-3.7, -1.0))) # # model.get_layer(model.layers[0].name).adapt(data=data) model.get_layer(model.layers[-1].name).adapt(data=data) - -# model.add(Dense(1, input_dim=1)) - -# model: keras.Model = keras.Sequential( -# -# [ -# -# keras.layers.Input([1]), -# -# MinMaxScalerLayer(feature_range=(0.0, 1.0)), -# -# # keras.layers.Dense(1, input_dim=1), -# -# # MinMaxUnScalerLayer(feature_range=(0.0, 1.0)), -# -# ] -# -# ) -output_testcase(model, test_x, test_y, 'scalingdense_1x1', '1e-3') +output_testcase(model, test_x, test_y, 'scalingdense_10x1', '1e-3') # Dense 1x1 test_x = np.arange(10) @@ -253,5 +227,4 @@ def output_testcase(model, test_x, test_y, name, eps): model.add(Dense(10, input_dim=10, activation='tanh')) model.add(Dense(10, input_dim=10, activation='tanh')) model.add(Dense(10, input_dim=10, activation='tanh')) -output_testcase(model, test_x, test_y, 'dense_tanh_10', '1e-6') - +output_testcase(model, test_x, test_y, 'dense_tanh_10', '1e-6') \ No newline at end of file diff --git a/opm/ml/ml_tools/include/test_dense_10x1.h b/tests/ml/ml_tools/include/test_dense_10x1.hpp similarity index 79% rename from opm/ml/ml_tools/include/test_dense_10x1.h rename to tests/ml/ml_tools/include/test_dense_10x1.hpp index 7306e3f47c8..63059dd4a4b 100644 --- a/opm/ml/ml_tools/include/test_dense_10x1.h +++ b/tests/ml/ml_tools/include/test_dense_10x1.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -39,17 +39,17 @@ bool test_dense_10x1(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.07588807,0.46424174,0.2545689,0.24965246,0.48471555,0.9185193, -0.33841145,0.30067867,0.98624486,0.85875916}; + in.data_ = {0.3686802,0.37949404,0.42777044,0.3353853,0.9465501,0.045944117, +0.877874,0.11395996,0.6830254,0.40130788}; Opm::Tensor out{1}; - out.data_ = {-0.6094914}; + out.data_ = {-1.4414413}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x1.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_dense_10x1.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10.h b/tests/ml/ml_tools/include/test_dense_10x10.hpp similarity index 79% rename from opm/ml/ml_tools/include/test_dense_10x10.h rename to tests/ml/ml_tools/include/test_dense_10x10.hpp index 1f14f6f5739..951548d865d 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10.h +++ b/tests/ml/ml_tools/include/test_dense_10x10.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -39,17 +39,17 @@ bool test_dense_10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.74464816,0.063315846,0.2233216,0.3184675,0.017677268,0.24977225, -0.5242765,0.27742663,0.009411842,0.27946305}; + in.data_ = {0.9865467,0.36973363,0.36496657,0.34069845,0.28187922,0.061007407, +0.7788553,0.620593,0.54009753,0.09182126}; Opm::Tensor out{1}; - out.data_ = {0.06583358}; + out.data_ = {0.09297238}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x10.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_dense_10x10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_10x10x10.h b/tests/ml/ml_tools/include/test_dense_10x10x10.hpp similarity index 75% rename from opm/ml/ml_tools/include/test_dense_10x10x10.h rename to tests/ml/ml_tools/include/test_dense_10x10x10.hpp index d373bffc066..da9582baa91 100644 --- a/opm/ml/ml_tools/include/test_dense_10x10x10.h +++ b/tests/ml/ml_tools/include/test_dense_10x10x10.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -39,18 +39,18 @@ bool test_dense_10x10x10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.84246427,0.15756324,0.8924635,0.5069177,0.8633376,0.31142905, -0.7651278,0.5454816,0.22917923,0.54828155}; + in.data_ = {0.21841241,0.690713,0.2402783,0.70226014,0.3015559,0.5127232, +0.37969366,0.5222581,0.90413934,0.30193302}; Opm::Tensor out{10}; - out.data_ = {0.767188,0.23175952,0.036515277,-0.2622609,-0.25455678, -0.157909,-0.6259325,-0.6256348,0.4324326,-0.4141315}; + out.data_ = {-0.40694734,-0.06657142,0.3262723,-0.9006126,0.011047224, +-0.83712757,-0.49354577,0.0790175,-0.5138001,-0.69188976}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_10x10x10.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_dense_10x10x10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_1x1.h b/tests/ml/ml_tools/include/test_dense_1x1.hpp similarity index 86% rename from opm/ml/ml_tools/include/test_dense_1x1.h rename to tests/ml/ml_tools/include/test_dense_1x1.hpp index 5410cee5d08..a295b63af75 100644 --- a/opm/ml/ml_tools/include/test_dense_1x1.h +++ b/tests/ml/ml_tools/include/test_dense_1x1.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -48,7 +48,7 @@ bool test_dense_1x1(Evaluation* load_time, Evaluation* apply_time) load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_1x1.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_dense_1x1.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_2x2.h b/tests/ml/ml_tools/include/test_dense_2x2.hpp similarity index 83% rename from opm/ml/ml_tools/include/test_dense_2x2.h rename to tests/ml/ml_tools/include/test_dense_2x2.hpp index 1bbfe040217..72a127f666b 100644 --- a/opm/ml/ml_tools/include/test_dense_2x2.h +++ b/tests/ml/ml_tools/include/test_dense_2x2.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -39,16 +39,16 @@ bool test_dense_2x2(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{2}; - in.data_ = {0.6440019,0.62654394}; + in.data_ = {0.4572911,0.40170738}; Opm::Tensor out{1}; - out.data_ = {0.7173992}; + out.data_ = {0.22109468}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_2x2.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_dense_2x2.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_relu_10.h b/tests/ml/ml_tools/include/test_dense_relu_10.hpp similarity index 77% rename from opm/ml/ml_tools/include/test_dense_relu_10.h rename to tests/ml/ml_tools/include/test_dense_relu_10.hpp index 2031e90b6f3..7933ca37e97 100644 --- a/opm/ml/ml_tools/include/test_dense_relu_10.h +++ b/tests/ml/ml_tools/include/test_dense_relu_10.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -39,18 +39,18 @@ bool test_dense_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.58381814,0.90178627,0.13896127,0.18618706,0.94524324,0.11974335, -0.88227147,0.09502208,0.71341133,0.53053087}; + in.data_ = {0.81092674,0.28423905,0.7424001,0.63347864,0.024311712, +0.20913002,0.0037298917,0.33594763,0.013057965,0.33818316}; Opm::Tensor out{10}; - out.data_ = {0.,0.,0.,0.,0.,0.20002396, -0.19065511,0.,0.,0.1995258}; + out.data_ = {0.16579644,0.,0.024009448,0.00081627944,0.122673295, +0.,0.,0.1815404,0.,0.11925792}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_relu_10.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_dense_relu_10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_dense_tanh_10.h b/tests/ml/ml_tools/include/test_dense_tanh_10.hpp similarity index 75% rename from opm/ml/ml_tools/include/test_dense_tanh_10.h rename to tests/ml/ml_tools/include/test_dense_tanh_10.hpp index 9785b41416d..2223fee76f5 100644 --- a/opm/ml/ml_tools/include/test_dense_tanh_10.h +++ b/tests/ml/ml_tools/include/test_dense_tanh_10.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -39,18 +39,18 @@ bool test_dense_tanh_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.5133757,0.8992964,0.018602798,0.8300745,0.43004134,0.16437091, -0.13667183,0.7081913,0.39895463,0.53926337}; + in.data_ = {0.8417535,0.01666395,0.40597403,0.72943276,0.55192524, +0.8613093,0.8216251,0.0077196797,0.9292973,0.050378576}; Opm::Tensor out{10}; - out.data_ = {-0.16390416,-0.11630989,0.37623432,-0.65770155,0.1101914, --0.097250186,0.5037399,-0.2223558,0.3810121,0.6196858}; + out.data_ = {0.005546283,-0.32751718,-0.54984826,0.12813118,0.034228113, +-0.15042743,-0.12779453,-0.43155488,-0.18912314,0.07741854}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_dense_tanh_10.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_dense_tanh_10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_relu_10.h b/tests/ml/ml_tools/include/test_relu_10.hpp similarity index 77% rename from opm/ml/ml_tools/include/test_relu_10.h rename to tests/ml/ml_tools/include/test_relu_10.hpp index 86d8e3c9611..2972c18fff1 100644 --- a/opm/ml/ml_tools/include/test_relu_10.h +++ b/tests/ml/ml_tools/include/test_relu_10.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,6 +24,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; @@ -39,18 +39,18 @@ bool test_relu_10(Evaluation* load_time, Evaluation* apply_time) KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.120741345,0.59726936,0.9251051,0.87210053,0.6669108,0.13732599, -0.3093547,0.77527475,0.3986614,0.943842}; + in.data_ = {0.67226,0.14416263,0.92274326,0.1796348,0.66230893,0.043213055, +0.9826259,0.23941626,0.21915485,0.30863634}; Opm::Tensor out{10}; - out.data_ = {0.,0.,0.48979148,0.,1.1085179,0., -0.,0.33353794,0.7359366,0.8868316}; + out.data_ = {0.,0.14516208,0.017886672,0.3325293,0.19996727,0., +0.,0.5177354,0.47141758,0.2587896}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_relu_10.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_relu_10.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/opm/ml/ml_tools/include/test_scalingdense_1x1.h b/tests/ml/ml_tools/include/test_scalingdense_10x1.hpp similarity index 70% rename from opm/ml/ml_tools/include/test_scalingdense_1x1.h rename to tests/ml/ml_tools/include/test_scalingdense_10x1.hpp index 3e16e372023..5d97957c682 100644 --- a/opm/ml/ml_tools/include/test_scalingdense_1x1.h +++ b/tests/ml/ml_tools/include/test_scalingdense_10x1.hpp @@ -4,12 +4,11 @@ * Copyright (c) 2016 Robert W. Rose * Copyright (c) 2018 Paul Maevskikh * - * MIT License, see LICENSE.OLD file. + * MIT License, see LICENSE.MIT file. */ /* - * Copyright (c) 2024 Birane Kane - * Copyright (c) 2024 Tor Harald Sandve + * Copyright (c) 2024 NORCE This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify @@ -25,32 +24,33 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ + #include #include namespace fs = std::filesystem; using namespace Opm; template -bool test_scalingdense_1x1(Evaluation* load_time, Evaluation* apply_time) +bool test_scalingdense_10x1(Evaluation* load_time, Evaluation* apply_time) { - printf("TEST scalingdense_1x1\n"); + printf("TEST scalingdense_10x1\n"); KASSERT(load_time, "Invalid Evaluation"); KASSERT(apply_time, "Invalid Evaluation"); Opm::Tensor in{10}; - in.data_ = {0.22338921,0.8132339,0.43024784,0.26458433,0.92503846,0.6615654, -0.88089544,0.34508273,0.6916904,0.57852364}; + in.data_ = {0.2977481,0.38920167,0.40215403,0.13134468,0.78471553,0.6248962, +0.3632944,0.61598396,0.41296104,0.68129736}; Opm::Tensor out{10}; - out.data_ = {670.77625,672.4989,709.0858,640.06885,827.44714,736.1234,617.30554, -638.03955,629.93115,653.84595}; + out.data_ = {511.78174,453.4956,583.66986,302.5313,474.43433,384.96466,471.34137, +348.2467,418.59845,414.25787}; KerasTimer load_timer; load_timer.Start(); KerasModel model; - KASSERT(model.LoadModel("/Users/macbookn/hackatonwork/opm-common/opm/ml/ml_tools/models/test_scalingdense_1x1.model"), "Failed to load model"); + KASSERT(model.LoadModel("./ml/ml_tools/models/test_scalingdense_10x1.model"), "Failed to load model"); *load_time = load_timer.Stop(); diff --git a/tests/ml/ml_tools/models/test_dense_10x1.model b/tests/ml/ml_tools/models/test_dense_10x1.model new file mode 100644 index 0000000000000000000000000000000000000000..ed84459636fb72de1283c829f54c6c1ec3f1a252 GIT binary patch literal 68 zcmZQ%U|?VYVlE(NgyQ^7Ec?^!RP6h`1oyYCUb1)APl^3UEY8_o_j$Z;Z;;4-?Jwf{ P?;L(pGPK15IH#@w!clS+>-nnU0qO}q0ES)k=M6)v;S-vB26_M5AzHS+ zly-HQctv-DPVM$%Np)D*k@F1H>fw34ui!F%CU^ZbolRQ#r23?=r87&sJN^OUVPLEM z2MiFN-6qll#kYy3vbJ%Oud&V-I4>H*5+hZ^)_?R{QExxj)Th%OSXZfr`^Fj3d=6f=Qx z;yO|0Kr()bV(5mQ-nREUhKnB|w-oBQFc&6gVx+XuxUa~5Jn?sOW#5BkFN+J=3~6rU zkp8qA?t?9;Sof~7{*;H*Mt`So?&C<04dmO46C7_QS8;Fo^1Ox3BIw zP}U&rSU&4Fixk2<-4~9@d;_AQ zC_XTo3_2UVzL=m&p5|m_3eGHbp}+Df=4yuNbaW1JTZ<6&IcwsRKR?TfyVRVXeS%Q+th+mzp4yOPcMaiBB!3qUtoJv zC7xBDph@cxPA>UU2=`s&EDtQ4i#x-mR7~O@ty{Ph(tw)!E^N7VosORE6IN=+aky9| zJhjC`3%VQ8W+!;=L$7jWdkuIl3EZOgt_}f?9UzVv;(OD F@c}N#4xa!3 literal 0 HcmV?d00001 diff --git a/tests/ml/ml_tools/models/test_dense_relu_10.model b/tests/ml/ml_tools/models/test_dense_relu_10.model new file mode 100644 index 0000000000000000000000000000000000000000..3b1b656d3d5818a58aba8d89f3e8506b10c9a307 GIT binary patch literal 1384 zcmZ{kdrVVz6vtaA&;k-b7EoM=2m($wtf0>DI~RF5A0Q*B_y9Wt!W=51Bj}u>2rJ4I zCs9`zR3(mdyaouU_nzA^6osmlM+Gsi;~_;Dl8PuOb(h6I%#xktd%oXu{{7?}Qyz~e z;AHup-kP?MPwA~al?!%s~AU# zZ6G$f38+I|!Sv2OA_{&8#)f=*INjHYF`_pxx@|UX>>b70nODhYIW6RxOo4ujWPUe0 zMXWIOQ+(SuK(D-K!hV-{7$i=2VWdNd7oM84MSUd@zrY?O+J}&){L1h0-bdj3*HgSB zY)6f`nurT>nWk^7D2>N#RESof$9+?_X+R0hF41K95*}?lSOnn>rO-r9k(0)^kUPT1 z@IO*f+?b8sjazYCm<5|xVBkJR-z-;brBK3a5@F+P@2ud$-qh?qKXT>Vc{5`D$^oTQ5KY;-i}1m zzRczIh0u0`gKOBy}V$-unH&A`tj8&8p>UEle&-zn3ZnC$bm|T zvQNJjYoET1L&OW@@|RqWsohk~<7N}i|I1QZZ%P#lL-71-8wgzzL5?X;rLNL1%izU7BP}QqJ@!}%P)0nX}VJ#38 z>H~)TJSu8(1vq34gHq5AIavi{tz5*;w|2*zfj}~puZEmERcPImi{-`$)a%VyyHlS) z+{+#;$Q2R?|5@NOEezPZBKFM{KKN_3bm_yDm=koJ1XRQlg?lLA3kB%EmO+C_7)&m* zpxOd-ke|V)OdEVa>TOC@)X6}d)dg`Wsi+%HB0R5Auu6_&iqE>iQk!RF&ZFs!>bVol zxI)3mxF5P6sDvdBzvGGJm+*_%mh29TwOBVG$L&8VLHBV2^0x`uWbHz`Dn-%u-VdG7}hri z?oqp7o?!?`$~jc@SHtM9nRrWlm$a>Kg@0jjErDalaa|VAX==CSJ(h9*!_vo@#-5Wr z_Wby_=(JYDD2i{=nmMh+f4!R4q$HqiaVv2;9*owGL!gPaq%%_&vyF*roc*fXPvwLf?rFRGmLa zYdUr^ZURSC6zOTj5iu#wc818FlVDe6#ilhKVvf4hz{Tz^*y3>lj{0U|)Z9$6R41Z3 zDhI(oZvp@S literal 0 HcmV?d00001 diff --git a/tests/ml/ml_tools/models/test_dense_tanh_10.model b/tests/ml/ml_tools/models/test_dense_tanh_10.model new file mode 100644 index 0000000000000000000000000000000000000000..4e7541e4aa4b061498b971f97989c7ae32269326 GIT binary patch literal 1384 zcmZwGe>By19LI4#t{?ZREi|k;Ekd{@t4zoBeSPmXtrIbB()>uQb^I#ZB$Xu5NJ)t) zR3r@RmS$GC-}krG=*NUCnyaX^(CVhL^h4R#Is0RO^vC18-{gYhv=Pq*V;YMNZ zcbQw9_%jpQB;sCHG%=3P%9xO+d4< zL2X`|I2Fc}gqH9}7>+H$M^ED@sqMK;bw>?{-G-PZ2NkqUg+aN7f(kpaFKW zhNRr{qNkj}f*s6a3nka}>v~-K#}n&bXJOa22GoXMqA&S-s-l=S#%+HeM7r<8?C2h> zvz4$O@nZg{(L^pL)89c;yFvhMD{lHfF0DI2iL z{70_bEDxEzj?`M)MK``MMWlE;os}x->Ckd?ZV>ZTidM|k(@+op0@lSuR&y*E9nUw2 zn$S-5L07Q7%78z;IfFW-1CaKY!PcaNA_hBg@zD*aWBO@eO96G=)@9>H<%rSKVbdc- zteLL?T}f_*n|n5r&91`FqY=tr5ej5Aw8Ao5byKpx;g+upy-YsASnfGVK6QhXmt4uc zw6lk)*qa>A{)Bg!JWAZq!AbpM(WI8JrxS}9|E@pDk?*9W^SE2=;F zE@fSJ=5!8<_@X0@h(9)lk(mr#xxI!0X6W!+HJcc(_j_T?pgs++QUkOg+*hpr!Jf1eU5AvHMzNWOZbTB2D)S+#R;dK%(Ivx z$nMJN#?(T37Ny}fwN%2u{Zm>HZQ!;wCzRB=IT)+m$5r~(QIw>R6#awHTz-NXvqzaH z9X<^C4bx!X1!lTQ1AGrmzz4C0?9zZ1Dm#RA7{4EH`7i#KWpDrh literal 0 HcmV?d00001 diff --git a/tests/ml/ml_tools/models/test_relu_10.model b/tests/ml/ml_tools/models/test_relu_10.model new file mode 100644 index 0000000000000000000000000000000000000000..27d191391c9e4845775a561f437b9a32f2b50ebe GIT binary patch literal 472 zcmZQ#U|?VYVlE`idgSvye(x`~s~`97J8I&xZ>DUz-2<^pwi>e!+V${Eu)8chao^Er zQF}Aw7ue2=YPb91(rKsZe%bazY52Ya$*ndM=3TM#f1mv}mi=G+zwV1!cxK5ha`itBBNc_B4zn#Ticy{ML8=skW z?RCBT66DzSZi;-hkE8s$9n&_Geg0MqdnX*z+H3sI%Wlp4CcAT!R_^Ox%5Hz8CCM(K z`qZ8^OQze2{w&*fl#Rt+W>bTm#Pxmqe4ga)GoK!0_v_U6eMT9#_pSTjy>Gqclzk!b zr|sS=zt}s?XU4wU3Osh3!WP=is`zAQ_4}To`>3rhTIr^K^s@2s^q z?H={dvRkwLsNEOy2X>raC+(~MyKrBx63hOgGfn$`hOq1xUemu%!n<}~Q23I4=6#O) z{wv?!7qIcJo!$3ycCx2F?|XM+piPd5M5hrMwidApGw6C4`CrDFH;3M-hCaB3L$E(O?N19G!7@I(uin_niBkIe&fb zcaG4^%#3H!(~%l=XuA7iQ)@cW4BvE%-_p?>qpV=zeF$pt#gu|}P`YFQMzoV)A2Ij* zhy|z8_TxzVAg=$dnXDGZBDMCV&-(LG%5S35_`gG#)nV|6KZUoSoPzQO9usCS!e~ z{D;6YVlm4JzeL+ChS2)?aCuWRMD2>B-2+n0Rq>gK(0@XMbR(|VVWgeQ8*%pZCFpK1 zhh-1UIm_-ZWe%S_g2{H*F(8!3NViqN-uhu+U2mg$<9o2X+B6qfNW=gAfc$l03QlrN zf{?-lYCHEDHnRh8C#(Z{7mq^fSufm{-(7WRN zS^v@))J>5sOkAg=`9ZAh=mF=D=cNuTyNUu(>-H2JUI0u#gkW!V{m zxOQ4B{bGX-%iJ`0U4D;FtLA~nZZ*7Xn+EDLVv_4+15t|y@$kxVOx?9~^p0LaDu!C| zVk2d*CGnW*Vv0=}A7FzA4|R^4An&fW-Yg3|pI{ zL1EPi`iv9wqMw-YG-Q+N33_mfSVS_usl%#6cF1#m4Buoc@X5aA@VKAPJzKRIVltki z^=ArPc5*KCTn)iTRx0?#$r&py6k%)6*YI>0ssE>cfxgM-@tC3r?p|(@8M9mH6^BG@ zQMtjSch7^FR*z9B?bPC&h)eWzAjt_g(8cW*#0kr2Ub29h^1YmG&(h$6S+y{_e;9qf z&V}@^giLycITvhV%RGFDvC3PRw?_;E6}B`*Pyk0uoZydFgxop%@%UaqHooTdisxG# z$N0VS{vXQ@=kfTHHpq?2x8aAb*Q;cgQ^2R-Tl8AfC0k&KA+Cq((II3A_s-3x(#K6O zEVx7q_gkX5u!^nNn2Eu^w!>Y=P0+v8^#6;Wf?{?(tlCnBP31eeczF62|NVG?METE)*ShP4G$*vK@{yT7DPGsTS6R|49tSq_nZ5ON>CtV8MATX=8iTS&Oc<5K@* zUm>F6D^TU9MaTQj< znbEayR(~HwD|*rG$K%vxr~|Y`eb_Wv#9f_ghHXhY4Di|s(>%J-Q)GlwIp*{eZ6+F) zR?1>|a`-U57sBT>V6|NqOkdLm>hS&evEd;)>(ArC+MN&|e;+&iB+RdV+u_c#8xX;j zfik)VKAKm9`;f=jI5CjEdKSdlUnPq={a{;kF*feFgkE9pIC6Cte4#DIXBNw`bc&cm pQ5)*}HKaxR4i~pB Date: Wed, 2 Oct 2024 19:40:42 +0200 Subject: [PATCH 7/7] Implementing changes requested in PR review part 1. --- opm/ml/ml_model.cpp | 444 +++++++++++++++++++++++++++++++++++++ opm/ml/ml_model.hpp | 437 ++++++++++++++++++++++++++++++++++++ tests/ml/ml_model_test.cpp | 201 +++++++++++++++++ 3 files changed, 1082 insertions(+) create mode 100644 opm/ml/ml_model.cpp create mode 100644 opm/ml/ml_model.hpp create mode 100644 tests/ml/ml_model_test.cpp diff --git a/opm/ml/ml_model.cpp b/opm/ml/ml_model.cpp new file mode 100644 index 00000000000..0552568b91e --- /dev/null +++ b/opm/ml/ml_model.cpp @@ -0,0 +1,444 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.MIT file. + */ + +/* + Copyright (c) 2024 NORCE + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#include "ml_model.hpp" + +#include +#include +#include +#include +#include + +#include +#include + +namespace Opm { + + +template +bool readFile(std::ifstream& file, T& data, size_t n=1) +{ + file.read(reinterpret_cast(&data), sizeof (T)* n); + return !file.fail(); +} + + +// bool ReadUnsignedInt(std::ifstream* file, unsigned int* i) { +// // KASSERT(file, "Invalid file stream"); +// // // KASSERT(i, "Invalid pointer"); + +// // KASSERT(file, "Invalid file stream"); + +// OPM_ERROR_IF(!file, +// "Invalid file stream"); + +// OPM_ERROR_IF(!i, +// "Invalid pointer"); + +// file->read((char*)i, sizeof(unsigned int)); +// KASSERT(file->gcount() == sizeof(unsigned int), "Expected unsigned int"); + +// return true; +// } + +// bool ReadFloat(std::ifstream* file, float* f) { +// KASSERT(file, "Invalid file stream"); +// KASSERT(f, "Invalid pointer"); + +// file->read((char*)f, sizeof(float)); +// KASSERT(file->gcount() == sizeof(float), "Expected Evaluation"); + +// return true; +// } + +bool ReadFloats(std::ifstream* file, float* f, size_t n) { + KASSERT(file, "Invalid file stream"); + KASSERT(f, "Invalid pointer"); + + file->read((char*)f, sizeof(float) * n); + KASSERT(((unsigned int)file->gcount()) == sizeof(float) * n, + "Expected Evaluations"); + + return true; +} + +template +bool KerasLayerActivation::loadLayer(std::ifstream& file) { + // KASSERT(file, "Invalid file stream"); + + unsigned int activation = 0; + KASSERT(readFile(file, activation), + "Failed to read activation type"); + + switch (activation) { + case kLinear: + activation_type_ = kLinear; + break; + case kRelu: + activation_type_ = kRelu; + break; + case kSoftPlus: + activation_type_ = kSoftPlus; + break; + case kHardSigmoid: + activation_type_ = kHardSigmoid; + break; + case kSigmoid: + activation_type_ = kSigmoid; + break; + case kTanh: + activation_type_ = kTanh; + break; + default: + KASSERT(false, "Unsupported activation type %d", activation); + } + + return true; +} + +template +bool KerasLayerActivation::apply(Tensor& in, Tensor& out) { + // KASSERT(in, "Invalid input"); + // KASSERT(out, "Invalid output"); + + out = in; + + switch (activation_type_) { + case kLinear: + break; + case kRelu: + for (size_t i = 0; i < out.data_.size(); i++) { + if (out.data_[i] < 0.0) { + out.data_[i] = 0.0; + } + } + break; + case kSoftPlus: + for (size_t i = 0; i < out.data_.size(); i++) { + out.data_[i] = log(1.0 + exp(out.data_[i])); + } + break; + case kHardSigmoid: + for (size_t i = 0; i < out.data_.size(); i++) { + Evaluation x = (out.data_[i] * 0.2) + 0.5; + + if (x <= 0) { + out.data_[i] = 0.0; + } else if (x >= 1) { + out.data_[i] = 1.0; + } else { + out.data_[i] = x; + } + } + break; + case kSigmoid: + for (size_t i = 0; i < out.data_.size(); i++) { + Evaluation& x = out.data_[i]; + + if (x >= 0) { + out.data_[i] = 1.0 / (1.0 + exp(-x)); + } else { + Evaluation z = exp(x); + out.data_[i] = z / (1.0 + z); + } + } + break; + case kTanh: + for (size_t i = 0; i < out.data_.size(); i++) { + out.data_[i] = sinh(out.data_[i])/cosh(out.data_[i]); + } + break; + default: + break; + } + + return true; +} + + +template +bool KerasLayerScaling::loadLayer(std::ifstream& file) { + KASSERT(file, "Invalid file stream"); + + KASSERT(readFile(file, data_min), "Failed to read min"); + KASSERT(readFile(file, data_max), "Failed to read min"); + KASSERT(readFile(file, feat_inf), "Failed to read min"); + KASSERT(readFile(file, feat_sup), "Failed to read min"); + return true; +} + +template +bool KerasLayerScaling::apply(Tensor& in, Tensor& out) { + // KASSERT(in, "Invalid input"); + // KASSERT(out, "Invalid output"); + + Tensor temp_in, temp_out; + + out = in; + + for (size_t i = 0; i < out.data_.size(); i++) { + auto tempscale = (out.data_[i] - data_min)/(data_max - data_min); + out.data_[i] = tempscale * (feat_sup - feat_inf) + feat_inf; + } + + return true; +} + +template +bool KerasLayerUnScaling::loadLayer(std::ifstream& file) { + KASSERT(file, "Invalid file stream"); + + KASSERT(readFile(file, data_min), "Failed to read min"); + KASSERT(readFile(file, data_max), "Failed to read max"); + KASSERT(readFile(file, feat_inf), "Failed to read inf"); + KASSERT(readFile(file, feat_sup), "Failed to read sup"); + + return true; +} + +template +bool KerasLayerUnScaling::apply(Tensor& in, Tensor& out) { + // KASSERT(in, "Invalid input"); + // KASSERT(out, "Invalid output"); + + out = in; + + for (size_t i = 0; i < out.data_.size(); i++) { + auto tempscale = (out.data_[i] - feat_inf)/(feat_sup - feat_inf); + + out.data_[i] = tempscale * (data_max - data_min) + data_min; + } + + + return true; +} + + +template +bool KerasLayerDense::loadLayer(std::ifstream& file) { + KASSERT(file, "Invalid file stream"); + + unsigned int weights_rows = 0; + KASSERT(readFile(file, weights_rows), "Expected weight rows"); + KASSERT(weights_rows > 0, "Invalid weights # rows"); + + unsigned int weights_cols = 0; + KASSERT(readFile(file, weights_cols), "Expected weight cols"); + KASSERT(weights_cols > 0, "Invalid weights shape"); + + unsigned int biases_shape = 0; + KASSERT(readFile(file, biases_shape), "Expected biases shape"); + KASSERT(biases_shape > 0, "Invalid biases shape"); + + weights_.resize(weights_rows, weights_cols); + KASSERT( + ReadFloats(&file, weights_.data_.data(), weights_rows * weights_cols), + "Expected weights"); + + biases_.resize(biases_shape); + KASSERT(ReadFloats(&file, biases_.data_.data(), biases_shape), + "Expected biases"); + + KASSERT(activation_.loadLayer(file), "Failed to load activation"); + + return true; +} + +template +bool KerasLayerDense::apply(Tensor& in, Tensor& out) { + // KASSERT(in, "Invalid input"); + // KASSERT(out, "Invalid output"); + KASSERT(in.dims_.size() <= 2, "Invalid input dimensions"); + + if (in.dims_.size() == 2) { + KASSERT(in.dims_[1] == weights_.dims_[0], "Dimension mismatch %d %d", + in.dims_[1], weights_.dims_[0]); + } + + Tensor tmp(weights_.dims_[1]); + + for (int i = 0; i < weights_.dims_[0]; i++) { + for (int j = 0; j < weights_.dims_[1]; j++) { + tmp(j) += (in)(i)*weights_(i, j); + } + } + + for (int i = 0; i < biases_.dims_[0]; i++) { + tmp(i) += biases_(i); + } + + KASSERT(activation_.apply(tmp, out), "Failed to apply activation"); + + return true; +} + +template +bool KerasLayerFlatten::loadLayer(std::ifstream& file) { + KASSERT(file, "Invalid file stream"); + return true; +} + +template +bool KerasLayerFlatten::apply(Tensor& in, Tensor& out) { + // KASSERT(in, "Invalid input"); + // KASSERT(out, "Invalid output"); + + out = in; + out.flatten(); + + return true; +} + + + +template +bool KerasLayerEmbedding::loadLayer(std::ifstream& file) { + KASSERT(file, "Invalid file stream"); + + unsigned int weights_rows = 0; + KASSERT(readFile(file, weights_rows), "Expected weight rows"); + KASSERT(weights_rows > 0, "Invalid weights # rows"); + + unsigned int weights_cols = 0; + KASSERT(readFile(file, weights_cols), "Expected weight cols"); + KASSERT(weights_cols > 0, "Invalid weights shape"); + + weights_.resize(weights_rows, weights_cols); + KASSERT( + ReadFloats(&file, weights_.data_.data(), weights_rows * weights_cols), + "Expected weights"); + + return true; +} + +template +bool KerasLayerEmbedding::apply(Tensor& in, Tensor& out) { + int output_rows = in.dims_[1]; + int output_cols = weights_.dims_[1]; + out.dims_ = {output_rows, output_cols}; + out.data_.reserve(output_rows * output_cols); + + std::for_each(in.data_.begin(), in.data_.end(), [=](Evaluation i) { + typename std::vector::const_iterator first = + this->weights_.data_.begin() + (getValue(i) * output_cols); + typename std::vector::const_iterator last = + this->weights_.data_.begin() + (getValue(i) + 1) * output_cols; + + out.data_.insert(out.data_.end(), first, last); + }); + + return true; +} + + +template +bool KerasModel::loadModel(const std::string& filename) { + std::ifstream file(filename.c_str(), std::ios::binary); + KASSERT(file.is_open(), "Unable to open file %s", filename.c_str()); + + unsigned int num_layers = 0; + KASSERT(readFile(file, num_layers), "Expected number of layers"); + + for (unsigned int i = 0; i < num_layers; i++) { + unsigned int layer_type = 0; + KASSERT(readFile(file, layer_type), "Expected layer type"); + + // KerasLayer* layer = NULL; + std::unique_ptr> layer = nullptr; + + switch (layer_type) { + case kFlatten: + // layer = new KerasLayerFlatten(); + layer = std::make_unique>() ; + break; + case kScaling: + // layer = new KerasLayerScaling(); + layer = std::make_unique>() ; + break; + case kUnScaling: + // layer = new KerasLayerUnScaling(); + layer = std::make_unique>() ; + break; + case kDense: + // layer = new KerasLayerDense(); + layer = std::make_unique>() ; + break; + case kActivation: + // layer = new KerasLayerActivation(); + layer = std::make_unique>() ; + break; + default: + break; + } + + KASSERT(layer, "Unknown layer type %d", layer_type); + + bool result = layer->loadLayer(file); + if (!result) { + std::printf("Failed to load layer %d", i); + // delete layer; + return false; + } + + // layers_.push_back(layer); + layers_.emplace_back(std::move(layer)); + + } + + return true; +} + +template +bool KerasModel::apply(Tensor& in, Tensor& out) { + Tensor temp_in, temp_out; + + for (unsigned int i = 0; i < layers_.size(); i++) { + if (i == 0) { + temp_in = in; + } + + KASSERT(layers_[i]->apply(temp_in, temp_out), + "Failed to apply layer %d", i); + + temp_in = temp_out; + } + + out = temp_out; + + return true; +} + +template class KerasModel; + +template class KerasModel; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; +template class KerasModel>; + +} // namespace Opm diff --git a/opm/ml/ml_model.hpp b/opm/ml/ml_model.hpp new file mode 100644 index 00000000000..b1473fbfc1d --- /dev/null +++ b/opm/ml/ml_model.hpp @@ -0,0 +1,437 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.MIT file. + */ + +/* + Copyright (c) 2024 NORCE + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#ifndef ML_MODEL_H_ +#define ML_MODEL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Opm { + +#define KASSERT(x, ...) \ + if (!(x)) { \ + std::printf("KASSERT: %s(%d): ", __FILE__, __LINE__); \ + std::printf(__VA_ARGS__); \ + std::printf("\n"); \ + return false; \ + } + +#define KASSERT_EQ(x, y, eps) \ + if (fabs(x.value() - y.value()) > eps) { \ + std::printf("KASSERT: Expected %f, got %f\n", y.value(), x.value()); \ + return false; \ + } + +#ifdef DEBUG +#define KDEBUG(x, ...) \ + if (!(x)) { \ + std::printf("%s(%d): ", __FILE__, __LINE__); \ + std::printf(__VA_ARGS__); \ + std::printf("\n"); \ + exit(-1); \ + } +#else +#define KDEBUG(x, ...) ; +#endif + +template +class Tensor { + public: + Tensor() {} + + explicit Tensor(int i) { resize(i); } + + Tensor(int i, int j) { resize(i, j); } + + Tensor(int i, int j, int k) { resize(i, j, k); } + + Tensor(int i, int j, int k, int l) { resize(i, j, k, l); } + + void resize(int i) { + dims_ = {i}; + data_.resize(i); + } + + void resize(int i, int j) { + dims_ = {i, j}; + data_.resize(i * j); + } + + void resize(int i, int j, int k) { + dims_ = {i, j, k}; + data_.resize(i * j * k); + } + + void resize(int i, int j, int k, int l) { + dims_ = {i, j, k, l}; + data_.resize(i * j * k * l); + } + + inline void flatten() { + KDEBUG(dims_.size() > 0, "Invalid tensor"); + + int elements = dims_[0]; + for (unsigned int i = 1; i < dims_.size(); i++) { + elements *= dims_[i]; + } + dims_ = {elements}; + } + + inline T& operator()(int i) { + KDEBUG(dims_.size() == 1, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + + return data_[i]; + } + + inline T& operator()(int i, int j) { + KDEBUG(dims_.size() == 2, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + + return data_[dims_[1] * i + j]; + } + + const T& operator()(int i, int j) const { + KDEBUG(dims_.size() == 2, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + + return data_[dims_[1] * i + j]; + } + + inline T& operator()(int i, int j, int k) { + KDEBUG(dims_.size() == 3, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]); + + return data_[dims_[2] * (dims_[1] * i + j) + k]; + } + const T& operator()(int i, int j, int k) const { + KDEBUG(dims_.size() == 3, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]); + + return data_[dims_[2] * (dims_[1] * i + j) + k]; + } + + inline T& operator()(int i, int j, int k, int l) { + KDEBUG(dims_.size() == 4, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]); + KDEBUG(l < dims_[3] && l >= 0, "Invalid l: %d (max %d)", l, dims_[3]); + + return data_[dims_[3] * (dims_[2] * (dims_[1] * i + j) + k) + l]; + } + + const T& operator()(int i, int j, int k, int l) const{ + KDEBUG(dims_.size() == 4, "Invalid indexing for tensor"); + KDEBUG(i < dims_[0] && i >= 0, "Invalid i: %d (max %d)", i, dims_[0]); + KDEBUG(j < dims_[1] && j >= 0, "Invalid j: %d (max %d)", j, dims_[1]); + KDEBUG(k < dims_[2] && k >= 0, "Invalid k: %d (max %d)", k, dims_[2]); + KDEBUG(l < dims_[3] && l >= 0, "Invalid l: %d (max %d)", l, dims_[3]); + + return data_[dims_[3] * (dims_[2] * (dims_[1] * i + j) + k) + l]; + } + void fill(const T & value) { + std::fill(data_.begin(), data_.end(), value); + } + + // Tensor Unpack(int row) const { + // KASSERT(dims_.size() >= 2, "Invalid tensor"); + // std::vector pack_dims = + // std::vector(dims_.begin() + 1, dims_.end()); + // int pack_size = std::accumulate(pack_dims.begin(), pack_dims.end(), 0); + + // typename std::vector::const_iterator first = + // data_.begin() + (row * pack_size); + // typename std::vector::const_iterator last = + // data_.begin() + (row + 1) * pack_size; + + // Tensor x = Tensor(); + // x.dims_ = pack_dims; + // x.data_ = std::vector(first, last); + + // return x; + // } + + // Tensor Select(int row) const { + // Tensor x = Unpack(row); + // x.dims_.insert(x.dims_.begin(), 1); + + // return x; + // } + + Tensor operator+(const Tensor& other) { + // KASSERT(dims_ == other.dims_, + // "Cannot add tensors with different dimensions"); + OPM_ERROR_IF(dims_.size() != other.dims_.size() , + "Cannot add tensors with different dimensions"); +// std::cout<<"dims_ "< dims_; + std::vector data_; +}; + +template +class KerasLayer { + public: + KerasLayer() {} + + virtual ~KerasLayer() {} + + virtual bool loadLayer(std::ifstream& file) = 0; + + virtual bool apply(Tensor& in, Tensor& out) = 0; +}; + +template +class KerasLayerActivation : public KerasLayer { + public: + enum ActivationType { + kLinear = 1, + kRelu = 2, + kSoftPlus = 3, + kSigmoid = 4, + kTanh = 5, + kHardSigmoid = 6 + }; + + KerasLayerActivation() : activation_type_(ActivationType::kLinear) {} + + virtual ~KerasLayerActivation() {} + + virtual bool loadLayer(std::ifstream& file); + + virtual bool apply(Tensor& in, Tensor& out); + + private: + ActivationType activation_type_; +}; + +template +class KerasLayerScaling : public KerasLayer { + public: + KerasLayerScaling(): data_min(1.0f), data_max(1.0f), feat_inf(1.0f), feat_sup(1.0f) {} + + virtual ~KerasLayerScaling() {} + + virtual bool loadLayer(std::ifstream& file); + + virtual bool apply(Tensor& in, Tensor& out); + + private: + Tensor weights_; + Tensor biases_; + float data_min; + float data_max; + float feat_inf; + float feat_sup; +}; + +template +class KerasLayerUnScaling : public KerasLayer { + public: + KerasLayerUnScaling(): data_min(1.0f), data_max(1.0f), feat_inf(1.0f), feat_sup(1.0f) {} + + virtual ~KerasLayerUnScaling() {} + + virtual bool loadLayer(std::ifstream& file); + + virtual bool apply(Tensor& in, Tensor& out); + + private: + Tensor weights_; + Tensor biases_; + float data_min; + float data_max; + float feat_inf; + float feat_sup; +}; + + +template +class KerasLayerDense : public KerasLayer { + public: + KerasLayerDense() {} + + virtual ~KerasLayerDense() {} + + virtual bool loadLayer(std::ifstream& file); + + virtual bool apply(Tensor& in, Tensor& out); + + private: + Tensor weights_; + Tensor biases_; + + KerasLayerActivation activation_; +}; + +template +class KerasLayerFlatten : public KerasLayer { + public: + KerasLayerFlatten() {} + + virtual ~KerasLayerFlatten() {} + + virtual bool loadLayer(std::ifstream& file); + + virtual bool apply(Tensor& in, Tensor& out); + + // private: +}; + + +template +class KerasLayerEmbedding : public KerasLayer { + public: + KerasLayerEmbedding() {} + + virtual ~KerasLayerEmbedding() {} + + virtual bool loadLayer(std::ifstream& file); + + virtual bool apply(Tensor& in, Tensor& out); + + private: + Tensor weights_; +}; + +template +class KerasModel { + public: + enum LayerType { + kFlatten = 1, + kScaling = 2, + kUnScaling = 3, + kDense = 4, + kActivation = 5 + }; + + KerasModel() {} + + virtual ~KerasModel() { + // for (unsigned int i = 0; i < layers_.size(); i++) { + // delete layers_[i]; + // } + } + + virtual bool loadModel(const std::string& filename); + + virtual bool apply(Tensor& in, Tensor& out); + + private: + // std::vector*> layers_; + std::vector>> layers_; +}; + +class KerasTimer { + public: + KerasTimer() {} + + void start() { start_ = std::chrono::high_resolution_clock::now(); } + + float stop() { + std::chrono::time_point now = + std::chrono::high_resolution_clock::now(); + + std::chrono::duration diff = now - start_; + + return diff.count(); + } + + private: + std::chrono::time_point start_; +}; + +} // namespace Opm + +#endif // ML_MODEL_H_ diff --git a/tests/ml/ml_model_test.cpp b/tests/ml/ml_model_test.cpp new file mode 100644 index 00000000000..94383fbee11 --- /dev/null +++ b/tests/ml/ml_model_test.cpp @@ -0,0 +1,201 @@ +/* + + * Copyright (c) 2016 Robert W. Rose + * Copyright (c) 2018 Paul Maevskikh + * + * MIT License, see LICENSE.MIT file. + */ + +/* + Copyright (c) 2024 NORCE + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Opm { + +template +bool tensor_test() { + printf("TEST tensor_test\n"); + + { + const int i = 3; + const int j = 5; + const int k = 10; + Tensor t(i, j, k); + + Evaluation c = 1.f; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + t(ii, jj, kk) = c; + c += 1.f; + } + } + } + + c = 1.f; + int cc = 0; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + KASSERT_EQ(t(ii, jj, kk), c, 1e-9); + KASSERT_EQ(t.data_[cc], c, 1e-9); + c += 1.f; + cc++; + } + } + } + } + + { + const int i = 2; + const int j = 3; + const int k = 4; + const int l = 5; + Tensor t(i, j, k, l); + + Evaluation c = 1.f; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + for (int ll = 0; ll < l; ll++) { + t(ii, jj, kk, ll) = c; + c += 1.f; + } + } + } + } + + c = 1.f; + int cc = 0; + for (int ii = 0; ii < i; ii++) { + for (int jj = 0; jj < j; jj++) { + for (int kk = 0; kk < k; kk++) { + for (int ll = 0; ll < l; ll++) { + KASSERT_EQ(t(ii, jj, kk, ll), c, 1e-9); + KASSERT_EQ(t.data_[cc], c, 1e-9); + c += 1.f; + cc++; + } + } + } + } + } + + { + Tensor a(2, 2); + Tensor b(2, 2); + + a.data_ = {1.0, 2.0, 3.0, 5.0}; + b.data_ = {2.0, 5.0, 4.0, 1.0}; + + Tensor result = a + b; + KASSERT(result.data_ == std::vector({3.0, 7.0, 7.0, 6.0}), + "Vector add failed"); + } + + { + Tensor a(2, 2); + Tensor b(2, 2); + + a.data_ = {1.0, 2.0, 3.0, 5.0}; + b.data_ = {2.0, 5.0, 4.0, 1.0}; + + Tensor result = a.multiply(b); + KASSERT(result.data_ == std::vector({2.0, 10.0, 12.0, 5.0}), + "Vector multiply failed"); + } + + { + Tensor a(2, 1); + Tensor b(1, 2); + + a.data_ = {1.0, 2.0}; + b.data_ = {2.0, 5.0}; + + Tensor result = a.dot(b); + KASSERT(result.data_ == std::vector({2.0, 5.0, 4.0, 10.0}), + "Vector dot failed"); + } + + return true; +} + +} + + +int main() { + typedef Opm::DenseAd::Evaluation Evaluation; + + Evaluation load_time = 0.0; + Evaluation apply_time = 0.0; + + if (!tensor_test()) { + return 1; + } + + if (!test_dense_1x1(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_10x1(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_2x2(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_10x10(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_10x10x10(&load_time, &apply_time)) { + return 1; + } + + if (!test_relu_10(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_relu_10(&load_time, &apply_time)) { + return 1; + } + + if (!test_dense_tanh_10(&load_time, &apply_time)) { + return 1; + } + + if (!test_scalingdense_10x1(&load_time, &apply_time)) { + return 1; + } + + return 0; +} \ No newline at end of file