Potential issues

  • net doesn't know the upstream array shape...
    • solution: always use just functional code to contruct the network

Overall TODO

  • [ ] require Keras>=2.2.4 for the pickle-ing support

TODO

  • [x] add interpretation methods
    • get a separate interpreter function?
  • [ ] add the bias method
    • Head - focused
      • bias_target=
In [1]:
import basepair

import keras

import deepexplain

import comet_ml
Using TensorFlow backend.
In [2]:
from basepair.config import create_tf_session
In [2]:
from gin_train.metrics import ClassificationMetrics
import keras.backend as K
import tensorflow as tf


def id_fn(x):
    return x

def named_tensor(x, name):
    return kl.Lambda(id_fn, name=name)(x)


class BinaryClassificationHead:

    def __init__(self, net, 
                 loss='binary_crossentropy',
                 loss_weight=0.5, 
                 metric=ClassificationMetrics(), 
                 target='{task}/profile',
                 # bias input
                 use_bias=False,
                 bias_input='bias/{task}/profile',
                 bias_shape=(2,),
                 ):
        self.net = net
        self.loss = loss
        self.loss_weight = loss_weight
        self.metric = metric
        self.target = target
        self.bias_input = bias_input
        self.use_bias = use_bias
        self.bias_shape = bias_shape
        
    def neutral_bias_input(self, task, length):
        """Create dummy bias input
        """
        return {self.get_bias_input(task): np.zeros((length, ) + self.bias_shape)}
        
    def get_target(self, task):
        return self.target.format(task=task)
    
    def get_bias_input(self, task):
        return self.bias_input.format(task=task)

    def __call__(self, inp, task):
        o = self.net(inp)
        
        # remember the tensors useful for interpretation (referred by name)
        self.pre_act = o.name
        
        # add the target bias
        if self.use_bias:
            binp = kl.Input(self.bias_shape, name=self.get_bias_input(task))
            bias_inputs = [binp]
            
            # add the bias term
            bias_x = kl.Dense(1)(binp)
            o = kl.add([o, bias_x])
        else:
            bias_inputs = []

        o = kl.Activation("sigmoid")(o)
        self.post_act = o.name
        
        # label the target op so that we can use a dictionary of targets
        # to train the model
        return named_tensor(o, name=self.get_target(task)), bias_inputs
    
    def get_preact_tensor(self, graph=None):
        if graph is None:
            graph = tf.get_default_graph()
        return graph.get_tensor_by_name(self.pre_act)

    def intp_tensors(self, preact_only=False, graph=None):
        """Return the required interpretation tensors
        """
        if graph is None:
            graph = tf.get_default_graph()
        if preact_only:
            return {"logit": graph.get_tensor_by_name(self.pre_act)}
        else:            
            return {"logit": graph.get_tensor_by_name(self.pre_act),
                    "p": graph.get_tensor_by_name(self.post_act)}

    def get_intp_tensor(self, which='logit'):
        return self.interpretation_tensors()[which]
    
    def copy(self):
        from copy import deepcopy
        return deepcopy(self)
In [3]:
from keras.optimizers import Adam
from collections import OrderedDict, defaultdict
from copy import deepcopy
from keras.models import Model
from kipoi.data_utils import numpy_collate_concat
from basepair.data import numpy_minibatch, nested_numpy_minibatch


