Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions cgcnn2/cli/cgcnn_ft.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from cgcnn2.data import CIFData, collate_pool, full_set_split
from cgcnn2.model import CrystalGraphConvNet
from cgcnn2.utils import (
Normalizer,
cgcnn_test,
get_lr,
print_checkpoint_info,
Expand Down Expand Up @@ -293,7 +292,7 @@ def main():
sys.exit(1)
# Load checkpoint onto device
checkpoint = torch.load(
args.model_path, map_location=args.device, weights_only=False
args.model_path, map_location=args.device, weights_only=True
)
model_args = argparse.Namespace(**checkpoint["args"])

Expand Down Expand Up @@ -321,9 +320,6 @@ def main():
model.to(args.device)
model.eval()

normalizer = Normalizer(torch.zeros(3))
normalizer.load_state_dict(checkpoint["normalizer"])

print_checkpoint_info(checkpoint, args.model_path)

# Initialize DataLoader
Expand Down Expand Up @@ -522,7 +518,6 @@ def main():
savepoint = {
"epoch": epoch + 1,
"state_dict": model.state_dict(),
"normalizer": normalizer.state_dict(),
"best_mse_error": avg_valid_loss,
"args": vars(model_args),
}
Expand All @@ -547,7 +542,7 @@ def main():
# TEST WITH BEST MODEL
# --------------------
checkpoint = torch.load(
os.path.join(output_folder, "best_model.ckpt"), weights_only=False
os.path.join(output_folder, "best_model.ckpt"), weights_only=True
)
model.load_state_dict(checkpoint["state_dict"])

Expand Down
2 changes: 1 addition & 1 deletion cgcnn2/cli/cgcnn_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def main():

# Load checkpoint onto device
checkpoint = torch.load(
args.model_path, map_location=args.device, weights_only=False
args.model_path, map_location=args.device, weights_only=True
)
model_args = argparse.Namespace(**checkpoint["args"])

Expand Down
27 changes: 2 additions & 25 deletions cgcnn2/cli/cgcnn_tr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
import os
from pprint import pformat
from random import sample
import sys

import torch
Expand All @@ -11,7 +10,7 @@

from cgcnn2.data import CIFData, collate_pool, full_set_split
from cgcnn2.model import CrystalGraphConvNet
from cgcnn2.utils import Normalizer, cgcnn_test, get_lr, seed_everything, setup_logging
from cgcnn2.utils import cgcnn_test, get_lr, seed_everything, setup_logging


def parse_arguments(args=None):
Expand Down Expand Up @@ -275,26 +274,6 @@ def main():
)
sys.exit(1)

full_dataset = [*train_dataset, *valid_dataset, *test_dataset]

# Normalizer setup
# For classification we use a dummy normalizer, otherwise compute mean/std from data
if args.task == "classification":
normalizer = Normalizer(torch.zeros(2))
normalizer.load_state_dict({"mean": 0.0, "std": 1.0})
else:
if len(full_dataset) < 500:
logging.warning(
"Dataset has fewer than 500 data points; results may have higher variance."
)
sample_data_list = [full_dataset[i] for i in range(len(full_dataset))]
else:
sample_indices = sample(range(len(full_dataset)), 500)
sample_data_list = [full_dataset[i] for i in sample_indices]

_, sample_target, _ = collate_pool(sample_data_list)
normalizer = Normalizer(sample_target)

# Build model
# 1) gather input dimensions from first sample
structures, _, _ = train_dataset[0]
Expand Down Expand Up @@ -446,7 +425,6 @@ def main():
savepoint = {
"epoch": epoch + 1,
"state_dict": model.state_dict(),
"normalizer": normalizer.state_dict(),
"best_mse_error": avg_valid_loss,
"args": vars(args),
}
Expand All @@ -470,10 +448,9 @@ def main():
# TEST WITH BEST MODEL
# --------------------
best_checkpoint = torch.load(
os.path.join(output_folder, "best_model.ckpt"), weights_only=False
os.path.join(output_folder, "best_model.ckpt"), weights_only=True
)
model.load_state_dict(best_checkpoint["state_dict"])
normalizer.load_state_dict(best_checkpoint["normalizer"])

cgcnn_test(
model,
Expand Down
6 changes: 2 additions & 4 deletions cgcnn2/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,8 +708,8 @@ def cgcnn_pred(

checkpoint = torch.load(
model_path,
map_location=lambda storage, loc: storage if not cuda else None,
weights_only=False,
map_location="cuda" if cuda else "cpu",
weights_only=True,
)
structures, _, _ = total_dataset[0]
orig_atom_fea_len = structures[0].shape[-1]
Expand All @@ -726,8 +726,6 @@ def cgcnn_pred(
if cuda:
model.cuda()

normalizer = Normalizer(torch.zeros(3))
normalizer.load_state_dict(checkpoint["normalizer"])
model.load_state_dict(checkpoint["state_dict"])

if verbose >= 100:
Expand Down
4 changes: 2 additions & 2 deletions docs/3_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ Besides, we need some information about the pre-trained model architecture, whic
import torch
import argparse

checkpoint = torch.load(args.model_path, map_location=args.device, weights_only=False)
checkpoint = torch.load(args.model_path, map_location=args.device, weights_only=True)
model_args = argparse.Namespace(**checkpoint["args"])
atom_fea_len = model_args.atom_fea_len
n_conv = model_args.n_conv
h_fea_len = model_args.h_fea_len
n_h = model_args.n_h
```

where `atom_fea_len`, `n_conv`, `h_fea_len`, and `n_h` are the dimensions of the atom features, the number of convolutional layers, the dimension of the hidden features, and the number of hidden layers, respectively. Since PyTorch 2.6, `torch.load` defaults to `weights_only=True`, so `weights_only=False` is required to load full CGCNN checkpoints; only load checkpoint files from sources you trust. Now, we can initialize the model by:
where `atom_fea_len`, `n_conv`, `h_fea_len`, and `n_h` are the dimensions of the atom features, the number of convolutional layers, the dimension of the hidden features, and the number of hidden layers, respectively. CGCNN checkpoints contain only tensors and plain Python values, so they load with `weights_only=True` (the secure default since PyTorch 2.6), which prevents checkpoint files from executing arbitrary code when loaded. Now, we can initialize the model by:

```python
model = CrystalGraphConvNet(
Expand Down