File size: 5,023 Bytes
9c80ad1
6b5044a
9c80ad1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6b5044a
9c80ad1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6b5044a
9c80ad1
6b5044a
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
---
license: mit
library_name: bpnet
tags:
  - bpnet
  - dna
  - genomics
  - transcription-factor-binding
  - chip-seq
  - encode
  - encode-bpnet-atlas
  - hg38
  - qc-unvalidated
  - ZSCAN26
---

# ENCODE BPNet Atlas

As part of the ENCODE 4 Project, we trained BPNet models on 2,339 ENCODE
transcription factor ChIP-seq experiments spanning 788 targets across
175 biosamples. Here, we provide all models for open-source use.

For more information about the models, see:

- Main ENCODE 4 Paper
- A unified lexicon of predictive DNA sequence motifs from ENCODE transcription
  factor binding and chromatin accessibility assays (Deshpande et al., Zenodo 2025)
- Base-resolution models of transcription-factor binding reveal soft motif syntax
  (Avsec et al., Nat Genet 2021)

## BPNet model: ZSCAN26 ChIP-seq in HEK293 (ENCSR501NSC)

- Model: BPNet
- Assay: TF ChIP-seq
- Target: ZSCAN26
- Experiment: [ENCSR501NSC](https://www.encodeproject.org/experiments/ENCSR501NSC/)
- Model annotation: [ENCSR408NKD](https://www.encodeproject.org/annotations/ENCSR408NKD/)
- Biosample: HEK293 (Full name: Homo sapiens HEK293 genetically modified (insertion) using site-specific recombination targeting H. sapiens ZSCAN26)
- Cell slim(s): epithelial cell
- Organ slim(s): epithelium, kidney
- Developmental slim(s): mesoderm
- System slim(s): excretory system
- Assembly: hg38

## QC

- Status: unvalidated
- Notes: Low complexity motifs only (counts, profile); Not found direct motif (ZNF);

## Directory structure

5-fold cross-validation. Each `fold_*/` contains the trained BPNet model in two formats:

- `fold_0/model.h5` — BPNet model in .h5 (Keras) format
- `fold_0/saved_model/` — BPNet model in TensorFlow SavedModel format (a directory; load directly)
- `config.json` — training / architecture parameters

## Instructions

BPNet takes a one-hot DNA sequence plus control (bias) inputs and predicts
stranded profile logits and total logcounts. The control inputs come from the
matched WCE/Input DNA control and **can be passed as zeros**.

### 1. Loading the SavedModel and making predictions

```python
import numpy as np
import tensorflow as tf
from scipy.special import logsumexp

model = tf.saved_model.load("fold_0/saved_model")
# sequence: (N, 2114, 4) one-hot [A,C,G,T]
# profile_bias_input: (N, 1000, 2) per-base profile bias from WCE/Input control, or zeros
# counts_bias_input:  (N, 2) log2 total counts from WCE/Input control, or zeros
predictions = model.signatures["serving_default"](**{
    "sequence": sequence.astype("float32"),
    "profile_bias_input_0": profile_bias_input.astype("float32"),
    "counts_bias_input_0": counts_bias_input.astype("float32")})
# predictions["profile_predictions"]:   (N, 1000, 2) logits (strands NOT independent)
# predictions["logcounts_predictions"]: (N, 1) total logcount

output_len = 1000
def vectorized_prediction_to_profile(predictions):
    logits_arr = predictions["profile_predictions"]
    counts_arr = predictions["logcounts_predictions"]
    pred_profile_logits = np.reshape(logits_arr, [-1, 1, output_len * 2])
    probVals_array = np.exp(pred_profile_logits - logsumexp(
        pred_profile_logits, axis=2).reshape([len(logits_arr), 1, 1]))
    profile_predictions = np.multiply(
        np.exp(counts_arr).reshape([len(counts_arr), 1, 1]), probVals_array)
    plus  = np.reshape(profile_predictions, [len(counts_arr), output_len, 2])[:, :, 0]
    minus = np.reshape(profile_predictions, [len(counts_arr), output_len, 2])[:, :, 1]
    return plus, minus, counts_arr

plus, minus, logcounts = vectorized_prediction_to_profile(predictions)
```

### 2. Loading the .h5 (Keras) and making predictions

```python
import numpy as np
import tensorflow as tf
import tensorflow.keras.backend as kb
from tensorflow.keras.models import load_model
from tensorflow.keras.utils import CustomObjectScope
from bpnet.model.custommodel import CustomModel

def get_model(model_path):
    with CustomObjectScope({"kb": kb, "tf": tf, "CustomModel": CustomModel}):
        return load_model(model_path)

model = get_model("fold_0/model.h5")
N = sequence.shape[0]
predictions = model.predict([
    sequence,                     # (N, 2114, 4)
    np.zeros((N, 1000, 2)),       # profile_bias_input (or real WCE/Input control values)
    np.zeros((N, 2))])            # counts_bias_input  (or real control log2 counts)
# predictions[0]: (N, 1000, 2) logits;  predictions[1]: (N, 1) logcounts
# convert with the same vectorized_prediction_to_profile() (predictions[0], predictions[1])
```

## Docker image to load and use the models

`kundajelab/bpnet-atlas` (placeholder — image forthcoming).

## Code

- Code: https://github.com/kundajelab/bpnet/
- Toolbox & downstream analysis: https://github.com/kundajelab/bpnet/wiki

## License & citation

Released under the MIT license.

The models are derived from ENCODE data (unrestricted use under the ENCODE
data-use policy). Please cite the ENCODE Project Consortium and the model
software: BPNet (Avsec et al., Nat Genet 2021).