Datawhale 春训营 材料设计赛道

作业1:理解赛题

🤔:本题任务是什么?这个任务是典型的什么问题?输入与输出是什么?

聚焦于 3D分子构象条件生成, 旨在通过生成式AI技术解决材料科学领域的核心挑战。

相关领域难点

  • 实验方法面临 高昂成本 与 复杂操作流程, 尤其在新材料、催化剂设计中分子结构数据严重匮乏。

  • 理论计算依赖 海量算力资源 (如量子力学计算),生成效率低,难以快速满足科研需求。

竞赛分为初赛(生成合理分子结构)和复赛(根据能量值定制分子),要求选手以人工智能方法生成符合 价键理论 且具有潜在应用价值的新分子。

赛题解读

初赛任务:生成合理的的 3D 分子结构 。选手通过训练集训练 AI 生成式模型,再用该模型生成 1 万个分子的 3D 结构(由原子元素种类和原子坐标表示,无顺序约束),后台会评测生成分子的合理性以及是否新颖。

输入数据: 分子构象数据,文件格式为 .pkl ,是用来训练模型的分子样本

由一个包含若干训练样本的 list 构成,每个样本包含一个 dict,字段说明如下:

字段

中文名

数据类型

说明

natoms

原子数量

int

表示当前样本总共的原子数量

elements

原子元素种类

List[str]

描述当前样本的组成原子种类,第 i 个元素表示第 i 个原子的元素种类

coordinates

原子坐标

List[List[float]]

描述当前样本每个原子的 3D 位置,顺序与 elements 的 value 对应,第 i 个元素表示第 i 个原子在笛卡尔坐标系中的坐标

样本数量

元素种类

单分子最大构象数量

4-5 万

C,H,O,N,F,P,S,Cl,Br

1

输出数据 :分子构象数据,文件格式为 .pkl ,生成的10000个分子结构

应通过基于输入数据训练出来的模型生成。 生成时,分子大小的分布,各元素出现频率的分布须与给定数据集一致;生成最大的分子的原子数不允许超过60,否则会影响最终提交结果及分数。 。文件中,所有分子数据存在一个列表中,每个分子表示为一个dict类,具有三个key:'natoms', 'elements', 'coordinates'。他们的value需要服从以下数据格式要求:

  • 'natoms' : int. # example: 46

  • 'elements' : list[str] # example: ['C', 'H', 'O']

  • 'coordinates' : list[list[float, float, float], list[float, float, float], ...] # example: [[1.2, 0.5, -0.2], [0.54, -0.41, 1.45]]

文件中生成的分子数目需严格等于10000。其它数目的提交文件被判作废

评价指标

首先根据真实的键长键角,判断生成分子中存在的化学键,根据化学键将 3D 分子映射为 2D 的图结构。

  1. 有效性 :根据价键理论判断原子和分子稳定性;利用 RDKiT 库函数及一些自定义规则判断分子是否合理,统计合理分子占总生成分子数的比例。

  2. 唯一性 :筛选具有有效性的去除所有重复分子,计算剩下不重复分子占总生成分子数的比例。

  3. 创新性 :在去重的分子中,统计训练集中未出现的分子占总生成分子数的比例。

  4. 数据集分布相似性(反作弊评分) :赛事方后台会计算选手提交文件和训练集分布的差异,严重脱离训练集分布的结果会被标记为异常结果,并会影响分数,赛事方会进行相应核查。

最终分数由 1,2,3 分数加权组合得到,对于满足原则的生成结果, 数据集分布相似性不会影响分数 。

🤔:我们需要用到的数据有哪些?长什么样子

import pickle
import sys
import pprint

