最近在看ESMfold和embedding的知识,然后就来简单写一个简单易懂的蛋白质embedding的demo
这是esm的官网截图,很震撼,meta团队预测了772 million个蛋白质序列,然后将这些蛋白再组合成一个atom map就是上图的样子。
然后我们开始我们今天的代码部分,首先embedding的作用大家应该知道,但是以防读者不清楚,我们今天再来介绍一下:
代码语言:javascript复制`embedding`是深度学习中常用的一种技术,它用于将离散的符号(如单词、字符、类别等)映射到一个低维的连续向量空间中。嵌入向量(Embedding Vector)是这个映射的结果,也称为嵌入表示(Embedding Representation)或嵌入表征。
嵌入的作用主要有以下几个方面:
1. **降低维度和稀疏性:** 在自然语言处理(NLP)中,文本数据通常是高维且稀疏的,每个单词或字符都对应于一个独立的维度。通过使用嵌入技术,可以将高维的离散输入转换为低维的连续向量表示,从而降低了数据的维度,并且减少了数据中的稀疏性。
2. **提取语义信息:** 嵌入向量可以捕捉到输入符号之间的语义关系。相似的符号在嵌入空间中通常具有较近的距离,而语义上不相关的符号则具有较远的距离。通过学习这样的嵌入表示,模型可以更好地理解和表示输入符号之间的语义关联。
3. **通用特征表示:** 嵌入向量的学习是无监督的过程,因此可以在大规模的语料库上进行预训练。这些预训练的嵌入向量可以被用作下游任务的通用特征表示,从而提供了更好的初始特征表示,减少了对大量标注数据的依赖。
4. **改善模型性能:** 嵌入向量的使用通常可以提升深度学习模型在各种任务上的性能。在自然语言处理中,常见的应用包括文本分类、命名实体识别、机器翻译等任务。通过将离散的符号映射为连续的嵌入向量,模型可以更好地捕捉输入数据的结构和语义信息,从而提升模型的表达能力和泛化能力。
总而言之,嵌入技术通过将离散的符号映射到低维的连续向量空间中,克服了高维和稀疏数据的问题,并提供了更好的特征表示和语义信息,从而改善了深度学习模型在各种任务上的性能。
其实embedding就是将独热编码那种稀疏和高纬度的缺点给改良了一些
接下来我们对代码部分进行说明,首先是对蛋白质进行编码:
代码语言:javascript复制# 定义氨基酸编码映射
amino_acid_map = {
'A': 0, 'R': 1, 'N': 2, 'D': 3, 'C': 4, 'Q': 5, 'E': 6, 'G': 7, 'H': 8, 'I': 9,
'L': 10, 'K': 11, 'M': 12, 'F': 13, 'P': 14, 'S': 15, 'T': 16, 'W': 17, 'Y': 18, 'V': 19
}
20个氨基酸的编码映射
然后进行独热编码:
代码语言:javascript复制def amino_acid_to_one_hot(amino_acid):
# 创建20维独热编码向量
one_hot_encoded = np.zeros(len(amino_acid_map))
# 将对应氨基酸位置设置为1
one_hot_encoded[amino_acid_map[amino_acid]] = 1
return one_hot_encoded
这样可以把一个向量转化成一个20维的向量
现在氨基酸已经编码成功了,我们只需要把我们输入的蛋白质序列转化成高维序列
代码语言:javascript复制def protein_to_high_dimensional(protein_sequence):
one_hot_encoded = [amino_acid_to_one_hot(amino_acid) for amino_acid in protein_sequence]
high_dimensional_vector = torch.LongTensor(np.array(one_hot_encoded))
return high_dimensional_vector
这一步利用编码好的氨基酸编码,然后对序列进行再次编码
然后创建我们的embedding嵌入矩阵:
打印一下权重:
Embedding的第一个参数20代表了20种氨基酸,40代表了我们要设置的维度,这里设置为了40,大家也可以设置成其他数字
然后把我们的蛋白质序列进行embedding:
代码语言:javascript复制proteinA1_sequence = 'ADNKFNKREGGFDDFGFDGDDGNGFIQSLKDDPSQSANLLAEAKKLNDAQAPK'
high_dimensional_vector1 = protein_to_high_dimensional(proteinA1_sequence)
print("Protein Sequence:", proteinA1_sequence)
print("High-Dimensional Vector Shape:", high_dimensional_vector1.shape)
e1=embedding(high_dimensional_vector1)
e1就是我们的embedding之后的结果
e1的shape是我们的蛋白质长度N*20*40
然后再对另外一条蛋白质进行embedding也会得到一个结果e2
然后就可以对e1和e2求余弦相似度了
代码语言:javascript复制similarity = torch.nn.functional.cosine_similarity(e1.flatten(), e2.flatten(), dim=0)
可以看到通过embedding后 这两个蛋白序列的相似度是
0.9981