From d0fd4a2a9e4a1567b8fed4f8a344cbf129dd60af Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:26:34 +0000 Subject: [PATCH 01/31] Create gad_mall --- SciAI/sciai/model/gad_mall/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 SciAI/sciai/model/gad_mall/.keep diff --git a/SciAI/sciai/model/gad_mall/.keep b/SciAI/sciai/model/gad_mall/.keep new file mode 100644 index 000000000..e69de29bb -- Gitee From 1c4a8600f47fb75a35b3b2d95d25f234818f33c0 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:27:30 +0000 Subject: [PATCH 02/31] Update README files Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/README.md | 169 +++++++++++++++++++++++ SciAI/sciai/model/gad_mall/README_CN.md | 170 ++++++++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 SciAI/sciai/model/gad_mall/README.md create mode 100644 SciAI/sciai/model/gad_mall/README_CN.md diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md new file mode 100644 index 000000000..0ed5462ad --- /dev/null +++ b/SciAI/sciai/model/gad_mall/README.md @@ -0,0 +1,169 @@ +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: + ```bash + python3.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) + 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 000000000..d3885acff --- /dev/null +++ b/SciAI/sciai/model/gad_mall/README_CN.md @@ -0,0 +1,170 @@ +[English](./README.md) | 简体中文 + +## 目录 + +- [目录](#目录) +- [GAD-MALL 描述](#gad-mall-描述) + - [主要特性](#主要特性) +- [数据集](#数据集) +- [环境要求](#环境要求) +- [快速开始](#快速开始) + - [快速开始](#快速开始-1) + - [管道流程](#管道流程) +- [脚本说明](#脚本说明) + - [脚本和示例代码](#脚本和示例代码) + - [项目文件说明](#项目文件说明) +- [更多信息](#更多信息) + + +## GAD-MALL 描述 + +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 + - 安装依赖库可以通过以下命令: + ```bash + 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) + -- Gitee From cc78e25d8c0f16deaa47cf4c4512ab978aa4a40e Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:29:32 +0000 Subject: [PATCH 03/31] Create src --- SciAI/sciai/model/gad_mall/src/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 SciAI/sciai/model/gad_mall/src/.keep diff --git a/SciAI/sciai/model/gad_mall/src/.keep b/SciAI/sciai/model/gad_mall/src/.keep new file mode 100644 index 000000000..e69de29bb -- Gitee From bd85e2be2fb298008f01425265128c9783a4ce84 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:29:41 +0000 Subject: [PATCH 04/31] Create data --- SciAI/sciai/model/gad_mall/src/data/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 SciAI/sciai/model/gad_mall/src/data/.keep 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 000000000..e69de29bb -- Gitee From 85d076d1ce4f1bcd9d52e7aeea02cf7283ded91c Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:29:57 +0000 Subject: [PATCH 05/31] Create model --- SciAI/sciai/model/gad_mall/src/model/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 SciAI/sciai/model/gad_mall/src/model/.keep 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 000000000..e69de29bb -- Gitee From f9d1557c14160720a3bb01eb7827d756f918f326 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:30:12 +0000 Subject: [PATCH 06/31] Create results --- SciAI/sciai/model/gad_mall/src/results/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 SciAI/sciai/model/gad_mall/src/results/.keep 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 000000000..e69de29bb -- Gitee From 5fe217ada4429b355e39765839601f4678070fc8 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:30:56 +0000 Subject: [PATCH 07/31] upload models Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py | 134 ++++ SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py | 136 +++++ .../src/GAD_MALL_Active_learning_ms.py | 572 ++++++++++++++++++ 3 files changed, 842 insertions(+) create mode 100644 SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py create mode 100644 SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py create mode 100644 SciAI/sciai/model/gad_mall/src/GAD_MALL_Active_learning_ms.py diff --git a/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py b/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py new file mode 100644 index 000000000..efbf4418d --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py @@ -0,0 +1,134 @@ +import numpy as np +from sklearn.model_selection import train_test_split +from mindspore import nn, Tensor, context +from mindspore.train.callback import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau +from mindspore.common.initializer import Normal +from mindspore.train import Model +import mindspore.dataset as ds +import mindspore.ops as ops +from mindspore.train.callback import CheckpointConfig, LossMonitor + +# 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): + 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 +# 加进度条 +from mindspore.train.callback import Callback +from tqdm import tqdm + +class TQDMProgressBar(Callback): + 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): + 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): + self.progress_bar.update(1) + + def on_train_epoch_end(self, run_context): + self.progress_bar.close() + +# Number of steps per epoch +total_steps_per_epoch = train_data.get_dataset_size() +# Total number of epochs +total_epochs = 10 +# Initialize the progress bar callback +tqdm_callback = TQDMProgressBar(total_steps_per_epoch=total_steps_per_epoch, total_epochs=total_epochs) + + + +# Train the model with progress bar +model.train(total_epochs, train_data, callbacks=[es, mc, re, ls, tqdm_callback], dataset_sink_mode=False) diff --git a/SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py b/SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py new file mode 100644 index 000000000..196c9fea5 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py @@ -0,0 +1,136 @@ +import numpy as np +import pandas as pd +from mindspore import nn, Tensor, context +from mindspore.train.callback import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau, 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): + 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): + 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): + 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): + 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): + self.progress_bar.update(1) + run_context.original_args() # Suppress extra output + + def on_train_epoch_end(self, run_context): + 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 +total_epochs = 5 + +# Initialize the progress bar callback +tqdm_callback = TQDMProgressBar(total_steps_per_epoch=total_steps_per_epoch, total_epochs=total_epochs) + +# Initialize and train the model +net = Model(network=model, loss_fn=loss_fn, optimizer=optimizer, metrics={"mae": MAE()}) +net.train(total_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=total_epochs) + +net2 = Model(network=model2, loss_fn=loss_fn, optimizer=optimizer2, metrics={"mae": MAE()}) +net2.train(total_epochs, train_dataset2, callbacks=[ckpoint_cb2, es, ls, tqdm_callback2], dataset_sink_mode=False) + 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 000000000..81aaa8a60 --- /dev/null +++ b/SciAI/sciai/model/gad_mall/src/GAD_MALL_Active_learning_ms.py @@ -0,0 +1,572 @@ +from sklearn.mixture import GaussianMixture +import mindspore as ms +from mindspore import nn +from mindspore import Tensor +from mindspore import context +from mindspore import ops +from mindspore.nn import Cell +from mindspore.dataset import GeneratorDataset +from mindspore.train.callback import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau +from mindspore.train import Model +from mindspore.common.initializer import XavierUniform +from mindspore.dataset import vision, transforms +import mindspore.dataset as ds +from mindspore.train.serialization import load_checkpoint, load_param_into_net ## + +from sklearn.model_selection import train_test_split +import numpy as np +import matplotlib.pyplot as plt +from prettytable import PrettyTable +import pandas as pd +from prettytable import PrettyTable +from tqdm import tqdm +# import mindspore.dataset as ds + +# 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): + 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): + 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): + 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: + 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: + 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): + 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): + 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,positon,nofv,dofv): + neibourhoods=findneighbour(datainput,positon) + 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- + 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 findneighbour(inputdata,position): + 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 rejSampling(gm, n_samples, target): + target_upper=1.05*target + target_lower=0.95*target + Y_total = data['yield'] + E_data=dataE['E'][dataE['E']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=[] + + rejSampling_decode(n_samples, batchsize,sample_z) + + 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: + print('no valid structure!') + sample_Y_final=[] + sample_S_final=[] + return sample_S_final, sample_Y_final + +def rejSampling_decode(n_samples, batchsize,sample_z): + print('decoding started...') + for i in tqdm(range(0, n_samples, batchsize)): + temp_s0=Structure(sample_z[i:i+batchsize],decoder) + temp_s3=[] + for i in range(len(temp_s0)): + temp_x=density(temp_s0[i]) + temp_s3.append(temp_x) + temp_s=np.asarray(temp_s3) + temp_s3=np.asarray(temp_s3) + temp_s60=To60(temp_s3) + temp_E=[] + temp_E=ensemble_predict_E(temp_s60) + try: + E_target=temp_E['E'][temp_E['E']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('strcuture sampled!') + sample_target.append(acc_sample_S) + sample_Y.append(acc_sample_Y) + except: + continue + print('decoding completed!') + return + +def Structure(x1, decoder): + # Assuming that the decoder expects 128 channels, you may need to modify the input here + x1 = np.expand_dims(x1, axis=1) # Expand dimensions as required + 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(S): + 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) + + S = Tensor(S, ms.float32) + E = model.predict(S).asnumpy() + E = pd.DataFrame(E) + E.columns = ['E'] + return E + +def ensemble_predict_Y(S): + 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) + + S = Tensor(S, ms.float32) + Y = model.predict(S).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) +dataE = pd.read_csv("data/E.csv") +E_total = dataE['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 = rejSampling(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) -- Gitee From 24caa7591c632ee66876be72dd2d3303c9da1d7f Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:31:53 +0000 Subject: [PATCH 08/31] upload requirement.txt and training bash file Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/requirements.txt | 6 ++++++ SciAI/sciai/model/gad_mall/src/run_GAD_MALL.sh | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 SciAI/sciai/model/gad_mall/src/requirements.txt create mode 100644 SciAI/sciai/model/gad_mall/src/run_GAD_MALL.sh 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 000000000..b3ea5ba1e --- /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/run_GAD_MALL.sh b/SciAI/sciai/model/gad_mall/src/run_GAD_MALL.sh new file mode 100644 index 000000000..18e7e573d --- /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 + + -- Gitee From ac660ec368da9ef498f943375fa4ce27fb8322df Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 3 Sep 2024 13:34:32 +0000 Subject: [PATCH 09/31] upload dataset Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/data/E.csv | 76 ++++++++++++++++++ .../model/gad_mall/src/data/Matrix12.npy | Bin 0 -> 1036928 bytes .../sciai/model/gad_mall/src/data/ReadMe.txt | 7 ++ SciAI/sciai/model/gad_mall/src/data/yield.csv | 76 ++++++++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 SciAI/sciai/model/gad_mall/src/data/E.csv create mode 100644 SciAI/sciai/model/gad_mall/src/data/Matrix12.npy create mode 100644 SciAI/sciai/model/gad_mall/src/data/ReadMe.txt create mode 100644 SciAI/sciai/model/gad_mall/src/data/yield.csv 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 000000000..74e70aa4e --- /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 GIT binary patch literal 1036928 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ⅅ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 B5f%Ud literal 0 HcmV?d00001 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 000000000..c39b6de91 --- /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 000000000..ace5d220e --- /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 -- Gitee From c58341b2ae3e0a521dea9041746e477cae0fd4d3 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 10 Sep 2024 16:50:03 +0000 Subject: [PATCH 10/31] correct code spell: position Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/GAD_MALL_Active_learning_ms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 81aaa8a60..74558d6e2 100644 --- 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 @@ -151,8 +151,8 @@ def createv_2(data,sizeofdata,nofv,dofv): v=np.concatenate((v,temp2),axis=2) return v -def createunitofv(datainput,positon,nofv,dofv): - neibourhoods=findneighbour(datainput,positon) +def createunitofv(datainput,position,nofv,dofv): + 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] -- Gitee From 744cf1f5e4cf449c7dbf9dbd9f28f739b9f409a3 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 10 Sep 2024 17:03:44 +0000 Subject: [PATCH 11/31] markdownlint correction Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/README.md | 72 ++++++++++++---------------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md index 0ed5462ad..f53e939f4 100644 --- a/SciAI/sciai/model/gad_mall/README.md +++ b/SciAI/sciai/model/gad_mall/README.md @@ -1,6 +1,5 @@ English | [简体中文](./README_CN.md) - ## Table of Contents - [Table of Contents](#table-of-contents) @@ -16,7 +15,6 @@ English | [简体中文](./README_CN.md) - [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. @@ -31,21 +29,20 @@ GAD-MALL is a deep learning framework based on Active Learning and 3D Convolutio > 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. - + - `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: + - `Matrix12.npy`, `E.csv`, and `yield.csv` are located in the `./src/data` directory: ```txt ├── data │ ├── E.csv @@ -53,43 +50,42 @@ These datasets support the training and testing of various models within the GAD │ ├── 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). + - `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. +- **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 +## 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 + - 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 + - Windows WSL Ubuntu-2 0.04 - **Python Version**: - - Python 3.9 + - Python 3.9 - **Framework** - - [MindSpore](https://www.mindspore.cn/install/) + - [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: + - 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: ```bash python3.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) - + - [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 @@ -98,7 +94,6 @@ This project is based on the MindSpore deep learning framework. Below are the ma 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 @@ -115,22 +110,20 @@ After installing MindSpore from the official website and downloading the require 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 +├── 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 +│ │ └── README.txt # Download links for datasets │ ├── model # Directory for storing checkpoint files │ ├── results # Directory for storing experimental results │ ├── src # Source code @@ -141,10 +134,8 @@ The file structure is as follows: │ ├── 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. @@ -160,10 +151,7 @@ The file structure is as follows: - `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) - +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 -- Gitee From 38339eb9e24eb860b6948edb3c2337a0fa0f5cd2 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Tue, 10 Sep 2024 17:46:44 +0000 Subject: [PATCH 12/31] pylint check correction Signed-off-by: chunguangx_1b70 --- .../src/GAD_MALL_Active_learning_ms.py | 414 +++++++++--------- 1 file changed, 219 insertions(+), 195 deletions(-) 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 index 74558d6e2..2923a379d 100644 --- 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 @@ -1,3 +1,6 @@ +''' +This file integrate CAE and CNN model +''' from sklearn.mixture import GaussianMixture import mindspore as ms from mindspore import nn @@ -33,7 +36,6 @@ context.set_context(max_call_depth=10000) class AutoEncoder(nn.Cell): 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(), @@ -57,7 +59,6 @@ class AutoEncoder(nn.Cell): x = self.encoder(x) x = self.decoder(x) return x - # Define the decoder model class class Decoder(nn.Cell): def __init__(self, autoencoder): @@ -73,7 +74,6 @@ class Decoder(nn.Cell): def construct(self, x): return self.decoder_layers(x) - # Define the encoder model class class Encoder(nn.Cell): def __init__(self, autoencoder): @@ -96,252 +96,276 @@ def density(input_) -> np.array: 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=[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) + blocks = blocks.round(1) return blocks -def matrix_maker(value,n) -> np.array: +def matrix_maker(value, n) -> np.array: temp_x = [[[value for k in range(n)] for j in range(n)] for i in range(n)] - matrix= np.array(temp_x) + matrix = np.array(temp_x) return matrix ### def To60(matrix): - the606060=[] - N=len(matrix) + the606060 = [] + N = len(matrix) # r1_100=np.tile(r1, (N,1,1)) - finished=(10*(1-matrix).reshape(N,27,1))*0.282-0.469 + 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 + 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) + 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): +def createv_2(data, sizeofdata, nofv, dofv): v=[] for k in range(sizeofdata[2]): - temp2=[] + temp2 = [] for j in range(sizeofdata[1]): - temp1=[] + temp1 = [] for i in range(sizeofdata[0]): - position=[i,j,k] - varray=createunitofv(data,position,nofv,dofv) - if i<1: - temp1=varray + 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 + 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 + temp2 = np.concatenate((temp2,temp1), axis=1) + if k < 1: + v = temp2 else: - v=np.concatenate((v,temp2),axis=2) + v = np.concatenate((v, temp2), axis=2) return v -def createunitofv(datainput,position,nofv,dofv): - 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] +def createunitofv(datainput, position, nofv, dofv): + 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 + 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 + + 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- - 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] + 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 findneighbour(inputdata,position): - neighbourhoods=np.zeros((3,3,3)) - neighbourhoods[:,:,:]=np.nan - r=len(inputdata) - flag=0 +def findneighbour(inputdata, position): + 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: + 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 + 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 rejSampling(gm, n_samples, target): - target_upper=1.05*target - target_lower=0.95*target + target_upper = 1.05 * target + target_lower = 0.95 * target + Y_total = data['yield'] - E_data=dataE['E'][dataE['E']target_lower] + E_data = dataE['E'][dataE['E'] < target_upper] + E_data = E_data[E_data > target_lower] print(E_data) + if len(E_data) == 0: - Y_max=24 + 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] + 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 = [] + sample_Y = [] - rejSampling_decode(n_samples, batchsize,sample_z) + rejSampling_decode(n_samples, batchsize, sample_z) 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)) + 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: - print('no valid structure!') - sample_Y_final=[] - sample_S_final=[] + print('No valid structure!') + sample_Y_final = [] + sample_S_final = [] + return sample_S_final, sample_Y_final -def rejSampling_decode(n_samples, batchsize,sample_z): - print('decoding started...') +def rejSampling_decode(n_samples, batchsize, sample_z): + print('Decoding started...') for i in tqdm(range(0, n_samples, batchsize)): - temp_s0=Structure(sample_z[i:i+batchsize],decoder) - temp_s3=[] - for i in range(len(temp_s0)): - temp_x=density(temp_s0[i]) - temp_s3.append(temp_x) - temp_s=np.asarray(temp_s3) - temp_s3=np.asarray(temp_s3) - temp_s60=To60(temp_s3) - temp_E=[] - temp_E=ensemble_predict_E(temp_s60) - try: - E_target=temp_E['E'][temp_E['E']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('strcuture sampled!') - sample_target.append(acc_sample_S) - sample_Y.append(acc_sample_Y) - except: - continue + 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 def Structure(x1, decoder): # Assuming that the decoder expects 128 channels, you may need to modify the input here - x1 = np.expand_dims(x1, axis=1) # Expand dimensions as required + # 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) -- Gitee From b7f91affa1bdc15fde313b169b87a074dbf62bfb Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 12:42:58 +0000 Subject: [PATCH 13/31] markdownlint correction Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md index f53e939f4..156ad392b 100644 --- a/SciAI/sciai/model/gad_mall/README.md +++ b/SciAI/sciai/model/gad_mall/README.md @@ -14,7 +14,6 @@ English | [简体中文](./README_CN.md) - [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. @@ -28,7 +27,6 @@ GAD-MALL is a deep learning framework based on Active Learning and 3D Convolutio 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: @@ -54,9 +52,7 @@ These datasets support the training and testing of various models within the GAD - `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: @@ -86,7 +82,6 @@ This project is based on the MindSpore deep learning framework. Below are the ma - 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 @@ -94,7 +89,7 @@ This project is based on the MindSpore deep learning framework. Below are the ma After installing MindSpore from the official website, you can start training and validation as follows: - Run on GPU -```bash run_GAD_MALL.sh``` + ```bash run_GAD_MALL.sh``` ### Pipeline Workflow @@ -109,12 +104,12 @@ After installing MindSpore from the official website and downloading the require ```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 @@ -151,7 +146,6 @@ The file structure is as follows: - `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 -- Gitee From 336a82e552d94a1de30ed10985f8222c2650f17d Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 12:44:41 +0000 Subject: [PATCH 14/31] pylint check correction Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py | 34 ++++++++++++--------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py b/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py index efbf4418d..aafd8847a 100644 --- a/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py +++ b/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py @@ -1,12 +1,15 @@ +''' +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, Tensor, context +from mindspore import nn, context from mindspore.train.callback import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau -from mindspore.common.initializer import Normal from mindspore.train import Model import mindspore.dataset as ds -import mindspore.ops as ops 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) @@ -14,7 +17,7 @@ context.set_context(max_call_depth=10000) # Import matrix = np.load('data/3D_CAE_Train.npy', allow_pickle=True) -Ran = range(len(matrix)) +ran = range(len(matrix)) X = matrix.reshape(17835, 12, 12, 12, 1) # Convert the data type to Float32 @@ -23,10 +26,10 @@ 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 +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) +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 @@ -43,10 +46,10 @@ 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): +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(), @@ -98,10 +101,9 @@ model = Model(autoencoder, loss_fn=loss_fn, optimizer=optimizer) # progress bar # 加进度条 -from mindspore.train.callback import Callback -from tqdm import tqdm 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 @@ -109,16 +111,20 @@ class TQDMProgressBar(Callback): self.progress_bar = None self.current_epoch = 0 - def on_train_epoch_begin(self, run_context): + # 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") + 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): + 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, run_context): + def on_train_epoch_end(self): self.progress_bar.close() # Number of steps per epoch -- Gitee From d4a2967dc865c80b4746b1604d531b66c8f49cad Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 12:45:01 +0000 Subject: [PATCH 15/31] Renamed SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py to SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py --- SciAI/sciai/model/gad_mall/src/{3D_CAE_ms.py => CAE_3D_ms.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SciAI/sciai/model/gad_mall/src/{3D_CAE_ms.py => CAE_3D_ms.py} (100%) diff --git a/SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py b/SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py similarity index 100% rename from SciAI/sciai/model/gad_mall/src/3D_CAE_ms.py rename to SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py -- Gitee From 47a20d0d95deb48db9f4d50a7276bc4366591604 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 12:45:15 +0000 Subject: [PATCH 16/31] Renamed SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py to SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py --- SciAI/sciai/model/gad_mall/src/{3D_CNN_ms.py => CNN_3D_ms.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SciAI/sciai/model/gad_mall/src/{3D_CNN_ms.py => CNN_3D_ms.py} (100%) diff --git a/SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py b/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py similarity index 100% rename from SciAI/sciai/model/gad_mall/src/3D_CNN_ms.py rename to SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py -- Gitee From 332223828b0fd138ca62a1353f00de6f8d1db892 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 12:46:05 +0000 Subject: [PATCH 17/31] pylint check correction Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py | 32 +++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py b/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py index 196c9fea5..62721797b 100644 --- a/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py +++ b/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py @@ -1,7 +1,10 @@ +''' +This file defines CNN_3D model and trains the model. +''' import numpy as np import pandas as pd -from mindspore import nn, Tensor, context -from mindspore.train.callback import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau, LossMonitor, Callback +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 @@ -15,6 +18,7 @@ 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)) @@ -44,6 +48,7 @@ class CNN3D(nn.Cell): # Custom TQDM progress bar callback class TQDMProgressBar(Callback): + '''add progress bar thile training''' def __init__(self, total_steps_per_epoch, total_epochs): super(TQDMProgressBar, self).__init__() self.total_steps_per_epoch = total_steps_per_epoch @@ -51,29 +56,33 @@ class TQDMProgressBar(Callback): self.progress_bar = None self.current_epoch = 0 - def on_train_epoch_begin(self, run_context): + # 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") + 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, 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] +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) +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) @@ -109,13 +118,13 @@ net = Model(network=model, loss_fn=loss_fn, optimizer=optimizer, metrics={"mae": net.train(total_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) +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) +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) @@ -133,4 +142,3 @@ tqdm_callback2 = TQDMProgressBar(total_steps_per_epoch=train_dataset2.get_datase net2 = Model(network=model2, loss_fn=loss_fn, optimizer=optimizer2, metrics={"mae": MAE()}) net2.train(total_epochs, train_dataset2, callbacks=[ckpoint_cb2, es, ls, tqdm_callback2], dataset_sink_mode=False) - -- Gitee From 78f8655be619b2be98f9ecd258efdb6b91c93d59 Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Wed, 11 Sep 2024 21:33:41 +0800 Subject: [PATCH 18/31] format correction --- SciAI/sciai/model/gad_mall/README.md | 4 + SciAI/sciai/model/gad_mall/README_CN.md | 21 +-- SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py | 12 +- SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py | 12 +- .../src/GAD_MALL_Active_learning_ms.py | 125 ++++++++++-------- 5 files changed, 89 insertions(+), 85 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md index 156ad392b..a887f2df0 100644 --- a/SciAI/sciai/model/gad_mall/README.md +++ b/SciAI/sciai/model/gad_mall/README.md @@ -41,6 +41,7 @@ These datasets support the training and testing of various models within the GAD - Data Download: - `Matrix12.npy`, `E.csv`, and `yield.csv` are located in the `./src/data` directory: + - ```txt ├── data │ ├── E.csv @@ -76,12 +77,15 @@ This project is based on the MindSpore deep learning framework. Below are the ma - matplotlib==3.9.1 - tqdm==4.66.5 - You can install the dependencies using the following command: + ```bash python3.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 diff --git a/SciAI/sciai/model/gad_mall/README_CN.md b/SciAI/sciai/model/gad_mall/README_CN.md index d3885acff..cd0f27d53 100644 --- a/SciAI/sciai/model/gad_mall/README_CN.md +++ b/SciAI/sciai/model/gad_mall/README_CN.md @@ -3,7 +3,7 @@ ## 目录 - [目录](#目录) -- [GAD-MALL 描述](#gad-mall-描述) +- [GAD-MAL 描述](#gad-mal-描述) - [主要特性](#主要特性) - [数据集](#数据集) - [环境要求](#环境要求) @@ -15,8 +15,7 @@ - [项目文件说明](#项目文件说明) - [更多信息](#更多信息) - -## GAD-MALL 描述 +## GAD-MAL 描述 GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络(3D CNN)的深度学习框架,旨在处理多目标高维优化问题。该框架通过生成模型、有限元方法(FEM)和3D打印技术相结合,提供了一种高效的数据驱动设计方法,尤其适用于具有复杂结构的材料的优化设计。该框架特别应用于实现高效的建筑材料设计优化特别是针对复杂的多目标优化问题,如异质材料在生物工程和材料科学领域中的应用。可以完成像骨移植支架的设计,通过优化支架的弹性模量和屈服强度,实现了具有生物相容性和高机械强度的异质性架构。 @@ -28,11 +27,8 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 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 - - ## 数据集 该项目使用的主要数据集包括以下文件: @@ -47,6 +43,7 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 - 数据下载: - `Matrix12.npy`,`E.csv` 和 `yield.csv`: 存放于 `./src/data` 目录下 + - ```txt ├── data │ ├── E.csv @@ -54,13 +51,12 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 │ ├── 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深度学习框架。以下是主要的(**测试/开发**)环境依赖: @@ -92,7 +88,6 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 - [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) - ## 快速开始 ### 快速开始 @@ -100,9 +95,7 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 通过官网安装好MindSpore后,就可以开始训练和验证如下: - 在 GPU 上运行 - -```bash run_GAD_MALL.sh``` - + ```bash run_GAD_MALL.sh``` ### 管道流程 @@ -118,7 +111,6 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 python3.9 -u GAD_MALL_Active_learning.py 4. 完成 GAD-MALL 流程后,您将获得具有特定预测弹性模量(E=2500 MPa、E=5000 MPa)和最高预测屈服强度的孔隙度矩阵。 - ## 脚本说明 ### 脚本和示例代码 @@ -146,7 +138,6 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 | └── requirements.txt # Python环境依赖文件 ``` - ### 项目文件说明 - `3D_CNN_ms.py`:实现了基于3D卷积神经网络的模型,适用于处理三维数据集,特别是在高维多目标优化问题中的应用。该模型通过体素化处理输入数据,并利用3D卷积层提取高层信息,最终进行材料性能的预测。 @@ -163,8 +154,6 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 - `requirements.txt`: Python环境依赖文件。 - - ## 更多信息 有关更多信息请参阅原项目说明[GAD-MALL](https://github.com/Bop2000/GAD-MALL/tree/main) diff --git a/SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py b/SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py index aafd8847a..8cd2826ca 100644 --- a/SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py +++ b/SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py @@ -1,6 +1,6 @@ ''' 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 @@ -29,7 +29,7 @@ X = np.transpose(X, (0, 4, 1, 2, 3)) # Now X is [batch_size, channels, depth, h 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) +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 @@ -38,15 +38,15 @@ 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) +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): +class AutoEncoder(nn.Cell): '''Definition of AutoEncoder''' def __init__(self): super(AutoEncoder, self).__init__() @@ -111,7 +111,7 @@ class TQDMProgressBar(Callback): self.progress_bar = None self.current_epoch = 0 - # def on_train_epoch_begin(self, run_context): + # 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: diff --git a/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py b/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py index 62721797b..2c5acda97 100644 --- a/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py +++ b/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py @@ -82,11 +82,11 @@ X = matrix.reshape(len(data), 1, 60, 60, 60) # MindSpore expects [batch_size, c 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) +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) +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 @@ -124,10 +124,10 @@ 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) +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 = 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) 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 index 2923a379d..63c1b64a3 100644 --- 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 @@ -21,7 +21,7 @@ import numpy as np import matplotlib.pyplot as plt from prettytable import PrettyTable import pandas as pd -from prettytable import PrettyTable + from tqdm import tqdm # import mindspore.dataset as ds @@ -34,6 +34,7 @@ context.set_context(max_call_depth=10000) # Model architecture class AutoEncoder(nn.Cell): + '''doc str''' def __init__(self): super(AutoEncoder, self).__init__() self.encoder = nn.SequentialCell([ @@ -61,6 +62,7 @@ class AutoEncoder(nn.Cell): return x # Define the decoder model class class Decoder(nn.Cell): + '''class doc str''' def __init__(self, autoencoder): super(Decoder, self).__init__() self.decoder_layers = nn.SequentialCell([ @@ -76,6 +78,7 @@ class Decoder(nn.Cell): return self.decoder_layers(x) # Define the encoder model class class Encoder(nn.Cell): + '''class doc str''' def __init__(self, autoencoder): super(Encoder, self).__init__() self.encoder_layers = nn.SequentialCell([ @@ -92,17 +95,18 @@ class Encoder(nn.Cell): # helper functions def density(input_) -> np.array: + '''doc str''' 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 = [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 + loc_input[2]-2:loc_input[2]+2]) + blocks = blocks.round(1) + return blocks def matrix_maker(value, n) -> np.array: temp_x = [[[value for k in range(n)] for j in range(n)] for i in range(n)] @@ -112,31 +116,33 @@ def matrix_maker(value, n) -> np.array: ### def To60(matrix): + '''func str''' the606060 = [] N = len(matrix) # r1_100=np.tile(r1, (N,1,1)) - finished=(10 * (1-matrix).reshape(N,27,1)) * 0.282-0.469 + 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 + 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) + the606060_cell = np.where(the606060_cell < 0.9, 1, 0) return the606060_cell -def createv_2(data, sizeofdata, nofv, dofv): - v=[] +def createv_2(data, sizeofdata, nofv, dofv): + '''doc str''' + 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) + varray = createunitofv(data,position, nofv, dofv) if i < 1: temp1 = varray else: @@ -144,14 +150,15 @@ def createv_2(data, sizeofdata, nofv, dofv): if j < 1: temp2 = temp1 else: - temp2 = np.concatenate((temp2,temp1), axis=1) + 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): +def createunitofv(datainput, position, nofv, dofv): + '''docs str''' neibourhoods = findneighbour(datainput, position) unitofv = np.ones((nofv - 2 * dofv, nofv - 2 * dofv, nofv - 2 * dofv)) @@ -231,8 +238,8 @@ def createunitofv(datainput, position, nofv, dofv): 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- - + 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- @@ -258,6 +265,7 @@ def createunitofv(datainput, position, nofv, dofv): return unitofv def findneighbour(inputdata, position): + '''fucstre''' neighbourhoods = np.zeros((3, 3, 3)) neighbourhoods[:, :, :] = np.nan @@ -280,77 +288,78 @@ def findneighbour(inputdata, position): return neighbourhoods def rejSampling(gm, n_samples, target): + '''''' target_upper = 1.05 * target target_lower = 0.95 * target - Y_total = data['yield'] - E_data = dataE['E'][dataE['E'] < target_upper] - E_data = E_data[E_data > target_lower] - print(E_data) + y_total = data['yield'] + e_data = dataE['E'][dataE['E'] < target_upper] + e_data = e_data[e_data > target_lower] + print(e_data) - if len(E_data) == 0: - Y_max = 24 + 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] + 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)) + 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_y = [] + + rej_sampling_decode(n_samples, batchsize, sample_z) - rejSampling_decode(n_samples, batchsize, sample_z) - 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)) + 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: print('No valid structure!') - sample_Y_final = [] - sample_S_final = [] + sample_y_final = [] + sample_s_final = [] - return sample_S_final, sample_Y_final + return sample_s_final, sample_y_final -def rejSampling_decode(n_samples, batchsize, sample_z): +def rej_sampling_decode(n_samples, batchsize, sample_z): print('Decoding started...') - for i in tqdm(range(0, n_samples, batchsize)): + 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) + 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] + 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 + 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) + 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) @@ -359,8 +368,8 @@ def rejSampling_decode(n_samples, batchsize, sample_z): except Exception as e: continue - print('decoding completed!') - return + print('decoding completed!') + return def Structure(x1, decoder): # Assuming that the decoder expects 128 channels, you may need to modify the input here @@ -383,14 +392,14 @@ def Structure(x1, decoder): new_x = recon.asnumpy() new_x1 = np.round(new_x, 1) return new_x1 - + def ensemble_predict_E(S): 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) - + S = Tensor(S, ms.float32) E = model.predict(S).asnumpy() E = pd.DataFrame(E) @@ -403,7 +412,7 @@ def ensemble_predict_Y(S): param_dict = ms.load_checkpoint(model_path) ms.load_param_into_net(model_Y, param_dict) model = Model(model_Y) - + S = Tensor(S, ms.float32) Y = model.predict(S).asnumpy() Y = pd.DataFrame(Y) @@ -424,7 +433,9 @@ 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_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) -- Gitee From 582648912c4987530eb15be08332d5ebf2f9defe Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Wed, 11 Sep 2024 23:15:38 +0800 Subject: [PATCH 19/31] add doc str --- .../src/GAD_MALL_Active_learning_ms.py | 330 ++++++++++++++++-- 1 file changed, 300 insertions(+), 30 deletions(-) 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 index 63c1b64a3..7b4dda088 100644 --- 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 @@ -6,24 +6,13 @@ import mindspore as ms from mindspore import nn from mindspore import Tensor from mindspore import context -from mindspore import ops -from mindspore.nn import Cell -from mindspore.dataset import GeneratorDataset -from mindspore.train.callback import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau from mindspore.train import Model -from mindspore.common.initializer import XavierUniform -from mindspore.dataset import vision, transforms -import mindspore.dataset as ds -from mindspore.train.serialization import load_checkpoint, load_param_into_net ## - -from sklearn.model_selection import train_test_split import numpy as np import matplotlib.pyplot as plt from prettytable import PrettyTable import pandas as pd - from tqdm import tqdm -# import mindspore.dataset as ds + # GPU Configuration # Set the MindSpore context @@ -34,7 +23,36 @@ context.set_context(max_call_depth=10000) # Model architecture class AutoEncoder(nn.Cell): - '''doc str''' + """ + 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. + + Example: + -------- + model = AutoEncoder() + x = Tensor(np.random.randn(batch_size, 1, 12, 12, 12), ms.float32) + reconstructed = model(x) + """ def __init__(self): super(AutoEncoder, self).__init__() self.encoder = nn.SequentialCell([ @@ -62,7 +80,29 @@ class AutoEncoder(nn.Cell): return x # Define the decoder model class class Decoder(nn.Cell): - '''class doc str''' + """ + A 3D Convolutional Decoder model extracted from an AutoEncoder. + + This class takes the decoder part of a pre-trained AutoEncoder model and uses it to decode + compressed representations (latent vectors) back to their original form. The decoder + reconstructs the 3D volumetric data through a series of upsampling and convolutional layers. + + 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([ @@ -78,7 +118,29 @@ class Decoder(nn.Cell): return self.decoder_layers(x) # Define the encoder model class class Encoder(nn.Cell): - '''class doc str''' + """ + 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([ @@ -95,7 +157,21 @@ class Encoder(nn.Cell): # helper functions def density(input_) -> np.array: - '''doc str''' + """ + 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): @@ -109,6 +185,23 @@ def density(input_) -> np.array: 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 @@ -116,7 +209,21 @@ def matrix_maker(value, n) -> np.array: ### def To60(matrix): - '''func str''' + """ + 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)) @@ -134,7 +241,35 @@ def To60(matrix): return the606060_cell def createv_2(data, sizeofdata, nofv, dofv): - '''doc str''' + """ + 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 = [] @@ -157,8 +292,34 @@ def createv_2(data, sizeofdata, nofv, dofv): v = np.concatenate((v, temp2), axis=2) return v -def createunitofv(datainput, position, nofv, dofv): - '''docs str''' +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)) @@ -168,7 +329,6 @@ def createunitofv(datainput, position, nofv, dofv): 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]): @@ -221,7 +381,6 @@ def createunitofv(datainput, position, nofv, dofv): 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)) @@ -239,7 +398,6 @@ def createunitofv(datainput, position, nofv, dofv): 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- @@ -265,7 +423,26 @@ def createunitofv(datainput, position, nofv, dofv): return unitofv def findneighbour(inputdata, position): - '''fucstre''' + """ + 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 @@ -287,8 +464,31 @@ def findneighbour(inputdata, position): return neighbourhoods -def rejSampling(gm, n_samples, target): - '''''' +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 @@ -311,7 +511,7 @@ def rejSampling(gm, n_samples, target): sample_target = [] sample_y = [] - rej_sampling_decode(n_samples, batchsize, sample_z) + 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] @@ -327,7 +527,32 @@ def rejSampling(gm, n_samples, target): return sample_s_final, sample_y_final -def rej_sampling_decode(n_samples, batchsize, sample_z): +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) @@ -352,7 +577,7 @@ def rej_sampling_decode(n_samples, batchsize, sample_z): sample_60 = To60(sample_60) uniform_rand = np.random.uniform(size=len(sample_)) - uniform_y = up * Y_max + uniform_rand * (1 - up) * Y_max + 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) @@ -372,6 +597,25 @@ def rej_sampling_decode(n_samples, batchsize, sample_z): return 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) @@ -394,6 +638,19 @@ def Structure(x1, decoder): return new_x1 def ensemble_predict_E(S): + """ + 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) @@ -407,6 +664,19 @@ def ensemble_predict_E(S): return E def ensemble_predict_Y(S): + """ + 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) @@ -518,7 +788,7 @@ print(mean_try) ######### main # resapmling -sample_S, sample_Y = rejSampling(gm, n_samples=sam_, target=target) +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:] -- Gitee From 5afb020b1cfc3c73cbdf403381900f45efde2af1 Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Wed, 11 Sep 2024 23:17:31 +0800 Subject: [PATCH 20/31] format correction --- .../src/GAD_MALL_Active_learning_ms.py | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) 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 index 7b4dda088..4ca1b0c8d 100644 --- 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 @@ -588,7 +588,7 @@ def rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target): if len(acc_sample_S) > 0: print('Structure sampled!') sample_target.append(acc_sample_S) - sample_Y.append(acc_sample_Y) + sample_y.append(acc_sample_Y) except Exception as e: continue @@ -788,14 +788,14 @@ print(mean_try) ######### main # resapmling -sample_S, sample_Y = rej_sampling(gm, n_samples=sam_, target=target) -if len(sample_S) > 1000: +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] + 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) +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): @@ -805,20 +805,20 @@ 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) +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) +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:] +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 +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) @@ -833,13 +833,13 @@ for i in range(len(E_20)): print(table) # Filtering, Reshaping -if len(sample_S) > 1000: +if len(sample_s) > 1000: top = 1000 - ind = np.argpartition(sample_Y, -top)[-top:] - sample_S = sample_S[ind] + 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) +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): @@ -849,20 +849,20 @@ 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) +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) +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:] +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 +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) -- Gitee From 8343dfdd3d6463d9d7ed469f3a2acead370175fe Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Wed, 11 Sep 2024 23:51:14 +0800 Subject: [PATCH 21/31] format correction --- SciAI/sciai/model/gad_mall/README_CN.md | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/README_CN.md b/SciAI/sciai/model/gad_mall/README_CN.md index cd0f27d53..9ee9cfc7e 100644 --- a/SciAI/sciai/model/gad_mall/README_CN.md +++ b/SciAI/sciai/model/gad_mall/README_CN.md @@ -54,7 +54,6 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 - `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)下载。 - - **预处理**: 在使用前,需要对数据进行归一化处理,并可能需要对数据进行裁剪或补零操作以适配模型的输入尺寸。 ## 环境要求 @@ -62,17 +61,17 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 该项目基于MindSpore深度学习框架。以下是主要的(**测试/开发**)环境依赖: - **硬件** (GPU) - - 显卡:NVIDIA GeForce RTX 4060 Laptop GPU + - 显卡:NVIDIA GeForce RTX 4060 Laptop GPU - 驱动:CUDA 12.3 - CUDA: 11.6 - CUDNN: 8.4.1 -- **操作系统**: +- **操作系统**: - Windows WSL Ubuntu-20.04 -- **Python 版本**: +- **Python 版本**: - Python 3.9 - 框架 - [MindSpore](https://www.mindspore.cn/install/) -- **依赖库**: +- **依赖库**: - mindspore==2.2.14 - numpy==1.23.5 - scipy==1.13.1 @@ -101,13 +100,10 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 通过官网安装好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)和最高预测屈服强度的孔隙度矩阵。 @@ -117,6 +113,7 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 文件结构如下: + ```text ├── gad_mall │ ├── data # 数据文件 @@ -138,22 +135,18 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 | └── 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) -- Gitee From a60ec35de885f6daf44a379b6e341574f6136310 Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Thu, 12 Sep 2024 00:04:07 +0800 Subject: [PATCH 22/31] format correction --- .../src/GAD_MALL_Active_learning_ms.py | 154 ++++++++---------- 1 file changed, 65 insertions(+), 89 deletions(-) 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 index 4ca1b0c8d..dca29cc78 100644 --- 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 @@ -26,32 +26,24 @@ 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 + 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 + 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 + 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 + 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. - - Example: - -------- - model = AutoEncoder() - x = Tensor(np.random.randn(batch_size, 1, 12, 12, 12), ms.float32) - reconstructed = model(x) """ def __init__(self): super(AutoEncoder, self).__init__() @@ -83,14 +75,10 @@ class Decoder(nn.Cell): """ A 3D Convolutional Decoder model extracted from an AutoEncoder. - This class takes the decoder part of a pre-trained AutoEncoder model and uses it to decode - compressed representations (latent vectors) back to their original form. The decoder - reconstructs the 3D volumetric data through a series of upsampling and convolutional layers. - Attributes: ----------- decoder_layers : nn.SequentialCell - The decoder layers from the provided AutoEncoder, including upsampling and 3D convolutional + 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: @@ -121,8 +109,8 @@ 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 + 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: @@ -168,7 +156,7 @@ def density(input_) -> np.array: Returns: -------- blocks : np.array - A 3x3x3 numpy array where each element is the averaged density value of the corresponding + 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. """ @@ -192,10 +180,8 @@ def matrix_maker(value, n) -> np.array: ----------- 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 @@ -208,9 +194,9 @@ def matrix_maker(value, n) -> np.array: ### -def To60(matrix): +def to60(matrix): """ - Transform a given matrix into a specific 60x60x60 output by combining it with additional + Transform a given matrix into a specific 60x60x60 output by combining it with additional features and performing a series of transformations and calculations. Parameters: @@ -221,18 +207,18 @@ def To60(matrix): Returns: -------- the606060_cell : np.array - A binary numpy array representing the transformed 60x60x60 output. Values are set to 1 + 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 + 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) + data0 = np.concatenate((r1, r2), axis=1) v = createv_2(data0, sizeofdata0, accu, 3) ov = oo + v the606060.append(ov) @@ -242,32 +228,30 @@ def To60(matrix): 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 + 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 + 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 + 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 + 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 = [] @@ -277,7 +261,7 @@ def createv_2(data, sizeofdata, nofv, dofv): temp1 = [] for i in range(sizeofdata[0]): position = [i, j, k] - varray = createunitofv(data,position, nofv, dofv) + varray = createunitofv(data, position, nofv, dofv) if i < 1: temp1 = varray else: @@ -294,7 +278,7 @@ def createv_2(data, sizeofdata, nofv, dofv): def createunitofv(datainput, position, nofv, dofv): """ - Generate a volumetric unit (3D matrix) by processing the neighboring values + Generate a volumetric unit (3D matrix) by processing the neighboring values around a given position in the input data. Parameters: @@ -303,7 +287,7 @@ def createunitofv(datainput, position, nofv, dofv): 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 + 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 @@ -315,9 +299,9 @@ def createunitofv(datainput, position, nofv, dofv): 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 + 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) @@ -429,18 +413,17 @@ def findneighbour(inputdata, position): Parameters: ----------- inputdata : np.array - A 2D numpy array where each row represents a data point in the 3D space with the format + 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 + 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, + 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)) @@ -448,7 +431,6 @@ def findneighbour(inputdata, position): 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 @@ -471,21 +453,19 @@ def rej_sampling(gm, n_samples, target): Parameters: ----------- gm : object - The generative model used to sample the latent space. It should have a `sample` method that generates latent + 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 + 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. """ @@ -493,7 +473,7 @@ def rej_sampling(gm, n_samples, target): target_lower = 0.95 * target y_total = data['yield'] - e_data = dataE['E'][dataE['E'] < target_upper] + e_data = data_e['E'][data_e['E'] < target_upper] e_data = e_data[e_data > target_lower] print(e_data) @@ -535,7 +515,6 @@ def rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target): ----------- n_samples : int The total number of latent variables to sample and decode. - batchsize : int The size of each batch to process during decoding. @@ -565,8 +544,8 @@ def rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target): temp_s = np.asarray(temp_s3) temp_s3 = np.asarray(temp_s3) - temp_s60 = To60(temp_s3) - temp_e = ensemble_predict_E(temp_s60) + temp_s60 = to60(temp_s3) + temp_e = ensemble_predict_e(temp_s60) try: e_target = temp_e['E'][temp_e['E'] < target_upper] @@ -574,11 +553,11 @@ def rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target): sample_ = temp_s[e_target.index] sample_60 = np.asarray(sample_) - sample_60 = To60(sample_60) + 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 + temp_Y = ensemble_predict_y(sample_60).values accepted = uniform_y.reshape(-1, 1) < temp_Y.reshape(-1, 1) acc_idx = accepted.reshape(-1) @@ -604,15 +583,14 @@ def Structure(x1, decoder): ----------- 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 + 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 decoded 3D structures with the output values rounded to one decimal place. The array is of shape (n_samples, 3D structure dimensions). """ @@ -637,7 +615,7 @@ def Structure(x1, decoder): new_x1 = np.round(new_x, 1) return new_x1 -def ensemble_predict_E(S): +def ensemble_predict_e(ss): """ Predicts the 'E' value from the input tensor using a pre-trained 3D CNN model. @@ -645,7 +623,6 @@ def ensemble_predict_E(S): ----------- S : numpy.ndarray Input tensor data, which will be converted to a MindSpore Tensor for prediction. - Returns: -------- E : pandas.DataFrame @@ -657,13 +634,13 @@ def ensemble_predict_E(S): ms.load_param_into_net(model_E, param_dict) model = Model(model_E) - S = Tensor(S, ms.float32) - E = model.predict(S).asnumpy() - E = pd.DataFrame(E) - E.columns = ['E'] - return E + ss = Tensor(ss, ms.float32) + e = model.predict(ss).asnumpy() + e = pd.DataFrame(e) + e.columns = ['E'] + return e -def ensemble_predict_Y(S): +def ensemble_predict_y(ss): """ Predicts the 'yield' value from the input tensor using a pre-trained 3D CNN model. @@ -671,23 +648,22 @@ def ensemble_predict_Y(S): ----------- 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 + 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) + ms.load_param_into_net(model_y, param_dict) + model = Model(model_y) - S = Tensor(S, ms.float32) - Y = model.predict(S).asnumpy() - Y = pd.DataFrame(Y) - Y.columns = ['yield'] - return 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 @@ -731,8 +707,8 @@ ms.load_param_into_net(autoencoder, param_dict) # Import data matrix = np.load("data/Matrix12.npy", allow_pickle=True) -dataE = pd.read_csv("data/E.csv") -E_total = dataE['E'] +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) @@ -746,8 +722,8 @@ 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) +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] @@ -782,7 +758,7 @@ for i in range(len(matrix)): xx = density(temp_x) input_.append(xx) matrix2 = np.array(input_) -matrix60 = To60(matrix2) +matrix60 = to60(matrix2) mean_try = np.mean(matrix60.reshape(len(matrix60), 60*60*60), axis=1) print(mean_try) @@ -802,11 +778,11 @@ 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) +X60 = to60(matrix_x) # Predictions using the ensemble models -pred_e = ensemble_predict_E(X60) -pred_y = ensemble_predict_Y(X60) +pred_e = ensemble_predict_e(X60) +pred_y = ensemble_predict_y(X60) # Convert the predictions to NumPy arrays pred_e = np.asarray(pred_e) @@ -846,11 +822,11 @@ 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) +X60 = to60(matrix_x) # Predictions using the ensemble models -pred_e = ensemble_predict_E(X60) -pred_y = ensemble_predict_Y(X60) +pred_e = ensemble_predict_e(X60) +pred_y = ensemble_predict_y(X60) # Convert the predictions to NumPy arrays pred_e = np.asarray(pred_e) -- Gitee From 280c6e8f12bdda6320ff6880c8bdd989406a1622 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 16:06:11 +0000 Subject: [PATCH 23/31] rename SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py to SciAI/sciai/model/gad_mall/src/cae_3d_ms.py. Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/{CAE_3D_ms.py => cae_3d_ms.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SciAI/sciai/model/gad_mall/src/{CAE_3D_ms.py => cae_3d_ms.py} (100%) diff --git a/SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py b/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py similarity index 100% rename from SciAI/sciai/model/gad_mall/src/CAE_3D_ms.py rename to SciAI/sciai/model/gad_mall/src/cae_3d_ms.py -- Gitee From fd970dd0af1cc001a341f4c45c02922fe4efd58b Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 16:07:42 +0000 Subject: [PATCH 24/31] rename SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py to SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py. Signed-off-by: chunguangx_1b70 --- SciAI/sciai/model/gad_mall/src/{CNN_3D_ms.py => cnn_3d_ms.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SciAI/sciai/model/gad_mall/src/{CNN_3D_ms.py => cnn_3d_ms.py} (100%) diff --git a/SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py similarity index 100% rename from SciAI/sciai/model/gad_mall/src/CNN_3D_ms.py rename to SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py -- Gitee From b68d0fb4ae979983293832622097fdf31a44aa84 Mon Sep 17 00:00:00 2001 From: chunguangx_1b70 Date: Wed, 11 Sep 2024 16:08:17 +0000 Subject: [PATCH 25/31] rename to SciAI/sciai/model/gad_mall/src/gad_mall_active_learning_ms.py. Signed-off-by: chunguangx_1b70 --- ..._MALL_Active_learning_ms.py => gad_mall_active_learning_ms.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SciAI/sciai/model/gad_mall/src/{GAD_MALL_Active_learning_ms.py => gad_mall_active_learning_ms.py} (100%) 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 similarity index 100% rename from SciAI/sciai/model/gad_mall/src/GAD_MALL_Active_learning_ms.py rename to SciAI/sciai/model/gad_mall/src/gad_mall_active_learning_ms.py -- Gitee From 27d738208101a33e411863d4a07abe7c664c2a98 Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Thu, 12 Sep 2024 00:22:04 +0800 Subject: [PATCH 26/31] format correction --- SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py | 5 ++- .../src/gad_mall_active_learning_ms.py | 41 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py index 2c5acda97..830dc8dab 100644 --- a/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py +++ b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py @@ -61,8 +61,9 @@ class TQDMProgressBar(Callback): 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") + 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): 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 index dca29cc78..9bcbb6b3d 100644 --- 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 @@ -27,7 +27,7 @@ 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, + 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. @@ -42,7 +42,7 @@ class AutoEncoder(nn.Cell): Methods: -------- construct(x): - Passes the input `x` through the encoder to compress it and then through the decoder + Passes the input `x` through the encoder to compress it and then through the decoder to reconstruct the original input. """ def __init__(self): @@ -472,7 +472,7 @@ def rej_sampling(gm, n_samples, target): target_upper = 1.05 * target target_lower = 0.95 * target - y_total = data['yield'] + # 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) @@ -491,7 +491,7 @@ def rej_sampling(gm, n_samples, target): sample_target = [] sample_y = [] - rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target) + 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] @@ -500,7 +500,7 @@ def rej_sampling(gm, n_samples, target): 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: + except Exception as e: print('No valid structure!') sample_y_final = [] sample_s_final = [] @@ -534,7 +534,7 @@ def rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target): """ print('Decoding started...') for i in tqdm(range(0, n_samples, batchsize)): - temp_s0 = Structure(sample_z[i:i + batchsize], decoder) + temp_s0 = structure(sample_z[i:i + batchsize], decoder) temp_s3 = [] for j in range(len(temp_s0)): @@ -557,25 +557,25 @@ def rej_sampling_decode(n_samples, batchsize, sample_z, y_max, sample_target): 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 + temp_y = ensemble_predict_y(sample_60).values - accepted = uniform_y.reshape(-1, 1) < temp_Y.reshape(-1, 1) + 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] + acc_sample_s = sample_[acc_idx] + acc_sample_y = temp_y[acc_idx] - if len(acc_sample_S) > 0: + if len(acc_sample_s) > 0: print('Structure sampled!') - sample_target.append(acc_sample_S) - sample_y.append(acc_sample_Y) + sample_target.append(acc_sample_s) + sample_y.append(acc_sample_y) except Exception as e: continue print('decoding completed!') - return + return sample_target -def Structure(x1, decoder): +def structure(x1, decoder): """ Process latent variables through a decoder model to generate 3D structures. @@ -618,7 +618,6 @@ def Structure(x1, decoder): def ensemble_predict_e(ss): """ Predicts the 'E' value from the input tensor using a pre-trained 3D CNN model. - Parameters: ----------- S : numpy.ndarray @@ -629,10 +628,10 @@ def ensemble_predict_e(ss): 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 + 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) + ms.load_param_into_net(model_e, param_dict) + model = Model(model_e) ss = Tensor(ss, ms.float32) e = model.predict(ss).asnumpy() @@ -708,7 +707,7 @@ 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'] +e_total = data_e['E'] data = pd.read_csv("data/yield.csv") i = len(data) X = matrix.reshape(i, 12, 12, 12, 1) @@ -720,7 +719,7 @@ decoder = Decoder(autoencoder) # Instantiate the encoder model encoder = Encoder(autoencoder) -# embedding the input data using the encoder model and +# 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) -- Gitee From 954df600a7d64a5458039ccbcf411c95b35e03cf Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Thu, 12 Sep 2024 00:29:17 +0800 Subject: [PATCH 27/31] format correction --- SciAI/sciai/model/gad_mall/README.md | 19 +++++++---- SciAI/sciai/model/gad_mall/README_CN.md | 43 ++++++++++++------------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md index a887f2df0..42d17b35f 100644 --- a/SciAI/sciai/model/gad_mall/README.md +++ b/SciAI/sciai/model/gad_mall/README.md @@ -14,6 +14,7 @@ English | [简体中文](./README_CN.md) - [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. @@ -40,8 +41,8 @@ The primary datasets used in this project include the following files: 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: - - + - `Matrix12.npy`, `E.csv`, and `yield.csv` are located in the `./src/data` directory: + ```txt ├── data │ ├── E.csv @@ -50,8 +51,8 @@ These datasets support the training and testing of various models within the GAD │ └── 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). + - `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 @@ -78,9 +79,7 @@ This project is based on the MindSpore deep learning framework. Below are the ma - tqdm==4.66.5 - You can install the dependencies using the following command: - ```bash - python3.9 -u pip install -r requirement.txt - ``` + ```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) @@ -93,21 +92,26 @@ This project is based on the MindSpore deep learning framework. Below are the ma 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 @@ -150,6 +154,7 @@ The file structure is as follows: - `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 index 9ee9cfc7e..211aa89b8 100644 --- a/SciAI/sciai/model/gad_mall/README_CN.md +++ b/SciAI/sciai/model/gad_mall/README_CN.md @@ -43,7 +43,7 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 - 数据下载: - `Matrix12.npy`,`E.csv` 和 `yield.csv`: 存放于 `./src/data` 目录下 - - + ```txt ├── data │ ├── E.csv @@ -61,27 +61,26 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 该项目基于MindSpore深度学习框架。以下是主要的(**测试/开发**)环境依赖: - **硬件** (GPU) - - 显卡:NVIDIA GeForce RTX 4060 Laptop GPU - - 驱动:CUDA 12.3 - - CUDA: 11.6 - - CUDNN: 8.4.1 + - 显卡:NVIDIA GeForce RTX 4060 Laptop GPU + - 驱动:CUDA 12.3 + - CUDA: 11.6 + - CUDNN: 8.4.1 - **操作系统**: - - Windows WSL Ubuntu-20.04 + - Windows WSL Ubuntu-20.04 - **Python 版本**: - - Python 3.9 + - Python 3.9 - 框架 - - [MindSpore](https://www.mindspore.cn/install/) + - [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 - - 安装依赖库可以通过以下命令: - ```bash - python3.9 -u pip install -r requirement.txt - ``` + - 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) @@ -113,16 +112,16 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 文件结构如下: - ```text -├── gad_mall + +├── gad_mall │ ├── data # 数据文件 │ │ ├── E.csv # 包含材料弹性模量的数据文件 │ │ ├── yield.csv # 包含材料屈服强度的数据文件 │ │ ├── Matrix12.npy # 矩阵数据,用于架构生成和优化过程 │ │ ├── (Matrix60.npy) # 矩阵数据,用于架构生成和优化过程 │ │ ├── (3D_CAE_Train.npy) # 用于3D卷积自编码器的训练数据,存储为NumPy数组 -│ │ └── README.txt # 数据下载地址 +│ │ └── README.txt # 数据下载地址 │ ├── model # checkpoint文件 │ ├── results # 实验结果存放 │ ├── src # 源代码 @@ -133,8 +132,8 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 │ ├── README_CN.md # 中文模型说明 │ ├── run_GAD_MALL.sh # 训练启动脚本 | └── requirements.txt # Python环境依赖文件 -``` +``` ### 项目文件说明 -- Gitee From c53f876a6cbf95128baa9de5ab8dd981aa0fa4cc Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Thu, 12 Sep 2024 00:39:02 +0800 Subject: [PATCH 28/31] format correction --- SciAI/sciai/model/gad_mall/README.md | 8 ++++---- SciAI/sciai/model/gad_mall/README_CN.md | 13 +++++++------ SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py | 3 ++- .../gad_mall/src/gad_mall_active_learning_ms.py | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md index 42d17b35f..68ea1b253 100644 --- a/SciAI/sciai/model/gad_mall/README.md +++ b/SciAI/sciai/model/gad_mall/README.md @@ -78,7 +78,7 @@ This project is based on the MindSpore deep learning framework. Below are the ma - 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: @@ -99,15 +99,15 @@ After installing MindSpore from the official website, you can start training and 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. diff --git a/SciAI/sciai/model/gad_mall/README_CN.md b/SciAI/sciai/model/gad_mall/README_CN.md index 211aa89b8..c7af15f47 100644 --- a/SciAI/sciai/model/gad_mall/README_CN.md +++ b/SciAI/sciai/model/gad_mall/README_CN.md @@ -42,8 +42,8 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 这些数据集用于支持GAD-MALL框架中各个模型的训练和测试。 - 数据下载: - - `Matrix12.npy`,`E.csv` 和 `yield.csv`: 存放于 `./src/data` 目录下 - + - `Matrix12.npy`,`E.csv` 和 `yield.csv`: 存放于 `./src/data` 目录下 + ```txt ├── data │ ├── E.csv @@ -98,13 +98,14 @@ GAD-MALL是一个基于主动学习(Active Learning)和3D卷积神经网络 ### 管道流程 通过官网安装好MindSpore和上面需要的数据集后,就可以开始在 GPU 上运行训练,生成架构设计-多目标主动学习循环 (GAD-MALL) 管道,请按照以下步骤操作: - 1. 训练 3D-CAE 模型作为生成模型GAD-MALL,请在终端中运行以下行: + + 1. 训练 3D-CAE 模型作为生成模型GAD-MALL,请在终端中运行以下行 python3.9 3D_CAE_ms.py - 2. 训练 3D-CNN 模型作为 GAD-MALL 的替代模型GAD-MALL,请在终端中运行以下行: + 2. 训练 3D-CNN 模型作为 GAD-MALL 的替代模型GAD-MALL,请在终端中运行以下行 python3.9 3D_CNN_ms.py - 3. 使用 GAD-MALL 搜索具有特定弹性模量和高屈服强度的高性能建筑材料,请在终端中运行以下行: + 3. 使用 GAD-MALL 搜索具有特定弹性模量和高屈服强度的高性能建筑材料,请在终端中运行以下行 python3.9 -u GAD_MALL_Active_learning.py - 4. 完成 GAD-MALL 流程后,您将获得具有特定预测弹性模量(E=2500 MPa、E=5000 MPa)和最高预测屈服强度的孔隙度矩阵。 + 4. 完成 GAD-MALL 流程后,您将获得具有特定预测弹性模量(E=2500 MPa、E=5000 MPa)和最高预测屈服强度的孔隙度矩阵 ## 脚本说明 diff --git a/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py index 830dc8dab..19667f3d2 100644 --- a/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py +++ b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py @@ -33,6 +33,7 @@ class CNN3D(nn.Cell): 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)) @@ -48,8 +49,8 @@ class CNN3D(nn.Cell): # Custom TQDM progress bar callback class TQDMProgressBar(Callback): - '''add progress bar thile training''' 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 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 index 9bcbb6b3d..8b5a29f83 100644 --- 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 @@ -457,7 +457,7 @@ def rej_sampling(gm, n_samples, target): 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%). -- Gitee From 88aa37154cd4ef700c6d007b55632bf65f71fb21 Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Thu, 12 Sep 2024 00:50:13 +0800 Subject: [PATCH 29/31] format correction --- .../src/gad_mall_active_learning_ms.py | 239 +++++++++++++++--- 1 file changed, 208 insertions(+), 31 deletions(-) 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 index 8b5a29f83..3531c24f3 100644 --- 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 @@ -276,43 +276,151 @@ def createv_2(data, sizeofdata, nofv, dofv): v = np.concatenate((v, temp2), axis=2) return v -def createunitofv(datainput, position, nofv, dofv): +# 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): """ - Generate a volumetric unit (3D matrix) by processing the neighboring values - around a given position in the input data. - + Handles NaN values in the neighboring data by interpolating them + based on surrounding valid data points. + 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. - + neibourhoods : np.array + A 3x3x3 array representing neighboring data points around a position. + 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 : np.array + The neighboring data array with NaN values replaced by interpolated values. """ - 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]): @@ -365,6 +473,29 @@ def createunitofv(datainput, position, nofv, dofv): 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)) @@ -406,6 +537,52 @@ def createunitofv(datainput, position, nofv, dofv): 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. -- Gitee From b5ba55fe162909d2180ad543a76fbe7949c140c8 Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Thu, 12 Sep 2024 00:56:34 +0800 Subject: [PATCH 30/31] format correction --- .../src/gad_mall_active_learning_ms.py | 1846 ++++++++--------- 1 file changed, 923 insertions(+), 923 deletions(-) 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 index 3531c24f3..ae3dbda19 100644 --- 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 @@ -1,318 +1,426 @@ -''' -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 +# ''' +# 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. -# def createunitofv(datainput, position, nofv, dofv): +# 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. # """ -# Generate a volumetric unit (3D matrix) by processing the neighboring values -# around a given position in the input data. +# 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: # ----------- -# datainput : np.array -# The input 3D data array representing a volumetric dataset. +# 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. -# 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. +# 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. -# nofv : int -# The size or number of features used for the construction of the volumetric unit. +# 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. -# dofv : int -# The degree of freedom or margin used to define the size of the volumetric unit around the neighborhood. +# 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: # -------- -# 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. +# 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. + # """ -# neibourhoods = findneighbour(datainput, position) -# unitofv = np.ones((nofv - 2 * dofv, nofv - 2 * dofv, nofv - 2 * dofv)) +# 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. -# 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 +# 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]): @@ -365,6 +473,29 @@ def createv_2(data, sizeofdata, nofv, dofv): # 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)) @@ -406,624 +537,493 @@ def createv_2(data, sizeofdata, nofv, dofv): # 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) +# 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) -- Gitee From d7d7acd303880e7f4e405f9b8a5667b1f463808e Mon Sep 17 00:00:00 2001 From: Noah-Xie Date: Thu, 12 Sep 2024 01:11:37 +0800 Subject: [PATCH 31/31] format correction --- SciAI/sciai/model/gad_mall/README.md | 2 ++ SciAI/sciai/model/gad_mall/src/cae_3d_ms.py | 8 ++++---- SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py | 11 ++++++----- .../gad_mall/src/gad_mall_active_learning_ms.py | 12 ++++++------ 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/SciAI/sciai/model/gad_mall/README.md b/SciAI/sciai/model/gad_mall/README.md index 68ea1b253..89e1f8349 100644 --- a/SciAI/sciai/model/gad_mall/README.md +++ b/SciAI/sciai/model/gad_mall/README.md @@ -55,6 +55,7 @@ These datasets support the training and testing of various models within the GAD - `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: @@ -98,6 +99,7 @@ After installing MindSpore from the official website, you can start training and ### 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``` diff --git a/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py b/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py index 8cd2826ca..718a19e20 100644 --- a/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py +++ b/SciAI/sciai/model/gad_mall/src/cae_3d_ms.py @@ -128,13 +128,13 @@ class TQDMProgressBar(Callback): self.progress_bar.close() # Number of steps per epoch -total_steps_per_epoch = train_data.get_dataset_size() +tot_steps_per_epoch = train_data.get_dataset_size() # Total number of epochs -total_epochs = 10 +tot_epochs = 10 # Initialize the progress bar callback -tqdm_callback = TQDMProgressBar(total_steps_per_epoch=total_steps_per_epoch, total_epochs=total_epochs) +tqdm_callback = TQDMProgressBar(total_steps_per_epoch=tot_steps_per_epoch, total_epochs=tot_epochs) # Train the model with progress bar -model.train(total_epochs, train_data, callbacks=[es, mc, re, ls, tqdm_callback], dataset_sink_mode=False) +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 index 19667f3d2..44bdaff1a 100644 --- a/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py +++ b/SciAI/sciai/model/gad_mall/src/cnn_3d_ms.py @@ -49,6 +49,7 @@ class CNN3D(nn.Cell): # 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__() @@ -110,14 +111,14 @@ ls = LossMonitor() total_steps_per_epoch = train_dataset.get_dataset_size() # Total number of epochs -total_epochs = 5 +tot_epochs = 5 # Initialize the progress bar callback -tqdm_callback = TQDMProgressBar(total_steps_per_epoch=total_steps_per_epoch, total_epochs=total_epochs) +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(total_epochs, train_dataset, callbacks=[ckpoint_cb, es, ls, tqdm_callback], dataset_sink_mode=False) +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") @@ -140,7 +141,7 @@ 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=total_epochs) +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(total_epochs, train_dataset2, callbacks=[ckpoint_cb2, es, ls, tqdm_callback2], dataset_sink_mode=False) +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/gad_mall_active_learning_ms.py b/SciAI/sciai/model/gad_mall/src/gad_mall_active_learning_ms.py index ae3dbda19..8e65f983e 100644 --- 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 @@ -410,12 +410,12 @@ # """ # 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 @@ -479,18 +479,18 @@ # 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 -- Gitee