Python 利用深度学习从序列预测子序列

Python 利用深度学习从序列预测子序列,python,theano,deep-learning,keras,Python,Theano,Deep Learning,Keras,我的数据如下所示: 它可以查看,并已包含在下面的代码中。 事实上,我有大约7000个样品(行) 任务是给定抗原,预测相应的表位。 所以表位总是抗原的一个精确的亚链。这相当于 。下面是我在Keras下运行的递归神经网络代码。它是根据模型建立的 我的问题是: RNN、LSTM或GRU能否用于预测上述子序列 如何提高代码的准确性 如何修改代码以使其运行更快 这是我的运行代码,它给出了非常差的准确度分数 #!/usr/bin/env python # -*- coding: utf-8 -*- fro

我的数据如下所示:

它可以查看,并已包含在下面的代码中。 事实上,我有大约7000个样品(行)

任务是给定抗原,预测相应的表位。 所以表位总是抗原的一个精确的亚链。这相当于 。下面是我在Keras下运行的递归神经网络代码。它是根据模型建立的

我的问题是:

  • RNN、LSTM或GRU能否用于预测上述子序列
  • 如何提高代码的准确性
  • 如何修改代码以使其运行更快
  • 这是我的运行代码,它给出了非常差的准确度分数

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    from __future__ import print_function
    import sys
    import json
    import pandas as pd
    from keras.models import Sequential
    from keras.engine.training import slice_X
    from keras.layers.core import Activation,  RepeatVector, Dense
    from keras.layers import recurrent, TimeDistributed
    import numpy as np
    from six.moves import range
    
    class CharacterTable(object):
        '''
        Given a set of characters:
        + Encode them to a one hot integer representation
        + Decode the one hot integer representation to their character output
        + Decode a vector of probabilties to their character output
        '''
        def __init__(self, chars, maxlen):
            self.chars = sorted(set(chars))
            self.char_indices = dict((c, i) for i, c in enumerate(self.chars))
            self.indices_char = dict((i, c) for i, c in enumerate(self.chars))
            self.maxlen = maxlen
    
        def encode(self, C, maxlen=None):
            maxlen = maxlen if maxlen else self.maxlen
            X = np.zeros((maxlen, len(self.chars)))
            for i, c in enumerate(C):
                X[i, self.char_indices[c]] = 1
            return X
    
        def decode(self, X, calc_argmax=True):
            if calc_argmax:
                X = X.argmax(axis=-1)
            return ''.join(self.indices_char[x] for x in X)
    
    class colors:
        ok = '\033[92m'
        fail = '\033[91m'
        close = '\033[0m'
    
    INVERT = True
    HIDDEN_SIZE = 128
    BATCH_SIZE = 64
    LAYERS = 3
    # Try replacing GRU, or SimpleRNN
    RNN = recurrent.LSTM
    
    
    def main():
        """
        Epitope_core = answers
        Antigen      = questions
        """
    
        epi_antigen_df = pd.io.parsers.read_table("http://dpaste.com/2PZ9WH6.txt")
        antigens = epi_antigen_df["Antigen"].tolist()
        epitopes = epi_antigen_df["Epitope Core"].tolist()
    
        if INVERT:
            antigens = [ x[::-1] for x in antigens]
    
        allchars = "".join(antigens+epitopes)
        allchars = list(set(allchars))
        aa_chars =  "".join(allchars)
        sys.stderr.write(aa_chars + "\n")
    
        max_antigen_len = len(max(antigens, key=len))
        max_epitope_len = len(max(epitopes, key=len))
    
        X = np.zeros((len(antigens),max_antigen_len, len(aa_chars)),dtype=np.bool)
        y = np.zeros((len(epitopes),max_epitope_len, len(aa_chars)),dtype=np.bool)
    
        ctable = CharacterTable(aa_chars, max_antigen_len)
    
        sys.stderr.write("Begin vectorization\n")
        for i, antigen in enumerate(antigens):
            X[i] = ctable.encode(antigen, maxlen=max_antigen_len)
        for i, epitope in enumerate(epitopes):
            y[i] = ctable.encode(epitope, maxlen=max_epitope_len)
    
    
        # Shuffle (X, y) in unison as the later parts of X will almost all be larger digits
        indices = np.arange(len(y))
        np.random.shuffle(indices)
        X = X[indices]
        y = y[indices]
    
        # Explicitly set apart 10% for validation data that we never train over
        split_at = len(X) - len(X) / 10
        (X_train, X_val) = (slice_X(X, 0, split_at), slice_X(X, split_at))
        (y_train, y_val) = (y[:split_at], y[split_at:])
    
        sys.stderr.write("Build model\n")
        model = Sequential()
        # "Encode" the input sequence using an RNN, producing an output of HIDDEN_SIZE
        # note: in a situation where your input sequences have a variable length,
        # use input_shape=(None, nb_feature).
        model.add(RNN(HIDDEN_SIZE, input_shape=(max_antigen_len, len(aa_chars))))
        # For the decoder's input, we repeat the encoded input for each time step
        model.add(RepeatVector(max_epitope_len))
        # The decoder RNN could be multiple layers stacked or a single layer
        for _ in range(LAYERS):
            model.add(RNN(HIDDEN_SIZE, return_sequences=True))
    
        # For each of step of the output sequence, decide which character should be chosen
        model.add(TimeDistributed(Dense(len(aa_chars))))
        model.add(Activation('softmax'))
    
        model.compile(loss='categorical_crossentropy',
                    optimizer='adam',
                    metrics=['accuracy'])
    
        # Train the model each generation and show predictions against the validation dataset
        for iteration in range(1, 200):
            print()
            print('-' * 50)
            print('Iteration', iteration)
            model.fit(X_train, y_train, batch_size=BATCH_SIZE, nb_epoch=5,
                    validation_data=(X_val, y_val))
            ###
            # Select 10 samples from the validation set at random so we can visualize errors
            for i in range(10):
                ind = np.random.randint(0, len(X_val))
                rowX, rowy = X_val[np.array([ind])], y_val[np.array([ind])]
                preds = model.predict_classes(rowX, verbose=0)
                q = ctable.decode(rowX[0])
                correct = ctable.decode(rowy[0])
                guess = ctable.decode(preds[0], calc_argmax=False)
                # print('Q', q[::-1] if INVERT else q)
                print('T', correct)
                print(colors.ok + '☑' + colors.close if correct == guess else colors.fail + '☒' + colors.close, guess)
                print('---')
    
    if __name__ == '__main__':
        main()
    
  • RNN、LSTM或GRU能否用于预测上述子序列
  • 是的,你可以用任何一种。LSTM和GRU是RNN的类型;如果你说的RNN是指a,那么这些已经不受欢迎了,因为梯度消失的问题(,)。由于数据集中的示例相对较少,GRU可能比LSTM更适合,因为它的体系结构更简单

  • 如何提高代码的准确性
  • 您提到培训和验证错误都很糟糕。一般来说,这可能是由于以下几个因素之一:

    • 学习率太低(这不是问题,因为您使用的是Adam,一种每参数自适应学习率算法)
    • 模型对于数据来说太简单(根本不是问题,因为您有一个非常复杂的模型和一个小的数据集)
    • 您有消失的渐变(可能是因为您有一个3层RNN)。试着把层数减少到1(一般来说,从一个简单的模型开始工作,然后增加复杂性)是很好的,并且还考虑超参数搜索(例如128维隐藏状态可能太大-尝试30?)
    另一种选择是,由于你的表位是你输入的一个子串,预测抗原序列中表位的起始和结束指数(可能通过抗原序列的长度标准化),而不是一次预测一个字符的子串。这将是一个包含两个任务的回归问题。例如,如果抗原为FSKIAGLTVT(10个字母长),其表位为KIAGL(位置3至7,一个基),则输入为FSKIAGLTVT,输出为0.3(第一个任务)和0.7(第二个任务)

    或者,如果您可以使所有抗原的长度相同(通过删除数据集中含有短抗原的部分和/或切掉长抗原的末端,假设您事先知道表位不在末端附近),您可以将其作为一个分类问题,包括两个任务(开始和结束)和序列长度类,你试图给抗原分配一个概率,从每个位置开始和结束

  • 如何修改代码以使其运行更快
  • 减少层的数量将大大加快代码的速度。此外,由于GRU的体系结构更简单,因此GRU将比LSTM更快。然而,这两种类型的循环网络都比卷积网络慢


    如果您对合作感兴趣,请随时向我发送电子邮件(我个人资料中的地址)。

    该地址必须是抗原的精确子字符串,还是允许模糊匹配?这是个好问题!1.看起来抗原表位从来都不是抗原的精确子串?2.在这项任务中使用序列对序列学习是非常好的,但我的直觉是7000个示例太少了。3.你是如何处理表位的可变长度的?原始示例中填充了空格。4.你试过超参数搜索吗?5.模型是过拟合还是欠拟合(即,训练误差是好的,验证误差是坏的,还是两者都坏)?6.在运行时方面,代码中的瓶颈是什么?7.指向数据集的链接已断开。@1'':1。总是准确的。3.按原样对待可变长度。5.都不好。6.约7000个样本时,约20分钟/历元。7.链接已更新。我还包括了。如果匹配是准确的,字典搜索就足够了。这正是fgrep所做的:构建一个DFA,识别要在任何草堆中搜索的针的集合。预期的复杂度约为O log(M)*NK,其中M*为模式的典型大小(示例中约为15),N为干草堆的大小,K:=干草堆的数量。@无论如何,您可以尝试GRU而不是LSTM来加速,这可能会减少您遇到的不适。你能澄清一下“按原样对待可变长度”吗?我同意你应该尝试模拟两个切割点(表位的起始点和结束点)。您观察到的选择性是蛋白水解酶的选择性(以及它们的控制方式)@“1:您能否具体说明第2部分。两项任务的分类问题?示例代码?@”1:谢谢。但是
    X_列,y_列
    X_测试,y_测试
    看起来是什么样子?@neversaint
    X
    和以前一样,但是
    y
    是一个7000 X 2的矩阵。例如,
    y\u train[0]
    可能是
    [0.3,0.7]
    @neversaint这能回答你的问题吗?还有什么我可以澄清的吗?