class SeqModel:
    """Model interpreting the genome sequence
    """

    def __init__(self,
                 body,
                 # will be used for each task
                 heads,
                 tasks,
                 optimizer=Adam(lr=0.004),
                 ):
        """
        1. build the keras model (don't )
        2. compile the Keras model
        """
        self.body = body
        self.tasks = tasks
        
        inp = kl.Input(shape=(None, 4), name='seq')    
        bottleneck = body(inp)
        self.bottleneck_name = bottleneck.name  # remember the bottleneck tensor name
        
        # create different heads
        outputs = []
        self.all_heads = defaultdict(list)
        self.losses = []
        self.loss_weights = []
        self.target_names = []
        bias_inputs = []
        for task in tasks:
            for head in heads:
                head = head.copy()
                self.all_heads[task].append(head)
                out, bias_input = head(bottleneck, task)
                outputs.append(out)
                bias_inputs += bias_input
                self.target_names.append(head.get_target(task))
                self.losses.append(head.loss)
                self.loss_weights.append(head.loss_weight)
                
        # create and compile the model
        self.model = Model([inp] + bias_inputs, outputs)
        self.model.compile(optimizer=optimizer,
                           loss=self.losses, loss_weights=self.loss_weights)
        
        # start without any importance function
        self.imp_fns = {}
        
    def _get_input_tensor(self):
        return self.model.inputs[0]
    
    def get_bottleneck_tensor(self, graph=None):
        if graph is None:
            graph = tf.get_default_graph()
        return graph.get_tensor_by_name(self.bottleneck_name)
    
    def bottleneck_model(self):
        return Model(self._get_input_tensor(),
                     self.get_bottleneck_tensor())
    
    def preact_model(self):
        outputs = [head.get_preact_tensor()
                  for task, heads in self.all_heads.items()
                  for head in heads]
        return Model(self._get_input_tensor(), outputs)
    
    def predict_preact(self, seq, batch_size=256):
        m = self.preact_model()
        preds = m.predict(seq, batch_size=batch_size)
        return {k:v for k,v in zip(self.target_names, preds)}
    
    def get_intp_tensors(self, preact_only=True):
        intp_targets = []
        for task, heads in self.all_heads.items():
            for head in heads:
                for k,v in head.intp_tensors(preact_only=preact_only).items():
                    intp_targets.append((head.get_target(task) + "/" + k, v))
        return intp_targets
    
    def _imp_deeplift_fn(self, x, name, preact_only=True):
        """Deeplift importance score tensors
        """
        k = f"deeplift/{name}"
        if k in self.imp_fns:
            return self.imp_fns[k]

        import deepexplain
        from deepexplain.tensorflow.methods import DeepLIFTRescale
        from deepexplain.tensorflow import DeepExplain
        from deeplift.dinuc_shuffle import dinuc_shuffle
        from collections import OrderedDict
        from keras.models import load_model, Model
        import keras.backend as K
        import numpy as np
        import tempfile
        
        self.imp_fns = {}
        with tempfile.NamedTemporaryFile(suffix='.pkl') as temp:
            self.model.save(temp.name)
            K.clear_session()
            self.model = load_model(temp.name)

        # get the interpretation tensors
        intp_names, intp_tensors = list(zip(*self.get_intp_tensors(preact_only)))
        # input_tensor = self._get_input_tensor()
        input_tensor = self.model.inputs
        
        if isinstance(x, list):
            x_subset = [ix[:1] for ix in x]
        elif isinstance(x, dict):
            x_subset = [v[:1] for k,v in x.items()]
        else:
            x_subset = x[:1]
        
        with deepexplain.tensorflow.DeepExplain(session=K.get_session()) as de:
            fModel = Model(inputs=input_tensor, outputs=intp_tensors)
            target_tensors = fModel(input_tensor)
            for name, target_tensor in zip(intp_names, target_tensors):
                # input_tensor = fModel.inputs[0]
                print(name)
                print(target_tensor)
                self.imp_fns["deeplift/" + name] = de.explain('deeplift', 
                                                              target_tensor,
                                                              input_tensor, 
                                                              x_subset)

        return self.imp_fns[k]

    def imp_score(self, x, name, method='deeplift', batch_size=512, preact_only=True):
        """Compute the importance score

        Args:
          x: one-hot encoded DNA sequence
          method: which importance score to use. Available: grad, ism, deeplift
          name: which interepretation method to compute
        """
        if method == "deeplift":
            fn = self._imp_deeplift_fn(x, name, preact_only=preact_only)
        else:
            raise ValueError("Please provide a valid importance scoring method: grad, ism or deeplift")

            
        def input_to_list(input_names, x):
            if isinstance(x, list):
                return x
            elif isinstance(x, dict):
                return [x[k] for k in input_names]
            else:
                return [x]
        input_names = self.model.input_names
        assert input_names[0] == "seq"
        
        if batch_size is None:
            return fn(input_to_list(input_names, x))[0]
        else:
            return numpy_collate_concat([fn(input_to_list(input_names, batch))[0]
                                         for batch in nested_numpy_minibatch(x, batch_size=batch_size)])

    def imp_score_all(self, seq, method='deeplift', batch_size=512, preact_only=True):
        """Compute all importance scores

        Args:
          seq: one-hot encoded DNA sequences
          method: 'deeplift'
          aggregate_strands: if True, the average importance scores across strands will be returned
          batch_size: batch size when computing the importance scores

        Returns:
          dictionary with keys: {task}/{head}/{interpretation_tensor}
          and values with the same shape as `seq` corresponding to importance scores
        """
        return {name: self.imp_score(seq, name, method=method, batch_size=batch_size)
                for name, _ in self.get_intp_tensors(preact_only=preact_only)}

    def predict(self, seq, batch_size=256):
        """Convert to dictionary
        """
        preds = self.model.predict(seq, batch_size=batch_size)
        return {k:v for k,v in zip(self.target_names, preds)}
    
    def save(self, file_path):
        """Save model to a file
        """
        from basepair.utils import write_pkl
        write_pkl(self, file_path)

    @classmethod
    def load(cls, file_path):
        """Load model from a file
        """
        from basepair.utils import read_pkl
        return read_pkl(file_path)

    @classmethod
    def from_mdir(cls, model_dir):
        """Load the model from pkl
        """
        return cls.load(os.path.join(model_dir, 'seq_model.pkl'))