def print_pkl_content(file_path):
    """打印pkl文件的内容"""
    try:
        with open(file_path, 'rb') as f:
            data = pickle.load(f)
        
        print(f"数据类型: {type(data)}")
        
        if isinstance(data, dict):
            print("\n字典键:")
            for key in data.keys():
                print(f"  - {key} (类型: {type(data[key])})")
            
            print("\n详细内容:")
            pp = pprint.PrettyPrinter(indent=2)
            pp.pprint(data)
        elif isinstance(data, list):
            print(f"\n列表长度: {len(data)}")
            if len(data) > 0:
                print(f"第一个元素类型: {type(data[0])}")
                print("\n前几个元素:")
                pp = pprint.PrettyPrinter(indent=2)
                pp.pprint(data)
        else:
            print("\n内容:")
            pp = pprint.PrettyPrinter(indent=2)
            pp.pprint(data)
            
    except Exception as e:
        print(f"打开文件时出错: {e}")

if __name__ == "__main__":
    file_path = "/root/competition/data_all.pkl"
    print_pkl_content(file_path)

一开始我们可能会觉得 赛事提供的 data_all.pkl 和提供的 baseline 的中包含的数据不一致,

但事实上是一致的 但是赛事方帮我们把原本的数据进行拆解为三个子集,并且按照训练的输入输出进行了转化,可以从下面的代码去观察整个 baseline 训练数据的分布和数据的输入格式,注意修改 directory_path

import pickle
import numpy as np
import os
import pprint
from pathlib import Path

def print_pickle_content(file_path):
    """打印pickle文件的内容"""
    try:
        with open(file_path, 'rb') as f:
            data = pickle.load(f)
        
        print(f"文件: {os.path.basename(file_path)}")
        print(f"数据类型: {type(data)}")
        
        if isinstance(data, dict):
            print("\n字典键:")
            for key in data.keys():
                print(f"  - {key} (类型: {type(data[key])})")
                
                # 打印字典值的更多信息
                if isinstance(data[key], np.ndarray):
                    print(f"    形状: {data[key].shape}, 数据类型: {data[key].dtype}")
                    if data[key].size < 10:
                        print(f"    内容: {data[key]}")
                    else:
                        print(f"    前几个元素: {data[key].flatten()[:5]}...")
                elif isinstance(data[key], list):
                    print(f"    长度: {len(data[key])}")
                    if len(data[key]) < 5:
                        print(f"    内容: {data[key]}")
                    else:
                        print(f"    前几个元素: {data[key][:5]}...")
            
            # 对于较小的字典,打印完整内容
            if len(data) < 5:
                print("\n完整内容:")
                pp = pprint.PrettyPrinter(indent=2)
                pp.pprint(data)
                
        elif isinstance(data, list):
            print(f"\n列表长度: {len(data)}")
            if len(data) > 0:
                print(f"第一个元素类型: {type(data[0])}")
                print("\n前几个元素:")
                pp = pprint.PrettyPrinter(indent=2)
                pp.pprint(data[:5] if len(data) > 5 else data)
        else:
            print("\n内容:")
            pp = pprint.PrettyPrinter(indent=2)
            pp.pprint(data)
            
    except Exception as e:
        print(f"打开pickle文件时出错: {e}")

def print_npz_content(file_path):
    """打印npz文件的内容"""
    try:
        data = np.load(file_path)
        
        print(f"文件: {os.path.basename(file_path)}")
        print(f"数据类型: {type(data)}")
        
        if isinstance(data, np.lib.npyio.NpzFile):
            print("\n数组键:")
            for key in data.files:
                array = data[key]
                print(f"  - {key}: 形状 {array.shape}, 数据类型 {array.dtype}")
                if array.size < 10:
                    print(f"    内容: {array}")
                else:
                    if array.ndim > 1:
                        print(f"    第一行内容: {array[0]} 长度为{len(array[0])}")
                    else:
                        print(f"    前几个元素: {array[:5]}...")
        else:
            print(f"形状: {data.shape}, 数据类型: {data.dtype}")
            if data.size < 10:
                print(f"内容: {data}")
            else:
                print(f"前几个元素: {data.flatten()[:5]}...")
            
    except Exception as e:
        print(f"打开npz文件时出错: {e}")

