embkit 0.2__tar.gz → 0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {embkit-0.2 → embkit-0.3}/PKG-INFO +3 -1
- {embkit-0.2 → embkit-0.3}/pyproject.toml +5 -3
- {embkit-0.2 → embkit-0.3}/src/embkit/__init__.py +23 -8
- {embkit-0.2 → embkit-0.3}/src/embkit/__main__.py +14 -4
- {embkit-0.2 → embkit-0.3}/src/embkit/align.py +0 -41
- {embkit-0.2 → embkit-0.3}/src/embkit/commands/__init__.py +2 -2
- {embkit-0.2 → embkit-0.3}/src/embkit/commands/align.py +2 -7
- {embkit-0.2 → embkit-0.3}/src/embkit/commands/cbio.py +1 -1
- {embkit-0.2 → embkit-0.3}/src/embkit/commands/model.py +98 -85
- {embkit-0.2 → embkit-0.3}/src/embkit/commands/protein.py +21 -6
- embkit-0.2/src/embkit/commands/datasets.py → embkit-0.3/src/embkit/commands/resources.py +6 -6
- {embkit-0.2 → embkit-0.3}/src/embkit/constraints/network_constraint.py +19 -1
- embkit-0.3/src/embkit/datasets/__init__.py +51 -0
- embkit-0.3/src/embkit/encoding/__init__.py +155 -0
- embkit-0.3/src/embkit/encoding/protein.py +98 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/estimator/vae_estimator.py +2 -2
- embkit-0.3/src/embkit/factory/__init__.py +17 -0
- embkit-0.3/src/embkit/factory/core.py +46 -0
- embkit-0.3/src/embkit/factory/layers.py +253 -0
- embkit-0.3/src/embkit/factory/mapping.py +117 -0
- embkit-0.3/src/embkit/factory/registry.py +71 -0
- embkit-0.3/src/embkit/files/__init__.py +3 -0
- embkit-0.3/src/embkit/files/h5.py +131 -0
- embkit-0.3/src/embkit/files/json.py +20 -0
- {embkit-0.2/src/embkit/file_readers → embkit-0.3/src/embkit/files}/read_csv.py +57 -47
- {embkit-0.2 → embkit-0.3}/src/embkit/losses/vae_loss.py +6 -5
- embkit-0.3/src/embkit/models/ffnn.py +50 -0
- embkit-0.3/src/embkit/models/vae/base_vae.py +112 -0
- embkit-0.3/src/embkit/models/vae/decoder.py +84 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/models/vae/encoder.py +57 -37
- embkit-0.3/src/embkit/models/vae/net_vae.py +115 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/models/vae/rna_vae.py +5 -5
- embkit-0.3/src/embkit/models/vae/vae.py +102 -0
- embkit-0.3/src/embkit/modules/__init__.py +18 -0
- {embkit-0.2/src/embkit/layers → embkit-0.3/src/embkit/modules}/masked_linear.py +2 -2
- {embkit-0.2/src/embkit/layers → embkit-0.3/src/embkit/modules}/tsp.py +3 -3
- embkit-0.3/src/embkit/optimize/__init__.py +504 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/pathway.py +50 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/preprocessing/__init__.py +2 -2
- embkit-0.3/src/embkit/preprocessing/dataset.py +35 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/preprocessing/normalize.py +35 -4
- {embkit-0.2/src/embkit/datasets → embkit-0.3/src/embkit/resources}/c_bio_portal.py +4 -3
- {embkit-0.2/src/embkit/datasets → embkit-0.3/src/embkit/resources}/gtex.py +2 -2
- {embkit-0.2/src/embkit/datasets → embkit-0.3/src/embkit/resources}/hugo.py +1 -1
- embkit-0.2/src/embkit/datasets/dataset.py → embkit-0.3/src/embkit/resources/resource.py +24 -20
- {embkit-0.2/src/embkit/datasets → embkit-0.3/src/embkit/resources}/sif.py +1 -1
- {embkit-0.2 → embkit-0.3}/src/embkit/utilities/kmeans.py +1 -1
- {embkit-0.2 → embkit-0.3}/src/embkit/utilities/pca.py +1 -1
- embkit-0.3/src/embkit/version.py +62 -0
- {embkit-0.2 → embkit-0.3}/src/embkit.egg-info/PKG-INFO +3 -1
- {embkit-0.2 → embkit-0.3}/src/embkit.egg-info/SOURCES.txt +27 -20
- {embkit-0.2 → embkit-0.3}/src/embkit.egg-info/requires.txt +2 -0
- {embkit-0.2 → embkit-0.3}/tests/test_main.py +29 -0
- embkit-0.2/src/embkit/file_readers/__init__.py +0 -1
- embkit-0.2/src/embkit/layers/__init__.py +0 -33
- embkit-0.2/src/embkit/layers/constraint_info.py +0 -111
- embkit-0.2/src/embkit/layers/layer_info.py +0 -108
- embkit-0.2/src/embkit/models/ffnn.py +0 -151
- embkit-0.2/src/embkit/models/hla2vec.py +0 -307
- embkit-0.2/src/embkit/models/protein.py +0 -175
- embkit-0.2/src/embkit/models/vae/base_vae.py +0 -327
- embkit-0.2/src/embkit/models/vae/decoder.py +0 -58
- embkit-0.2/src/embkit/models/vae/hla2vec.py +0 -307
- embkit-0.2/src/embkit/models/vae/net_vae.py +0 -192
- embkit-0.2/src/embkit/models/vae/pytorch.py +0 -150
- embkit-0.2/src/embkit/models/vae/vae.py +0 -218
- {embkit-0.2 → embkit-0.3}/README.md +0 -0
- {embkit-0.2 → embkit-0.3}/setup.cfg +0 -0
- {embkit-0.2 → embkit-0.3}/setup.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/bmeg.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/c_bio/__init__.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/c_bio/api.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/commands/matrix.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/constraints/__init__.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/estimator/__init__.py +0 -0
- {embkit-0.2/src/embkit/preprocessing → embkit-0.3/src/embkit/files}/loaders.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/losses/__init__.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/metrics/__init__.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/metrics/distance/__init__.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/metrics/distance/metrics.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/models/__init__.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/models/vae/__init__.py +0 -0
- {embkit-0.2/src/embkit/layers → embkit-0.3/src/embkit/modules}/pairwise_comparison_layer.py +0 -0
- {embkit-0.2/src/embkit/datasets → embkit-0.3/src/embkit/resources}/__init__.py +0 -0
- {embkit-0.2/src/embkit/datasets → embkit-0.3/src/embkit/resources}/util.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit/utilities/__init__.py +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit.egg-info/dependency_links.txt +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit.egg-info/entry_points.txt +0 -0
- {embkit-0.2 → embkit-0.3}/src/embkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: embkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3
|
|
4
4
|
Summary: Embedding Kit for embedding models
|
|
5
5
|
Author-email: Kyle Ellrott <ellrott@ohsu.edu>, Raphael Kirchgaessner <kirchgae@ohsu.edu>
|
|
6
6
|
License: MIT
|
|
@@ -17,6 +17,8 @@ Requires-Dist: gripql
|
|
|
17
17
|
Requires-Dist: tqdm
|
|
18
18
|
Requires-Dist: biopython
|
|
19
19
|
Requires-Dist: fair-esm
|
|
20
|
+
Requires-Dist: faiss-cpu
|
|
21
|
+
Requires-Dist: h5py
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
# Embedding Kit
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "embkit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3"
|
|
8
8
|
description = "Embedding Kit for embedding models"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -24,7 +24,9 @@ dependencies = [
|
|
|
24
24
|
"gripql",
|
|
25
25
|
"tqdm",
|
|
26
26
|
"biopython",
|
|
27
|
-
"fair-esm"
|
|
27
|
+
"fair-esm",
|
|
28
|
+
"faiss-cpu",
|
|
29
|
+
"h5py"
|
|
28
30
|
]
|
|
29
31
|
|
|
30
32
|
[tool.setuptools]
|
|
@@ -34,4 +36,4 @@ package-dir = { "" = "src" }
|
|
|
34
36
|
where = ["src"]
|
|
35
37
|
|
|
36
38
|
[project.scripts]
|
|
37
|
-
embkit = "embkit.__main__:cli"
|
|
39
|
+
embkit = "embkit.__main__:cli"
|
|
@@ -24,7 +24,7 @@ def get_device() -> torch.device:
|
|
|
24
24
|
logger.info("Using CPU")
|
|
25
25
|
return torch.device("cpu")
|
|
26
26
|
|
|
27
|
-
def dataframe_tensor(df: pd.DataFrame,device=None) -> torch.Tensor:
|
|
27
|
+
def dataframe_tensor(df: pd.DataFrame, device=None, dtype=torch.float32) -> torch.Tensor:
|
|
28
28
|
"""
|
|
29
29
|
dataframe_tensor
|
|
30
30
|
|
|
@@ -32,7 +32,7 @@ def dataframe_tensor(df: pd.DataFrame,device=None) -> torch.Tensor:
|
|
|
32
32
|
"""
|
|
33
33
|
if device is None:
|
|
34
34
|
device = get_device()
|
|
35
|
-
return torch.from_numpy(df.
|
|
35
|
+
return torch.from_numpy(df.to_numpy(copy=True)).to(device=device, dtype=dtype)
|
|
36
36
|
|
|
37
37
|
def tensor_dataframe(tn: torch.Tensor, index=None, columns=None) -> pd.DataFrame:
|
|
38
38
|
"""
|
|
@@ -40,11 +40,29 @@ def tensor_dataframe(tn: torch.Tensor, index=None, columns=None) -> pd.DataFrame
|
|
|
40
40
|
|
|
41
41
|
take a torch tensor, create a pandas dataframe
|
|
42
42
|
"""
|
|
43
|
-
return pd.DataFrame(tn.cpu
|
|
43
|
+
return pd.DataFrame(tn.to(device="cpu", dtype=torch.float32).detach().numpy(), index=index, columns=columns)
|
|
44
|
+
|
|
45
|
+
def dataframe_dataset(df: pd.DataFrame, device=None, dtype=torch.float32) -> torch.utils.data.Dataset:
|
|
46
|
+
"""
|
|
47
|
+
dataframe_dataset
|
|
48
|
+
|
|
49
|
+
take a pandas dataframe and return a pytorch dataset
|
|
50
|
+
|
|
51
|
+
:param df: Input pandas Dataframe
|
|
52
|
+
:type df: pd.DataFrame
|
|
53
|
+
:param device: Device to put torch tensors on
|
|
54
|
+
:return: Description
|
|
55
|
+
:rtype: Dataset
|
|
56
|
+
"""
|
|
57
|
+
if device is None:
|
|
58
|
+
device = get_device()
|
|
59
|
+
x = torch.from_numpy(df.to_numpy(copy=True)).to(device=device, dtype=dtype)
|
|
60
|
+
dataset = TensorDataset(x)
|
|
61
|
+
return dataset
|
|
44
62
|
|
|
45
63
|
def dataframe_loader(df: pd.DataFrame,
|
|
46
64
|
batch_size = 256, shuffle=True,
|
|
47
|
-
device=None) -> torch.utils.data.DataLoader:
|
|
65
|
+
device=None, dtype=torch.float32) -> torch.utils.data.DataLoader:
|
|
48
66
|
"""
|
|
49
67
|
dataframe_loader
|
|
50
68
|
|
|
@@ -54,9 +72,6 @@ def dataframe_loader(df: pd.DataFrame,
|
|
|
54
72
|
:param device: Device the where tensor should be moved. If None, use get_device
|
|
55
73
|
"""
|
|
56
74
|
|
|
57
|
-
|
|
58
|
-
device = get_device()
|
|
59
|
-
x = torch.from_numpy(df.values.astype(np.float32)).to(device)
|
|
60
|
-
dataset = TensorDataset(x)
|
|
75
|
+
dataset = dataframe_dataset(df, device=device, dtype=dtype)
|
|
61
76
|
data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=shuffle)
|
|
62
77
|
return data_loader
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import click
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
-
from .
|
|
4
|
+
from embkit.version import get_version
|
|
5
|
+
|
|
6
|
+
from .commands import model, matrix, cbio_cmd, protein, resources, align
|
|
5
7
|
|
|
6
8
|
@click.group(invoke_without_command=True)
|
|
7
9
|
@click.option('--verbose', is_flag=True, help="Enable verbose logging")
|
|
10
|
+
@click.option('--version', is_flag=True, help="Show version information")
|
|
8
11
|
@click.pass_context
|
|
9
|
-
def cli(ctx, verbose):
|
|
12
|
+
def cli(ctx, verbose, version):
|
|
10
13
|
"""Embedding Kit CLI.
|
|
11
14
|
|
|
12
15
|
Use 'embkit help [COMMAND]' for details on a specific command.
|
|
@@ -20,6 +23,10 @@ def cli(ctx, verbose):
|
|
|
20
23
|
ctx.ensure_object(dict)
|
|
21
24
|
ctx.obj["VERBOSE"] = verbose
|
|
22
25
|
|
|
26
|
+
if version:
|
|
27
|
+
click.echo(get_version())
|
|
28
|
+
ctx.exit()
|
|
29
|
+
|
|
23
30
|
if ctx.invoked_subcommand is None:
|
|
24
31
|
click.echo(ctx.get_help())
|
|
25
32
|
|
|
@@ -29,7 +36,7 @@ cli.add_command(model)
|
|
|
29
36
|
cli.add_command(matrix)
|
|
30
37
|
cli.add_command(cbio_cmd)
|
|
31
38
|
cli.add_command(protein)
|
|
32
|
-
cli.add_command(
|
|
39
|
+
cli.add_command(resources)
|
|
33
40
|
cli.add_command(align)
|
|
34
41
|
|
|
35
42
|
|
|
@@ -62,11 +69,14 @@ def help_cmd(ctx, path):
|
|
|
62
69
|
info_name = []
|
|
63
70
|
parent = ctx.parent # start from top-level context
|
|
64
71
|
for part in path:
|
|
65
|
-
if not
|
|
72
|
+
if not isinstance(cmd, click.Group):
|
|
66
73
|
click.echo(cli.get_help(ctx)) # pragma: no cover
|
|
74
|
+
return
|
|
75
|
+
|
|
67
76
|
nxt_cmd = cmd.get_command(parent, part)
|
|
68
77
|
if nxt_cmd is None:
|
|
69
78
|
raise click.UsageError(f"Unknown command: {' '.join(path)}")
|
|
79
|
+
|
|
70
80
|
info_name.append(part)
|
|
71
81
|
cmd = nxt_cmd
|
|
72
82
|
parent = click.Context(cmd, info_name=part, parent=parent)
|
|
@@ -2,8 +2,6 @@ import numpy as np
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
from scipy.stats import spearmanr
|
|
4
4
|
from scipy.optimize import linear_sum_assignment
|
|
5
|
-
from hopcroftkarp import HopcroftKarp
|
|
6
|
-
|
|
7
5
|
|
|
8
6
|
def calc_rmsd(array1, array2):
|
|
9
7
|
"""
|
|
@@ -58,45 +56,6 @@ def matrix_spearman_alignment_linear(a, b, cutoff=0.0):
|
|
|
58
56
|
return out_a, out_b, out_score
|
|
59
57
|
|
|
60
58
|
|
|
61
|
-
def matrix_spearman_alignment_hopkraft(a, b, cutoff=0.0):
|
|
62
|
-
"""
|
|
63
|
-
matrix_spearman_alignment_hopkraft
|
|
64
|
-
|
|
65
|
-
Uses the HopcroftKarp maximum *cardinality* matching algorithm.
|
|
66
|
-
It finds the LARGEST NUMBER of matches, not the BEST (highest score)
|
|
67
|
-
match.
|
|
68
|
-
|
|
69
|
-
Note: This is fundamentally different from linear_sum_assignment.
|
|
70
|
-
"""
|
|
71
|
-
isect = a.columns.intersection(b.columns)
|
|
72
|
-
|
|
73
|
-
combined_df = pd.concat([a[isect], b[isect]], axis=0)
|
|
74
|
-
o = spearmanr(combined_df, axis=1)
|
|
75
|
-
|
|
76
|
-
a_count = a.shape[0]
|
|
77
|
-
sdf = pd.DataFrame(o.correlation[a_count:, :a_count], index=b.index, columns=a.index)
|
|
78
|
-
|
|
79
|
-
m = {}
|
|
80
|
-
s_result = sdf.apply(lambda x: x.nlargest(10).index, axis=0)
|
|
81
|
-
for k, row in s_result.items():
|
|
82
|
-
m[k] = row.tolist()
|
|
83
|
-
|
|
84
|
-
id_map = HopcroftKarp(m).maximum_matching(keys_only=True)
|
|
85
|
-
|
|
86
|
-
out_a = []
|
|
87
|
-
out_b = []
|
|
88
|
-
out_score = []
|
|
89
|
-
|
|
90
|
-
for k, v in id_map.items():
|
|
91
|
-
c = sdf.loc[v, k]
|
|
92
|
-
if c >= cutoff:
|
|
93
|
-
out_a.append(k)
|
|
94
|
-
out_b.append(v)
|
|
95
|
-
out_score.append(c)
|
|
96
|
-
|
|
97
|
-
return out_a, out_b, out_score
|
|
98
|
-
|
|
99
|
-
|
|
100
59
|
def procrustes(X, Y):
|
|
101
60
|
"""
|
|
102
61
|
Computes the Procrustes transformation (optimal PURE rotation)
|
|
@@ -13,8 +13,8 @@ embkit cbio <> : cBIO methods for data querying and download
|
|
|
13
13
|
from .model import model
|
|
14
14
|
from .matrix import matrix
|
|
15
15
|
from .cbio import cbio_cmd
|
|
16
|
-
from .
|
|
16
|
+
from .resources import resources
|
|
17
17
|
from .protein import protein
|
|
18
18
|
from .align import align
|
|
19
19
|
|
|
20
|
-
__all__ = ["model", "matrix", "
|
|
20
|
+
__all__ = ["model", "matrix", "resources", "protein"]
|
|
@@ -6,7 +6,7 @@ Command line tools for aligning embedding spaces
|
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
8
|
import pandas as pd
|
|
9
|
-
from ..align import matrix_spearman_alignment_linear
|
|
9
|
+
from ..align import matrix_spearman_alignment_linear
|
|
10
10
|
|
|
11
11
|
align = click.Group(name="align", help="Embedding Alignment methods")
|
|
12
12
|
|
|
@@ -24,12 +24,7 @@ def pair(matrix1, matrix2, method, cutoff):
|
|
|
24
24
|
m1 = pd.read_csv(matrix1, sep="\t", index_col=0)
|
|
25
25
|
m2 = pd.read_csv(matrix2, sep="\t", index_col=0)
|
|
26
26
|
|
|
27
|
-
if method == "
|
|
28
|
-
out = matrix_spearman_alignment_hopkraft(m1, m2)
|
|
29
|
-
for k, v in out.items():
|
|
30
|
-
print(f"{k}\t{v[0]}\t{v[1]}")
|
|
31
|
-
|
|
32
|
-
elif method == "linear":
|
|
27
|
+
if method == "linear":
|
|
33
28
|
out = matrix_spearman_alignment_linear(m1, m2, cutoff)
|
|
34
29
|
for k, v in out.items():
|
|
35
30
|
print(f"{k}\t{v[0]}\t{v[1]}")
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
|
|
2
2
|
import click
|
|
3
3
|
import pandas as pd
|
|
4
|
-
import numpy as np
|
|
5
|
-
import torch
|
|
6
4
|
|
|
7
5
|
from sklearn.preprocessing import MinMaxScaler
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
from
|
|
11
|
-
|
|
12
|
-
from ..
|
|
7
|
+
import torch
|
|
8
|
+
from torch.utils.data import DataLoader
|
|
9
|
+
|
|
10
|
+
from .. import dataframe_loader, dataframe_tensor, get_device, dataframe_dataset
|
|
11
|
+
from ..files import H5Reader
|
|
12
|
+
from ..factory import save, load
|
|
13
|
+
from ..factory.layers import Layer, LayerList, ConstraintInfo
|
|
14
|
+
from ..optimize import fit_vae
|
|
15
|
+
from ..models.vae.vae import VAE
|
|
16
|
+
from ..preprocessing import ExpMinMaxScaler, get_dataset_nonzero_mask
|
|
17
|
+
from ..datasets import DatasetMask
|
|
13
18
|
from ..losses import bce_with_logits, bce, mse
|
|
14
19
|
from ..pathway import extract_pathway_interactions, feature_map_intersect, FeatureGroups
|
|
15
20
|
|
|
@@ -17,57 +22,95 @@ model = click.Group(name="model", help="VAE Model commands.")
|
|
|
17
22
|
|
|
18
23
|
@model.command()
|
|
19
24
|
@click.argument("input_path", type=click.Path(exists=True, dir_okay=False, readable=True, path_type=str))
|
|
25
|
+
@click.option("--group", "-g", default=None, help="HD5F group name")
|
|
20
26
|
@click.option("--latent", "-l", type=int, default=256, show_default=True, help="Latent dimension size.")
|
|
21
27
|
@click.option("--epochs", "-e", type=int, default=20, show_default=True, help="Training epochs.")
|
|
28
|
+
@click.option("--batch-size", "-b", type=int, default=256)
|
|
22
29
|
@click.option("--encode-layers", type=str, default="400,200")
|
|
23
30
|
@click.option("--decode-layers", type=str, default="200,400")
|
|
24
31
|
@click.option("--normalize", "-n", type=str, default="none")
|
|
32
|
+
@click.option("--final-activation", default="none", type=click.Choice(["none", "sigmoid", "relu"]))
|
|
25
33
|
@click.option("--learning-rate", "-r", type=float, default=0.0001)
|
|
26
34
|
@click.option("--out", "-o", type=str, default=None)
|
|
27
35
|
@click.option("--schedule", "-s", type=str, default=None, help="20:0,20:0.1,40:.3,40:.4")
|
|
28
36
|
@click.option("--loss", type=click.Choice(["mse", "bce", "bce-logit"]), default="bce-logit")
|
|
29
37
|
@click.option("--save-stats", is_flag=True)
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
@click.option("--zero-mask", default=None, type=float)
|
|
39
|
+
@click.option("--seed", default=42, type=int)
|
|
40
|
+
@click.option("--bfloat16", is_flag=True)
|
|
41
|
+
def train_vae(input_path: str,
|
|
42
|
+
group: str,
|
|
43
|
+
latent: int,
|
|
44
|
+
epochs: int,
|
|
45
|
+
batch_size: int,
|
|
46
|
+
out: str, normalize:str,
|
|
32
47
|
encode_layers:str, decode_layers:str,
|
|
33
48
|
learning_rate: float,
|
|
49
|
+
final_activation: str,
|
|
34
50
|
loss: str,
|
|
35
|
-
schedule:str,
|
|
36
|
-
|
|
51
|
+
schedule:str,
|
|
52
|
+
zero_mask: float,
|
|
53
|
+
save_stats: bool,
|
|
54
|
+
seed: int,
|
|
55
|
+
bfloat16: bool
|
|
37
56
|
):
|
|
38
|
-
"""
|
|
39
|
-
|
|
57
|
+
"""
|
|
58
|
+
Train VAE model from a TSV file.
|
|
59
|
+
"""
|
|
60
|
+
device = get_device()
|
|
61
|
+
dtype = torch.float32
|
|
62
|
+
if bfloat16:
|
|
63
|
+
dtype = torch.bfloat16
|
|
40
64
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
65
|
+
torch.manual_seed(seed)
|
|
66
|
+
df = None
|
|
67
|
+
if group is not None:
|
|
68
|
+
dataset = H5Reader(input_path, group)
|
|
69
|
+
#TODO add normalization here
|
|
70
|
+
if zero_mask is not None:
|
|
71
|
+
dataset_mask = get_dataset_nonzero_mask(dataset, zero_mask)
|
|
72
|
+
mask = dataset_mask[0].cpu().numpy()
|
|
73
|
+
#print(mask)
|
|
74
|
+
features = dataset.columns[mask]
|
|
75
|
+
dataset = DatasetMask(dataset, dataset_mask, device)
|
|
76
|
+
else:
|
|
77
|
+
dataset.to(device)
|
|
78
|
+
features = dataset.columns
|
|
79
|
+
|
|
80
|
+
else:
|
|
81
|
+
df = pd.read_csv(input_path, sep="\t", index_col=0)
|
|
82
|
+
|
|
83
|
+
if normalize == "expMinMax":
|
|
84
|
+
norm = ExpMinMaxScaler()
|
|
85
|
+
norm.fit(df)
|
|
86
|
+
df = pd.DataFrame( norm.transform(df), index=df.index, columns=df.columns)
|
|
87
|
+
elif normalize == "minMax":
|
|
88
|
+
norm = MinMaxScaler()
|
|
89
|
+
norm.fit(df)
|
|
90
|
+
df = pd.DataFrame( norm.transform(df), index=df.index, columns=df.columns)
|
|
91
|
+
features = df.columns
|
|
92
|
+
dataset = dataframe_dataset(df, device=device, dtype=dtype)
|
|
93
|
+
|
|
94
|
+
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
|
|
95
|
+
|
|
52
96
|
|
|
53
97
|
layer_sizes = list( int(i) for i in encode_layers.split(",") )
|
|
54
|
-
layer_sizes
|
|
55
|
-
enc_layers = build_layers( layer_sizes )
|
|
98
|
+
enc_layers_list = LayerList( layer_sizes )
|
|
56
99
|
|
|
57
100
|
layer_sizes = list( int(i) for i in decode_layers.split(",") )
|
|
58
|
-
layer_sizes
|
|
59
|
-
dec_layers = build_layers( layer_sizes, end_activation="none" )
|
|
101
|
+
dec_layers_list = LayerList( layer_sizes, end_activation=final_activation )
|
|
60
102
|
|
|
61
103
|
beta_schedule = None
|
|
62
104
|
if schedule is not None:
|
|
63
|
-
beta_schedule = []
|
|
105
|
+
beta_schedule = []
|
|
64
106
|
for b in schedule.split(","):
|
|
65
107
|
e, b = b.split(":")
|
|
66
108
|
beta_schedule.append( (float(b), int(e)) )
|
|
67
|
-
vae = VAE(features=
|
|
109
|
+
vae = VAE(features=features,
|
|
68
110
|
latent_dim=latent,
|
|
69
|
-
encoder_layers=
|
|
70
|
-
decoder_layers=
|
|
111
|
+
encoder_layers=enc_layers_list,
|
|
112
|
+
decoder_layers=dec_layers_list,
|
|
113
|
+
device=device, dtype=dtype)
|
|
71
114
|
|
|
72
115
|
loss_func = bce_with_logits
|
|
73
116
|
if loss == "mse":
|
|
@@ -75,7 +118,7 @@ def train_vae(input_path: str, latent: int,
|
|
|
75
118
|
elif loss == "bce":
|
|
76
119
|
loss_func = bce
|
|
77
120
|
|
|
78
|
-
vae
|
|
121
|
+
fit_vae(vae, dataloader, epochs=epochs,
|
|
79
122
|
beta_schedule=beta_schedule, lr=learning_rate, loss=loss_func)
|
|
80
123
|
click.echo("Training complete.")
|
|
81
124
|
|
|
@@ -83,11 +126,7 @@ def train_vae(input_path: str, latent: int,
|
|
|
83
126
|
click.echo(f"No output path provided, using default naming.")
|
|
84
127
|
out = f"vae_latent{latent}_epochs{epochs}.model"
|
|
85
128
|
|
|
86
|
-
|
|
87
|
-
vae.save(out, df)
|
|
88
|
-
else:
|
|
89
|
-
vae.save(out)
|
|
90
|
-
|
|
129
|
+
save(vae, out)
|
|
91
130
|
click.echo(f"Model saved, to {out}")
|
|
92
131
|
|
|
93
132
|
|
|
@@ -133,15 +172,15 @@ def train_netvae(input_path: str, pathway_sif:str, out:str,
|
|
|
133
172
|
gcounts = [5,2,1]
|
|
134
173
|
|
|
135
174
|
enc_layers = [
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
175
|
+
Layer(group_count*gcounts[0], op="masked_linear", constraint=ConstraintInfo("features-to-group", fmap, out_group_count=gcounts[0])),
|
|
176
|
+
Layer(group_count*gcounts[1], op="masked_linear", constraint=ConstraintInfo("group-to-group", fmap, in_group_count=gcounts[0], out_group_count=gcounts[1])),
|
|
177
|
+
Layer(group_count, op="masked_linear", constraint=ConstraintInfo("group-to-group", fmap, in_group_count=gcounts[1], out_group_count=gcounts[2]))
|
|
139
178
|
]
|
|
140
179
|
|
|
141
180
|
dec_layers = [
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
181
|
+
Layer(group_count*gcounts[1], op="masked_linear", constraint=ConstraintInfo("group-to-group", fmap, in_group_count=gcounts[2], out_group_count=gcounts[1])),
|
|
182
|
+
Layer(group_count*gcounts[0], op="masked_linear", constraint=ConstraintInfo("group-to-group", fmap, in_group_count=gcounts[1], out_group_count=gcounts[0])),
|
|
183
|
+
Layer(feature_count, op="masked_linear", constraint=ConstraintInfo("group-to-features", fmap, in_group_count=gcounts[0]), activation="none")
|
|
145
184
|
]
|
|
146
185
|
|
|
147
186
|
loss_func = bce_with_logits
|
|
@@ -150,18 +189,24 @@ def train_netvae(input_path: str, pathway_sif:str, out:str,
|
|
|
150
189
|
elif loss == "bce":
|
|
151
190
|
loss_func = bce
|
|
152
191
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
vae = VAE(df.columns, latent_dim=group_count, encoder_layers=enc_layers, decoder_layers=dec_layers)
|
|
157
|
-
vae.fit(X=dataloader, beta_schedule=schedule, lr=learning_rate, loss=loss_func)
|
|
192
|
+
schedule = [(0.0, epochs)]
|
|
193
|
+
vae = VAE(list(df.columns), latent_dim=group_count, encoder_layers=enc_layers, decoder_layers=dec_layers)
|
|
194
|
+
fit_vae(vae, X=dataloader, beta_schedule=schedule, lr=learning_rate, loss=loss_func)
|
|
158
195
|
|
|
159
196
|
click.echo("Training complete.")
|
|
160
197
|
|
|
198
|
+
if out is None:
|
|
199
|
+
click.echo("No output path provided, using default naming.")
|
|
200
|
+
out = f"netvae_latent{group_count}_epochs{epochs}.model"
|
|
201
|
+
|
|
202
|
+
save(vae, out)
|
|
203
|
+
click.echo(f"Model saved, to {out}")
|
|
204
|
+
|
|
161
205
|
if save_stats:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
206
|
+
stats = pd.DataFrame({"mean": df.mean(), "std": df.std(ddof=0)})
|
|
207
|
+
stats_path = f"{out}.stats.tsv"
|
|
208
|
+
stats.to_csv(stats_path, sep="\t")
|
|
209
|
+
click.echo(f"Stats saved, to {stats_path}")
|
|
165
210
|
|
|
166
211
|
@model.command()
|
|
167
212
|
@click.argument("input_path", type=click.Path(exists=True, dir_okay=False, readable=True, path_type=str))
|
|
@@ -169,11 +214,9 @@ def train_netvae(input_path: str, pathway_sif:str, out:str,
|
|
|
169
214
|
@click.option("--normalize", "-n", type=str, default="none")
|
|
170
215
|
@click.option("--out", "-o", type=str, default="embedding.tsv")
|
|
171
216
|
def encode(input_path: str, model_path:str, normalize:str, out:str):
|
|
172
|
-
m = VAE.open_model(path=model_path)
|
|
173
|
-
df = pd.read_csv(input_path, sep="\t", index_col=0)
|
|
174
217
|
|
|
175
|
-
|
|
176
|
-
|
|
218
|
+
m = load(model_path)
|
|
219
|
+
df = pd.read_csv(input_path, sep="\t", index_col=0)
|
|
177
220
|
|
|
178
221
|
df = df[m.features]
|
|
179
222
|
if normalize == "expMinMax":
|
|
@@ -188,33 +231,3 @@ def encode(input_path: str, model_path:str, normalize:str, out:str):
|
|
|
188
231
|
martix = result[2].detach().cpu().numpy()
|
|
189
232
|
out_df = pd.DataFrame(martix, index=df.index)
|
|
190
233
|
out_df.to_csv(out, sep="\t")
|
|
191
|
-
|
|
192
|
-
@model.command()
|
|
193
|
-
@click.argument("h5", type=str)
|
|
194
|
-
@click.option("--epochs", "-e", type=int, default=5, show_default=True, help="Training epochs")
|
|
195
|
-
@click.option("--batch-size", type=int, default=1024, show_default=True, help="Batch Size")
|
|
196
|
-
@click.option("--learning-rate", type=float, default=1e-3, show_default=True, help="Learning Rate")
|
|
197
|
-
@click.option("--seed", type=int, default=42, show_default=True, help="Batch Size")
|
|
198
|
-
@click.option("--embedding-dim", type=int, default=64)
|
|
199
|
-
def train_hla2vec(h5:str, epochs:int, batch_size:int, learning_rate:float, seed:int, embedding_dim:int):
|
|
200
|
-
|
|
201
|
-
#TODO: this should be put into a library function
|
|
202
|
-
np.random.seed(seed)
|
|
203
|
-
if torch.cuda.is_available():
|
|
204
|
-
torch.cuda.manual_seed_all(seed)
|
|
205
|
-
torch.manual_seed(seed)
|
|
206
|
-
|
|
207
|
-
data = load_bigmhc(h5)
|
|
208
|
-
|
|
209
|
-
model, history = fit_hla2vec(
|
|
210
|
-
**data,
|
|
211
|
-
emb_dim=embedding_dim,
|
|
212
|
-
batch_size=batch_size,
|
|
213
|
-
epochs=epochs,
|
|
214
|
-
lr=learning_rate,
|
|
215
|
-
seed=seed,
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
print("Final epoch:", history[-1])
|
|
219
|
-
torch.save(model.state_dict(), "hla2vec_demo.pt")
|
|
220
|
-
print("Saved weights -> hla2vec_demo.pt")
|
|
@@ -5,10 +5,14 @@ import re
|
|
|
5
5
|
import sys
|
|
6
6
|
from typing import List
|
|
7
7
|
import click
|
|
8
|
+
import json
|
|
9
|
+
from ..files.json import StringTrimEncoder
|
|
8
10
|
from Bio import SeqIO
|
|
9
11
|
|
|
12
|
+
import torch
|
|
13
|
+
|
|
10
14
|
from .. import get_device
|
|
11
|
-
from ..
|
|
15
|
+
from ..encoding.protein import ProteinEncoder
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
protein = click.Group(name="protein", help="Protein commands.")
|
|
@@ -37,9 +41,10 @@ def stringify(l:List[float], trim=None) -> List[str]:
|
|
|
37
41
|
@click.option("--batch-size", type=int, default=128)
|
|
38
42
|
@click.option("--trim", type=int, default=None)
|
|
39
43
|
@click.option("--model", "-m", type=click.Choice(['t6', 't12', 't30', 't33', 't36', 't48']), default="t33")
|
|
40
|
-
@click.option("--pool", "-p", type=click.Choice(["mean", "sum"]), default="mean")
|
|
44
|
+
@click.option("--pool", "-p", type=click.Choice(["mean", "sum", "none"]), default="mean")
|
|
41
45
|
@click.option("--output", "-o", type=str, default=None)
|
|
42
|
-
|
|
46
|
+
@click.option("--fix-len", type=int, default=None)
|
|
47
|
+
def encode(fasta: str, filter:str, batch_size:int, model:str, trim:int, pool:str, output:str, fix_len):
|
|
43
48
|
pool_map = {
|
|
44
49
|
"mean" : "mean-pool",
|
|
45
50
|
"sum" : "sum-pool"
|
|
@@ -50,7 +55,17 @@ def encode(fasta: str, filter:str, batch_size:int, model:str, trim:int, pool:str
|
|
|
50
55
|
|
|
51
56
|
enc = ProteinEncoder(batch_size=batch_size, model=model)
|
|
52
57
|
enc.to(get_device())
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
if pool == "none":
|
|
59
|
+
for i, emb in enc.encode(fasta_reader(fasta, filter=filter), output="vector", fix_len=fix_len):
|
|
60
|
+
out.write(f"{i}\t")
|
|
61
|
+
if trim:
|
|
62
|
+
out.write(json.dumps(emb, cls=StringTrimEncoder, trim=trim ))
|
|
63
|
+
else:
|
|
64
|
+
out.write(json.dumps(emb.tolist()))
|
|
65
|
+
#out.write( f"{i}\t" + "\t".join(stringify(emb.tolist(), trim)))
|
|
66
|
+
out.write("\n")
|
|
67
|
+
else:
|
|
68
|
+
for i, emb in enc.encode(fasta_reader(fasta, filter=filter), output=pool_map[pool]):
|
|
69
|
+
out.write( f"{i}\t" + "\t".join(stringify(emb.tolist(), trim)))
|
|
70
|
+
out.write("\n")
|
|
56
71
|
out.close()
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import click
|
|
2
2
|
import pandas as pd
|
|
3
|
-
from ..
|
|
4
|
-
from ..
|
|
3
|
+
from ..files import load_raw_hugo, load_gct
|
|
4
|
+
from ..resources import GTEx, Hugo, SIF
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
resources = click.Group(name="resources", help="Resource commands.")
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
@
|
|
9
|
+
@resources.command()
|
|
10
10
|
@click.option("--data_type", "-t", required=False, type=str, help="Name of the dataset to download.")
|
|
11
11
|
@click.option("--output_folder", "-f", required=True, type=str, help="The folder to download the dataset into.")
|
|
12
12
|
def gtex(data_type: str, output_folder: str):
|
|
@@ -20,7 +20,7 @@ def gtex(data_type: str, output_folder: str):
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
@
|
|
23
|
+
@resources.command()
|
|
24
24
|
@click.option("--output_folder", "-f", required=True, type=str, help="The folder to download the dataset into.")
|
|
25
25
|
def sif(output_folder: str):
|
|
26
26
|
"""Download SIF dataset."""
|
|
@@ -28,7 +28,7 @@ def sif(output_folder: str):
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
@
|
|
31
|
+
@resources.command()
|
|
32
32
|
@click.option("--output_folder", "-f", required=True, type=str, help="The folder to download the dataset into.")
|
|
33
33
|
@click.option("--gtex_conversion", "-gtex", required=False, is_flag=True, type=bool, default=False,
|
|
34
34
|
help="Whether to convert the hugo data to a gtex version.")
|
|
@@ -51,4 +51,22 @@ class NetworkConstraint:
|
|
|
51
51
|
self._mask_np = mask
|
|
52
52
|
|
|
53
53
|
def as_torch(self, device: torch.device) -> torch.Tensor:
|
|
54
|
-
return torch.tensor(self._mask_np, device=device)
|
|
54
|
+
return torch.tensor(self._mask_np, device=device)
|
|
55
|
+
|
|
56
|
+
def to_dict(self) -> dict:
|
|
57
|
+
return {
|
|
58
|
+
"feature_index": self.feature_index,
|
|
59
|
+
"latent_index": self.latent_index,
|
|
60
|
+
"latent_membership": self.latent_membership,
|
|
61
|
+
"active": self.active,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def from_dict(cls, d: dict) -> "NetworkConstraint":
|
|
66
|
+
obj = cls(
|
|
67
|
+
feature_index=d["feature_index"],
|
|
68
|
+
latent_index=d["latent_index"],
|
|
69
|
+
latent_membership=d.get("latent_membership"),
|
|
70
|
+
)
|
|
71
|
+
obj.set_active(d.get("active", True))
|
|
72
|
+
return obj
|