In [4]:
# K.reset_uids()

# K.clear_session()

# sess = K.get_session()
In [5]:
from basepair.utils import write_pkl

from keras.models import Model
from keras.models import Sequential
import keras.layers as kl
In [6]:
# some example layers


class TopDense:
    """Class to be used as functional model interpretation
    """
    def __init__(self, pool_size=2):
        self.pool_size = pool_size
        
    def __call__(self, inp):
        x = kl.GlobalAvgPool1D()(inp)
        return kl.Dense(1)(x)

class BaseNet:
    """Class to be used as functional model interpretation
    """
    def __init__(self, activation='relu'):
        self.activation = activation
        
    def __call__(self, inp):
        x = kl.Conv1D(16, kernel_size=3, activation=self.activation)(inp)
        return x
In [7]:
import numpy as np
from concise.preprocessing import encodeDNA

# test the model
seqs = encodeDNA(['ACAGA']*100)
inputs = {"seq": seqs,
          "bias/a/profile": np.random.randint(low=0, high=2, size=(100, 2)).astype(bool),
          "bias/b/profile": np.random.randint(low=0, high=2, size=(100, 2)).astype(bool)}

targets = {"a/profile": np.random.randint(low=0, high=2, size=(100, 1)).astype(bool),
           "b/profile": np.random.randint(low=0, high=2, size=(100, 1)).astype(bool),
          }
In [8]:
m = SeqModel(
    body=BaseNet('relu'),
    heads=[BinaryClassificationHead(net=TopDense(pool_size=2), use_bias=True)],
    tasks=['a', 'b']
)
WARNING:tensorflow:From /users/amr1/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py:497: calling conv1d (from tensorflow.python.ops.nn_ops) with data_format=NHWC is deprecated and will be removed in a future version.
Instructions for updating:
`NHWC` for data_format is deprecated, use `NWC` instead
2019-02-09 12:30:53,711 [WARNING] From /users/amr1/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py:497: calling conv1d (from tensorflow.python.ops.nn_ops) with data_format=NHWC is deprecated and will be removed in a future version.
Instructions for updating:
`NHWC` for data_format is deprecated, use `NWC` instead
In [9]:
m.imp_fns
Out[9]:
{}
In [10]:
isinstance(m.model.inputs, list)
Out[10]:
True
In [11]:
m.imp_score_all(list(inputs.values()), preact_only=True, method='deeplift')['a/profile/logit'][0]
a/profile/logit
Tensor("model_1/dense_1/BiasAdd:0", shape=(?, 1), dtype=float32)
DeepExplain: running "deeplift" explanation method (5)
Model with multiple inputs:  True
b/profile/logit
Tensor("model_1/dense_3/BiasAdd:0", shape=(?, 1), dtype=float32)
DeepExplain: running "deeplift" explanation method (5)
Model with multiple inputs:  True
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-6435bbd69efa> in <module>()
----> 1 m.imp_score_all(list(inputs.values()), preact_only=True, method='deeplift')['a/profile/logit'][0]