def print_directory_contents(directory_path):
    """打印目录中所有文件的内容"""
    dir_path = Path(directory_path)
    
    if not dir_path.exists() or not dir_path.is_dir():
        print(f"错误: {directory_path} 不是一个有效的目录")
        return
    
    files = list(dir_path.glob("*"))
    print(f"目录 {directory_path} 中共有 {len(files)} 个文件")
    
    for file_path in files:
        print("\n" + "="*50)
        print(f"处理文件: {file_path}")
        
        if file_path.suffix.lower() in ('.pickle', '.pkl'):
            print_pickle_content(file_path)
        elif file_path.suffix.lower() == '.npz':
            print_npz_content(file_path)
        else:
            print(f"不支持的文件类型: {file_path.suffix}")
        
        print("="*50)

if __name__ == "__main__":
    directory_path = "/root/competition/data/competition"
    print_directory_contents(directory_path) 

如果赛事方更新了训练数据,或者希望自己重新切分数据比例,或者针对数据进行增强,需要额外处理数据的格式,在这里我们给出数据切分代码,由 pkl 转为 train、valid、test 的三个 npz 文件。

import pickle
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
from copy import deepcopy

all_data = pickle.load(open('data_all.pkl', 'rb'))
all_data = pd.DataFrame(all_data)

natoms_data = all_data['natoms'].to_numpy()

atom_dict = {
    "C": 6,
    "H": 1,
    "O": 8,
    "N": 7,
    "F": 9,
    "P": 15,
    "S": 16,
    "Cl": 17,
    "Br": 35,
}
elements_data = []
for element in all_data["elements"]:
    element_list = []
    for atom in element:
        element_list.append(atom_dict[atom])
    element_list = np.array(element_list)
    element_list = np.pad(element_list, (0, 60 - len(element_list)), mode="constant", constant_values=0)
    element_list = element_list[:60]
    elements_data.append(element_list)
elements_data = np.array(elements_data)

coor_list = []
for element in all_data["coordinates"]:
    element = deepcopy(element)
    if len(element) < 60:
        element.extend([[0.0, 0.0, 0.0]] * (60 - len(element)))
    element = np.array(element)
    element = element[:60]
    coor_list.append(element)
coor_data = np.array(coor_list)

train_natoms, temp_natoms = train_test_split(natoms_data, test_size=0.2, random_state=42)
val_natoms, test_natoms = train_test_split(temp_natoms, test_size=0.5, random_state=42)

train_elements, temp_elements = train_test_split(elements_data, test_size=0.2, random_state=42)
val_elements, test_elements = train_test_split(temp_elements, test_size=0.5, random_state=42)

train_coor, temp_coor = train_test_split(coor_data, test_size=0.2, random_state=42)
val_coor, test_coor = train_test_split(temp_coor, test_size=0.5, random_state=42)

train_data = np.savez_compressed('train.npz', natoms=train_natoms, charges=train_elements, positions=train_coor)

val_data = np.savez_compressed('valid.npz', natoms=val_natoms, charges=val_elements, positions=val_coor)

test_data = np.savez_compressed('test.npz', natoms=test_natoms, charges=test_elements, positions=test_coor)

‘/

num_atoms: [17 21 19 ... 25 32 18] 表示为原子数量
charges:[ 6  6  8  8  6  6  6  7  6 16  1  1  1  1  1  1  1  0  0  0  0  0  0  0
  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  0  0  0  0  0  0  0  0  0  0  0  0] 长度为60 表示为对应的原子序列数 赛事要求生成的原子序列数得小于60 
  这样的输入符合条件
  positions:[[-3.21805733e+00  7.10018754e-01  2.50179573e-01]
 [-2.23032949e+00 -4.05445001e-01  1.49888750e-02]
 [-2.50381737e+00 -1.55804960e+00 -2.07941942e-01]
 [-9.58817155e-01  5.01882687e-02  8.09005480e-02]
 [ 7.36242693e-02 -9.30148255e-01 -1.24097884e-01]
 [ 1.40729161e+00 -2.75227023e-01 -9.75905600e-04]
 [ 2.37120845e+00 -1.26356958e-01 -9.68925145e-01]
 [ 3.52556242e+00  5.03332756e-01 -5.88108377e-01]
 [ 3.46803644e+00  8.49552271e-01  6.62381934e-01]
 [ 1.98850575e+00  4.26801859e-01  1.48299858e+00]
 [-3.08777001e+00  1.49176138e+00 -5.14021375e-01]
 [-4.23860031e+00  3.11550965e-01  2.09990471e-01]
 [-3.03139238e+00  1.17887217e+00  1.22840531e+00]
 [-6.09373042e-02 -1.74530731e+00  6.05643289e-01]
 [-3.04329331e-02 -1.37704055e+00 -1.12549782e+00]
 [ 2.26174413e+00 -4.81177501e-01 -1.99641722e+00]
 [ 4.26418121e+00  1.37657377e+00  1.19419709e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]] 长度为60 表示为原子在3d空间的位置分布

