Skip to content

Commit be6d2e1

Browse files
authored
Merge pull request #144 from kathyxchen/heartenn-updates
Add HeartENN arch to models dir
2 parents cfc9671 + 2f1ca45 commit be6d2e1

File tree

5 files changed

+104
-18
lines changed

5 files changed

+104
-18
lines changed

models/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Models directory
22

3-
We will provide PyTorch modules of different model architectures here.
3+
We will provide example PyTorch modules of different model architectures here.
44

55
If you have any particular architecture requests, please let us know. Thanks!

models/heartenn.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""
2+
HeartENN architecture (Richter et al., 2020).
3+
"""
4+
import numpy as np
5+
import torch
6+
import torch.nn as nn
7+
8+
9+
class HeartENN(nn.Module):
10+
def __init__(self, sequence_length, n_genomic_features):
11+
"""
12+
Parameters
13+
----------
14+
sequence_length : int
15+
Length of sequence context on which to train.
16+
n_genomic_features : int
17+
The number of chromatin features to predict.
18+
19+
Attributes
20+
----------
21+
conv_net : torch.nn.Sequential
22+
classifier : torch.nn.Sequential
23+
24+
"""
25+
super(HeartENN, self).__init__()
26+
conv_kernel_size = 8
27+
pool_kernel_size = 4
28+
29+
self.conv_net = nn.Sequential(
30+
nn.Conv1d(4, 60, kernel_size=conv_kernel_size),
31+
nn.ReLU(inplace=True),
32+
nn.Conv1d(60, 60, kernel_size=conv_kernel_size),
33+
nn.ReLU(inplace=True),
34+
nn.MaxPool1d(
35+
kernel_size=pool_kernel_size, stride=pool_kernel_size),
36+
nn.BatchNorm1d(60),
37+
38+
nn.Conv1d(60, 80, kernel_size=conv_kernel_size),
39+
nn.ReLU(inplace=True),
40+
nn.Conv1d(80, 80, kernel_size=conv_kernel_size),
41+
nn.ReLU(inplace=True),
42+
nn.MaxPool1d(
43+
kernel_size=pool_kernel_size, stride=pool_kernel_size),
44+
nn.BatchNorm1d(80),
45+
nn.Dropout(p=0.4),
46+
47+
nn.Conv1d(80, 240, kernel_size=conv_kernel_size),
48+
nn.ReLU(inplace=True),
49+
nn.Conv1d(240, 240, kernel_size=conv_kernel_size),
50+
nn.ReLU(inplace=True),
51+
nn.BatchNorm1d(240),
52+
nn.Dropout(p=0.6))
53+
54+
reduce_by = 2 * (conv_kernel_size - 1)
55+
pool_kernel_size = float(pool_kernel_size)
56+
self._n_channels = int(
57+
np.floor(
58+
(np.floor(
59+
(sequence_length - reduce_by) / pool_kernel_size)
60+
- reduce_by) / pool_kernel_size)
61+
- reduce_by)
62+
self.classifier = nn.Sequential(
63+
nn.Linear(240 * self._n_channels, n_genomic_features),
64+
nn.ReLU(inplace=True),
65+
nn.BatchNorm1d(n_genomic_features),
66+
nn.Linear(n_genomic_features, n_genomic_features),
67+
nn.Sigmoid())
68+
69+
def forward(self, x):
70+
"""Forward propagation of a batch.i
71+
72+
"""
73+
for layer in self.conv_net.children():
74+
if isinstance(layer, nn.Conv1d):
75+
layer.weight.data.renorm_(2, 0, 0.9)
76+
for layer in self.classifier.children():
77+
if isinstance(layer, nn.Linear):
78+
layer.weight.data.renorm_(2, 0, 0.9)
79+
out = self.conv_net(x)
80+
reshape_out = out.view(out.size(0), 240 * self._n_channels)
81+
predict = self.classifier(reshape_out)
82+
return predict
83+
84+
def criterion():
85+
return nn.BCELoss()
86+
87+
def get_optimizer(lr):
88+
return (torch.optim.SGD,
89+
{"lr": lr, "weight_decay": 1e-6, "momentum": 0.9})

selene_sdk/utils/utils.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from collections import OrderedDict
88
import logging
99
import sys
10-
import traceback
1110

1211
import numpy as np
1312

@@ -99,32 +98,30 @@ def load_model_from_state_dict(state_dict, model):
9998
model_keys = model.state_dict().keys()
10099
state_dict_keys = state_dict.keys()
101100

102-
new_state_dict = OrderedDict()
103-
104101
if len(model_keys) != len(state_dict_keys):
105-
raise ValueError("State dict does not have the same "
106-
"number of modules as the specified model "
107-
"architecture. Please check whether you are using "
108-
"the expected model architecture and that your PyTorch "
109-
"version matches the version in which the loaded model "
110-
"was trained.\n\n"
111-
"\tExpected modules:\n\t{0}\n\n"
112-
"\tModules in the loaded model weights:\n\t{1}\n".format(
113-
model_keys, state_dict_keys))
102+
try:
103+
model.load_state_dict(state_dict, strict=False)
104+
return model
105+
except Exception as e:
106+
raise ValueError("Loaded state dict does not match the model "
107+
"architecture specified - please check that you are "
108+
"using the correct architecture file and parameters.\n\n"
109+
"{0}".format(e))
114110

111+
new_state_dict = OrderedDict()
115112
for (k1, k2) in zip(model_keys, state_dict_keys):
116113
value = state_dict[k2]
117114
try:
118115
new_state_dict[k1] = value
119-
except Exception:
116+
except Exception as e:
120117
raise ValueError(
121118
"Failed to load weight from module {0} in model weights "
122-
"into model architecture module {1}. (If module name "
119+
"into model architecture module {1}. (If module name has "
123120
"an additional prefix `model.` it is because the model is "
124121
"wrapped in `selene_sdk.utils.NonStrandSpecific`. This "
125122
"error was raised because the underlying module does "
126123
"not match that expected by the loaded model:\n"
127-
"{2}".format(k2, k1, traceback.print_exc()))
124+
"{2}".format(k2, k1, e))
128125
model.load_state_dict(new_state_dict)
129126
return model
130127

selene_sdk/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.4.7"
1+
__version__ = "0.4.8"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
cmdclass = {'build_ext': build_ext}
2626

2727
setup(name="selene-sdk",
28-
version="0.4.7",
28+
version="0.4.8",
2929
long_description=long_description,
3030
long_description_content_type='text/markdown',
3131
description=("framework for developing sequence-level "

0 commit comments

Comments
 (0)