<ipython-input-3-64da9cf72ce1> in imp_score_all(self, seq, method, batch_size, preact_only)
    179         """
    180         return {name: self.imp_score(seq, name, method=method, batch_size=batch_size)
--> 181                 for name, _ in self.get_intp_tensors(preact_only=preact_only)}
    182 
    183     def predict(self, seq, batch_size=256):

<ipython-input-3-64da9cf72ce1> in <dictcomp>(.0)
    179         """
    180         return {name: self.imp_score(seq, name, method=method, batch_size=batch_size)
--> 181                 for name, _ in self.get_intp_tensors(preact_only=preact_only)}
    182 
    183     def predict(self, seq, batch_size=256):

<ipython-input-3-64da9cf72ce1> in imp_score(self, x, name, method, batch_size, preact_only)
    163         else:
    164             return numpy_collate_concat([fn(input_to_list(input_names, batch))[0]
--> 165                                          for batch in nested_numpy_minibatch(x, batch_size=batch_size)])
    166 
    167     def imp_score_all(self, seq, method='deeplift', batch_size=512, preact_only=True):

<ipython-input-3-64da9cf72ce1> in <listcomp>(.0)
    163         else:
    164             return numpy_collate_concat([fn(input_to_list(input_names, batch))[0]
--> 165                                          for batch in nested_numpy_minibatch(x, batch_size=batch_size)])
    166 
    167     def imp_score_all(self, seq, method='deeplift', batch_size=512, preact_only=True):

~/deepexplain/DeepExplain/deepexplain/tensorflow/methods.py in func_to_return(inp)
    447                 feed_dict[input_tensor] = input_val
    448             sess = self.session
--> 449             return sess.run(outputs, feed_dict=feed_dict)
    450         return func_to_return
    451 

~/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/client/session.py in run(self, fetches, feed_dict, options, run_metadata)
    903     try:
    904       result = self._run(None, fetches, feed_dict, options_ptr,
--> 905                          run_metadata_ptr)
    906       if run_metadata:
    907         proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

~/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/client/session.py in _run(self, handle, fetches, feed_dict, options, run_metadata)
   1123     # Create a fetch handler to take care of the structure of fetches.
   1124     fetch_handler = _FetchHandler(
-> 1125         self._graph, fetches, feed_dict_tensor, feed_handles=feed_handles)
   1126 
   1127     # Run request and get response.

~/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/client/session.py in __init__(self, graph, fetches, feeds, feed_handles)
    425     """
    426     with graph.as_default():
--> 427       self._fetch_mapper = _FetchMapper.for_fetch(fetches)
    428     self._fetches = []
    429     self._targets = []

~/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/client/session.py in for_fetch(fetch)
    243     elif isinstance(fetch, (list, tuple)):
    244       # NOTE(touts): This is also the code path for namedtuples.
--> 245       return _ListFetchMapper(fetch)
    246     elif isinstance(fetch, dict):
    247       return _DictFetchMapper(fetch)

~/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/client/session.py in __init__(self, fetches)
    350     """
    351     self._fetch_type = type(fetches)
--> 352     self._mappers = [_FetchMapper.for_fetch(fetch) for fetch in fetches]
    353     self._unique_fetches, self._value_indices = _uniquify_fetches(self._mappers)
    354 