如何来解决这个题目?/

使用赛事官方提供的等变扩散模型(EDM),这是基于 Diffusion Model 的一种变种模型,加入了 E(3) 等变性。

E(3) 等变性'

在固体材料的晶体结构中,存在着一些特定的变化规律。我们想象一个在桌上放着的小球,现在有一个力施加在小球上面,现在将这个小球向右平移 10 厘米,这个力的方向和大小有什么变化?这个小球的势能有什么变化?

答案是:力和势能都不发生变化。

那同样的问题,这时候我们旋转小球呢?小球的势能依旧不变,但是这时候它的受力会跟着坐标轴的旋转而一起旋转。另外还有种情况就是镜像对称,假设有个魔法镜子,能生成一个镜像小球,那这个镜像小球的受力和势能会怎么变化呢?结果应该是势能不变,但是受力会随着镜面(实际是坐标轴)一起对称。

晶体是由许多个原子组成,在不考虑复杂的固体物理知识和宇称不守恒的前提下,我们可以将小球上会发生的事情套用在晶体中的原子上,我们发现,在材料的晶体结构中似乎存在着三种特殊的变化,它们分别与平移、旋转和镜面对称相关,这就是所谓的 E(3) 等变性

🤔:baseline里有哪些文件、有什么作用?吃透需要关注哪些核心函数?

训练脚本 train.sh

注意请不要修改 dataset 的参数

因为"competition"参数默认使用赛事要求的对应的元素种类【C,H,O,N,F,P,S,Cl,Br】 并且限制最大的分子原子数为 60。

参数设计小 tips

如果发现提交结果分数为 0 主要是因为设置的 n_epochs 太小在原本的 baseline 如果 epochs 小于 30 基本都为 0 可以尝试调大 layers 注意 diffusion_steps 没必要调太大(但也不能太小,500 合适) 这样会导致需要耗费很多的时间在后面生成分子上

##train.sh
python main.py --n_epochs 100 \
    --exp_name edm_competition \
    --n_stability_samples 1000 \
    --diffusion_noise_schedule polynomial_2 \
    --diffusion_noise_precision 1e-5 \
    --diffusion_steps 500 \
    --diffusion_loss_type l2 \
    --ema_decay 0.9999 \
    --dataset "competition" \
    --datadir "./data/competition"

生成分子的命令

需要修改的是--model_path 后的路径得是你训练后的路径 一般保存在 outputs 下面 然后 n_samples 不要修改一定要为 10000 赛事要求生成的分子数量得为 10000

python sample.py --model_path ./outputs/edm_competition_20250321_171233 \
    --n_samples 10000

进阶Task2:深入赛题  丝滑实现

节省算力 --- 无卡启动

jupyterlab 进入 /root/sais_third_material_baseline 目录

diffusion_steps 应该是扩散过程的总步数,diffusion_noise_schedule 是噪声的分布策略,diffusion_noise_precision 是噪声的精度,diffusion_loss_type 是损失函数的选择

parser.add_argument('--diffusion_steps', type=int, default=1000)  # 增加步数
parser.add_argument('--diffusion_noise_schedule', type=str, default='cosine')  # 使用余弦调度
parser.add_argument('--diffusion_noise_precision', type=float, default=1e-6)  # 增加精度
parser.add_argument('--diffusion_loss_type', type=str, default='vlb')  # 使用 VLB 损失

