wuxing0105's picture
Upload folder using huggingface_hub
34393ef verified
Raw
History Blame Contribute Delete
3.65 kB
import torch
import numpy as np
from torch import nn
from scipy import stats
from collections import OrderedDict
import torch.nn.functional as F
from sklearn.metrics import roc_auc_score, r2_score
from torch.nn.modules import activation
from torch.nn.modules.dropout import Dropout
class Conf_CNN(nn.Module):
r"""
Convolution hidden representative learning for DNA motifs detection by Peter Koo et al
https://doi.org/10.1371/journal.pcbi.1007560
The model forces the motifs to be detected in the first CNN layer
The certain receptive field set by different max pooling size
Parmas:
--------------------
conv_args
- channel_ls
list [4, x, x] , Koo_net only support 2 layer CNN
- kernel_size
list, defualt [8,5]
- stride
list [1, 1s]
pool_size
list [10,5]
"""
def __init__(self, conv_args, pool_size=[10,5]):
super().__init__()
channel_ls,kernel_size,stride,_,_,pad_to = conv_args
self.channel_ls =channel_ls
CNN_dims = list(zip(channel_ls[:-1], channel_ls[1:]))
self.CNN_dims = CNN_dims
self.kernel_size = kernel_size
self.stride = stride
self.pool_size = pool_size
# 2 CNN layer
nns = []
i = 1
for in_out , ks, strid, ps in zip(CNN_dims, kernel_size, stride, pool_size):
layer = nn.Sequential(
nn.Conv1d(*in_out, ks, strid),
nn.BatchNorm1d(in_out[1]),
nn.Mish()
)
nns.append((f'Conv_{i}', layer))
nns.append((f'MaxPool_{i}', nn.MaxPool1d(ps)))
i += 1
# 2 fc layers
fcs = [
("fc_3", nn.Linear(channel_ls[-1], 512)),
("BN_3", nn.BatchNorm1d(512)),
("Act_3", nn.ReLU()),
("fc_out", nn.Linear(512, 1))
]
self.network = nn.ModuleDict(
{"Conv":nn.Sequential(OrderedDict(nns)), "fc":nn.Sequential(OrderedDict(fcs))}
)
self.loss_fn = nn.MSELoss()
def __check_receptive_field(self):
assert len(self.channel_ls) == 3
k_len = len(self.kernel_size)
st_len = len(self.stride)
p_len = len(self.pool_size)
def forward(self,X):
"""
2 stage forward
"""
if X.shape[1] != 4:
X = X.transpose(1,2)
Conv_out = self.network['Conv'](X)
assert Conv_out.shape[-1] == 1, "the maxpooling is not restricting values to 1"
out = self.network['fc'](Conv_out.squeeze(dim=-1))
return out
def compute_loss(self, out,X,Y,popen):
if len(Y.shape) == 2:
Y = Y.squeeze(1)
if len(out.shape) == 2:
out = out.squeeze(1)
return {"Total":self.loss_fn(out, Y)}
def squeeze_out_Y(self,out,Y):
# ------ squeeze ------
if len(Y.shape) == 2:
Y = Y.squeeze(1)
if len(out.shape) == 2:
out = out.squeeze(1)
assert Y.shape == out.shape
return out,Y
def compute_acc(self,out,X,Y,popen=None):
try:
epsilon = popen.epsilon
except:
epsilon = 0.3
out,Y = self.squeeze_out_Y(out,Y)
# error smaller than epsilon
with torch.no_grad():
y_ay = Y.cpu().numpy()
out_ay = out.cpu().numpy()
# acc = torch.sum(torch.abs(Y-out) < epsilon).item() / Y.shape[0]
acc = stats.spearmanr(y_ay,out_ay)[0]
# acc = r2_score(y_ay, out_ay)
return {"Acc":acc}