~/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/client/session.py in <listcomp>(.0)
    350     """
    351     self._fetch_type = type(fetches)
--> 352     self._mappers = [_FetchMapper.for_fetch(fetch) for fetch in fetches]
    353     self._unique_fetches, self._value_indices = _uniquify_fetches(self._mappers)
    354 

~/miniconda3/envs/basepair/lib/python3.6/site-packages/tensorflow/python/client/session.py in for_fetch(fetch)
    240     if fetch is None:
    241       raise TypeError('Fetch argument %r has invalid type %r' % (fetch,
--> 242                                                                  type(fetch)))
    243     elif isinstance(fetch, (list, tuple)):
    244       # NOTE(touts): This is also the code path for namedtuples.

TypeError: Fetch argument None has invalid type <class 'NoneType'>
In [ ]:
fn = m.imp_fns['deeplift/a/profile/logit']
In [ ]:
fn??
In [ ]:
list(inputs)
In [ ]:
[x.shape for x in inputs.values()]
In [ ]:
%debug
In [ ]:
m.imp_fns['deeplift/a/profile/logit'](list(inputs.values()))
In [ ]:
 
In [ ]:
%debug
In [ ]:
m.get_intp_tensors()
In [ ]:
m.predict_preact(seqs)['a/profile'][:4]
In [ ]:
# TODO - can we force some tensors to be 0?
In [ ]:
m.all_heads['a'][0].neutral_bias_input('a', 10)
In [ ]:
m.model.inputs
In [ ]:
m.bottleneck_model().output
In [ ]:
m.model.fit(inputs, targets)
In [ ]:
m2 = SeqModel(
    body=m.bottleneck_model(),
    heads=[BinaryClassificationHead(net=TopDense(pool_size=2))],
    tasks=['a', 'b']
)
In [ ]:
m2.model.inputs
In [ ]:
m.model.inputs
In [ ]:
m2.body.inputs
In [ ]:
m2._get_input_tensor()
In [ ]:
m2.model.fit(seqs, targets)
In [ ]:
m = SeqModel.load("/tmp/m.pkl")
In [ ]:
m.model.save("/tmp/m.pkl")
In [ ]:
from keras.models import load_model
In [ ]:
inp = kl.Input((None, 4), name='seq')
In [ ]:
m.predict(encodeDNA(['ACAGA']))
In [ ]:
m.get_intp_tensors()
In [ ]:
m._imp_deeplift_fn
In [ ]:
m.model.fit(seqs, targets)
In [ ]:
K.clear_session()

g = tf.get_default_graph()
g.get_operations()
In [ ]:
g = tf.get_default_graph()
g.get_operations()
In [ ]:
m = SeqModel.load("/tmp/a.pkl")
In [ ]:
t = m.all_heads['a'][0]
In [ ]:
t.get_interpretation_tensor('logit')
In [ ]:
interpret_targets
In [ ]:
m.grad_fns = {}
In [ ]:
fns = _imp_deeplift_fn(m, seqs)
In [ ]:
fns['b/profile/logit']([seqs])[0]
In [ ]:
m
In [ ]:
g = tf.get_default_graph()
g.get_operations()

test

In [3]:
from basepair.config import create_tf_session
In [4]:
create_tf_session(0)
Out[4]:
<tensorflow.python.client.session.Session at 0x7ff851d43cc0>
In [5]:
"""Test sequence model
"""
from basepair.seqmodel import SeqModel
from basepair.heads import ScalarHead, BinaryClassificationHead, ProfileHead
import numpy as np
import keras.layers as kl


class TopDense:
    """Class to be used as functional model interpretation
    """

    def __init__(self, pool_size=2):
        self.pool_size = pool_size

    def __call__(self, inp):
        x = kl.GlobalAvgPool1D()(inp)
        return kl.Dense(1)(x)


class TopConv:
    """Class to be used as functional model interpretation
    """

    def __init__(self, n_output=2):
        self.n_output = n_output

    def __call__(self, inp):
        return kl.Conv1D(self.n_output, 1)(inp)


class BaseNet:
    """Class to be used as functional model interpretation
    """

    def __init__(self, activation='relu'):
        self.activation = activation

    def __call__(self, inp):
        x = kl.Conv1D(16, kernel_size=3, activation=self.activation, padding='same')(inp)
        return x


def test_interpret_wo_bias():
    from basepair.metrics import PeakPredictionProfileMetric
    from gin_train.metrics import RegressionMetrics, ClassificationMetrics
    from concise.preprocessing import encodeDNA
    # test the model
    seqs = encodeDNA(['ACAGA'] * 100)

    inputs = {"seq": seqs,
              "bias/a/profile": np.random.randn(100, 5, 2)}

    # Let's use regression
    targets = {"a/class": np.random.randint(low=0, high=2, size=(100, 1)).astype(float),
               "a/counts": np.random.randn(100),
               "a/profile": np.random.randn(100, 5, 2),
               }

    import keras.backend as K
    # K.clear_session()
    # use bias
    m = SeqModel(
        body=BaseNet('relu'),
        heads=[BinaryClassificationHead('{task}/class',
                                        net=TopDense(pool_size=2),
                                        use_bias=False),
               ScalarHead('{task}/counts',
                          loss='mse',
                          metric=RegressionMetrics(),
                          net=TopDense(pool_size=2),
                          use_bias=False),
               ProfileHead('{task}/profile',
                           loss='mse',
                           metric=PeakPredictionProfileMetric(),
                           net=TopConv(n_output=2),
                           use_bias=True,
                           bias_shape=(5, 2)),  # NOTE: the shape currently has to be hard-coded to the sequence length
               ],
        tasks=['a']
    )
    m.model.fit(inputs, targets)

    o = m.imp_score_all(seqs)
    assert 'a/profile/wn' in o
    assert o['a/profile/wn'].shape == seqs.shape
    assert 'a/profile/wn' in o
    assert o['a/profile/wn'].shape == seqs.shape

    # evaluate the dataset -> setup an array dataset (NumpyDataset) -> convert to
    from basepair.data import NumpyDataset
    ds = NumpyDataset({"inputs": inputs, "targets": targets})
    o = m.evaluate(ds)
    assert 'avg/counts/mad' in o
In [6]:
from basepair.metrics import PeakPredictionProfileMetric
from gin_train.metrics import RegressionMetrics, ClassificationMetrics
from concise.preprocessing import encodeDNA
# test the model
seqs = encodeDNA(['ACAGA'] * 100)

inputs = {"seq": seqs,
          "bias/a/profile": np.random.randn(100, 5, 2)}

# Let's use regression
targets = {"a/class": np.random.randint(low=0, high=2, size=(100, 1)).astype(float),
           "a/counts": np.random.randn(100),
           "a/profile": np.random.randn(100, 5, 2),
           }

import keras.backend as K
# K.clear_session()
# use bias
m = SeqModel(
    body=BaseNet('relu'),
    heads=[BinaryClassificationHead('{task}/class',
                                    net=TopDense(pool_size=2),
                                    use_bias=False),
           ScalarHead('{task}/counts',
                      loss='mse',
                      metric=RegressionMetrics(),
                      net=TopDense(pool_size=2),
                      use_bias=False),
           ProfileHead('{task}/profile',
                       loss='mse',
                       metric=PeakPredictionProfileMetric(),
                       net=TopConv(n_output=2),
                       use_bias=True,
                       bias_shape=(5, 2)),  # NOTE: the shape currently has to be hard-coded to the sequence length
           ],
    tasks=['a']
)
m.model.fit(inputs, targets)
WARNING:tensorflow:From /users/avsec/bin/anaconda3/envs/chipnexus/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py:497: calling conv1d (from tensorflow.python.ops.nn_ops) with data_format=NHWC is deprecated and will be removed in a future version.
Instructions for updating:
`NHWC` for data_format is deprecated, use `NWC` instead
2019-02-11 02:19:34,009 [WARNING] From /users/avsec/bin/anaconda3/envs/chipnexus/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py:497: calling conv1d (from tensorflow.python.ops.nn_ops) with data_format=NHWC is deprecated and will be removed in a future version.
Instructions for updating:
`NHWC` for data_format is deprecated, use `NWC` instead
Epoch 1/1
100/100 [==============================] - 2s 18ms/step - loss: 3.3443 - a/class_loss: 0.6840 - a/counts_loss: 1.0134 - a/profile_loss: 1.6469
Out[6]:
<keras.callbacks.History at 0x7ff851cc3208>
In [7]:
type(m)
Out[7]:
basepair.seqmodel.SeqModel
In [13]:
gin_file = '../train/seqmodel/example.gin'
In [14]:
import gin
In [19]:
import gin_train
In [21]:
from gin_train.cli.gin_train import train
In [22]:
gin.parse_config_files_and_bindings([gin_file], bindings='')
In [23]:
m = SeqModel()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-557873c2c186> in <module>
----> 1 m = SeqModel()

TypeError: __init__() missing 3 required positional arguments: 'body', 'heads', and 'tasks'
In [8]:
m.save("/tmp/a.pkl")
> /users/avsec/workspace/basepair/basepair/seqmodel.py(268)save()
-> write_pkl(self, file_path)
--Return--
> /users/avsec/workspace/basepair/basepair/seqmodel.py(268)save()->None
-> write_pkl(self, file_path)
In [ ]:
o = m.imp_score_all(seqs)
assert 'a/profile/wn' in o
assert o['a/profile/wn'].shape == seqs.shape
assert 'a/profile/wn' in o
assert o['a/profile/wn'].shape == seqs.shape

# evaluate the dataset -> setup an array dataset (NumpyDataset) -> convert to
from basepair.data import NumpyDataset
ds = NumpyDataset({"inputs": inputs, "targets": targets})
o = m.evaluate(ds)
assert 'avg/counts/mad' in o