clipnet 0.2.1__py3-none-any.whl

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.
clipnet/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ # __init__.py
2
+ # Adam He <adamyhe@gmail.com>
3
+
4
+ from importlib.metadata import PackageNotFoundError, version
5
+
6
+ try:
7
+ __version__ = version("clipnet")
8
+ except PackageNotFoundError:
9
+ __version__ = "unknown"
@@ -0,0 +1,159 @@
1
+ ## NOT IMPLEMENTED
2
+
3
+ """
4
+ Calculate contribution scores using shap.DeepExplainer.
5
+ """
6
+
7
+ import argparse
8
+ import gc
9
+
10
+ import numpy as np
11
+ import shap
12
+ import tensorflow as tf
13
+
14
+ import .utils
15
+
16
+ # This will fix an error message for running tf.__version__==2.5
17
+ shap.explainers._deep.deep_tf.op_handlers["AddV2"] = (
18
+ shap.explainers._deep.deep_tf.passthrough
19
+ )
20
+ tf.compat.v1.disable_v2_behavior()
21
+
22
+
23
+ def main():
24
+ parser = argparse.ArgumentParser(description=__doc__)
25
+ parser.add_argument("core_promoter_seq", type=str, help="")
26
+ parser.add_argument("motif", type=str, help="Where to write DeepSHAP scores.")
27
+ parser.add_argument(
28
+ "--model_dir",
29
+ type=str,
30
+ default="ensemble_models",
31
+ help="Directory to load models from",
32
+ )
33
+ parser.add_argument(
34
+ "--mode",
35
+ type=str,
36
+ default="quantity",
37
+ help="Calculate interaction strength using quantity or DFIM",
38
+ )
39
+ parser.add_argument("--gpu", action="store_true", help="Enable GPU.")
40
+ parser.add_argument(
41
+ "--use_specific_gpu",
42
+ type=int,
43
+ default=0,
44
+ help="Index of GPU to use (starting from 0). Does nothing if --gpu is not set.",
45
+ )
46
+ parser.add_argument(
47
+ "--n_subset",
48
+ type=int,
49
+ default=100,
50
+ help="Maximum number of sequences to use as background. \
51
+ Default is 100 to ensure reasonably fast compute on large datasets.",
52
+ )
53
+ parser.add_argument(
54
+ "--seed",
55
+ type=int,
56
+ default=617,
57
+ help="Random seed for selecting background sequences.",
58
+ )
59
+ args = parser.parse_args()
60
+ np.random.seed(args.seed)
61
+
62
+ assert args.mode in [
63
+ "quantity",
64
+ "dfim",
65
+ ], "mode must be either quantity or dfim."
66
+
67
+ # Load sequences ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
68
+
69
+ concat_ref = "".join(shuffled_ref)
70
+ embedded_promoter = (
71
+ ushuffle.shuffle(
72
+ concat_ref, int(np.floor((1000 - len(core_promoter_seq)) / 2)), 2
73
+ )
74
+ + core_promoter_seq
75
+ + ushuffle.shuffle(
76
+ concat_ref, int(np.ceil((1000 - len(core_promoter_seq)) / 2)), 2
77
+ )
78
+ )
79
+ seqs_to_explain = np.array([utils.OneHotDNA(seq).onehot for seq in sequences])
80
+
81
+ # Perform dinucleotide shuffle on n_subset random sequences
82
+ if len(sequences) < args.n_subset:
83
+ args.n_subset = len(sequences)
84
+ reference = [
85
+ sequences[i]
86
+ for i in np.random.choice(
87
+ np.array(range(len(sequences))), size=args.n_subset, replace=False
88
+ )
89
+ ]
90
+ shuffled_reference = [
91
+ utils.kshuffle(rec.seq, random_seed=args.seed)[0] for rec in reference
92
+ ]
93
+
94
+ # One-hot encode shuffled sequences
95
+ onehot_reference = np.array(
96
+ [utils.OneHotDNA(seq).onehot for seq in shuffled_reference]
97
+ )
98
+
99
+ # Load model and create explainer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100
+
101
+ if args.gpu:
102
+ gpus = tf.config.experimental.list_physical_devices("GPU")
103
+ for gpu in gpus:
104
+ tf.config.experimental.set_memory_growth(gpu, True)
105
+ tf.config.set_visible_devices(gpus[args.use_specific_gpu], "GPU")
106
+ else:
107
+ tf.config.set_visible_devices([], "GPU")
108
+
109
+ if args.model_fp is None:
110
+ models = [
111
+ tf.keras.models.load_model(f"{args.model_dir}/fold_{i}.h5", compile=False)
112
+ for i in range(1, 10)
113
+ ]
114
+ else:
115
+ models = [tf.keras.models.load_model(args.model_fp, compile=False)]
116
+ if args.mode == "quantity":
117
+ contrib = [model.output[1] for model in models]
118
+ else:
119
+ contrib = [
120
+ tf.reduce_mean(
121
+ tf.stop_gradient(tf.nn.softmax(model.output[0], axis=-1))
122
+ * model.output[0],
123
+ axis=-1,
124
+ keepdims=True,
125
+ )
126
+ for model in models
127
+ ]
128
+ explainers = [
129
+ shap.DeepExplainer((model.input, contrib), onehot_reference)
130
+ for (model, contrib) in zip(models, contrib)
131
+ ]
132
+
133
+ # Calculate scores ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134
+
135
+ raw_explanations = {i: [] for i in range(len(explainers))}
136
+ batch_size = 256
137
+ for i in range(len(explainers)):
138
+ for j in range(0, len(seqs_to_explain), batch_size):
139
+ shap_values = explainers[i].shap_values(seqs_to_explain[j : j + batch_size])
140
+ raw_explanations[i].append(shap_values)
141
+ gc.collect()
142
+
143
+ concat_explanations = []
144
+ for k in raw_explanations.keys():
145
+ concat_explanations.append(
146
+ np.concatenate([exp for exp in raw_explanations[k]], axis=1).sum(axis=0)
147
+ )
148
+
149
+ mean_explanations = np.array(concat_explanations).mean(axis=0)
150
+ scaled_explanations = mean_explanations * seqs_to_explain
151
+
152
+ # Save scores ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
153
+
154
+ np.savez_compressed(args.score_fp, scaled_explanations.swapaxes(1, 2))
155
+ np.savez_compressed(args.seq_fp, (seqs_to_explain / 2).astype(int).swapaxes(1, 2))
156
+
157
+
158
+ if __name__ == "__main__":
159
+ main()
@@ -0,0 +1,123 @@
1
+ ## NOT IMPLEMENTED. PART OF THE FITTING SCRIPTS
2
+
3
+ """
4
+ Calculates dataset parameters needed by clipnet. Supply a path to the processed data
5
+ and an output directory. This script will write json files to the output directory
6
+ for use in model training.
7
+ """
8
+
9
+ import argparse
10
+ import json
11
+ import os
12
+
13
+ import numpy as np
14
+
15
+
16
+ def write_dataset_params(i, datadir, outdir):
17
+ outdir = f"{outdir}/f{i}/"
18
+ os.makedirs(outdir, exist_ok=True)
19
+
20
+ test_folds = [i]
21
+ val_folds = [i % 9 + 1]
22
+ train_folds = [j for j in range(1, 10) if j not in test_folds + val_folds]
23
+ print(train_folds, val_folds, test_folds)
24
+
25
+ dataset_params = {
26
+ "train_seq": [
27
+ os.path.join(datadir, f"concat_sequence_{fold}.npz") for fold in train_folds
28
+ ],
29
+ "train_procap": [
30
+ os.path.join(datadir, f"concat_procap_{fold}.npz") for fold in train_folds
31
+ ],
32
+ "val_seq": [
33
+ os.path.join(datadir, f"concat_sequence_{fold}.npz") for fold in val_folds
34
+ ],
35
+ "val_procap": [
36
+ os.path.join(datadir, f"concat_procap_{fold}.npz") for fold in val_folds
37
+ ],
38
+ "test_seq": [
39
+ os.path.join(datadir, f"concat_sequence_{fold}.npz") for fold in test_folds
40
+ ],
41
+ "test_procap": [
42
+ os.path.join(datadir, f"concat_procap_{fold}.npz") for fold in test_folds
43
+ ],
44
+ }
45
+
46
+ dataset_params["n_train_folds"] = len(train_folds)
47
+ dataset_params["n_val_folds"] = len(val_folds)
48
+ dataset_params["n_test_folds"] = len(test_folds)
49
+
50
+ # Calculate n_samples_per_chunk
51
+ dataset_params["n_samples_per_train_fold"] = [
52
+ np.load(f)["arr_0"].shape[0] for f in dataset_params["train_procap"]
53
+ ]
54
+ dataset_params["n_samples_per_val_fold"] = [
55
+ np.load(f)["arr_0"].shape[0] for f in dataset_params["val_procap"]
56
+ ]
57
+ dataset_params["n_samples_per_test_fold"] = [
58
+ np.load(f)["arr_0"].shape[0] for f in dataset_params["test_procap"]
59
+ ]
60
+
61
+ dataset_params["window_length"] = np.load(dataset_params["train_seq"][0])["arr_0"][
62
+ 0
63
+ ].shape[0]
64
+
65
+ dataset_params["pad"] = int(dataset_params["window_length"] / 4)
66
+ dataset_params["output_length"] = int(
67
+ 2 * (dataset_params["window_length"] - 2 * dataset_params["pad"])
68
+ )
69
+
70
+ dataset_params["weight"] = 1 / 500
71
+
72
+ output_fp = os.path.join(outdir, "dataset_params.json")
73
+
74
+ with open(output_fp, "w") as handle:
75
+ json.dump(dataset_params, handle, indent=4, sort_keys=True)
76
+
77
+
78
+ def main():
79
+ parser = argparse.ArgumentParser()
80
+ parser.add_argument("datadir", type=str, help="directory containing data")
81
+ parser.add_argument(
82
+ "outdir",
83
+ type=str,
84
+ help="directory to save dataset params to (where models will be saved)",
85
+ )
86
+ parser.add_argument(
87
+ "--threads",
88
+ type=int,
89
+ default=9,
90
+ help="number of threads to use. Only used if not --fold is not selected.",
91
+ )
92
+ parser.add_argument(
93
+ "--fold",
94
+ type=int,
95
+ default=None,
96
+ help="fold to calculate dataset params for (will only run one).",
97
+ )
98
+ args = parser.parse_args()
99
+ if args.threads <= 0:
100
+ raise ValueError("--threads must be a positive integer")
101
+ if args.fold is not None:
102
+ write_dataset_params(args.fold, args.datadir, args.outdir)
103
+ else:
104
+ if args.threads == 1:
105
+ for i in range(1, 10):
106
+ write_dataset_params(i, args.datadir, args.outdir)
107
+ elif args.threads > 1:
108
+ import itertools
109
+ import multiprocessing as mp
110
+
111
+ with mp.Pool(9) as p:
112
+ p.starmap(
113
+ write_dataset_params,
114
+ zip(
115
+ range(1, 10),
116
+ itertools.repeat(args.datadir),
117
+ itertools.repeat(args.outdir),
118
+ ),
119
+ )
120
+
121
+
122
+ if __name__ == "__main__":
123
+ main()
@@ -0,0 +1,157 @@
1
+ ## NOT IMPLEMENTED
2
+
3
+ """
4
+ Calculate ISM shuffle scores.
5
+ """
6
+
7
+ import argparse
8
+ import logging
9
+ import os
10
+
11
+ import numpy as np
12
+ import pyfastx
13
+ import tqdm
14
+ from scipy.spatial.distance import cdist
15
+
16
+ import utils
17
+
18
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "4"
19
+ logging.getLogger("tensorflow").setLevel(logging.FATAL)
20
+ import clipnet
21
+
22
+
23
+ def main():
24
+ parser = argparse.ArgumentParser(description=__doc__)
25
+ parser.add_argument("fasta_fp", type=str, help="Fasta file path.")
26
+ parser.add_argument(
27
+ "score_fp", type=str, help="Where to write ISM shuffle results."
28
+ )
29
+ parser.add_argument(
30
+ "--model_dir",
31
+ type=str,
32
+ default="ensemble_models/",
33
+ help="directory to load models from.",
34
+ )
35
+ parser.add_argument(
36
+ "--gpu",
37
+ type=int,
38
+ default=None,
39
+ help="Index of GPU to use (starting from 0). If not invoked, uses CPU.",
40
+ )
41
+ parser.add_argument(
42
+ "--n_shuffles",
43
+ type=int,
44
+ default=5,
45
+ help="Number of shuffles/mutations to perform for each position.",
46
+ )
47
+ parser.add_argument(
48
+ "--mut_size", type=int, default=10, help="Size of mutations to use."
49
+ )
50
+ parser.add_argument(
51
+ "--edge_padding",
52
+ type=int,
53
+ default=50,
54
+ help="Number of positions from edge that we'll skip mutating on.",
55
+ )
56
+ parser.add_argument(
57
+ "--corr_pseudocount",
58
+ type=float,
59
+ default=1e-6,
60
+ help="Pseudocount for correlation calculation.",
61
+ )
62
+ parser.add_argument(
63
+ "--log_quantity_pseudocount",
64
+ type=float,
65
+ default=1e-3,
66
+ help="Pseudocount for log quantity calculation.",
67
+ )
68
+ parser.add_argument(
69
+ "--seed",
70
+ type=int,
71
+ default=617,
72
+ help="Random seed for generating mutations.",
73
+ )
74
+ parser.add_argument(
75
+ "--silence",
76
+ action="store_true",
77
+ help="Disables progress bars and other non-essential print statements.",
78
+ )
79
+ args = parser.parse_args()
80
+ np.random.seed(args.seed)
81
+
82
+ # Load models ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83
+
84
+ nn = (
85
+ clipnet.CLIPNET(n_gpus=1, use_specific_gpu=args.gpu)
86
+ if args.gpu is not None
87
+ else clipnet.CLIPNET(n_gpus=0)
88
+ )
89
+ ensemble = nn.construct_ensemble(args.model_dir, silence=args.silence)
90
+
91
+ # Load sequences ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92
+
93
+ sequences = pyfastx.Fasta(args.fasta_fp)
94
+ seqs_twohot = utils.get_twohot_fasta_sequences(args.fasta_fp, silence=args.silence)
95
+
96
+ # Calculate ISM shuffle scores ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97
+
98
+ wt_pred = ensemble.predict(seqs_twohot, batch_size=256, verbose=0)
99
+ corr_scores = []
100
+ log_quantity_scores = []
101
+ for i in tqdm.tqdm(
102
+ range(len(sequences)),
103
+ desc="Calculating ISM shuffle scores",
104
+ disable=args.silence,
105
+ ):
106
+ corr_score = []
107
+ log_quantity_score = []
108
+ rec = sequences[i]
109
+ positions = range(args.edge_padding, len(rec.seq) - args.edge_padding)
110
+ for shuffle in range(args.n_shuffles):
111
+ mutated_seqs = []
112
+ for pos in positions:
113
+ mut = utils.kshuffle(rec.seq, random_seed=args.seed)[0][: args.mut_size]
114
+ mutated_seq = (
115
+ rec.seq[0 : pos - int(len(mut) / 2)]
116
+ + mut
117
+ + rec.seq[pos + int(len(mut) / 2) :]
118
+ )
119
+ mutated_seqs.append(mutated_seq)
120
+ mut_pred = ensemble.predict(
121
+ np.array([utils.TwoHotDNA(seq).twohot for seq in mutated_seqs]),
122
+ batch_size=256,
123
+ verbose=0,
124
+ )
125
+ mut_corr = (
126
+ 1
127
+ - cdist(
128
+ np.array(
129
+ [wt_pred[0][i, :]] * len(positions)
130
+ + np.random.normal(
131
+ 0, args.corr_pseudocount, mut_pred[0].shape[1]
132
+ )
133
+ ),
134
+ mut_pred[0]
135
+ + np.random.normal(0, args.corr_pseudocount, mut_pred[0].shape[1]),
136
+ metric="correlation",
137
+ )[0, :]
138
+ )
139
+ mut_log_quantity = np.log10(
140
+ mut_pred[1] + args.log_quantity_pseudocount
141
+ ) - np.log10(wt_pred[1][i] + args.log_quantity_pseudocount)
142
+ corr_score.append(mut_corr)
143
+ log_quantity_score.append(mut_log_quantity)
144
+ corr_scores.append(np.array(corr_score).mean(axis=0))
145
+ log_quantity_scores.append(np.array(log_quantity_score).mean(axis=0))
146
+
147
+ # Save scores ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
148
+
149
+ np.savez_compressed(
150
+ args.score_fp,
151
+ corr_ism_shuffle=np.array(corr_scores),
152
+ log_quantity_ism_shuffle=np.array(log_quantity_scores),
153
+ )
154
+
155
+
156
+ if __name__ == "__main__":
157
+ main()
@@ -0,0 +1,150 @@
1
+ ## NOT IMPLEMENTED
2
+
3
+ """
4
+ This script calculates performance metrics given a set of predictions and ground truth.
5
+ """
6
+
7
+ import argparse
8
+
9
+ import h5py
10
+ import numpy as np
11
+ import pandas as pd
12
+ from scipy.spatial.distance import jensenshannon
13
+ from scipy.stats import pearsonr, spearmanr
14
+
15
+
16
+ def main():
17
+ parser = argparse.ArgumentParser(description=__doc__)
18
+ parser.add_argument(
19
+ "predictions",
20
+ type=str,
21
+ help="An hdf5 file containing predictions (track, quantity).",
22
+ )
23
+ parser.add_argument(
24
+ "observed",
25
+ type=str,
26
+ help="A csv(.gz), npy, or npz file containing the observed procap tracks.",
27
+ )
28
+ parser.add_argument(
29
+ "output",
30
+ type=str,
31
+ help="An hdf5 file to write the performance metrics to.",
32
+ )
33
+ args = parser.parse_args()
34
+
35
+ # Load predictions
36
+ with h5py.File(args.predictions, "r") as hf:
37
+ track = hf["track"][:]
38
+ if len(hf["quantity"].shape) == 2:
39
+ quantity = hf["quantity"][:, 0]
40
+ else:
41
+ quantity = hf["quantity"][:]
42
+
43
+ # Load observed data
44
+ if args.observed.endswith(".npz") or args.observed.endswith(".npy"):
45
+ observed = np.load(args.observed)
46
+ if args.observed.endswith(".npz"):
47
+ observed = observed["arr_0"]
48
+ elif args.observed.endswith(".csv.gz") or args.observed.endswith(".csv"):
49
+ observed = pd.read_csv(args.observed, header=None, index_col=0).to_numpy()
50
+ else:
51
+ raise ValueError(
52
+ f"File with observed PRO-cap data ({args.observed}) must be numpy or csv format."
53
+ )
54
+
55
+ # Validate dimensions
56
+ if track.shape[0] != observed.shape[0]:
57
+ raise ValueError(
58
+ f"n predictions ({track.shape[0]}) and n observed ({observed.shape[0]}) do not match."
59
+ )
60
+ if track.shape[1] > observed.shape[1]:
61
+ raise ValueError(
62
+ f"Predicted tracks ({track.shape[1]}) are longer than observed ({observed.shape[1]})."
63
+ )
64
+ if (observed.shape[1] - track.shape[1]) % 4 != 0:
65
+ raise ValueError(
66
+ f"Padding around predicted tracks ({observed.shape[1] - track.shape[1]}) must be divisible by 4."
67
+ )
68
+
69
+ # Trim off padding for observed tracks
70
+ start = (observed.shape[1] - track.shape[1]) // 4
71
+ end = observed.shape[1] // 2 - start
72
+ observed_clipped = observed[
73
+ :,
74
+ np.r_[start:end, observed.shape[1] // 2 + start : observed.shape[1] // 2 + end],
75
+ ]
76
+
77
+ # Benchmark directionality
78
+ track_directionality = np.log1p(
79
+ track[:, : track.shape[1] // 2].sum(axis=1)
80
+ ) - np.log1p(track[:, track.shape[1] // 2 :].sum(axis=1))
81
+ observed_directionality = np.log1p(
82
+ observed_clipped[:, : observed_clipped.shape[1] // 2].sum(axis=1)
83
+ ) - np.log1p(observed_clipped[:, observed_clipped.shape[1] // 2 :].sum(axis=1))
84
+ directionality_pearson = pearsonr(track_directionality, observed_directionality)
85
+
86
+ # Benchmark TSS position
87
+ strand_break = track.shape[1] // 2
88
+ pred_tss = np.concatenate(
89
+ [track[:, :strand_break].argmax(axis=1), track[:, strand_break:].argmax(axis=1)]
90
+ )
91
+ obs_tss = np.concatenate(
92
+ [
93
+ observed_clipped[:, :strand_break].argmax(axis=1),
94
+ observed_clipped[:, strand_break:].argmax(axis=1),
95
+ ]
96
+ )
97
+ tss_pos_pearson = pearsonr(pred_tss, obs_tss)
98
+
99
+ # Benchmark profile
100
+ track_pearson = pd.DataFrame(track).corrwith(pd.DataFrame(observed_clipped), axis=1)
101
+ track_js_distance = jensenshannon(track, observed_clipped, axis=1)
102
+
103
+ # Benchmark quantity
104
+ quantity_log_pearson = pearsonr(
105
+ np.log1p(quantity), np.log1p(observed_clipped.sum(axis=1))
106
+ )
107
+ quantity_spearman = spearmanr(quantity, observed_clipped.sum(axis=1))
108
+
109
+ # Print summary
110
+ print(f"Median Track Pearson: {track_pearson.median():.4f}")
111
+ print(
112
+ f"Mean Track Pearson: {track_pearson.mean():.4f} "
113
+ + f"+/- {track_pearson.std():.4f}"
114
+ )
115
+ print(f"Median Track JS Distance: {pd.Series(track_js_distance).median():.4f} ")
116
+ print(
117
+ f"Mean Track JS Distance: {pd.Series(track_js_distance).mean():.4f} "
118
+ + f"+/- {pd.Series(track_js_distance).std():.4f}"
119
+ )
120
+ print(f"Track Directionality Pearson: {directionality_pearson[0]:.4f}")
121
+ print(f"TSS Position Pearson: {tss_pos_pearson[0]:.4f}")
122
+ print(f"Quantity Log Pearson: {quantity_log_pearson[0]:.4f}")
123
+ print(f"Quantity Spearman: {quantity_spearman[0]:.4f}")
124
+
125
+ # Save metrics
126
+ with h5py.File(args.output, "w") as hf:
127
+ hf.create_dataset(
128
+ "track_pearson", data=track_pearson.to_numpy(), compression="gzip"
129
+ )
130
+ hf.create_dataset(
131
+ "track_js_distance", data=track_js_distance, compression="gzip"
132
+ )
133
+ hf.create_dataset(
134
+ "track_directionality",
135
+ data=np.array(directionality_pearson),
136
+ compression="gzip",
137
+ )
138
+ hf.create_dataset("tss_pos_pearson", data=tss_pos_pearson, compression="gzip")
139
+ hf.create_dataset(
140
+ "quantity_log_pearson",
141
+ data=np.array(quantity_log_pearson),
142
+ compression="gzip",
143
+ )
144
+ hf.create_dataset(
145
+ "quantity_spearman", data=np.array(quantity_spearman), compression="gzip"
146
+ )
147
+
148
+
149
+ if __name__ == "__main__":
150
+ main()
clipnet/_fit_nn.py ADDED
@@ -0,0 +1,63 @@
1
+ ## NOT IMPLEMENTED
2
+
3
+ """
4
+ This script fits a NN model using clipnet.py. It requires a NN architecture file, which
5
+ must contain a function named construct_nn that returns a tf.keras.models.Model object.
6
+ It also requires a dataset_params.py file which specifies parameters and file paths
7
+ associated with the dataset of interest.
8
+ """
9
+
10
+ import argparse
11
+ import logging
12
+ import os
13
+
14
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "4"
15
+ logging.getLogger("tensorflow").setLevel(logging.FATAL)
16
+ from . import clipnet
17
+
18
+
19
+ def main():
20
+ parser = argparse.ArgumentParser(description=__doc__)
21
+ parser.add_argument("model_dir", type=str, help="directory to save models to")
22
+ parser.add_argument(
23
+ "--prefix",
24
+ type=str,
25
+ default="rnn_v10",
26
+ help="the prefix of the nn architecture file. Must contain a construct_nn \
27
+ method, an opt hash that contains all the optimizer hyperparameters, and a \
28
+ compile_params hash that specifies what loss and metrics are reported. \
29
+ Models will be saved under this prefix.",
30
+ )
31
+ parser.add_argument(
32
+ "--resume_checkpoint",
33
+ type=str,
34
+ default=None,
35
+ help="resume training from this model.",
36
+ )
37
+ parser.add_argument(
38
+ "--gpu",
39
+ type=int,
40
+ default=None,
41
+ help="Index of GPU to use (starting from 0). If not invoked, uses CPU.",
42
+ )
43
+ parser.add_argument(
44
+ "--n_gpus",
45
+ type=int,
46
+ default=0,
47
+ help="Number of GPUs to use. If not invoked, uses CPU.",
48
+ )
49
+ args = parser.parse_args()
50
+
51
+ if args.n_gpus > 1:
52
+ nn = clipnet.CLIPNET(n_gpus=args.n_gpus, prefix=args.prefix)
53
+ else:
54
+ nn = (
55
+ clipnet.CLIPNET(n_gpus=1, use_specific_gpu=args.gpu, prefix=args.prefix)
56
+ if args.gpu is not None
57
+ else clipnet.CLIPNET(n_gpus=0, prefix=args.prefix)
58
+ )
59
+ nn.fit(model_dir=args.model_dir, resume_checkpoint=args.resume_checkpoint)
60
+
61
+
62
+ if __name__ == "__main__":
63
+ main()