# parser.add_argument("--conditioning", nargs='+', default=[],
#                     help='arguments : homo | lumo | alpha | gap | mu | Cv' )

一
parser.add_argument("--conditioning", nargs='+', default=['homo', 'lumo', 'gap'],
                    help='arguments : homo | lumo | alpha | gap | mu | Cv')
二
parser.add_argument("--conditioning", nargs='+', default=['mu', 'Cv'],
                    help='arguments : homo | lumo | alpha | gap | mu | Cv')
三
parser.add_argument("--conditioning", nargs='+', default=['homo', 'lumo', 'gap'],
                    help='arguments : homo | lumo | alpha | gap | mu | Cv')

保存并关机

突然变一卡了 ,非常纳闷 

可以设一个200min左右的定时关机

edm_competition_resume_xxxx 目录替换到下面的命令中

python sample.py --model_path ./outputs/替换到这里 --n_samples 10000


/competition/outputs/debug_10_20250424_120247

python sample.py --model_path ./outputs/debug_10_20250424_120247 --n_samples 10000

进阶三 - - 

Dataset  数据集

Offical Dataset  官方数据集

The offical raw GEOM dataset is avaiable [here].
官方原始 GEOM 数据集可在[此处]获取。

Preprocessed dataset  预处理数据集

We provide the preprocessed datasets (GEOM) in this [google drive folder]. After downleading the dataset, it should be put into the folder path as specified in the dataset variable of config files ./configs/*.yml.
我们在此[谷歌驱动文件夹]中提供了预处理的 GEOM 数据集( ./configs/*.yml )。下载数据集后,应将其放入配置文件中指定的 dataset 变量路径下。

Prepare your own GEOM dataset from scratch (optional)
从头开始准备自己的 GEOM 数据集(可选)

You can also download origianl GEOM full dataset and prepare your own data split. A guide is available at previous work ConfGF's [github page].
您也可以下载原始 GEOM 完整数据集并准备您自己的数据分割。指南可在之前工作的 ConfGF 的[github 页面]找到。

https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/JNGTDF

原始数据就不下载了

Preprocessed dataset  预处理数据集 下载

ICLR22 GeoDiff - Google Drive

python train.py /config/drugs_default.yml

 参考——————————————————————————————————————————————————

原笔迹



第三届世界科学智能大赛材料设计赛道:3D分子构象条件生成

http://competition.sais.com.cn/competitionDetail/532312/format

赛题和数据

http://competition.sais.com.cn/competitionDetail/532312/competitionData

Task

然而,在许多特定领域(如新材料设计、催化剂设计等),分子结构数据往往存在严重匮乏的现象。实验方法受限于高昂的成本与复杂性,而理论计算则需要投入大量时间和计算资源,难以快速填补这一空白。为应对这一挑战,本次比赛以“分子设计”为主题,聚焦生成式AI在3D分子结构生成中的应用潜力,期待选手利用生成式模型建立有效的3D结构生成模型,探索如何利用人工智能技术高效生成具有潜在应用价值的分子结构。

选手可以获取赛事方提供的小分子结构数据集,其中包含某一领域分子的结构信息。参赛者需基于该数据,训练生成式AI模型,完成以下目标

初赛

任务:广泛生成可能存在的3D分子结构。生成的分子需符合物理化学规则并保证新颖性。具体任务如下:

  • 训练生成模型后,无条件地生成1万个分子的3D结构(由原子元素种类和原子坐标表示,无顺序约束)。后台会用相关指标判断分子的生成质量和新颖性。

PS注意

选手必须通过训练集训练AI生成式模型,再用该模型生成1万个分子的3D结构(由原子元素种类和原子坐标表示,无顺序约束)

每天可提交次数 3 次(提交的结果output.pkl, 不能超过 100M)

competition

https://gitcode.com/gh_mirrors/e3/e3_diffusion_for_molecules

我们先跑一遍baseline,打个分

依据readme创建虚拟环境

## 配置环境
```
conda create -n com python==3.12.0
conda activate com
pip install -r /group_share/3Dmol/competition/requirements.txt
```
cd /group_share/3Dmol/competition
## 训练EDM模型
```
bash train.sh                        ## 50% A100 左右启动训练
```
## 采样生成数据
```
python sample.py --model_path "./outputs/competition" \
    --n_samples
```

Clipped gradient with value 50.3 while allowed 5.9

梯度裁剪(Gradient Clipping)机制正在保护你的模型训练过程

 

python sample.py --model_path ./outputs/edm_competition_20250328_224703 \ --n_samples 10

查看目录

 
(com) root@intern-studio-50153054:/group_share/3Dmol# tree -L 3
.
|-- __MACOSX
|   `-- competition
|-- attempt.ipynb                #新建
|-- competition
|   |-- README.md
|   |-- __pycache__
|   |   `-- utils.cpython-310.pyc
|   |-- configs
|   |   |-- __pycache__
|   |   |-- datasets_config.py
|   |   `-- qm9_config.yaml
|   |-- data
|   |   `-- competition
|   |-- egnn
|   |   |-- __pycache__
|   |   |-- egnn.py
|   |   |-- egnn_new.py
|   |   `-- models.py
|   |-- equivariant_diffusion
|   |   |-- __init__.py
|   |   |-- __pycache__
|   |   |-- distributions.py
|   |   |-- en_diffusion.py
|   |   |-- overview.png
|   |   |-- training.png
|   |   `-- utils.py
|   |-- main.py
|   |-- qm9
|   |   |-- __init__.py
|   |   |-- __pycache__
|   |   |-- analyze.py
|   |   |-- bond_analyze.py
|   |   |-- data
|   |   |-- dataset.py
|   |   |-- losses.py
|   |   |-- models.py
|   |   |-- property_prediction
|   |   |-- rdkit_functions.py
|   |   |-- sampling.py
|   |   |-- utils.py
|   |   `-- visualizer.py
|   |-- requirements.txt
|   |-- sample.py
|   |-- sample.sh
|   |-- train.sh
|   |-- train_test.py
|   `-- utils.py
|-- competition.zip
|-- data
|   |-- data_all.pkl
|   `-- data_all.zip
`-- data.csv       # pkl 转的        

17 directories, 35 files

python sample.py --model_path ./outputs/edm_competition_20250329_225950 --n_samples 1000 ## X 10 = 10000

相关模型github地址与文章

https://github.com/MinkaiXu/GeoDiff

https://mp.weixin.qq.com/s/Qx5U0xhdlfu7vUmKQY2Q6A

https://github.com/tencent-ailab/MDM

https://zhuanlan.zhihu.com/p/668287513

扩散模型算法实战——分子生成:从理论到药物发现革命_扩散模型edm-优快云博客

SQL Prompt是Red Gate Software公司开发的一款强大的SQL代码编辑和优化工具,主要面向数据库开发者和管理员。版本11.0.1.16766是一个更新版本,它提供了更高效、更便捷的SQL编写环境,旨在提升SQL代码的可读性、效率和一致性。这个安装包包含了所有必要的组件,用于在用户的计算机上安装SQL Prompt工具。 SQL Prompt的核心功能包括自动完成、智能提示、格式化和重构。自动完成功能能够帮助用户快速输入SQL语句,减少键入错误;智能提示则基于上下文提供可能的选项,加快编写速度;格式化功能允许用户按照自定义或预设的编码规范对SQL代码进行美化,提升代码的可读性;而重构工具则可以帮助用户优化代码结构,消除潜在问题。 在描述中提到的“代码格式化规则来源于网络”,指的是用户可以通过下载网络上的json文件来扩展或定制SQL Prompt的代码格式化规则。这些json文件包含了特定的格式设置,如缩进风格、空格使用、注释位置等。将这些文件复制到指定的目录(例如:C:\Users\用户名\AppData\Local\Red Gate\SQL Prompt 10\Styles)后,SQL Prompt会读取这些规则并应用到代码格式化过程中,使得用户可以根据个人偏好或团队规范调整代码样式。 以下几点请注意: 1. 经实测,此版本支持最新的Sql Server 2022版的SSMS21 2. 此安装包中不包括keygen,请自行解决
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值