diff --git a/SciAI/sciai/model/gad_mall/.keep b/SciAI/sciai/model/gad_mall/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md new file mode 100644 index 0000000000000000000000000000000000000000..89e1f834937a59efc434c840777be2b6d6f16b69 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/README.md @@ -0,0 +1,162 @@ +English | [简体中文](./README_CN.md) + +## Table of Contents + +- [Table of Contents](#table-of-contents) +- [GAD-MALL Description](#gad-mall-description) + - [Key Features](#key-features) +- [Dataset](#dataset) +- [Environment Requirements](#environment-requirements) +- [Quick Start](#quick-start) + - [Quick Start](#quick-start-1) + - [Pipeline Workflow](#pipeline-workflow) +- [Script Explanation](#script-explanation) + - [Scripts and Example Code](#scripts-and-example-code) + - [Project File Explanation](#project-file-explanation) +- [More Information](#more-information) + +## GAD-MALL Description + +GAD-MALL is a deep learning framework based on Active Learning and 3D Convolutional Neural Networks (3D CNN) designed to tackle multi-objective high-dimensional optimization problems. By integrating generative models, Finite Element Method (FEM), and 3D printing technology, this framework offers an efficient data-driven design approach, particularly suitable for optimizing materials with complex structures. It is specifically applied to achieve efficient optimization of building materials, especially for complex multi-objective optimization problems, such as the application of heterogeneous materials in bioengineering and materials science. For example, it can be used to design bone graft scaffolds by optimizing the scaffold's elastic modulus and yield strength, resulting in a heterogeneous structure with biocompatibility and high mechanical strength. + +### Key Features + +1. **Generative Architecture Design (GAD)**: GAD uses an autoencoder network to generate a set of architectures with unknown properties. The autoencoder, through unsupervised learning, transforms the exploration of the high-dimensional design space into a low-dimensional space, effectively representing high-dimensional data and making the design process more efficient. + +2. **Multi-objective Active Learning Loop (MALL)**: MALL iteratively queries the Finite Element Method (FEM) to evaluate the generated datasets, gradually optimizing the architecture's performance. This method continuously updates the training data through an active learning loop, progressively improving the accuracy of the model's predictions. + +3. **3D Printing and Testing**: Architected materials designed by the ML framework are manufactured using laser powder bed fusion technology, and their mechanical properties are experimentally validated. + +> Paper: Peng, B., Wei, Y., Qin, Y. et al. Machine learning-enabled constrained multi-objective design of architected materials. Nat Commun 14, 6630 (2023). https://doi.org/10.1038/s41467-023-42415-y +## Dataset + +The primary datasets used in this project include the following files: + +- Input Data: + - `3D_CAE_Train.npy`: Training data for the 3D convolutional autoencoder, stored as a NumPy array. + - `Matrix12.npy` and `Matrix60.npy`: These files contain matrix data for different - configurations used in the architecture generation and optimization process. + - `E.csv`: A data file containing the elastic modulus of materials. + - `yield.csv`: A data file containing the yield strength of materials. + +These datasets support the training and testing of various models within the GAD-MALL framework. + +- Data Download: + - `Matrix12.npy`, `E.csv`, and `yield.csv` are located in the `./src/data` directory: + + ```txt + ├── data + │ ├── E.csv + │ ├── yield.csv + │ ├── Matrix12.npy + │ └── README.txt + ``` + + - `3D_CAE_Train.npy` can be downloaded via the link provided in README.txt [here](https://drive.google.com/file/d/1BfmD4bsPS2hG5zm7XGLHc8lpUN_WqhgV/view?usp=share_link). + - `Matrix60.npy can` be downloaded via the link provided in README.txt [here](https://drive.google.com/file/d/1VRH4X_mACxM82HoaplwV0ThaDiN3iPXm/view?usp=share_link). + +- **Preprocessing**: Before use, the data needs to be normalized, and may require cropping or padding to fit the input size of the model. + +## Environment Requirements + +This project is based on the MindSpore deep learning framework. Below are the main (**test/development**) environment dependencies: + +- **Hardware** (GPU) + - GPU: NVIDIA GeForce RTX 4060 Laptop GPU + - Driver: CUDA 12.3 + - CUDA: 11.6 + - CUDNN: 8.4.1 +- **Operating System**: + - Windows WSL Ubuntu-2 0.04 +- **Python Version**: + - Python 3.9 +- **Framework** + - [MindSpore](https://www.mindspore.cn/install/) +- **Dependencies**: + - mindspore==2.2.14 + - numpy==1.23.5 + - scipy==1.13.1 + - pandas==2.2.2 + - matplotlib==3.9.1 + - tqdm==4.66.5 + - You can install the dependencies using the following command: + + ```bashpython3.9 -u pip install -r requirement.txt``` + +- For more information, please refer to the following resources: + - [MindSpore Tutorials](https://www.mindspore.cn/tutorials/zh-CN/r2.2/index.html) + - [MindSpore Python API](https://www.mindspore.cn/docs/zh-CN/master/index.html) + +## Quick Start + +### Quick Start + +After installing MindSpore from the official website, you can start training and validation as follows: + +- Run on GPU + + ```bash run_GAD_MALL.sh``` + +### Pipeline Workflow + +After installing MindSpore from the official website and downloading the required datasets, you can begin running the training and generating the Generative Architecture Design-Multi-objective Active Learning Loop (GAD-MALL) pipeline on GPU. Please follow the steps below: + + 1. Train the 3D-CAE model as the generative model for GAD-MALL. Run the following command in the terminal: + + ```python3.9 3D_CAE_ms.py``` + + 2. Train the 3D-CNN model as the surrogate model for GAD-MALL. Run the following command in the terminal: + + ```python3.9 3D_CNN_ms.py``` + + 3. Use GAD-MALL to search for high-performance architected materials with specific elastic modulus and high yield strength. Run the following command in the terminal: + + ```python3.9 -u GAD_MALL_Active_learning.py``` + + 4. After completing the GAD-MALL process, you will obtain porosity matrices with specific predicted elastic modulus (E=2500 MPa, E=5000 MPa) and the highest predicted yield strength. + +## Script Explanation + +### Scripts and Example Code + +The file structure is as follows: + +```text +├── gad_mall +│ ├── data # Data files +│ │ ├── E.csv # Data file containing the elastic modulus of materials +│ │ ├── yield.csv # Data file containing the yield strength of materials +│ │ ├── Matrix12.npy # Matrix data used for architecture generation and optimization +│ │ ├── (Matrix60.npy) # Matrix data used for architecture generation and optimization +│ │ ├── (3D_CAE_Train.npy) # Training data for the 3D convolutional autoencoder, stored as a NumPy array +│ │ └── README.txt # Download links for datasets +│ ├── model # Directory for storing checkpoint files +│ ├── results # Directory for storing experimental results +│ ├── src # Source code +│ │ ├── 3D_CAE_ms.py # Implementation of the 3D convolutional autoencoder +│ │ ├── 3D_CNN_ms.py # Implementation of the 3D convolutional neural network model +│ │ └── GAD_MALL_Active_learning.py # Implementation of the GAD-MALL framework +│ ├── README.md # English documentation for the model +│ ├── README_CN.md # Chinese documentation for the model +│ ├── run_GAD_MALL.sh # Script for starting the training process +│ └── requirements.txt # Python environment dependencies +``` + +### Project File Explanation + +- `3D_CNN_ms.py`: Implements a model based on 3D Convolutional Neural Networks, suitable for handling three-dimensional datasets, particularly in high-dimensional multi-objective optimization problems. This model voxelizes the input data and uses 3D convolutional layers to extract high-level features, ultimately predicting material properties. + +- `GAD_MALL_Active_learning_ms.py`: Implements the active learning strategy for the GAD-MALL framework, used to optimize models in scenarios where data labeling is costly. This script combines generative models and the Finite Element Method (FEM) to iteratively search for high-performance architectures through active learning. + +- `3D_CAE_ms.py`: Implements a 3D Convolutional Autoencoder, used for feature extraction or dimensionality reduction in unsupervised learning. This autoencoder is a key component in the Generative Architecture Design (GAD) process. It uses an encoder-decoder network to represent input data in a low-dimensional space and reconstruct the original data. + +- `data/`: Directory containing training and testing datasets. + +- `models/`: Directory for storing trained models and weight files. + +- `results/`: Directory for storing the results of model inference and evaluation. + +- `requirements.txt`: File listing the Python environment dependencies. + +## More Information + +For additional details, please refer to the original project documentation for[GAD-MALL](https://github.com/Bop2000/GAD-MALL/tree/main) \ No newline at end of file diff --git a/SciAI/sciai/model/gad_mall/README_CN.md b/SciAI/sciai/model/gad_mall/README_CN.md new file mode 100644 index 0000000000000000000000000000000000000000..c7af15f47e1d61c7142262ae11ff5e5d7766c03f --- /dev/null +++ b/SciAI/sciai/model/gad_mall/README_CN.md @@ -0,0 +1,152 @@ +[English](./README.md) | 简体中文 + +## 目录 + +- [目录](#目录) +- [GAD-MAL 描述](#gad-mal-描述) + - [主要特性](#主要特性) +- [数据集](#数据集) +- [环境要求](#环境要求) +- [快速开始](#快速开始) + - [快速开始](#快速开始-1) + - [管道流程](#管道流程) +- [脚本说明](#脚本说明) + - [脚本和示例代码](#脚本和示例代码) + - [项目文件说明](#项目文件说明) +- [更多信息](#更多信息) + +## GAD-MAL 描述 + +GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络(3D CNN)的深度学习框架,旨在处理多目标高维优化问题。该框架通过生成模型、有限元方法(FEM)和3D打印技术相结合,提供了一种高效的数据驱动设计方法,尤其适用于具有复杂结构的材料的优化设计。该框架特别应用于实现高效的建筑材料设计优化特别是针对复杂的多目标优化问题,如异质材料在生物工程和材料科学领域中的应用。可以完成像骨移植支架的设计,通过优化支架的弹性模量和屈服强度,实现了具有生物相容性和高机械强度的异质性架构。 + +### 主要特性 + +1. **生成架构设计(GAD)**: GAD利用编码器-解码器网络(autoencoder)生成具有未知特性的架构集。自动编码器通过无监督学习将高维设计空间的探索转化为低维空间,并有效地表示高维数据,使设计过程更为高效。 + +2. **多目标主动学习环(MALL)**: MALL通过迭代地查询有限元方法(FEM)来评估生成的数据集,逐步优化架构性能。该方法通过主动学习循环,不断更新训练数据,逐步提高模型预测的准确性。 + +1. **3D打印与测试**: 通过激光粉末床熔融技术制造ML设计的架构材料,并实验验证其机械性能。 + +>论文:Peng, B., Wei, Y., Qin, Y. et al. Machine learning-enabled constrained multi-objective design of architected materials. Nat Commun 14, 6630 (2023). https://doi.org/10.1038/s41467-023-42415-y + +## 数据集 + +该项目使用的主要数据集包括以下文件: + +- 输入数据: + - `3D_CAE_Train.npy`: 用于3D卷积自编码器的训练数据,存储为NumPy数组。 + - `Matrix12.npy` 和 `Matrix60.npy`: 这些文件包含不同构建的矩阵数据,用于架构生成和优化过程。 + - `E.csv`: 包含材料弹性模量的数据文件。 + - `yield.csv`: 包含材料屈服强度的数据文件。 + +这些数据集用于支持GAD-MALL框架中各个模型的训练和测试。 + +- 数据下载: + - `Matrix12.npy`,`E.csv` 和 `yield.csv`: 存放于 `./src/data` 目录下 + + ```txt + ├── data + │ ├── E.csv + │ ├── yield.csv + │ ├── Matrix12.npy + │ └── README.txt + ``` + + - `3D_CAE_Train.npy` 可通过README.txt中的[链接](https://drive.google.com/file/d/1BfmD4bsPS2hG5zm7XGLHc8lpUN_WqhgV/view?usp=share_link)下载。 + - `Matrix60.npy` 可通过README.txt中的[链接](https://drive.google.com/file/d/1VRH4X_mACxM82HoaplwV0ThaDiN3iPXm/view?usp=share_link)下载。 +- **预处理**: 在使用前,需要对数据进行归一化处理,并可能需要对数据进行裁剪或补零操作以适配模型的输入尺寸。 + +## 环境要求 + +该项目基于MindSpore深度学习框架。以下是主要的(**测试/开发**)环境依赖: + +- **硬件** (GPU) + - 显卡:NVIDIA GeForce RTX 4060 Laptop GPU + - 驱动:CUDA 12.3 + - CUDA: 11.6 + - CUDNN: 8.4.1 +- **操作系统**: + - Windows WSL Ubuntu-20.04 +- **Python 版本**: + - Python 3.9 +- 框架 + - [MindSpore](https://www.mindspore.cn/install/) +- **依赖库**: + - mindspore==2.2.14 + - numpy==1.23.5 + - scipy==1.13.1 + - pandas==2.2.2 + - matplotlib==3.9.1 + - tqdm==4.66.5 + - 安装依赖库可以通过以下命令: + + ```python3.9 -u pip install -r requirement.txt``` + +- 欲了解更多信息,请查看以下资源: + - [MindSpore教程](https://www.mindspore.cn/tutorials/zh-CN/r2.2/index.html) + - [MindSpore Python API](https://www.mindspore.cn/docs/zh-CN/master/index.html) + +## 快速开始 + +### 快速开始 + +通过官网安装好MindSpore后,就可以开始训练和验证如下: + +- 在 GPU 上运行 + ```bash run_GAD_MALL.sh``` + +### 管道流程 + +通过官网安装好MindSpore和上面需要的数据集后,就可以开始在 GPU 上运行训练,生成架构设计-多目标主动学习循环 (GAD-MALL) 管道,请按照以下步骤操作: + + 1. 训练 3D-CAE 模型作为生成模型GAD-MALL,请在终端中运行以下行 + python3.9 3D_CAE_ms.py + 2. 训练 3D-CNN 模型作为 GAD-MALL 的替代模型GAD-MALL,请在终端中运行以下行 + python3.9 3D_CNN_ms.py + 3. 使用 GAD-MALL 搜索具有特定弹性模量和高屈服强度的高性能建筑材料,请在终端中运行以下行 + python3.9 -u GAD_MALL_Active_learning.py + 4. 完成 GAD-MALL 流程后,您将获得具有特定预测弹性模量(E=2500 MPa、E=5000 MPa)和最高预测屈服强度的孔隙度矩阵 + +## 脚本说明 + +### 脚本和示例代码 + +文件结构如下: + +```text + +├── gad_mall +│ ├── data # 数据文件 +│ │ ├── E.csv # 包含材料弹性模量的数据文件 +│ │ ├── yield.csv # 包含材料屈服强度的数据文件 +│ │ ├── Matrix12.npy # 矩阵数据,用于架构生成和优化过程 +│ │ ├── (Matrix60.npy) # 矩阵数据,用于架构生成和优化过程 +│ │ ├── (3D_CAE_Train.npy) # 用于3D卷积自编码器的训练数据,存储为NumPy数组 +│ │ └── README.txt # 数据下载地址 +│ ├── model # checkpoint文件 +│ ├── results # 实验结果存放 +│ ├── src # 源代码 +│ │ ├── 3D_CAE_ms.py # 3D卷积自编码器的实现 +│ │ ├── 3D_CNN_ms.py # 3D卷积神经网络模型的实现 +│ │ └── GAD_MALL_Active_learning.py # GAD-MALL框架的实现 +│ ├── README.md # 英文模型说明 +│ ├── README_CN.md # 中文模型说明 +│ ├── run_GAD_MALL.sh # 训练启动脚本 +| └── requirements.txt # Python环境依赖文件 + +``` + +### 项目文件说明 + +- `3D_CNN_ms.py`:实现了基于3D卷积神经网络的模型,适用于处理三维数据集,特别是在高维多目标优化问题中的应用。该模型通过体素化处理输入数据,并利用3D卷积层提取高层信息,最终进行材料性能的预测。 +- `GAD_MALL_Active_learning_ms.py`:实现了GAD-MALL框架的主动学习策略,用于在数据标注成本高的场景中优化模型。该脚本结合生成模型和有限元方法,通过主动学习迭代搜索高性能架构。 +- `3D_CAE_ms.py`:实现了3D卷积自编码器,用于无监督学习中的特征提取或数据降维。该自编码器是生成架构设计(GAD)过程中的关键组成部分。通过编码器-解码器网络对输入数据进行低维表示,并重建原始数据。 +- `data/`: 数据文件夹,包含训练和测试数据集。 +- `models/`: 存放训练好的模型和权重文件。 +- `results/`: 存放模型推理和评估的结果。 +- `requirements.txt`: Python环境依赖文件。 + +## 更多信息 + +有关更多信息请参阅原项目说明[GAD-MALL](https://github.com/Bop2000/GAD-MALL/tree/main) + diff --git a/SciAI/sciai/model/gad_mall/src/.keep b/SciAI/sciai/model/gad_mall/src/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py b/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py new file mode 100644 index 0000000000000000000000000000000000000000..718a19e207c4821346ac96ceb7da95edaca82c29 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py @@ -0,0 +1,140 @@ +''' +This file defines and trains a 3D_CAE model +''' +import numpy as np +from sklearn.model_selection import train_test_split +from mindspore import nn, context +from mindspore.train.callback import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau +from mindspore.train import Model +import mindspore.dataset as ds +from mindspore.train.callback import CheckpointConfig, LossMonitor +from mindspore.train.callback import Callback +from tqdm import tqdm + +# GPU Configuration +context.set_context(mode=context.GRAPH_MODE, device_target="GPU", device_id=0) +context.set_context(max_call_depth=10000) + +# Import +matrix = np.load('data/3D_CAE_Train.npy', allow_pickle=True) +ran = range(len(matrix)) +X = matrix.reshape(17835, 12, 12, 12, 1) + +# Convert the data type to Float32 +X = X.astype(np.float32) + +# Adjust the shape to be [batch_size, channels, depth, height, width] +X = np.transpose(X, (0, 4, 1, 2, 3)) # Now X is [batch_size, channels, depth, height, width] + +ran = np.arange(len(matrix)) # Create labels or indices, similar to TensorFlow code + +# Split +x_train, x_test, y_train, y_test = train_test_split(X, ran, test_size=0.2, random_state=1) + +# Model parameters +b_size = 64 +k_size = 4 +f_size = 60 +lr = 0.000753014797772 + +# Create MindSpore training & testing dataset +train_data = ds.NumpySlicesDataset((x_train, x_train), shuffle=True) +test_data = ds.NumpySlicesDataset((x_test, x_test), shuffle=False) + +# Apply batching to the datasets +train_data = train_data.batch(batch_size=b_size, drop_remainder=True) +test_data = test_data.batch(batch_size=b_size, drop_remainder=True) + +# Model architecture +class AutoEncoder(nn.Cell): + '''Definition of AutoEncoder''' + def __init__(self): + super(AutoEncoder, self).__init__() + self.encoder = nn.SequentialCell([ + nn.Conv3d(1, 32, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 32, 12, 12, 12] + nn.ReLU(), + nn.Conv3d(32, 64, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 64, 12, 12, 12] + nn.ReLU(), + nn.Conv3d(64, 128, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 128, 12, 12, 12] + nn.ReLU(), + nn.MaxPool3d(kernel_size=2, stride=2, pad_mode='same') # Output shape: [batch_size, 128, 6, 6, 6] + ]) + + self.decoder = nn.SequentialCell([ + nn.Upsample(scale_factor=(2.0, 2.0, 2.0), mode='nearest'), # Upsample to [batch_size, 128, 12, 12, 12] + nn.Conv3d(128, 64, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 64, 12, 12, 12] + nn.ReLU(), + nn.Conv3d(64, 32, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 32, 12, 12, 12] + nn.ReLU(), + nn.Conv3d(32, 1, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 1, 12, 12, 12] + ]) + + def construct(self, x): + x = self.encoder(x) + x = self.decoder(x) + return x + + +# Create Model +autoencoder = AutoEncoder() + +loss_fn = nn.MSELoss() +optimizer = nn.Adam(autoencoder.trainable_params(), learning_rate=lr) + +# Configure the Checkpoint +config_ck = CheckpointConfig(save_checkpoint_steps=1, keep_checkpoint_max=5) +# ModelCheckpoint callback +mc = ModelCheckpoint(prefix='3D_CAE_model', directory='model', config=config_ck) + +# LossMonitor callback to print loss values +ls = LossMonitor() + +# Callbacks +re = ReduceLROnPlateau(monitor='loss', factor=0.1, patience=10) +es = EarlyStopping(monitor='loss', mode='min', patience=20) + +# Configure training model +model = Model(autoencoder, loss_fn=loss_fn, optimizer=optimizer) + +# # Train the model +# model.train(500, train_data, callbacks=[es, mc, re, ls], dataset_sink_mode=False) + +# progress bar +# 加进度条 + +class TQDMProgressBar(Callback): + '''add progress bar while training the model''' + def __init__(self, total_steps_per_epoch, total_epochs): + super(TQDMProgressBar, self).__init__() + self.total_steps_per_epoch = total_steps_per_epoch + self.total_epochs = total_epochs + self.progress_bar = None + self.current_epoch = 0 + + # def on_train_epoch_begin(self, run_context): + def on_train_epoch_begin(self): + self.current_epoch += 1 + if self.progress_bar is not None: + self.progress_bar.close() # Close the previous bar if it exists + self.progress_bar = tqdm(total=self.total_steps_per_epoch, \ + desc=f"Epoch {self.current_epoch}/{self.total_epochs}", ncols=100, unit=" step") + + # def on_train_step_end(self, run_context): + def on_train_step_end(self): + self.progress_bar.update(1) + + # def on_train_epoch_end(self, run_context): + def on_train_epoch_end(self): + self.progress_bar.close() + +# Number of steps per epoch +tot_steps_per_epoch = train_data.get_dataset_size() +# Total number of epochs +tot_epochs = 10 +# Initialize the progress bar callback +tqdm_callback = TQDMProgressBar(total_steps_per_epoch=tot_steps_per_epoch, total_epochs=tot_epochs) + + + +# Train the model with progress bar +model.train(tot_epochs, train_data, callbacks=[es, mc, re, ls, tqdm_callback], dataset_sink_mode=False) diff --git a/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py new file mode 100644 index 0000000000000000000000000000000000000000..44bdaff1a271ce11cdf0331298a811c91c1a62a2 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py @@ -0,0 +1,147 @@ +''' +This file defines CNN_3D model and trains the model. +''' +import numpy as np +import pandas as pd +from mindspore import nn, context +from mindspore.train.callback import ModelCheckpoint, EarlyStopping, LossMonitor, Callback +from mindspore.train import Model +from mindspore.common.initializer import Normal +import mindspore.dataset as ds +from mindspore.train.callback import CheckpointConfig +from mindspore.train.metrics import MAE +from sklearn.model_selection import train_test_split +from tqdm import tqdm + +# Set the context for MindSpore +context.set_context(mode=context.GRAPH_MODE, device_target="GPU", device_id=0) + +# Define the 3D convolutional neural network model +class CNN3D(nn.Cell): + '''definition of CNN model''' + def __init__(self): + super(CNN3D, self).__init__() + self.conv1 = nn.Conv3d(1, 8, kernel_size=3, pad_mode='same', has_bias=True, weight_init=Normal(0.02)) + self.conv2 = nn.Conv3d(8, 4, kernel_size=3, pad_mode='same', has_bias=True, weight_init=Normal(0.02)) + self.conv3 = nn.Conv3d(4, 2, kernel_size=3, pad_mode='same', has_bias=True, weight_init=Normal(0.02)) + self.maxpool = nn.MaxPool3d(kernel_size=2, stride=2, pad_mode='same') + self.flatten = nn.Flatten() + self.fc1 = nn.Dense(2*8*8*8, 128, weight_init=Normal(0.02)) + self.fc2 = nn.Dense(128, 64, weight_init=Normal(0.02)) + self.fc3 = nn.Dense(64, 32, weight_init=Normal(0.02)) + self.fc4 = nn.Dense(32, 1, weight_init=Normal(0.02)) + self.elu = nn.ELU() + + def construct(self, x): + '''construct ''' + x = self.elu(self.conv1(x)) + x = self.maxpool(x) + x = self.elu(self.conv2(x)) + x = self.maxpool(x) + x = self.elu(self.conv3(x)) + x = self.maxpool(x) + x = self.flatten(x) + x = self.elu(self.fc1(x)) + x = self.elu(self.fc2(x)) + x = self.elu(self.fc3(x)) + x = self.fc4(x) + return x + +# Custom TQDM progress bar callback +class TQDMProgressBar(Callback): + '''add progress bar''' + def __init__(self, total_steps_per_epoch, total_epochs): + '''init ''' + super(TQDMProgressBar, self).__init__() + self.total_steps_per_epoch = total_steps_per_epoch + self.total_epochs = total_epochs + self.progress_bar = None + self.current_epoch = 0 + + # def on_train_epoch_begin(self, run_context): + def on_train_epoch_begin(self): + self.current_epoch += 1 + if self.progress_bar is not None: + self.progress_bar.close() # Close the previous bar if it exists + self.progress_bar = tqdm(total=self.total_steps_per_epoch, \ + desc=f"Epoch {self.current_epoch}/{self.total_epochs}", \ + ncols=100, unit=" step") + + # def on_train_step_end(self, run_context): + def on_train_step_end(self, run_context): + self.progress_bar.update(1) + run_context.original_args() # Suppress extra output + + # def on_train_epoch_end(self, run_context): + def on_train_epoch_end(self): + self.progress_bar.close() + +# Load and preprocess the data +matrix = np.load("data/Matrix60.npy", allow_pickle=True) +data = pd.read_csv("data/E.csv") +X = matrix.reshape(len(data), 1, 60, 60, 60) # MindSpore expects [batch_size, channels, depth, height, width] + +# Convert the data to Float32 +X = X.astype(np.float32) + +# Split the data into training and testing sets +x_train, x_test, y_train, y_test = train_test_split(X, data['E'].values, test_size=0.2, random_state=0) + +# Create MindSpore datasets +train_dataset = ds.NumpySlicesDataset((x_train, y_train), shuffle=True) +test_dataset = ds.NumpySlicesDataset((x_test, y_test), shuffle=False) + +# Apply batching +batch_size = 32 +train_dataset = train_dataset.batch(batch_size=batch_size, drop_remainder=True) +test_dataset = test_dataset.batch(batch_size=batch_size, drop_remainder=True) + +# Initialize the model, loss function, and optimizer +model = CNN3D() +loss_fn = nn.MSELoss() +optimizer = nn.Adam(model.trainable_params(), learning_rate=0.005) + +# Define checkpoint configuration and callbacks +config_ck = CheckpointConfig(save_checkpoint_steps=1, keep_checkpoint_max=5) +ckpoint_cb = ModelCheckpoint(prefix="3dCNN_E", directory="model", config=config_ck) +es = EarlyStopping(monitor='loss', mode='min', patience=30) +ls = LossMonitor() + +# Get the number of steps per epoch +total_steps_per_epoch = train_dataset.get_dataset_size() + +# Total number of epochs +tot_epochs = 5 + +# Initialize the progress bar callback +tqdm_callback = TQDMProgressBar(total_steps_per_epoch=total_steps_per_epoch, total_epochs=tot_epochs) + +# Initialize and train the model +net = Model(network=model, loss_fn=loss_fn, optimizer=optimizer, metrics={"mae": MAE()}) +net.train(tot_epochs, train_dataset, callbacks=[ckpoint_cb, es, ls, tqdm_callback], dataset_sink_mode=False) + +# Repeat similar steps for the second model (for yield strength prediction) +data2 = pd.read_csv("data/yield.csv") +X2 = matrix.reshape(len(data2), 1, 60, 60, 60) + +# Convert the second dataset to Float32 +X2 = X2.astype(np.float32) + +x_train2, x_test2, y_train2, y_test2 = train_test_split(X2, data2['yield'].values, test_size=0.2, random_state=1) + +train_dataset2 = ds.NumpySlicesDataset((x_train2, y_train2), shuffle=True) +test_dataset2 = ds.NumpySlicesDataset((x_test2, y_test2), shuffle=False) + +train_dataset2 = train_dataset2.batch(batch_size=16, drop_remainder=True) +test_dataset2 = test_dataset2.batch(batch_size=16, drop_remainder=True) + +model2 = CNN3D() +optimizer2 = nn.Adam(model2.trainable_params(), learning_rate=0.005) + +ckpoint_cb2 = ModelCheckpoint(prefix="3dCNN_Y", directory="model", config=config_ck) + +# Initialize the progress bar callback for the second model +tqdm_callback2 = TQDMProgressBar(total_steps_per_epoch=train_dataset2.get_dataset_size(), total_epochs=tot_epochs) + +net2 = Model(network=model2, loss_fn=loss_fn, optimizer=optimizer2, metrics={"mae": MAE()}) +net2.train(tot_epochs, train_dataset2, callbacks=[ckpoint_cb2, es, ls, tqdm_callback2], dataset_sink_mode=False) diff --git a/SciAI/sciai/model/gad_mall/src/data/.keep b/SciAI/sciai/model/gad_mall/src/data/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SciAI/sciai/model/gad_mall/src/data/E.csv b/SciAI/sciai/model/gad_mall/src/data/E.csv new file mode 100644 index 0000000000000000000000000000000000000000..74e70aa4e80e6a4e334ee302355dbeb517163aff --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/data/E.csv @@ -0,0 +1,76 @@ +E +989.0702366 +2733.378253 +2637.078588 +2474.154559 +2209.242972 +4083.653853 +1086.677816 +3655.55268 +2247.932729 +1549.979233 +1807.938713 +1401.740728 +1939.977872 +1275.929224 +3995.661458 +1582.655825 +2528.2507 +2320.912754 +1154.856139 +1210.139467 +748.0263121 +3833.868464 +677.0229017 +991.8402288 +2468.93183 +2485.877205 +2910.167027 +1563.654379 +1501.159332 +2962.763581 +2951.284412 +1906.174319 +3735.882594 +897.8278148 +2709.916449 +4278.153402 +2451.275841 +4515.273193 +3147.847564 +765.5913466 +1542.806499 +1576.676604 +1791.514773 +2900.720522 +2439.422794 +2722.209522 +3593.107101 +2378.665083 +3360.72274 +3228.214636 +1486.385635 +1525.855768 +3760.059953 +3842.295218 +1921.684214 +3795.332902 +2706.338854 +3173.396567 +3243.475603 +5211.235866 +3704.033561 +4429.913206 +1770.342843 +2040.235181 +3336.096491 +3287.841021 +3876.897236 +4858.87906 +2592.795041 +1699.93388 +4070.045563 +3244.714179 +2869.832795 +3138.714897 +2678.212137 diff --git a/SciAI/sciai/model/gad_mall/src/data/Matrix12.npy b/SciAI/sciai/model/gad_mall/src/data/Matrix12.npy new file mode 100644 index 0000000000000000000000000000000000000000..2af1475713d2f1a8f7cf9b9064d903ddff1eaef4 Binary files /dev/null and b/SciAI/sciai/model/gad_mall/src/data/Matrix12.npy differ diff --git a/SciAI/sciai/model/gad_mall/src/data/ReadMe.txt b/SciAI/sciai/model/gad_mall/src/data/ReadMe.txt new file mode 100644 index 0000000000000000000000000000000000000000..c39b6de916e8f0a26defb35a312bb1f39885ad23 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/data/ReadMe.txt @@ -0,0 +1,7 @@ +The file "3D_CAE_Train.npy" could be download through this link: + +https://drive.google.com/file/d/1BfmD4bsPS2hG5zm7XGLHc8lpUN_WqhgV/view?usp=share_link + +The file "Matrix60.npy" could be download through this link: + +https://drive.google.com/file/d/1VRH4X_mACxM82HoaplwV0ThaDiN3iPXm/view?usp=share_link \ No newline at end of file diff --git a/SciAI/sciai/model/gad_mall/src/data/yield.csv b/SciAI/sciai/model/gad_mall/src/data/yield.csv new file mode 100644 index 0000000000000000000000000000000000000000..ace5d220e277d22e10f6e6a66104d9a109e7ed12 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/data/yield.csv @@ -0,0 +1,76 @@ +yield +23.81323978 +67.52746673 +65.62370228 +59.54408479 +51.98970464 +90.89648325 +27.96414534 +89.826719 +54.51691581 +38.24232568 +46.05671315 +31.78320161 +48.27680284 +31.24853427 +94.76166104 +42.96780916 +62.46596953 +61.55295225 +29.74964047 +33.47192386 +20.35088066 +87.88398625 +19.54326924 +24.85198091 +62.96012218 +60.30676095 +72.81915239 +40.27579146 +38.65391355 +75.01689852 +74.74086473 +43.73785192 +86.99928698 +22.13910966 +63.04101329 +100.2055916 +60.08482935 +105.5262361 +78.63557747 +20.95042501 +40.08236831 +38.39834518 +44.30300671 +70.41465884 +57.56602368 +64.37740965 +84.62115704 +56.83515507 +75.72038777 +71.74574416 +39.35440976 +37.06741297 +90.9608359 +94.03332843 +46.29440023 +90.97199885 +65.06289681 +80.71242697 +80.17801187 +115.9410229 +89.87303388 +103.1727721 +42.8241483 +44.13960881 +79.42002477 +78.0786333 +95.61563332 +119.8694487 +58.55634218 +48.82169627 +91.35057353 +73.60975381 +69.53075282 +75.66163341 +69.98255081 diff --git a/SciAI/sciai/model/gad_mall/src/gad_mall_active_learning_ms.py b/SciAI/sciai/model/gad_mall/src/gad_mall_active_learning_ms.py new file mode 100644 index 0000000000000000000000000000000000000000..8e65f983e0dc55f26503d8a33ecfd2e3b7ebb7bf --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/gad_mall_active_learning_ms.py @@ -0,0 +1,1029 @@ +# ''' +# This file integrate CAE and CNN model +# ''' +# from sklearn.mixture import GaussianMixture +# import mindspore as ms +# from mindspore import nn +# from mindspore import Tensor +# from mindspore import context +# from mindspore.train import Model +# import numpy as np +# import matplotlib.pyplot as plt +# from prettytable import PrettyTable +# import pandas as pd +# from tqdm import tqdm + + +# # GPU Configuration +# # Set the MindSpore context +# context.set_context(mode=context.GRAPH_MODE, device_target="GPU") +# context.set_context(max_call_depth=10000) + +# ####### helper functions + +# # Model architecture +# class AutoEncoder(nn.Cell): +# """ +# A 3D Convolutional Autoencoder for encoding and decoding 3D volumetric data. + +# The AutoEncoder consists of an encoder and a decoder. The encoder compresses the input +# 3D volume data to a latent representation using 3D convolutions and pooling operations, +# while the decoder reconstructs the original input from this compressed representation +# using upsampling and 3D convolutions. + +# Attributes: +# ----------- +# encoder : nn.SequentialCell +# The encoding path of the autoencoder that reduces the dimensionality of the input data +# through 3D convolutions and pooling layers. +# decoder : nn.SequentialCell +# The decoding path of the autoencoder that reconstructs the input data from the compressed +# latent representation using 3D convolutions and upsampling layers. +# Methods: +# -------- +# construct(x): +# Passes the input `x` through the encoder to compress it and then through the decoder +# to reconstruct the original input. +# """ +# def __init__(self): +# super(AutoEncoder, self).__init__() +# self.encoder = nn.SequentialCell([ +# nn.Conv3d(1, 32, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 32, 12, 12, 12] +# nn.ReLU(), +# nn.Conv3d(32, 64, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 64, 12, 12, 12] +# nn.ReLU(), +# nn.Conv3d(64, 128, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 128, 12, 12, 12] +# nn.ReLU(), +# nn.MaxPool3d(kernel_size=2, stride=2, pad_mode='same') # Output shape: [batch_size, 128, 6, 6, 6] +# ]) + +# self.decoder = nn.SequentialCell([ +# nn.Upsample(scale_factor=(2.0, 2.0, 2.0), mode='nearest'), # Upsample to [batch_size, 128, 12, 12, 12] +# nn.Conv3d(128, 64, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 64, 12, 12, 12] +# nn.ReLU(), +# nn.Conv3d(64, 32, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 32, 12, 12, 12] +# nn.ReLU(), +# nn.Conv3d(32, 1, kernel_size=3, pad_mode='pad', padding=1), # Output shape: [batch_size, 1, 12, 12, 12] +# ]) + +# def construct(self, x): +# x = self.encoder(x) +# x = self.decoder(x) +# return x +# # Define the decoder model class +# class Decoder(nn.Cell): +# """ +# A 3D Convolutional Decoder model extracted from an AutoEncoder. + +# Attributes: +# ----------- +# decoder_layers : nn.SequentialCell +# The decoder layers from the provided AutoEncoder, including upsampling and 3D convolutional +# layers that progressively reconstruct the data from the latent space to the original shape. + +# Methods: +# -------- +# construct(x): +# Passes the input latent vector `x` through the decoder layers to produce the reconstructed output. + +# Parameters: +# ----------- +# autoencoder : AutoEncoder +# An instance of an AutoEncoder model from which the decoder layers are extracted. +# """ +# def __init__(self, autoencoder): +# super(Decoder, self).__init__() +# self.decoder_layers = nn.SequentialCell([ +# autoencoder.decoder[0], # Upsample +# autoencoder.decoder[1], # Conv3d +# autoencoder.decoder[2], # ReLU +# autoencoder.decoder[3], # Conv3d +# autoencoder.decoder[4], # ReLU +# autoencoder.decoder[5] # Conv3d (final output layer) +# ]) + +# def construct(self, x): +# return self.decoder_layers(x) +# # Define the encoder model class +# class Encoder(nn.Cell): +# """ +# A 3D Convolutional Encoder model extracted from an AutoEncoder. + +# This class takes the encoder part of a pre-trained AutoEncoder model and uses it to encode +# 3D volumetric data into a latent representation. The encoder compresses the input through +# a series of 3D convolutional and pooling layers. + +# Attributes: +# ----------- +# encoder_layers : nn.SequentialCell +# The encoder layers from the provided AutoEncoder, including 3D convolutional layers and +# pooling layers that progressively reduce the dimensionality of the input data. + +# Methods: +# -------- +# construct(x): +# Passes the input data `x` through the encoder layers to produce the compressed latent representation. + +# Parameters: +# ----------- +# autoencoder : AutoEncoder +# An instance of an AutoEncoder model from which the encoder layers are extracted. +# """ +# def __init__(self, autoencoder): +# super(Encoder, self).__init__() +# self.encoder_layers = nn.SequentialCell([ +# autoencoder.encoder[0], # Conv3d +# autoencoder.encoder[1], # ReLU +# autoencoder.encoder[2], # Conv3d +# autoencoder.encoder[3], # ReLU +# autoencoder.encoder[4], # Conv3d +# autoencoder.encoder[5] # MaxPool3d +# ]) + +# def construct(self, x): +# return self.encoder_layers(x) + +# # helper functions +# def density(input_) -> np.array: +# """ +# Calculate the density of a 3D input array by averaging values in 4x4x4 blocks. + +# Parameters: +# ----------- +# input_ : np.array +# A 3D numpy array representing the input volumetric data. + +# Returns: +# -------- +# blocks : np.array +# A 3x3x3 numpy array where each element is the averaged density value of the corresponding +# 4x4x4 block in the input array, rounded to one decimal place. + +# """ +# blocks = matrix_maker(0.1, 3) +# for i in range(3): +# for j in range(3): +# for k in range(3): +# loc = [i, j, k] +# loc_input = [4*loc[0]+2, 4*loc[1]+2, 4*loc[2]+2] +# blocks[loc[0], loc[1], loc[2]] = np.mean(input_[loc_input[0]-2:loc_input[0]+2, \ +# loc_input[1]-2:loc_input[1]+2, \ +# loc_input[2]-2:loc_input[2]+2]) +# blocks = blocks.round(1) +# return blocks + +# def matrix_maker(value, n) -> np.array: +# """ +# Create a 3D matrix of size n x n x n filled with a specified value. + +# Parameters: +# ----------- +# value : float +# The value to fill the matrix with. +# n : int +# The size of the matrix along each dimension (i.e., the matrix will be n x n x n). +# Returns: +# -------- +# matrix : np.array +# A 3D numpy array of shape (n, n, n) filled with the specified value. + +# """ +# temp_x = [[[value for k in range(n)] for j in range(n)] for i in range(n)] +# matrix = np.array(temp_x) +# return matrix + +# ### + +# def to60(matrix): +# """ +# Transform a given matrix into a specific 60x60x60 output by combining it with additional +# features and performing a series of transformations and calculations. + +# Parameters: +# ----------- +# matrix : np.array +# The input 3D matrix (likely N x 27 in shape) that will be transformed and processed. + +# Returns: +# -------- +# the606060_cell : np.array +# A binary numpy array representing the transformed 60x60x60 output. Values are set to 1 +# where the condition `< 0.9` is met, and 0 otherwise. +# """ +# the606060 = [] +# N = len(matrix) +# # r1_100=np.tile(r1, (N,1,1)) +# finished = (10 * (1 - matrix).reshape(N, 27, 1)) * 0.282 - 0.469 +# # print(finished.shape) +# # data_all=np.concatenate((r1_100,finished),axis=2) +# for l in range(N): +# r2 = finished[l] +# data0 = np.concatenate((r1, r2), axis=1) +# v = createv_2(data0, sizeofdata0, accu, 3) +# ov = oo + v +# the606060.append(ov) +# the606060_cell = np.asarray(the606060) +# the606060_cell = np.where(the606060_cell < 0.9, 1, 0) +# return the606060_cell + +# def createv_2(data, sizeofdata, nofv, dofv): +# """ +# Generate a 3D matrix `v` by iterating through the positions of the input data and constructing +# a volumetric array using `createunitofv`. The function processes data block-wise and concatenates +# the results along three dimensions to form the final matrix. + +# Parameters: +# ----------- +# data : np.array +# The input 3D data array, where each element represents some volumetric information that +# will be processed by `createunitofv`. +# sizeofdata : list or tuple +# A list or tuple of three integers representing the dimensions (size) of the `data`. +# `sizeofdata[0]`, `sizeofdata[1]`, and `sizeofdata[2]` correspond to the dimensions along +# the x, y, and z axes, respectively. + +# nofv : int +# The number of features or values to consider when constructing the volumetric array. +# dofv : int +# The degree of freedom or margin to be used for the volumetric array construction. + +# Returns: +# -------- +# v : np.array +# A 3D numpy array representing the combined volumetric data constructed by concatenating +# smaller units generated by `createunitofv`. The final result is formed by iterating over +# the 3D positions in the input `data`. +# """ +# v = [] +# for k in range(sizeofdata[2]): +# temp2 = [] +# for j in range(sizeofdata[1]): +# temp1 = [] +# for i in range(sizeofdata[0]): +# position = [i, j, k] +# varray = createunitofv(data, position, nofv, dofv) +# if i < 1: +# temp1 = varray +# else: +# temp1 = np.concatenate((temp1, varray), axis=0) +# if j < 1: +# temp2 = temp1 +# else: +# temp2 = np.concatenate((temp2, temp1), axis=1) +# if k < 1: +# v = temp2 +# else: +# v = np.concatenate((v, temp2), axis=2) +# return v + +# # def createunitofv(datainput, position, nofv, dofv): +# # """ +# # Generate a volumetric unit (3D matrix) by processing the neighboring values +# # around a given position in the input data. + +# # Parameters: +# # ----------- +# # datainput : np.array +# # The input 3D data array representing a volumetric dataset. + +# # position : list or tuple +# # A list or tuple of three integers representing the coordinates (x, y, z) of the position +# # in the input data from which the neighborhood will be extracted. + +# # nofv : int +# # The size or number of features used for the construction of the volumetric unit. + +# # dofv : int +# # The degree of freedom or margin used to define the size of the volumetric unit around the neighborhood. + +# # Returns: +# # -------- +# # unitofv : np.array +# # A 3D numpy array representing the volumetric unit generated around the input position. +# # This array is adjusted by filling in NaN values with interpolated values based on neighboring +# # valid data points. If the central neighborhood value is NaN, the output will be a NaN-filled +# # matrix. +# # """ +# # neibourhoods = findneighbour(datainput, position) +# # unitofv = np.ones((nofv - 2 * dofv, nofv - 2 * dofv, nofv - 2 * dofv)) + +# # if not np.isnan(neibourhoods[1, 1, 1]): +# # unitofv = unitofv * neibourhoods[1, 1, 1] +# # else: +# # unitofv = np.zeros((nofv, nofv, nofv)) +# # unitofv[:, :, :] = np.nan +# # return unitofv +# # if np.isnan(neibourhoods[2, 1, 1]): +# # neibourhoods[2, 1, 1] = neibourhoods[1, 1, 1] +# # if np.isnan(neibourhoods[0, 1, 1]): +# # neibourhoods[0, 1, 1] = neibourhoods[1, 1, 1] +# # if np.isnan(neibourhoods[1, 2, 1]): +# # neibourhoods[1, 2, 1] = neibourhoods[1, 1, 1] +# # if np.isnan(neibourhoods[1, 0, 1]): +# # neibourhoods[1, 0, 1] = neibourhoods[1, 1, 1] +# # if np.isnan(neibourhoods[1, 1, 2]): +# # neibourhoods[1, 1, 2] = neibourhoods[1, 1, 1] +# # if np.isnan(neibourhoods[1, 1, 0]): +# # neibourhoods[1, 1, 0] = neibourhoods[1, 1, 1] +# # if np.isnan(neibourhoods[2, 2, 1]): +# # neibourhoods[2, 2, 1] = (neibourhoods[2, 1, 1] + neibourhoods[1, 2, 1]) / 2 +# # if np.isnan(neibourhoods[2, 0, 1]): +# # neibourhoods[2, 0, 1] = (neibourhoods[2, 1, 1] + neibourhoods[1, 0, 1]) / 2 +# # if np.isnan(neibourhoods[0, 2, 1]): +# # neibourhoods[0, 2, 1] = (neibourhoods[0, 1, 1] + neibourhoods[1, 2, 1]) / 2 +# # if np.isnan(neibourhoods[0, 0, 1]): +# # neibourhoods[0, 0, 1] = (neibourhoods[0, 1, 1] + neibourhoods[1, 0, 1]) / 2 +# # if np.isnan(neibourhoods[2, 1, 2]): +# # neibourhoods[2, 1, 2] = (neibourhoods[2, 1, 1] + neibourhoods[1, 1, 2]) / 2 +# # if np.isnan(neibourhoods[2, 1, 0]): +# # neibourhoods[2, 1, 0] = (neibourhoods[2, 1, 1] + neibourhoods[1, 1, 0]) / 2 +# # if np.isnan(neibourhoods[0, 1, 2]): +# # neibourhoods[0, 1, 2] = (neibourhoods[0, 1, 1] + neibourhoods[1, 1, 2]) / 2 +# # if np.isnan(neibourhoods[0, 1, 0]): +# # neibourhoods[0, 1, 0] = (neibourhoods[0, 1, 1] + neibourhoods[1, 1, 0]) / 2 +# # if np.isnan(neibourhoods[1, 2, 2]): +# # neibourhoods[1, 2, 2] = (neibourhoods[1, 2, 1] + neibourhoods[1, 1, 2]) / 2 +# # if np.isnan(neibourhoods[1, 2, 0]): +# # neibourhoods[1, 2, 0] = (neibourhoods[1, 2, 1] + neibourhoods[1, 1, 0]) / 2 +# # if np.isnan(neibourhoods[1, 0, 2]): +# # neibourhoods[1, 0, 2] = (neibourhoods[1, 0, 1] + neibourhoods[1, 1, 2]) / 2 +# # if np.isnan(neibourhoods[1, 0, 0]): +# # neibourhoods[1, 0, 0] = (neibourhoods[1, 0, 1] + neibourhoods[1, 1, 0]) / 2 +# # if np.isnan(neibourhoods[0, 0, 0]): +# # neibourhoods[0, 0, 0] = (neibourhoods[0, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 0]) / 3 +# # if np.isnan(neibourhoods[2, 0, 0]): +# # neibourhoods[2, 0, 0] = (neibourhoods[2, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 0]) / 3 +# # if np.isnan(neibourhoods[0, 2, 0]): +# # neibourhoods[0, 2, 0] = (neibourhoods[0, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 0]) / 3 +# # if np.isnan(neibourhoods[0, 0, 2]): +# # neibourhoods[0, 0, 2] = (neibourhoods[0, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 2]) / 3 +# # if np.isnan(neibourhoods[0, 2, 2]): +# # neibourhoods[0, 2, 2] = (neibourhoods[0, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 2]) / 3 +# # if np.isnan(neibourhoods[2, 0, 2]): +# # neibourhoods[2, 0, 2] = (neibourhoods[2, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 2]) / 3 +# # if np.isnan(neibourhoods[2, 2, 0]): +# # neibourhoods[2, 2, 0] = (neibourhoods[2, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 0]) / 3 +# # if np.isnan(neibourhoods[2, 2, 2]): +# # neibourhoods[2, 2, 2] = (neibourhoods[2, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 2]) / 3 +# # for i in range(dofv): +# # nownumber = neibourhoods[1, 1, 1] + i * (neibourhoods - neibourhoods[1, 1, 1]) / (2 * dofv + 1) +# # temp = np.zeros((1, nofv - 2 * dofv + 2 * i, nofv - 2 * dofv + 2 * i)) +# # temp[:, :, :] = nownumber[2, 1, 1] +# # unitofv = np.concatenate((unitofv, temp), axis=0) # x+ +# # temp[:, :, :] = nownumber[0, 1, 1] +# # unitofv = np.concatenate((temp, unitofv), axis=0) # x- +# # temp = np.zeros((nofv - 2 * dofv + 2 * i + 2, 1, nofv - 2 * dofv + 2 * i)) +# # temp[:, :, :] = nownumber[1, 2, 1] +# # unitofv = np.concatenate((unitofv, temp), axis=1) # y+ +# # temp[:, :, :] = nownumber[1, 0, 1] +# # unitofv = np.concatenate((temp, unitofv), axis=1) # y- +# # temp = np.zeros((nofv - 2 * dofv + 2 * i + 2, nofv - 2 * dofv + 2 * i + 2, 1)) +# # temp[:, :, :] = nownumber[1, 1, 2] +# # unitofv = np.concatenate((unitofv, temp), axis=2) # z+ +# # temp[:, :, :] = nownumber[1, 1, 0] +# # unitofv = np.concatenate((temp, unitofv), axis=2) # z- +# # # Updating corner values +# # unitofv[[-1], [-1], :] = nownumber[2, 2, 1] # x+,y+ +# # unitofv[0, 0, :] = nownumber[0, 0, 1] # x-,y- +# # unitofv[[-1], 0, :] = nownumber[2, 0, 1] # x+,y- +# # unitofv[0, [-1], :] = nownumber[0, 2, 1] # x,y+ +# # unitofv[[-1], :, [-1]] = nownumber[2, 1, 2] +# # unitofv[0, :, 0] = nownumber[0, 1, 0] +# # unitofv[[-1], :, 0] = nownumber[2, 1, 0] +# # unitofv[0, :, [-1]] = nownumber[0, 1, 2] +# # unitofv[:, [-1], [-1]] = nownumber[1, 2, 2] +# # unitofv[:, 0, 0] = nownumber[1, 0, 0] +# # unitofv[:, [-1], 0] = nownumber[1, 2, 0] +# # unitofv[:, 0, [-1]] = nownumber[1, 0, 2] +# # unitofv[[-1], [-1], [-1]] = nownumber[2, 2, 2] +# # unitofv[0, [-1], [-1]] = nownumber[0, 2, 2] +# # unitofv[[-1], 0, [-1]] = nownumber[2, 0, 2] +# # unitofv[[-1], [-1], 0] = nownumber[2, 2, 0] +# # unitofv[[-1], 0, 0] = nownumber[2, 0, 0] +# # unitofv[0, [-1], 0] = nownumber[0, 2, 0] +# # unitofv[0, 0, [-1]] = nownumber[0, 0, 2] +# # unitofv[0, 0, 0] = nownumber[0, 0, 0] + +# # return unitofv + +# def handle_nan_values(neibourhoods): +# """ +# Handles NaN values in the neighboring data by interpolating them +# based on surrounding valid data points. + +# Parameters: +# ----------- +# neibourhoods : np.array +# A 3x3x3 array representing neighboring data points around a position. + +# Returns: +# -------- +# neibourhoods : np.array +# The neighboring data array with NaN values replaced by interpolated values. +# """ +# if np.isnan(neibourhoods[2, 1, 1]): +# neibourhoods[2, 1, 1] = neibourhoods[1, 1, 1] +# if np.isnan(neibourhoods[0, 1, 1]): +# neibourhoods[0, 1, 1] = neibourhoods[1, 1, 1] +# if np.isnan(neibourhoods[1, 2, 1]): +# neibourhoods[1, 2, 1] = neibourhoods[1, 1, 1] +# if np.isnan(neibourhoods[1, 0, 1]): +# neibourhoods[1, 0, 1] = neibourhoods[1, 1, 1] +# if np.isnan(neibourhoods[1, 1, 2]): +# neibourhoods[1, 1, 2] = neibourhoods[1, 1, 1] +# if np.isnan(neibourhoods[1, 1, 0]): +# neibourhoods[1, 1, 0] = neibourhoods[1, 1, 1] +# if np.isnan(neibourhoods[2, 2, 1]): +# neibourhoods[2, 2, 1] = (neibourhoods[2, 1, 1] + neibourhoods[1, 2, 1]) / 2 +# if np.isnan(neibourhoods[2, 0, 1]): +# neibourhoods[2, 0, 1] = (neibourhoods[2, 1, 1] + neibourhoods[1, 0, 1]) / 2 +# if np.isnan(neibourhoods[0, 2, 1]): +# neibourhoods[0, 2, 1] = (neibourhoods[0, 1, 1] + neibourhoods[1, 2, 1]) / 2 +# if np.isnan(neibourhoods[0, 0, 1]): +# neibourhoods[0, 0, 1] = (neibourhoods[0, 1, 1] + neibourhoods[1, 0, 1]) / 2 +# if np.isnan(neibourhoods[2, 1, 2]): +# neibourhoods[2, 1, 2] = (neibourhoods[2, 1, 1] + neibourhoods[1, 1, 2]) / 2 +# if np.isnan(neibourhoods[2, 1, 0]): +# neibourhoods[2, 1, 0] = (neibourhoods[2, 1, 1] + neibourhoods[1, 1, 0]) / 2 +# if np.isnan(neibourhoods[0, 1, 2]): +# neibourhoods[0, 1, 2] = (neibourhoods[0, 1, 1] + neibourhoods[1, 1, 2]) / 2 +# if np.isnan(neibourhoods[0, 1, 0]): +# neibourhoods[0, 1, 0] = (neibourhoods[0, 1, 1] + neibourhoods[1, 1, 0]) / 2 +# if np.isnan(neibourhoods[1, 2, 2]): +# neibourhoods[1, 2, 2] = (neibourhoods[1, 2, 1] + neibourhoods[1, 1, 2]) / 2 +# if np.isnan(neibourhoods[1, 2, 0]): +# neibourhoods[1, 2, 0] = (neibourhoods[1, 2, 1] + neibourhoods[1, 1, 0]) / 2 +# if np.isnan(neibourhoods[1, 0, 2]): +# neibourhoods[1, 0, 2] = (neibourhoods[1, 0, 1] + neibourhoods[1, 1, 2]) / 2 +# if np.isnan(neibourhoods[1, 0, 0]): +# neibourhoods[1, 0, 0] = (neibourhoods[1, 0, 1] + neibourhoods[1, 1, 0]) / 2 +# if np.isnan(neibourhoods[0, 0, 0]): +# neibourhoods[0, 0, 0] = (neibourhoods[0, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 0]) / 3 +# if np.isnan(neibourhoods[2, 0, 0]): +# neibourhoods[2, 0, 0] = (neibourhoods[2, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 0]) / 3 +# if np.isnan(neibourhoods[0, 2, 0]): +# neibourhoods[0, 2, 0] = (neibourhoods[0, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 0]) / 3 +# if np.isnan(neibourhoods[0, 0, 2]): +# neibourhoods[0, 0, 2] = (neibourhoods[0, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 2]) / 3 +# if np.isnan(neibourhoods[0, 2, 2]): +# neibourhoods[0, 2, 2] = (neibourhoods[0, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 2]) / 3 +# if np.isnan(neibourhoods[2, 0, 2]): +# neibourhoods[2, 0, 2] = (neibourhoods[2, 1, 1] + neibourhoods[1, 0, 1] + neibourhoods[1, 1, 2]) / 3 +# if np.isnan(neibourhoods[2, 2, 0]): +# neibourhoods[2, 2, 0] = (neibourhoods[2, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 0]) / 3 +# if np.isnan(neibourhoods[2, 2, 2]): +# neibourhoods[2, 2, 2] = (neibourhoods[2, 1, 1] + neibourhoods[1, 2, 1] + neibourhoods[1, 1, 2]) / 3 + +# return neibourhoods + +# def fill_unit_volume(neibourhoods, nofv, dofv): +# """ +# Fills the volumetric unit using interpolated neighboring values. + +# Parameters: +# ----------- +# neibourhoods : np.array +# A 3x3x3 array representing neighboring data points around a position. + +# nofv : int +# The size or number of features used for the construction of the volumetric unit. + +# dofv : int +# The degree of freedom or margin used to define the size of the volumetric unit. + +# Returns: +# -------- +# unitofv : np.array +# A volumetric unit generated by filling with values based on the neighborhood data. +# """ +# for i in range(dofv): +# nownumber = neibourhoods[1, 1, 1] + i * (neibourhoods - neibourhoods[1, 1, 1]) / (2 * dofv + 1) +# temp = np.zeros((1, nofv - 2 * dofv + 2 * i, nofv - 2 * dofv + 2 * i)) +# temp[:, :, :] = nownumber[2, 1, 1] +# unitofv = np.concatenate((unitofv, temp), axis=0) # x+ +# temp[:, :, :] = nownumber[0, 1, 1] +# unitofv = np.concatenate((temp, unitofv), axis=0) # x- +# temp = np.zeros((nofv - 2 * dofv + 2 * i + 2, 1, nofv - 2 * dofv + 2 * i)) +# temp[:, :, :] = nownumber[1, 2, 1] +# unitofv = np.concatenate((unitofv, temp), axis=1) # y+ +# temp[:, :, :] = nownumber[1, 0, 1] +# unitofv = np.concatenate((temp, unitofv), axis=1) # y- +# temp = np.zeros((nofv - 2 * dofv + 2 * i + 2, nofv - 2 * dofv + 2 * i + 2, 1)) +# temp[:, :, :] = nownumber[1, 1, 2] +# unitofv = np.concatenate((unitofv, temp), axis=2) # z+ +# temp[:, :, :] = nownumber[1, 1, 0] +# unitofv = np.concatenate((temp, unitofv), axis=2) # z- +# # Updating corner values +# unitofv[[-1], [-1], :] = nownumber[2, 2, 1] # x+,y+ +# unitofv[0, 0, :] = nownumber[0, 0, 1] # x-,y- +# unitofv[[-1], 0, :] = nownumber[2, 0, 1] # x+,y- +# unitofv[0, [-1], :] = nownumber[0, 2, 1] # x,y+ +# unitofv[[-1], :, [-1]] = nownumber[2, 1, 2] +# unitofv[0, :, 0] = nownumber[0, 1, 0] +# unitofv[[-1], :, 0] = nownumber[2, 1, 0] +# unitofv[0, :, [-1]] = nownumber[0, 1, 2] +# unitofv[:, [-1], [-1]] = nownumber[1, 2, 2] +# unitofv[:, 0, 0] = nownumber[1, 0, 0] +# unitofv[:, [-1], 0] = nownumber[1, 2, 0] +# unitofv[:, 0, [-1]] = nownumber[1, 0, 2] +# unitofv[[-1], [-1], [-1]] = nownumber[2, 2, 2] +# unitofv[0, [-1], [-1]] = nownumber[0, 2, 2] +# unitofv[[-1], 0, [-1]] = nownumber[2, 0, 2] +# unitofv[[-1], [-1], 0] = nownumber[2, 2, 0] +# unitofv[[-1], 0, 0] = nownumber[2, 0, 0] +# unitofv[0, [-1], 0] = nownumber[0, 2, 0] +# unitofv[0, 0, [-1]] = nownumber[0, 0, 2] +# unitofv[0, 0, 0] = nownumber[0, 0, 0] + +# return unitofv + +# def createunitofv(datainput, position, nofv, dofv): +# """ +# Generate a volumetric unit (3D matrix) by processing the neighboring values +# around a given position in the input data. + +# Parameters: +# ----------- +# datainput : np.array +# The input 3D data array representing a volumetric dataset. + +# position : list or tuple +# A list or tuple of three integers representing the coordinates (x, y, z) of the position +# in the input data from which the neighborhood will be extracted. + +# nofv : int +# The size or number of features used for the construction of the volumetric unit. + +# dofv : int +# The degree of freedom or margin used to define the size of the volumetric unit around the neighborhood. + +# Returns: +# -------- +# unitofv : np.array +# A 3D numpy array representing the volumetric unit generated around the input position. +# """ +# neibourhoods = findneighbour(datainput, position) +# unitofv = np.ones((nofv - 2 * dofv, nofv - 2 * dofv, nofv - 2 * dofv)) + +# if not np.isnan(neibourhoods[1, 1, 1]): +# unitofv = unitofv * neibourhoods[1, 1, 1] +# else: +# unitofv = np.zeros((nofv, nofv, nofv)) +# unitofv[:, :, :] = np.nan +# return unitofv + +# # Handle NaN values in the neighboring data +# neibourhoods = handle_nan_values(neibourhoods) + +# # Generate the volumetric unit based on neighborhood values and dofv +# unitofv = fill_unit_volume(neibourhoods, nofv, dofv) + +# return unitofv + + + + +# def findneighbour(inputdata, position): +# """ +# Find the neighborhood values around a given position in a 3D dataset. + +# Parameters: +# ----------- +# inputdata : np.array +# A 2D numpy array where each row represents a data point in the 3D space with the format +# [x, y, z, value], where `x`, `y`, and `z` are the coordinates and `value` is the associated value. +# position : list or tuple +# A list or tuple representing the coordinates [x, y, z] of the target position +# where the neighborhood is to be found. + +# Returns: +# -------- +# neighbourhoods : np.array +# A 3x3x3 numpy array where each element corresponds to the value of a neighbor +# within the 1-unit radius around the given position. If a neighboring point doesn't exist, +# the corresponding element remains NaN. +# """ +# neighbourhoods = np.zeros((3, 3, 3)) +# neighbourhoods[:, :, :] = np.nan + +# r = len(inputdata) +# flag = 0 +# for i in range(r): +# if inputdata[i, 0] == position[0] and inputdata[i, 1] == position[1] and inputdata[i, 2] == position[2]: +# flag = 1 + +# if flag != 0: +# for i in range(r): +# dertax = inputdata[i, 0] - position[0] +# dertay = inputdata[i, 1] - position[1] +# dertaz = inputdata[i, 2] - position[2] + +# if abs(dertax) <= 1 and abs(dertay) <= 1 and abs(dertaz) <= 1: +# neighbourhoods[int(dertax + 1), int(dertay + 1), int(dertaz + 1)] = inputdata[i, 3] + +# return neighbourhoods + +# def rej_sampling(gm, n_samples, target): +# """ +# Perform rejection sampling using a generative model (gm) to sample structures that meet a target yield range. + +# Parameters: +# ----------- +# gm : object +# The generative model used to sample the latent space. It should have a `sample` method that generates latent +# variables. +# n_samples : int +# The number of samples to be drawn from the generative model. + +# target : float +# The target value for the `E` variable. The function filters samples based on this target value within +# a specified range (±5%). + +# Returns: +# -------- +# sample_s_final : np.array +# A numpy array containing the final valid samples (structures) that passed the rejection sampling. +# sample_y_final : pd.DataFrame +# A pandas DataFrame containing the corresponding yield (`Y`) values for the valid samples. +# """ +# target_upper = 1.05 * target +# target_lower = 0.95 * target + +# # y_total = data['yield'] +# e_data = data_e['E'][data_e['E'] < target_upper] +# e_data = e_data[e_data > target_lower] +# print(e_data) + +# if len(e_data) == 0: +# y_max = 24 +# else: +# y_new = data['yield'].iloc[e_data.index] +# y_max_idx = np.argmax(y_new) +# y_max = y_new.iloc[y_max_idx] + +# print('the max yield for E = {} is {}, sampling start!'.format(target, y_max)) + +# batchsize = b_size +# sample_z = gm.sample(n_samples)[0] +# sample_target = [] +# sample_y = [] + +# sample_target = rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target) + +# try: +# sample_s_final = [item for sublist in sample_target for item in sublist] +# sample_s_final = np.asarray(sample_s_final) +# sample_y_final = [item for sublist in sample_y for item in sublist] +# sample_y_final = pd.DataFrame(sample_y_final) +# sample_y_final.columns = ['Y'] +# print('Size of target sample is {}'.format(sample_s_final.shape)) +# except Exception as e: +# print('No valid structure!') +# sample_y_final = [] +# sample_s_final = [] + +# return sample_s_final, sample_y_final + +# def rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target): +# """ +# Perform rejection sampling and decode latent variables into valid structures based on a target yield range. + +# Parameters: +# ----------- +# n_samples : int +# The total number of latent variables to sample and decode. +# batchsize : int +# The size of each batch to process during decoding. + +# sample_z : np.array +# The latent variables sampled from the generative model. The array shape is typically (n_samples, latent_dim). + +# y_max : float +# The maximum yield value calculated based on the target range of `E` values. This is used for rejection sampling. + +# sample_target : list +# A list where the valid structures (samples that pass rejection sampling) are appended. + +# Returns: +# -------- +# None +# This function modifies `sample_target` in place by appending valid structures. +# """ +# print('Decoding started...') +# for i in tqdm(range(0, n_samples, batchsize)): +# temp_s0 = structure(sample_z[i:i + batchsize], decoder) +# temp_s3 = [] + +# for j in range(len(temp_s0)): +# temp_x = density(temp_s0[j]) +# temp_s3.append(temp_x) + +# temp_s = np.asarray(temp_s3) +# temp_s3 = np.asarray(temp_s3) + +# temp_s60 = to60(temp_s3) +# temp_e = ensemble_predict_e(temp_s60) + +# try: +# e_target = temp_e['E'][temp_e['E'] < target_upper] +# e_target = e_target[e_target > target_lower] + +# sample_ = temp_s[e_target.index] +# sample_60 = np.asarray(sample_) +# sample_60 = to60(sample_60) + +# uniform_rand = np.random.uniform(size=len(sample_)) +# uniform_y = up * y_max + uniform_rand * (1 - up) * y_max +# temp_y = ensemble_predict_y(sample_60).values + +# accepted = uniform_y.reshape(-1, 1) < temp_y.reshape(-1, 1) +# acc_idx = accepted.reshape(-1) +# acc_sample_s = sample_[acc_idx] +# acc_sample_y = temp_y[acc_idx] + +# if len(acc_sample_s) > 0: +# print('Structure sampled!') +# sample_target.append(acc_sample_s) +# sample_y.append(acc_sample_y) + +# except Exception as e: +# continue + +# print('decoding completed!') +# return sample_target + +# def structure(x1, decoder): +# """ +# Process latent variables through a decoder model to generate 3D structures. + +# Parameters: +# ----------- +# x1 : np.array +# The latent variable input to be decoded. It is typically of shape (n_samples, latent_dim). +# decoder : MindSpore network +# The decoder model that takes the latent variables and converts them into a reconstructed +# 3D structure. It expects a certain number of input channels (e.g., 128 channels). + +# Returns: +# -------- +# new_x1 : np.array +# The decoded 3D structures with the output values rounded to one decimal place. +# The array is of shape (n_samples, 3D structure dimensions). + +# """ +# # Assuming that the decoder expects 128 channels, you may need to modify the input here +# # Expand dimensions as required +# x1 = np.expand_dims(x1, axis=1) +# x1 = np.expand_dims(x1, axis=1) +# x1 = np.expand_dims(x1, axis=1) + +# # If the input has only 1 channel, you need to ensure it matches the expected number of channels +# # For example, if the decoder expects 128 channels: +# if x1.shape[1] != 128: +# x1 = np.tile(x1, (1, 128, 1, 1, 1)) # Repeat the channels to match expected input + +# x1 = Tensor(x1, ms.float32) + +# # Pass through the decoder +# recon = decoder(x1) + +# # Convert output back to numpy array +# new_x = recon.asnumpy() +# new_x1 = np.round(new_x, 1) +# return new_x1 + +# def ensemble_predict_e(ss): +# """ +# Predicts the 'E' value from the input tensor using a pre-trained 3D CNN model. +# Parameters: +# ----------- +# S : numpy.ndarray +# Input tensor data, which will be converted to a MindSpore Tensor for prediction. +# Returns: +# -------- +# E : pandas.DataFrame +# A DataFrame containing the predicted 'E' values with a single column named 'E'. +# """ +# model_path = "model/3dCNN_E-5_1.ckpt" +# model_e = YourMindSporeModelE() # Replace with your MindSpore model definition +# param_dict = ms.load_checkpoint(model_path) +# ms.load_param_into_net(model_e, param_dict) +# model = Model(model_e) + +# ss = Tensor(ss, ms.float32) +# e = model.predict(ss).asnumpy() +# e = pd.DataFrame(e) +# e.columns = ['E'] +# return e + +# def ensemble_predict_y(ss): +# """ +# Predicts the 'yield' value from the input tensor using a pre-trained 3D CNN model. + +# Parameters: +# ----------- +# S : numpy.ndarray +# Input tensor data, which will be converted to a MindSpore Tensor for prediction. +# Returns: +# -------- +# Y : pandas.DataFrame +# A DataFrame containing the predicted 'yield' values with a single column named 'yield'. +# """ +# model_path = "model/3dCNN_Y-5_3.ckpt" +# model_y = YourMindSporeModelY() # Replace with your MindSpore model definition +# param_dict = ms.load_checkpoint(model_path) +# ms.load_param_into_net(model_y, param_dict) +# model = Model(model_y) + +# ss = Tensor(ss, ms.float32) +# y = model.predict(ss).asnumpy() +# y = pd.DataFrame(y) +# y.columns = ['yield'] +# return y + +# ######## Setup +# # Choose a elastic modulus target, such as target = 2500 MPa +# target = 2500 +# target_upper = 1.05 * target +# target_lower = 0.95 * target +# sam_ = 1000000 # Sampling number +# up = 0.8 +# b_size = 2000 +# n_size = 6 +# n_accu = 60 +# pi = 3.14159265358979323846264 +# xxx = (1 / 2) * 2 * pi +# sizeofdata0 = [3, 3, 3] +# accu = 20 +# x_axis, y_axis, z_axis = np.linspace(n_size / (n_accu * 2), n_size - n_size / (n_accu * 2), n_accu), \ +# np.linspace(n_size / (n_accu * 2), n_size - n_size / (n_accu * 2), n_accu), np.linspace(n_size / (n_accu * 2), \ +# n_size - n_size / (n_accu * 2), n_accu) +# x, y, z = np.meshgrid(x_axis, y_axis, z_axis) + + +# r1 = np.zeros((27, 3)) +# for a in range(3): +# for b in range(3): +# for c in range(3): +# r1[9*a+3*b+c, 0] = a +# r1[9*a+3*b+c, 1] = b + +# oo = np.sin(pi*x) * np.cos(pi*y) + np.sin(pi*y) * np.cos(pi*z) + np.sin(pi*z) * np.cos(pi*x) + +# # Import models +# # Model architecture + +# # Create Model +# autoencoder = AutoEncoder() + +# # Load the checkpoint +# param_dict = ms.load_checkpoint('model/3D_CAE_model-5_222.ckpt') +# # Load parameters into the model +# ms.load_param_into_net(autoencoder, param_dict) + +# # Import data +# matrix = np.load("data/Matrix12.npy", allow_pickle=True) +# data_e = pd.read_csv("data/E.csv") +# e_total = data_e['E'] +# data = pd.read_csv("data/yield.csv") +# i = len(data) +# X = matrix.reshape(i, 12, 12, 12, 1) +# X = Tensor(X, ms.float32) + +# # create the encoder and decoder models from the autoencoder. +# # Instantiate the deceder model +# decoder = Decoder(autoencoder) +# # Instantiate the encoder model +# encoder = Encoder(autoencoder) + +# # embedding the input data using the encoder model and +# # performing Gaussian Mixture Model (GMM) fitting and evaluation +# xx = X.transpose(0, 4, 1, 2, 3) # Change from (batch_size, depth, height, width, channels) to (batch_size, channels, depth, height, width) +# embed = encoder(xx) +# embed_all = embed[:, 0].asnumpy() # Convert Tensor to NumPy array in MindSpore +# embed_all = embed_all[:, 0] +# embed_all = embed_all[:, 0] + +# # Average negative log likelihood +# scores = [] +# for i in range(1, 12): +# gm = GaussianMixture(n_components=i, random_state=0, init_params='kmeans').fit(embed_all) +# avg_neg_log_likelihood = -1 * gm.score(embed_all) +# print('Average negative log likelihood:', avg_neg_log_likelihood) +# scores.append(avg_neg_log_likelihood) + +# # Plot the results +# plt.figure() +# plt.scatter(range(1, 12), scores) +# plt.plot(range(1, 12), scores) +# plt.xlabel('Number of Components') +# plt.ylabel('Average Negative Log Likelihood') +# plt.title('Gaussian Mixture Model - Log Likelihood') + +# # Fit the final model with 4 components and print the log likelihood +# gm = GaussianMixture(n_components=4, random_state=0, init_params='kmeans').fit(embed_all) +# final_avg_neg_log_likelihood = -1 * gm.score(embed_all) +# print('Average negative log likelihood (n_components=4):', final_avg_neg_log_likelihood) + +# ###### + +# matrix = matrix.reshape(len(matrix), 12, 12, 12) +# input_ = [] +# for i in range(len(matrix)): +# temp_x = matrix[i] +# xx = density(temp_x) +# input_.append(xx) +# matrix2 = np.array(input_) +# matrix60 = to60(matrix2) +# mean_try = np.mean(matrix60.reshape(len(matrix60), 60*60*60), axis=1) +# print(mean_try) + +# ######### main +# # resapmling +# sample_s, sample_y = rej_sampling(gm, n_samples=sam_, target=target) +# if len(sample_s) > 1000: +# top = 1000 +# ind = np.argpartition(sample_y, -top)[-top:] +# sample_s = sample_s[ind] + +# sample_y.columns = ['yield'] # Corresponding yield strength +# matrix333 = sample_s.reshape(len(sample_s), 27) +# matrix_x = np.unique(matrix333, axis=0) + +# for i in range(27): +# matrix_x = matrix_x[(matrix_x[:, i] > 0) & (matrix_x[:, i] < 0.9)] + +# matrix_x = matrix_x.reshape(len(matrix_x), 3, 3, 3, 1) +# X60 = to60(matrix_x) + +# # Predictions using the ensemble models +# pred_e = ensemble_predict_e(X60) +# pred_y = ensemble_predict_y(X60) + +# # Convert the predictions to NumPy arrays +# pred_e = np.asarray(pred_e) +# pred_y = np.asarray(pred_y) +# pred_y = pred_y.reshape(-1) + +# # Pick the matrices with the highest yield strength +# top = 20 +# ind = np.argpartition(pred_y, -top)[-top:] +# matrix_20 = matrix_x[ind] # Top 20 porosity matrices +# Y_20 = pred_y[ind] # Corresponding yield strength +# E_20 = pred_e[ind] # Corresponding elastic modulus + +# # Save top 20 porosity matrices and use Matlab to generate STL file for finite element simulation +# np.save('results/PorosityMatrices_top20.npy', matrix_20, allow_pickle=True) + +# print('Sampling completed!') + +# # Display results in a table +# table = PrettyTable(['No.', 'Elastic modulus (MPa)', 'Yield strength (MPa)']) +# for i in range(len(E_20)): +# table.add_row([i + 1, E_20[i][0], Y_20[i]]) + +# print(table) + +# # Filtering, Reshaping +# if len(sample_s) > 1000: +# top = 1000 +# ind = np.argpartition(sample_y, -top)[-top:] +# sample_s = sample_s[ind] + +# sample_y.columns = ['yield'] # Corresponding yield strength +# matrix333 = sample_s.reshape(len(sample_s), 27) +# matrix_x = np.unique(matrix333, axis=0) + +# for i in range(27): +# matrix_x = matrix_x[(matrix_x[:, i] > 0) & (matrix_x[:, i] < 0.9)] + +# matrix_x = matrix_x.reshape(len(matrix_x), 3, 3, 3, 1) +# X60 = to60(matrix_x) + +# # Predictions using the ensemble models +# pred_e = ensemble_predict_e(X60) +# pred_y = ensemble_predict_y(X60) + +# # Convert the predictions to NumPy arrays +# pred_e = np.asarray(pred_e) +# pred_y = np.asarray(pred_y) +# pred_y = pred_y.reshape(-1) + +# # Pick the matrices with the highest yield strength +# top = 20 +# ind = np.argpartition(pred_y, -top)[-top:] +# matrix_20 = matrix_x[ind] # Top 20 porosity matrices +# Y_20 = pred_y[ind] # Corresponding yield strength +# E_20 = pred_e[ind] # Corresponding elastic modulus + +# # Save the top 20 porosity matrices and use Matlab to generate STL file for finite element simulation +# np.save('results/PorosityMatrices_top20.npy', matrix_20, allow_pickle=True) + +# print('Sampling completed!') + +# # Display results in a table +# table = PrettyTable(['No.', 'Elastic modulus (MPa)', 'Yield strength (MPa)']) +# for i in range(len(E_20)): +# table.add_row([i + 1, E_20[i][0], Y_20[i]]) + +# print(table) diff --git a/SciAI/sciai/model/gad_mall/src/model/.keep b/SciAI/sciai/model/gad_mall/src/model/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SciAI/sciai/model/gad_mall/src/requirements.txt b/SciAI/sciai/model/gad_mall/src/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..b3ea5ba1e7c9a26b77f108b89e8b8b8ee55d8b41 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/requirements.txt @@ -0,0 +1,6 @@ +mindspore==2.2.14 +numpy==1.23.5 +scipy==1.13.1 +pandas==2.2.2 +matplotlib==3.9.1 +tqdm==4.66.5 \ No newline at end of file diff --git a/SciAI/sciai/model/gad_mall/src/results/.keep b/SciAI/sciai/model/gad_mall/src/results/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/SciAI/sciai/model/gad_mall/src/run_GAD_MALL.sh b/SciAI/sciai/model/gad_mall/src/run_GAD_MALL.sh new file mode 100644 index 0000000000000000000000000000000000000000..18e7e573db811cfba95207b1e46db545a59cb0eb --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/run_GAD_MALL.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -ex + +# This is the master script for the capsule. When you click "Reproducible Run", the code in this file will execute. +python3.9 -u 3D_CNN.py +python3.9 -u 3D_CAE.py +python3.9 -u GAD_MALL_Active_learning.py + +