eluent 0.0.1__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.
eluent-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [year] [fullname]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
eluent-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,461 @@
1
+ Metadata-Version: 2.4
2
+ Name: eluent
3
+ Version: 0.0.1
4
+ Summary: Chemistry-aware splitting of large datasets.
5
+ Author-email: Eachan Johnson <eachan.johnson@crick.ac.uk>
6
+ License: MIT License
7
+
8
+ Copyright (c) [year] [fullname]
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://github.com/scbirlab/eluent
28
+ Project-URL: Bug Tracker, https://github.com/scbirlab/duvidnn/eluent
29
+ Keywords: ai,data,deep-learning,machine-learning,chemistry
30
+ Classifier: Development Status :: 3 - Alpha
31
+ Classifier: Intended Audience :: Science/Research
32
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3.11
35
+ Classifier: Programming Language :: Python :: 3.12
36
+ Classifier: Programming Language :: Python :: 3.13
37
+ Classifier: Programming Language :: Python :: 3 :: Only
38
+ Requires-Python: >=3.11
39
+ Description-Content-Type: text/markdown
40
+ License-File: LICENSE
41
+ Requires-Dist: carabiner-tools[mpl,pd]>=0.0.5.post3
42
+ Requires-Dist: datasets>=3.0.0
43
+ Requires-Dist: huggingface_hub
44
+ Requires-Dist: numpy
45
+ Requires-Dist: platformdirs>=4.4.0
46
+ Requires-Dist: scipy
47
+ Requires-Dist: tensorboard
48
+ Requires-Dist: tqdm
49
+ Requires-Dist: umap-learn
50
+ Requires-Dist: scipy
51
+ Requires-Dist: schemist>=0.0.6
52
+ Requires-Dist: tdigest>=0.5
53
+ Requires-Dist: faiss-cpu>=1.11
54
+ Provides-Extra: splits-gpu
55
+ Requires-Dist: faiss-gpu; extra == "splits-gpu"
56
+ Provides-Extra: dev
57
+ Requires-Dist: pytest; extra == "dev"
58
+ Requires-Dist: flake8; extra == "dev"
59
+ Dynamic: license-file
60
+
61
+ # 🧐 duvidnn
62
+
63
+ ![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/scbirlab/duvidnn/python-publish.yml)
64
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/duvidnn)
65
+ ![PyPI](https://img.shields.io/pypi/v/duvidnn)
66
+
67
+ **duvidnn** is a suite of python tools for calculating confidence and information metrics
68
+ for deep learning. It provides a higher-level framework for calculating confidence and information metrics
69
+ of general purpose, taxonomic and chemistry-specific neural networks.
70
+
71
+ As a bonus, **duvidnn** also provides an easy command-line interface for training and testing models.
72
+
73
+ - [Installation](#installation)
74
+ - [Command-line interface](#command-line-interface)
75
+ - [Python API](#python-api)
76
+ - [Neural networks](#neural-networks)
77
+ - [More advanced API](#more-advanced-python-api-implementing-a-new-modelbox)
78
+ - [Issues, problems, suggestions](#issues-problems-suggestions)
79
+ - [Documentation](#documentation)
80
+
81
+ ## Installation
82
+
83
+ ### The easy way
84
+
85
+ You can install the precompiled version directly using `pip`.
86
+
87
+ ```bash
88
+ $ pip install duvidnn
89
+ ```
90
+
91
+ If you want to use duvidnn for chemistry machine learning and AI, use:
92
+
93
+ ```bash
94
+ $ pip install duvidnn[chem]
95
+ ```
96
+
97
+ For integrating taxonomic information with [vectome](https://github.com/scbirlab/vectome), use:
98
+
99
+ ```bash
100
+ $ pip install duvidnn[bio]
101
+ ```
102
+
103
+ You can install both:
104
+
105
+ ```bash
106
+ $ pip install duvidnn[bio,chem]
107
+ ```
108
+
109
+ ### From source
110
+
111
+ Clone the repository, then `cd` into it. Then run:
112
+
113
+ ```bash
114
+ $ pip install -e .
115
+ ```
116
+
117
+ ## Command-line interface
118
+
119
+ **duvidnn** has a command-line interface for training and checkpointing the built-in models.
120
+
121
+ ```bash
122
+ $ duvidnn --help
123
+ usage: duvidnn [-h] [--version] {hyperprep,train,predict,split,percentiles} ...
124
+
125
+ Calculating exact and approximate confidence and information metrics for deep learning on general purpose and chemistry tasks.
126
+
127
+ options:
128
+ -h, --help show this help message and exit
129
+ --version, -v show program's version number and exit
130
+
131
+ Sub-commands:
132
+ {hyperprep,train,predict,split,percentiles}
133
+ Use these commands to specify the tool you want to use.
134
+ hyperprep Prepare inputs for hyperparameter search.
135
+ train Train a PyTorch model.
136
+ predict Make predictions and calculate uncertainty using a duvidnn checkpoint.
137
+ split Make chemical train-test-val splits on out-of-core datasets.
138
+ percentiles Add columns indicating whether rows are in a percentile.
139
+ ```
140
+
141
+ In all cases, you can get further options with `duvidnn <command> --help`, for example:
142
+
143
+ ```bash
144
+ duvidnn train --help
145
+ ```
146
+
147
+ ### Annotating top percentiles
148
+
149
+ You can add columns to datasets which annotate the top percentiles of named columns. This is compatible
150
+ with extremely large datasets that don't fit in memory.
151
+
152
+ ```bash
153
+ $ duvidnn percentiles \
154
+ hf://scbirlab/fang-2023-biogen-adme@scaffold-split:train \
155
+ --columns clogp tpsa \
156
+ --percentiles 1 5 10 \
157
+ --output percentiles.parquet \
158
+ --plot percentiles-plot.png \
159
+ --structure smiles
160
+ ```
161
+
162
+ In all cases, input data can be:
163
+ - Path to a _local_ file in CSV, Parquet, Arrow or HF Dataset format
164
+ - _or_ a remote dataset hosted on [🤗 Datasets](https://huggingface.co/datasets),
165
+ indicated by `hf://` followed by the repository name
166
+
167
+ ### Data splitting
168
+
169
+ There are utilities for out-of-memory scaffold and (approximate using FAISS) spectral splitting of datasets
170
+ that don't fit in memory. Make it random but reproducible with `--seed`, otherwise a deterministic bin-packing
171
+ algorithm is used.
172
+
173
+ ```bash
174
+ $ duvidnn split hf://scbirlab/fang-2023-biogen-adme@scaffold-split:train \
175
+ --train .7 \
176
+ --validation .15 \
177
+ --structure smiles \
178
+ --type faiss \
179
+ --seed 1 \
180
+ --output faiss.csv \
181
+ --plot faiss.png
182
+ ```
183
+
184
+ ### Model training and evaluation
185
+
186
+ To train:
187
+
188
+ ```bash
189
+ $ duvidnn train -1 hf://scbirlab/fang-2023-biogen-adme@scaffold-split:train \
190
+ -2 hf://scbirlab/fang-2023-biogen-adme@scaffold-split:test \
191
+ --class fingerprint \
192
+ --structure smiles \
193
+ --ensemble-size 10 \
194
+ --epochs 10 \
195
+ --learning-rate 0.001 \
196
+ --output model.dv
197
+ ```
198
+
199
+ Different model classes can be specified:
200
+
201
+
202
+ ### Hyperparameters
203
+
204
+ There is also a simple hyperparameter utility.
205
+
206
+ ```bash
207
+ $ printf '{"model_class": "fingerprint", use_2d": [true, false], "n_units": 16, "n_hidden": 3}' | duvidnn hyperprep -o hyperopt.json
208
+ ```
209
+
210
+ This generates a file containing all combinations. It can be indexed (0-based)
211
+ with the `-i <int>` option to supply a specific training configuration like so:
212
+
213
+ ```bash
214
+ $ duvidnn train \
215
+ -1 hf://scbirlab/fang-2023-biogen-adme@scaffold-split:train \
216
+ -2 hf://scbirlab/fang-2023-biogen-adme@scaffold-split:test \
217
+ -c hyperopt.json \
218
+ -i 0 \
219
+ --output model.dv
220
+ ```
221
+
222
+ In this way, you can generate all the hyperparameter combinations, then systematically test them one by one
223
+ (or in parallel using HPC or other methods).
224
+
225
+ ### Predictions
226
+
227
+ You can make predictions on datasets using `duvidnn predict`. Optionally, you can restrict prediction to only a chunk of the
228
+ dataset using `--start` and `--stop`. This can be useful to parallelize prediction across chunks.
229
+
230
+ When predicting, there is also the option to calculate uncertainty metrics like ensemble variance (`--variance`),
231
+ Tanimoto nearest neighbor distance to training set (`--tanimoto`, for chemistry models), doubtscore (`--doubtscore`),
232
+ and information sensitivity (`--information-sensitivity`).
233
+
234
+ ```bash
235
+ $ duvidnn predict \
236
+ --test hf://scbirlab/fang-2023-biogen-adme@scaffold-split:test \
237
+ --checkpoint model.dv \
238
+ --start 100 \
239
+ --end 200 \
240
+ --variance \
241
+ --tanimoto \
242
+ --doubtscore \
243
+ -y clogp \
244
+ --output predictions.parquet
245
+ ```
246
+
247
+ Outputs can be made in CSV, Parquet, Arrow, or HF Dataset format. This is inferred from the file extension of
248
+ the filename provided for `--output`.
249
+
250
+ Note that information sensitivity using default parameters can be very slow for large models with large
251
+ training data, since it must calculate second-order parameter gradients for every training example. There are
252
+ approximations which can speed it up substantially, at the cost of exactness:
253
+ - The `--last-layer` option gives the biggest speed-up, since it restricts the calculation to only the output layer of the model.
254
+ - Using `--optimality` assumes the model has been trained to an optimum (i.e. gradient of loss is zero).
255
+ - The `--approx bekas` option uses a fast approximation of second-order gradients.
256
+
257
+ ## Python API
258
+
259
+ **duvidnn** provides python classes and functions for custom analysis.
260
+
261
+ ### Neural networks
262
+
263
+ The core of **duvidnn** is the `ModelBox`, which is a container for a trainable model and its training data.
264
+ These are connected because measures of confidence and information gain depend directly on the information
265
+ or evidence already seen by the model.
266
+
267
+ There are several `ModelBox` classes for specific deep learning architechtures in pytorch.
268
+
269
+ ```python
270
+ >>> from duvidnn.autoclass import MODELBOX_REGISTRY
271
+ >>> from pprint import pprint
272
+ >>> pprint(MODELBOX_REGISTRY)
273
+ {'bilinear': <class 'duvidnn.torch.modelbox.modelboxes.TorchBilinearModelBox'>,
274
+ 'bilinear-fp': <class 'duvidnn.torch.modelbox.modelboxes.TorchBilinearFingerprintModelBox'>,
275
+ 'chemprop': <class 'duvidnn.torch.modelbox.modelboxes.ChempropModelBox'>,
276
+ 'cnn': <class 'duvidnn.torch.modelbox.modelboxes.TorchCNN2DModelBox'>,
277
+ 'fingerprint': <class 'duvidnn.torch.modelbox.modelboxes.TorchFingerprintModelBox'>,
278
+ 'mlp': <class 'duvidnn.torch.modelbox.modelboxes.TorchMLPModelBox'>}
279
+ ```
280
+
281
+ The modelboxes `chemprop`, `fingerprint`, and `bilinear-fp` featurize SMILES representations of chemical
282
+ structures. The modelbox `mlp` is a general purpose multilayer perceptron.
283
+
284
+ You can set up your model with various training parameters.
285
+
286
+ ```python
287
+ from duvidnn.autoclass import AutoClass
288
+ modelbox = AutoClass(
289
+ "fingerprint",
290
+ n_units=16,
291
+ n_hidden=2,
292
+ ensemble_size=10,
293
+ structure_column="smiles",
294
+ )
295
+ ```
296
+
297
+ The internal neural network is instantiated on loading training data.
298
+
299
+ ```python
300
+ modelbox.load_training_data(
301
+ data="hf://scbirlab/fang-2023-biogen-adme@scaffold-split:train",
302
+ inputs="smiles", # column name of the predictor values
303
+ labels="clogp", # column name of the values to predict
304
+ )
305
+ ```
306
+
307
+ The `data` can be a remote 🤗 dataset, in which case it is automatically downloaded. The `"@"`
308
+ indicates the dataset configuration, and the `":"` indicates the specific data split.
309
+
310
+ Alternatively, the training data can be a local CSV or TSV file, or in-memory Pandas dataframes
311
+ or dictionaries.
312
+
313
+ With training data loaded, the model can be trained!
314
+
315
+ ```python
316
+ modelbox.train(
317
+ val_filename="hf://scbirlab/fang-2023-biogen-adme@scaffold-split:test",
318
+ epochs=10,
319
+ batch_size=128,
320
+ )
321
+ ```
322
+
323
+ The `ModelBox.train()` method uses pytorch Lightning under the hood, so other options such as callbacks
324
+ for this framework should be accepted.
325
+
326
+ #### Saving and sharing a trained model
327
+
328
+ **duvidnn** provides a basic checkpointing mechanism to save model weights and training data to later reload.
329
+
330
+ ```python
331
+ modelbox.save_checkpoint("checkpoint.dv")
332
+ modelbox.load_checkpoint("checkpoint.dv")
333
+ ```
334
+
335
+ #### Evaluating and predicting on new data
336
+
337
+ **duvidnn** `ModelBox`es provide methods for evaluating predictions on new data.
338
+
339
+ ```python
340
+ predictions, metrics = modelbox.evaluate(
341
+ data="hf://scbirlab/fang-2023-biogen-adme@scaffold-split:test",
342
+ )
343
+ ```
344
+
345
+ #### Calculating uncertainty and information metrics
346
+
347
+ **duvidnn** `ModelBox`es provide methods for calculating prediction variance of ensembles,
348
+ doubtscore, and information sensitivity.
349
+
350
+ ```python
351
+ doubtscore = modelbox.doubtscore(
352
+ data="hf://scbirlab/fang-2023-biogen-adme@scaffold-split:test"
353
+ )
354
+ info_sens = modelbox.information_sensitivity(
355
+ data="hf://scbirlab/fang-2023-biogen-adme@scaffold-split:test",
356
+ approx="bekas", # approximate Hessian diagonals
357
+ n=10,
358
+ )
359
+ ```
360
+
361
+ To avoid storing large datasets in memory, **duvidnn** uses [🤗 datasets](https://huggingface.co/docs/datasets/) under the hood
362
+ to cache data. Results can be instantiated in memory with a little effort. For example:
363
+
364
+ ```python
365
+ doubtscore = doubtscore.to_pandas()
366
+ ```
367
+
368
+ See the [🤗 datasets documentation](https://huggingface.co/docs/datasets/) for more.
369
+
370
+ ## More advanced Python API: Implementing a new `ModelBox`
371
+
372
+ Bringing a new pytorch model to **duvidnn** is relatively straightforward. First, write your model,
373
+ adding Lighning logic and a `create_model()` method:
374
+
375
+ ```python
376
+ from typing import Callable, Iterable, List, Mapping, Optional
377
+
378
+ from torch.nn import BatchNorm1d, Dropout, Linear, Module, SiLU, Sequential
379
+ from duvidnn.torch import TorchEnsembleMixin
380
+ from duvidnn.torch.models.utils.lt import LightningMixin
381
+ from torch import nn
382
+ from torch.optim import Adam, Optimizer
383
+
384
+ class SimpleMLP(nn.Module, LightningMixin):
385
+
386
+ def __init__(
387
+ self,
388
+ n_input: int,
389
+ n_units: int = 16,
390
+ n_out: int = 1,
391
+ activation: Callable = nn.SiLU, # Smooth activation to prevent vanishing gradient
392
+ learning_rate: float = .01,
393
+ optimizer: Optimizer = Adam,
394
+ *args, **kwargs
395
+ ):
396
+ super().__init__(*args, **kwargs)
397
+ self.n_input = n_input
398
+ self.n_units = n_units
399
+ self.activation = activation
400
+ self.n_out = n_out
401
+ self.model_layers = nn.Sequential([
402
+ nn.Linear(self.n_input, self.n_units),
403
+ self.activation(),
404
+ nn.Linear(self.n_units, self.n_out),
405
+ ])
406
+ # Lightning logic
407
+ self._init_lightning(
408
+ optimizer=optimizer,
409
+ learning_rate=learning_rate,
410
+ model_attr='model_layers', # the attribute containing the model
411
+ )
412
+
413
+ def forward(self, x):
414
+ return self.model_layers(x)
415
+ ```
416
+
417
+ Then subclass `duvidnn.torch.modelbox.TorchModelBoxBase` and implement the `create_model()` method, which should
418
+ simply return your instantiated model. If you want to preprocess input data on the fly, then
419
+ add a `preprocess_data()` method which takes a data dictionary and returns a data dictionary.
420
+
421
+ ```python
422
+ from typing import Dict
423
+
424
+ from duvidnn.torch.modelbox import TorchModelBoxBase
425
+ import numpy as np
426
+
427
+ class MLPModelBox(TorchModelBoxBase):
428
+
429
+ def __init__(self, *args, **kwargs):
430
+ super().__init__()
431
+ self._mlp_kwargs = kwargs
432
+
433
+ def create_model(self, *args, **kwargs):
434
+ self._model_config.update(kwargs) # makes sure model checkpointing saves the keyword args
435
+ return SimpleMLP(
436
+ n_input=self.input_shape[-1], # defined on data loading
437
+ n_out=self.output_shape[-1],
438
+ *args,
439
+ **self._model_config,
440
+ **self._mlp_kwargs, # if init kwargs are relevant to model creation
441
+ )
442
+
443
+ # Define this method if your data needs preprocessing
444
+ @staticmethod
445
+ def preprocess_data(data: Dict[str, np.ndarray], _in_key, _out_key, **kwargs) -> Dict[str, np.ndarray]:
446
+ return {
447
+ _in_key: your_featurizer(data[_in_key]),
448
+ _out_key: np.asarray(data[_out_key])
449
+ }
450
+ ```
451
+
452
+ If you want to build `ModelBox`es based on a framework other than pytorch, you can subclass
453
+ the `duvidnn.base.ModelBoxBase` abstract class, making sure to implement its abstract methods.
454
+
455
+ ## Issues, problems, suggestions
456
+
457
+ Add to the [issue tracker](https://www.github.com/scbirlab/duvidnn/issues).
458
+
459
+ ## Documentation
460
+
461
+ (To come at [ReadTheDocs](https://duvidnn.readthedocs.org).)