蛋白质边的重新说明

inner_edges (ctx_edges)会包含全局节点的部分

第一部分即使E3-E3和Antibody-Antibody

还有三个是我之前忽略了的

在这里,每个蛋白质的 3 个全局节点分别代表抗原、重链和轻链的全局信息。让我们逐步解析 global_normalglobal_globalseq_edges 的含义,以及它们的构建逻辑。

1. 每个蛋白质的 3 个全局节点

每个蛋白质会有 3 个全局节点,用于分别代表:

  • 抗原的全局节点(标识为 BOA,如 '&'
  • 重链的全局节点(标识为 BOH,如 '+'
  • 轻链的全局节点(标识为 BOL,如 '-'

这些全局节点的设计目的是在模型中为每个链提供一个集中信息的节点,以帮助捕捉整个抗原、重链和轻链的全局特征。

2. global_normalglobal_global 边的含义

self._construct_global_edges() 方法中:

  • global_normal:连接 全局节点普通节点 的边。这些边确保每个链的全局节点与其链中的其他节点相连,以便在图中传递全局信息。

    • 例如,抗原全局节点 BOA 会与抗原链上的所有其他节点连接;重链和轻链的全局节点也分别与重链和轻链的普通节点连接。
  • global_global:连接 全局节点之间 的边,这些边允许不同链的全局节点之间通信。

    • 比如,抗原的全局节点可以连接到重链和轻链的全局节点,以共享跨链的全局信息。

3. seq_edges 的含义

seq_edges 表示序列中的相邻节点之间的边,即在一维序列上顺序相邻的节点之间建立连接。其目的是确保每个残基的相邻节点能够直接连接起来,从而保持蛋白质链的结构顺序。例如:

  • 如果节点 ii+1 在一维序列上是相邻的,那么它们之间会建立一个 seq_edge,帮助模型在图上保持链的顺序结构。

总结

  • global_normal:将链的全局节点与该链中的普通节点连接。
  • global_global:将不同链的全局节点相互连接,促进跨链的全局信息传递。
  • seq_edges:在序列上相邻的节点之间建立连接,确保模型理解蛋白质链的线性顺序。

这些边的设计帮助模型在全局和局部层面都能传递信息,确保不同链及其全局节点间的信息交换。

local_edges = local_ctx_edges + local_ inter_edges

在这个模型中,paratope 的设置直接影响 local_ctx_edgeslocal_inter_edges 的构建,限制了边构建的节点范围和连接方式。为了展示这个过程,从初始赋值开始,主要关注 paratope 是如何逐步影响到边构建的区域的。以下是从代码的核心流程一步步展示如何进行的:

1. 初始化 paratope 参数

在模型的初始化配置中,paratope 参数设置为 ["L3", "H3"],这意味着只将 L3H3 片段设置为抗体抗原接口(paratope)。在 E2EDataset 类的 __getitem__ 函数中,我们使用 paratope 来生成 paratope_mask,用于标记哪些片段参与到 paratope 区域内的计算。简化展示:

# 根据 paratope 设置生成 paratope_mask
paratope_mask = [0 for _ in range(len(ag_data['S']) + len(hc_data['S']) + len(lc_data['S']))]
paratope = [self.paratope] if type(self.paratope) == str else self.paratope
for cdr in paratope:
    cdr_range = item.get_cdr_pos(cdr)
    offset = len(ag_data['S']) + 1 + (0 if cdr[0] == 'H' else len(hc_data['S']))
    for idx in range(offset + cdr_range[0], offset + cdr_range[1] + 1):
        paratope_mask[idx] = 1
data['paratope_mask'] = paratope_mask

在这里,paratope_mask 的位置为 1 的元素对应于 L3H3 片段。这一掩码在 local_ctx_edgeslocal_inter_edges 的构建中直接限制了边的构建范围。

2. 在 _prepare_batch_constants 中生成 local_masklocal_is_ab

paratope_mask 接下来会在 dyMEANModel_prepare_batch_constants 函数中用于生成 local_mask,标记哪些节点被选为局部节点:

# 使用 paratope_mask 限制边构建的范围
local_mask = torch.logical_or(
    paratope_mask, torch.logical_and(is_ag, not_ag_global)  # 标记抗原的非全局节点
)

local_mask 将只包含 paratope 内的抗体节点 L3H3,以及非全局的抗原节点。这样,local_ctx_edges 只会考虑 L3H3 内部的连接,而不会涉及其他抗体片段(例如 H1L1)。

3. 构建 local_ctx_edges

dyMEANModelmessage_passing 函数中,根据 local_maskparatope_mask 来调用 _knn_edges 函数以构建 local_ctx_edges

local_ctx_edges = _knn_edges(
    local_X, atom_pos, local_ctx_edges.T,
    self.aa_feature.atom_pos_pad_idx, self.k_neighbors,
    (offsets, local_batch_id, max_n, gni2lni)
)

这里,local_ctx_edges 将只在 paratope_mask 内部构建边,_knn_edges 根据 k_neighbors 的限制生成 L3-L3H3-H3 的边,而不会跨越到其他区域,也不会包含 E-E 边。

4. 构建 local_inter_edges

对于 local_inter_edges,则是构建抗体和抗原之间的交互边,同样受到 paratope_mask 限制:

local_inter_edges = _knn_edges(
    local_X, atom_pos, local_inter_edges.T,
    self.aa_feature.atom_pos_pad_idx, self.k_neighbors,
    (offsets, local_batch_id, max_n, gni2lni), given_dist=p_edge_dist
)

local_inter_edges 这里会构建 E-H3E-L3 的边,因为它们被 paratope_mask 标记为抗体抗原交互区域,而不会包含 H1-H2 或其他非 paratope 的交互。

总结

通过 paratope_mask 的逐步应用,local_ctx_edges 仅构建 L3-L3H3-H3 内部边,local_inter_edges 仅包含 E-L3E-H3 边。

local_ctx_edges 不会包含 E-E 边,因为 local_ctx_edges 的构建仅在抗体(Antibody)链内有效,构建边的对象只会是 paratope 设置内的抗体片段,也就是 L3-L3H3-H3

因此,local_ctx_edges 只包含 L3-L3H3-H3 的局部边,而不会包含 E-E 的边。

在代码中设置了 args.paratope = ["L3", "H3"] 后,local_ctx_edgeslocal_inter_edges 的构建会受到 paratope 设置的影响,使得只在局部包含 paratope(即 L3 和 H3)相关的边。

以下是如何在代码实现中影响 local_ctx_edgeslocal_inter_edges

  1. local_ctx_edges:

    • local_ctx_edges 会构建同一 segment 内的边,即在 paratope 设置下仅包含 L3-L3H3-H3 的边。
    • 所以,即使代码有逻辑生成 H1-H1、H2-H2 等同一 segment 的边,这些边不会包含在 local_ctx_edges 中。代码会过滤掉这些非 paratope 相关的边,只保留 L3-L3H3-H3 的局部上下文边。
  2. local_inter_edges:

    • local_inter_edges 只包含 paratope(L3 和 H3)与抗原 E 的交互边。
    • 因此,在代码中设置 args.paratope = ["L3", "H3"] 后,local_inter_edges 只包含 L3-EH3-E 的交互边,而不会包含 H1-H2、L1-L2 等边。

总结:在设置了 paratope = ["L3", "H3"] 后,local_ctx_edges 只包含 L3-L3H3-H3,而 local_inter_edges 只包含 L3-EH3-E 的边。

关于不同部分的边是否包含全局节点

在代码逻辑中,local_protein_ids 是基于 local_segment_ids 构建的,而 local_segment_ids 本身是对局部区域(如 EH3L3)的节点进行标记。从代码来看,local_segment_ids 不包含全局节点。具体原因如下:

  1. local_segment_ids 构建
    在生成 local_segment_ids 时,代码中会过滤掉全局节点,仅保留与特定 CDR 相关的节点(例如 H3L3)以及抗原的局部节点(E),因此全局节点不会出现在 local_segment_ids 中。

  2. local_protein_ids 的生成
    local_protein_ids 是基于 local_segment_ids 的索引依次赋值,表明它只在每个局部区域中唯一标识残基链。因此,local_protein_ids 仅包含局部节点,和 local_segment_ids 保持一致。

  3. 边构建中的限制
    local_ctx_edgeslocal_inter_edges 的生成同样基于局部区域,不涉及全局节点的边,从而确保了 local_protein_idslocal_segment_ids 中都不含全局节点。

这样,local_protein_ids 中将仅包含 EH3L3 区域的残基,并不包括全局节点。这种设置确保了在局部消息传递时,操作仅限于特定区域的局部节点。

是的,代码中 segment_ids 包含全局节点,而 local_segment_ids 则不包含全局节点。以下是详细说明以及相关代码段验证如何在构建 local_segment_ids 时去掉了全局节点,包括 E 区域的全局节点。

1. segment_ids 的构建

在代码中,segment_ids 是通过 _construct_segment_ids(S) 方法构建的,通常如下:

segment_ids = self._construct_segment_ids(S)

segment_ids 包含所有节点,包括全局节点。全局节点通常使用特殊的标记 (boa_idxboh_idxbol_idx),这些标记会根据抗原、重链、轻链等分段进行区分和编号,存储在 segment_ids 中。因此,segment_ids 是包含全局节点的。

2. local_segment_ids 构建过程中去掉全局节点的代码逻辑

dyMEANModel 类中,通过以下代码实现 local_segment_ids 的构建,其中去掉了全局节点:

# Filtering to remove global nodes, and only keep specific regions based on args.paratope (e.g., H3, L3)
local_mask = torch.logical_or(
    paratope_mask, torch.logical_and(is_ag, not_ag_global) 
)
  • paratope_mask:根据 args.paratope 指定的 CDR 区域(例如 H3L3),在 S 中标记哪些节点属于 CDR 区域,这里不包含任何全局节点。
  • is_agnot_ag_globalis_ag 表示抗原节点,而 not_ag_global 去掉了抗原中的全局节点。

最终,local_mask 只保留了局部节点中的 E(去掉了抗原中的全局节点)和 args.paratope 指定的 CDR 区域。通过 local_mask 筛选后的 local_segment_ids 不包含任何全局节点。

3. 验证代码

# local_segment_ids 从 segment_ids 中去掉全局节点后的结果
local_segment_ids = segment_ids[local_mask]

通过 local_mask 过滤后,local_segment_ids 最终仅包含 E 区域的局部节点以及指定的 H3L3 区域,去掉了所有的全局节点(包括 E 区域的全局节点)。

是的,paratope_mask 仅标记指定的 paratope 区域(如 H3L3),不包含任何全局节点。其构建逻辑专门排除了全局节点,确保 paratope_mask 仅作用于需要关注的局部区域。

在代码中,paratope_mask 是通过 args.paratope 参数指定的 CDR 区域来设置的。例如,当 args.paratope 设为 ["H3", "L3"] 时,paratope_mask 将仅标记属于 H3L3 的局部区域节点,而不会包含全局节点 (boa_idxboh_idxbol_idx)。

以下代码片段展示了 paratope_mask 的构建过程:

# 初始化 paratope_mask
paratope_mask = [0 for _ in range(len(ag_data['S']) + len(hc_data['S']) + len(lc_data['S']))]

# 根据指定的 paratope 区域,如 H3 和 L3,标记 paratope_mask
paratope = [self.paratope] if type(self.paratope) == str else self.paratope
for cdr in paratope:
    cdr_range = item.get_cdr_pos(cdr)
    offset = len(ag_data['S']) + 1 + (0 if cdr[0] == 'H' else len(hc_data['S']))
    for idx in range(offset + cdr_range[0], offset + cdr_range[1] + 1):
        paratope_mask[idx] = 1

这个代码确保 paratope_mask 只对指定的 CDR 区域(H3L3)的节点生效,不会将全局节点包括进来。

关于三角矩阵是对哪部分进行构建

是的,local_segment_ids 确实不包含全局节点,它仅包括被 local_mask 标记为局部的节点。而对于每个批次(batch)的 local_segment_ids,根据 paratope 设置为 ["L3", "H3"] 的情况,确实会包含以下三个部分:

  1. 抗原 (Epitope, E): 包含所有被认为是抗原的非全局节点。
  2. H3 片段: 作为抗体的 CDR 区域之一,标记为 paratope 片段。
  3. L3 片段: 作为抗体的另一个 CDR 区域,也被标记为 paratope 片段。

更详细说明

local_mask 构建过程中,全局节点已经被排除在外,所以 local_segment_ids 只会保留与 paratope 和抗原有关的非全局节点。因此,local_segment_ids 会包括 E(抗原)、H3L3,且不会包含任何全局节点。

是的,在构建三角矩阵时,按照当前代码中的逻辑,会对 E(抗原)、H3、和 L3 分别构建矩阵。以下是如何实现的解释:

  1. 局部蛋白质的划分:根据 local_protein_ids 中的分配,将 inter_h 特征划分成三部分,分别对应 E(抗原)、H3、和 L3

  2. 矩阵构建

    • 使用 local_protein_idsunique_protein_ids 获取每个局部蛋白质。
    • 对每个局部蛋白质,构建一个矩阵,矩阵中的每个位置代表两两残基的特征组合。
    • 通过 mlp 函数进行逐元素拼接和计算,生成矩阵的每个元素。
  3. 三角消息传递

    • 将每个矩阵依次通过 triangle_multiply_outgoingtriangle_multiply_ingoingtriangle_attention_outgoingtriangle_attention_ingoing 进行三角消息传递和更新,保留局部蛋白质的上下文信息。
    • 最后在每个矩阵上批量化操作,以维持不同局部蛋白质之间的独立性,确保 EH3、和 L3 的矩阵单独操作。
  4. 特征提取和降维

    • 将消息传递后的矩阵提取出对角线的特征,表示每个残基更新后的特征。
    • 使用 reduce 将这些特征降维到统一维度,再拼接成最终的 inter_h

这种构建方式确保了对 EH3、和 L3 的独立处理,并在局部三角矩阵中保留每部分内部残基之间的消息传递。

p_edge_dist是什么 (r_ed_loss)

正是如此,p_edge_dist 主要关注 抗原(E)和抗体的特定部分(例如 H3)之间的交互。在代码中,这些距离计算会:

  1. 限定在 local_inter_edges 表示的交互边之内,这些边是 抗原(E)和抗体中 H3 残基 之间的关系。
  2. 对于每一对指定的交互边上的残基,通过计算每个原子对的距离并取最小值,得到这些边之间的最短距离。

这样计算出来的 p_edge_dist 可以有效反映 E 和 H3 之间的局部交互强度,为模型提供一个用于优化的交互损失(ed_loss),帮助模型更精确地捕捉抗原-抗体交互的关键特性。

是的,gt_edge_dist 中的每个元素表示 两个交互残基之间最近原子的距离。具体而言,对于在抗原和抗体之间定义的每对交互边,_get_inter_edge_dist 会计算该边上各原子对之间的距离,然后选择距离最短的原子对作为该边的距离。这种方式有效地表示了两个残基间的“最近接触点”,从而用于后续的交互距离损失计算。

p_edge_dist 实际上表示 在蛋白质中,特定残基与其他交互残基之间的最近距离。对于每个边上的残基对,它会计算:

  1. 该残基与其他残基的所有原子对之间的距离。
  2. 然后对这些原子对的距离取最小值。

这样,对于 p_edge_dist 中的每一个距离值,它代表了 两个残基之间的最小原子对距离,用于反映该交互边上的最近接触点,从而评估残基之间的相互作用强度。这些距离值在模型训练中作为参考,用于与 gt_edge_dist 比较计算损失。

有两种坐标,哪种是计算哪个指标

cal_metrics 中,代码使用了不同的坐标数据结构来计算各种指标。这里是代码中各个指标如何使用 pred_Xinterface_X 这两种坐标的详细说明:

  1. AAR(Amino Acid Recovery)和 CAAR(Contact Amino Acid Recovery)

    • 这些指标计算的是预测的氨基酸序列与真实序列之间的匹配率,不涉及结构坐标(pred_Xinterface_X)。
    • 因此,AAR 和 CAAR 只使用氨基酸序列信息,不会使用任何坐标信息。
  2. RMSD(CA)(Root Mean Square Deviation for C-alpha Atoms)

    • 代码中 RMSD(CA) 指标计算的是整个抗体结构的 RMSD,特别是 C-alpha 原子的对齐和未对齐的 RMSD。
    • 在计算该指标时使用 pred_X(即 mod_cplx 中的坐标)和真实结构 ref_cplx 的 C-alpha 原子坐标 gt_x
    • 例如代码中:
      results['RMSD(CA) aligned'] = compute_rmsd(gt_x, pred_x, aligned=False)
      
  3. TM-score

    • TM-score 计算了整个抗体结构的相似度,不只是针对交互区域。
    • 代码中直接计算的是抗体整体的 TM-score,使用 mod_cplx.antibodyref_cplx.antibody 对比 整个抗体的预测坐标 pred_X
    • 例如代码:
      results['TMscore'] = tm_score(mod_cplx.antibody, ref_cplx.antibody)
      
  4. LDDT (Local Distance Difference Test)

    • LDDT 计算的是局部区域的距离差分,衡量预测结构与真实结构在局部原子坐标上的一致性。
    • 在此代码中,LDDT 计算的是整个抗体的 pred_Xtrue_X,即 mod_cplx.antibodyref_cplx.antibody
    • 示例代码:
      score, _ = lddt(mod_cplx.antibody, ref_cplx.antibody)
      
  5. DockQ

    • DockQ 指标是一个综合评估抗体与抗原界面的对接质量的指标,尤其是界面残基的预测质量。
    • DockQ 使用的是 抗体界面区域的 interface_X 与真实界面的对比
    • 在代码中:
      score = dockq(mod_cplx, ref_cplx, cdrh3_only=True)
      

总结

  • pred_X:用于计算整个抗体结构的 RMSD、TM-score 和 LDDT。
  • interface_X:用于 DockQ 指标的界面区域评估。

我想知道这里E(抗原)坐标每次forward都会被替换成真实的么?

是的,代码的设计方式使得在每次 forward 过程中,抗原(E)的坐标会替换成真实的坐标。这一行为在你的代码中通过模板初始化、中心化、更新全局坐标等步骤实现,确保了抗原的坐标在 forward 过程中始终保持真实数据。

具体来说,这种替换在以下几个步骤中体现:

  1. 模板初始化和真实坐标设置

    • 在初始化阶段,通过使用模板文件,抗原(E)和抗体链的坐标被初始化为真实的模板坐标。
  2. 更新全局坐标

    • forward 中调用的 update_globel_coordinates 会使用真实数据更新抗原的质心坐标,确保抗原坐标在每一轮消息传递中都是准确的。
  3. 构建局部交互坐标

    • _get_inter_edge_dist 中,代码直接从输入的 true_X 提取局部区域的真实坐标,然后结合全局更新步骤,这些真实坐标会被使用在后续损失计算中。

总结

每次 forward 传递时,抗原的坐标在多步过程中都被重设为真实数据,因此模型在每次迭代中使用的抗原坐标可以认为是保持真实的。

是的,在代码中,抗原的坐标同样参与了中心化(centering)和归一化(normalize),这一处理确保整个分子(包括抗原和抗体链)的坐标都符合模型的输入标准,且具有一致的尺度和位置。下面详细说明抗原参与中心化和归一化的情况及原因:

1. 中心化(centering)

  • 目的:将抗原、抗体链的质心都移动到原点附近,以减少不同样本在空间位置上的偏差。
  • 操作:在 centering 中,抗原的质心和抗体链的质心分别被计算并移至原点。抗原和抗体链的中心坐标分别计算,确保两部分的整体位置在处理和消息传递时不偏离原点。
  • 效果:通过将抗原与抗体链分别中心化,模型可以更稳定地处理彼此相对的空间位置,尤其是在抗体和抗原之间的相互作用区域(如抗体的 paratope 与抗原的 epitope 之间)。

2. 归一化(normalize)

  • 目的:将所有坐标的数值范围标准化,以符合模型训练的尺度标准。
  • 操作:抗原的坐标在 normalize 步骤中和抗体链的坐标一同标准化,具体而言是减去一个全局均值并除以标准差。这样做后,抗原与抗体链的坐标都会被规范到一个较小的数值范围内,有助于提升训练收敛性和数值稳定性。
  • 效果:标准化后的抗原坐标在消息传递环节中的数值尺度与抗体链保持一致,使得模型处理和计算时不会因为尺度差异而导致数值上的偏差。

3. 对整体流程的影响

  • 在经过中心化和归一化后,抗原的坐标被拉到了和抗体链相同的数值范围,确保模型计算中的一致性。
  • 在反向的 uncenteringunnormalize 阶段中,抗原的坐标会恢复到原始尺度和位置,用于最终的坐标输出和损失计算。

总结

因此,抗原参与中心化和归一化并非为了改变其实际空间位置,而是为了在模型的处理过程中保持数值一致性,最终仍会在恢复原始尺度和位置后进行精确的坐标比对和损失计算。

是的,抗原(antigen)部分的坐标在模型中通常都是使用实际坐标。在代码执行时,对于抗原分子中的每个残基,如果原子存在实际的坐标,这些坐标会被直接使用,而不会进行额外的填充或替代。只有在个别情况下,例如残基缺少某些侧链原子时,才会用 CA 坐标或其他默认方式填充。

实际坐标使用的典型情况:

  1. 初始化阶段

    • construct_template 和其他初始化函数中,对于抗原的主链和侧链原子,通常会根据真实的 PDB 文件数据提取实际的坐标。
  2. 坐标更新和消息传递

    • 在模型的消息传递环节(例如 update_globel_coordinates 和其他 GNN 操作),这些实际坐标用于计算残基之间的相对位置和距离,并进一步用于模型的特征传递和坐标预测。
  3. 坐标损失计算

    • 在计算坐标损失时,抗原的坐标通常都是实际坐标。损失函数会对预测的 14 个原子坐标与真实结构中的原子坐标进行比对,其中对于抗原部分会直接使用真实坐标。

因此,除非抗原的残基中确实缺少一些原子,大部分情况下,模型计算和预测时所使用的抗原坐标都是真实的实际坐标。

两种坐标,两种损失

在这里的代码中,确实存在两种不同的坐标损失计算方式,分别用于不同的任务目标:

  1. structure_loss (全结构损失)

    • 目标:用于评估整个蛋白质的坐标预测精度,包括所有残基的主链和侧链原子。
    • 计算方式structure_loss 计算的是模型预测的全局坐标 pred_X 与真实结构 true_X 之间的差异。它采用了掩码 xloss_mask 来过滤掉不参与计算的原子坐标。
    • 计算范围:考虑所有残基中的有效原子,通过逐原子计算的方式,整合出一个总体损失。
    • 损失项:通常包括骨架原子的均方误差损失、侧链键长损失以及角度损失等,以保持预测结构的完整性。
  2. interface_loss (界面损失)

    • 目标:用于评估蛋白质界面(paratope)部分的预测准确性,特别是抗体-抗原相互作用区域。
    • 计算方式interface_loss 计算模型预测的界面坐标 r_interface_X(由最后一次更新的 interface_X 提供)与真实界面坐标 gt_interface_X 之间的差异。
    • 计算范围:只关注 paratope 区域的原子。通过 paratope_maskatom_pos_pad_idx 掩码过滤掉不在界面区域内的原子,计算界面相关坐标的损失。
    • 损失项:这部分的损失主要关注界面区域的相互作用原子位置,用来优化模型对界面位置的精确预测,从而提升抗体和抗原间的配体对接效果。

两种损失计算的区别在于,structure_loss 关注整个蛋白质结构的预测准确性,而 interface_loss 则专注于抗体和抗原界面区域的预测精度。

structure loss的计算

在这段代码中,coord_lossstructure_loss 都计算了坐标损失,但它们的作用和关注点有所不同:

  1. coord_loss

    • 主要作用:对预测和真实结构的全原子坐标进行损失计算,但其中使用了主链(backbone)原子进行配准。
    • 细节:在计算前,代码提取了主链坐标 pred_bbtrue_bb(即 N, CA, C, O 原子),使用 Kabsch 算法对这些主链原子进行对齐,得到旋转矩阵 R 和平移向量 t,以将真实结构 true_X 的坐标对齐到预测结构 pred_X 上。这种对齐能减少由刚体位移造成的误差影响。
    • 损失计算:损失函数是 smooth_l1_loss,对齐后的所有原子(包括侧链原子)之间的差异作为损失值。因此,coord_loss 涵盖了 14 个通道的所有原子坐标,并没有专门分开侧链和主链,只是用主链对齐来确保损失主要反映预测与真实结构的差异,而不是旋转平移的影响。
  2. structure_loss

    • 主要作用:在 coord_loss 的基础上进一步添加几何约束,确保模型预测的结构合理。
    • 骨架(主链)约束
      • 键长约束:调用 _cal_backbone_bond_lengths,计算主链键长(如 N-CA,CA-C 等),并将预测的键长与真实值比较。
      • 二面角和键角约束(若 full_profile=True):调用 _cal_angles 计算预测和真实结构的二面角和键角,并计算差异。
    • 侧链约束(若 self.backbone_only=False):
      • 侧链键长:调用 _cal_sidechain_bond_lengths 计算预测和真实结构侧链键长的差异。
      • 侧链二面角(若 full_profile=True):调用 _cal_sidechain_chis 计算预测和真实结构的侧链旋转角差异。
    • 最终损失structure_loss 中的总损失 loss 包括 coord_loss 和上述的主链、侧链的几何约束损失。这样做的目的是确保不仅整体结构接近真实值,还在几何结构上更加合理。

总结

  • coord_loss:主要关注于整体坐标(主链+侧链)与真实值的差异,用主链原子对齐后计算所有原子的损失。
  • structure_loss:在 coord_loss 的基础上,进一步施加了主链和侧链的几何约束,确保预测结构在主链键长、键角和侧链二面角等方面的物理合理性。

初始化未知残基的计算,估计就是4个主链原子embedding,加上一个24的残基embedding,还有位置embedding

是的,对于未知残基 24,代码确实只使用了主链原子(N, CA, C, O)来构建 atom_embedding。这样处理的原因在于:

  1. 避免无效信息:侧链原子信息在未知残基 24 中不可用,因此填充主链原子可以为模型提供基础的骨架信息,而不会引入无效或虚构的侧链原子数据。

  2. 掩码排除:代码通过填充标记 atom_pad_idxatom_pos_pad_idx 来屏蔽除主链原子外的其余嵌入位置。这些填充标记会将无效位的嵌入设置为零或其他无效值,并通过掩码确保这些位置不参与模型的更新过程。

因此,在模型的嵌入层和计算过程中,未知残基 24 只利用了主链原子坐标信息来构建嵌入。

在代码中,未知残基(填充值 24)的 embedding 是通过一套特定处理方式构建的。在这类处理过程中,未知残基 24 会有一个预定义的特定原子和位置填充值,确保嵌入在计算中对真实残基最少影响。以下是具体步骤:

1. 残基嵌入 (residue_embedding)

AminoAcidEmbedding 类的初始化中,residue_embedding 会将未知残基 24 的嵌入初始化为一个特定向量。由于这是直接查表操作,因此可以对未知残基 24 生成固定的嵌入。

2. 位置嵌入 (res_pos_embedding)

位置嵌入 (res_pos_embedding) 是基于位置的嵌入,而非残基本身。即使残基类型是 24,其位置编码仍按其在序列中的索引进行生成。代码中 SinusoidalPositionEmbedding 类负责该嵌入,其中使用了一个 sin-cos 函数来生成相对位置编码。

3. 原子嵌入 (atom_embedding)

对于未知残基 24atom_embedding 的处理稍有不同。代码中的逻辑会确保:

  • 原子类型默认填充为主链原子 N, CA, C, O,并对缺失的其他原子使用一个填充原子掩码。每个残基的原子数最多为 14
  • 如果 24 被识别为填充值,则填充的原子类型和位置都标记为 atom_pad_idx(通常为 0)。该标记确保 atom_embedding 使用了一个零向量或者特殊嵌入来隔离未知残基的填充值。

模板初始化抗体

在您的代码中,对于原子数量少于最大原子数(例如 14 个原子)的残基,剩余位置的填充是采用 CA 原子坐标 而非纯零向量。具体处理步骤如下:

  1. 残基初始化

    • construct_template 中,对于缺少侧链原子的残基,会填充其主链的 CA 原子坐标,使得每个残基的坐标维度一致。
    • 这种填充确保残基在构建模板时具有相同的通道数,便于后续的消息传递和坐标更新。
  2. 填充机制的实现

    • 当残基的实际原子数小于 14 时,代码会从 CA 原子复制坐标,以填满剩余的原子位置。例如,若某残基仅包含 6 个原子,代码会从第 7 到第 14 个位置填入 CA 的坐标。
  3. 避免错误梯度的作用

    • 使用 CA 坐标填充,而非零向量,能够在消息传递中减少因零向量引入的梯度问题。填充后的坐标更符合生物结构的自然性,也有助于模型更好地学习不同残基的空间关系。

这种填充策略确保了在消息传递和坐标更新时,不存在明显的零向量填充干扰,同时使得模型在计算坐标损失时仅关注实际存在的原子。

template.json 中的示例可以看出,每个残基仅包含四个原子的坐标信息,即 N, CA, C, 和 O,这些属于主链(backbone)原子。没有包含侧链原子的坐标信息。这是通过以下观察确认的:

  1. 每个残基的坐标数量:每个残基的坐标列表包含四个元素,而这四个元素在代码实现中分别对应 N, CA, C, 和 O 原子的位置。
  2. 代码实现细节:在 _chain_template 方法中,代码明确从模板中读取主链原子的位置,并且在生成过程中默认会填充 CA 的坐标以达到一致的通道数量。

因此,template.json 文件仅保存了主链原子 N, CA, C, 和 O 的坐标,没有包含任何侧链原子的位置。

在上述代码中,模板的生成并不仅仅是计算 CA 原子的坐标,而是涵盖了 backbone(主链)原子,包括 N, CA, C, O 原子的坐标。具体来说:

  • _chain_template 方法中,每个符合保守条件的残基会从 template_map 中读取预定义的坐标,包括 N, CA, C, O 四个主链原子。
  • 如果某个位置的原子缺失或不完整(例如部分侧链原子未定义),则会用 CA 原子的坐标来填充剩余的坐标,以保证所有残基的模板具有统一的形状 [n_channel, 3](其中 n_channel 为原子数,通常是 14 个通道,未使用的填零)。

因此,模板的生成会尽可能包括完整的主链坐标(N, CA, C, O),而不仅限于 CA 原子。

在上述代码中,模板的构建没有区分需要预测的残基和不需要预测的残基。模板是基于每个抗体链中的保守残基(conserved residues)来生成的,这些保守残基是通过统计得到的。在这个过程中,模板统一计算每个残基的坐标,无论该残基是否需要在模型中进行预测。

具体原因如下:

  1. 模板生成基于保守残基而非预测任务

    • main() 方法中,模板构建过程中首先根据保守阈值(conserve_th)确定了抗体链中每个残基是否为保守残基。这些被标记为保守的残基会被统一纳入模板计算和坐标对齐。
    • 被选择的保守残基并不考虑它们是否需要在预测任务中进行预测,因此不需要进行预测的残基也可能会包含在模板中。
  2. 统一模板填充与对齐

    • 模板填充和对齐的步骤(如 _chain_template 方法)是对保守残基进行统一处理。整个链的坐标信息被填充到固定的形状 [n_residues, n_channel, 3]
    • 在所有保守残基中,缺少的原子(例如非保守或插入的残基位置)会被全零填充,未定义的原子位置则通过 CA 坐标填充。
  3. 预测任务中对模板的使用

    • 由于模板中包含了所有保守残基的坐标信息,模型可以根据需要选择性地使用这些模板坐标。
    • 但是,模板本身并未主动区分哪些残基需要预测。通常,模型会基于上下文条件选择需要进行预测的残基,而不需要预测的残基可能在预测阶段会被忽略。

因此,在模板生成和填充过程中,代码不会区分残基是否需要预测,而是统一计算所有保守残基的位置。这确保了模板的完整性,而模型在预测过程中则可以有选择地利用模板中的残基信息。

坐标的处理

是的,中心坐标在一开始是有参与归一化的。在执行 centering 操作后,得到的“中心化”坐标会在后续的 normalize 步骤中进行归一化处理。具体流程如下:

  1. 中心化 (centering)

    • centering 操作计算每条链(例如抗原、抗体重链、轻链)的中心坐标,并将链中所有原子的坐标减去对应链的质心坐标,从而完成“中心化”。
  2. 归一化 (normalize)

    • 进行归一化时,所有坐标,包括已经被中心化的链质心,也都将通过标准差和均值来进行进一步的缩放处理,达到零均值、单位方差的分布。

这使得整个模型中的坐标(包括中心坐标)能够在一个统一的尺度上,为模型后续的计算提供标准化的输入。

在这段代码中,确实有两种不同的 uncentering 操作,分别针对整体坐标 pred_X接口区域 r_interface_X进行。它们的作用和计算方式如下:

  1. pred_Xuncentering

    • pred_X 是在消息传递和预测过程中生成的整体坐标,包括所有节点的坐标。
    • uncentering(pred_X, batch_id) 会将之前 centering 过程中减去的质心加回来,以恢复每个节点在真实空间中的位置。
    • 该操作是针对整个 pred_X 执行的,所以会包括所有的抗原和抗体链坐标,确保在损失计算前,所有坐标都回到真实坐标空间中。
  2. r_interface_Xuncentering

    • r_interface_X 只包含接口部分的坐标更新,如 E(抗原区域)和 H3(抗体重链 CDR 区域)部分。
    • uncentering(interface_X, interface_batch_id, _type=4) 是专门针对接口区域的坐标 uncentering 操作。这里 _type=4 指定了去中心化的方式,表示恢复接口区域坐标时,统一使用抗原链的质心作为中心,从而保持接口的参考位置。
    • 这使得接口区域 r_interface_X 的坐标能准确地与抗原部分对齐,用于最终的接口损失计算。

因此,整体上:

  • uncentering(pred_X, batch_id) 是针对整个预测坐标的去中心化,恢复所有节点的真实空间位置。
  • uncentering(interface_X, interface_batch_id, _type=4) 则专注于接口区域,确保接口部分的位置与抗原质心对齐。

根据您的代码,从 centeringupdate_globel_coordinates 函数的逻辑来看,质心的计算方式如下:

代码检查结论:

  1. centering 函数

    centering 函数的设计是以整条链为单位计算质心,分为抗原链和抗体链,不会针对每个 CDR(如 H1, H2, H3)片段单独计算质心。具体操作如下:

    • centering 会区分抗原 (E) 和抗体(重链和轻链)两个链组,分别计算它们的质心坐标。
    • 每个链组的质心是其所有有效原子的均值坐标,并不是对单个 CDR 区段计算质心。
  2. update_globel_coordinates 函数

    update_globel_coordinates 函数也以链为单位计算全局节点坐标。该函数具体执行了以下步骤:

    • 通过识别 S 中的全局节点(如抗体的中心节点 BOH 和抗原的中心节点 BOA),并为它们分配其所在链的质心坐标。
    • 这一步中,质心同样是对链整体而不是特定 CDR 片段的原子坐标均值。

代码结论

您的代码中,质心坐标计算是针对整个抗原链(E)和抗体链(包含 HL)的所有有效原子进行,而非每个 CDR 片段单独计算。

在代码实现中,确实是通过 均值计算 得到链的中心坐标(质心)。在 centeringupdate_globel_coordinates 两个方法中,均通过对坐标求均值的方式来获取链的质心。以下是具体方法的详细作用和顺序:


centering(X, S, batch_id, aa_feature)

  • 功能:对输入坐标 X 进行中心化。每条链(抗原、抗体重链 H3、抗体轻链 L3)分别进行处理。
  • 步骤
    1. 利用 segment_ids 将抗原和抗体链分开。
    2. 计算每个抗原和抗体链的中心坐标(质心):通过对链的所有节点坐标进行均值计算,得到每条链的质心。
    3. 对每条链的坐标减去其质心,使其中心对齐到原点附近。

normalize(X)

  • 功能:对坐标进行归一化,调整分布到标准正态分布的范围内。
  • 步骤
    1. 将坐标 X 减去数据集的预定义均值 mean,再除以标准差 std
    2. 归一化后的 X 均值接近 0,标准差为 1,有助于模型更快收敛并提升数值稳定性。

update_globel_coordinates(X, S)

  • 功能:根据链的节点坐标重新计算并更新全局节点的坐标,使其反映最新的链质心。
  • 步骤
    1. 识别全局节点(例如抗原中心节点、抗体链中心节点等)。
    2. 通过链节点坐标的均值计算质心,赋给全局节点,使这些节点始终表示链的整体位置。
    3. 更新的全局节点坐标用于下一轮消息传递,为链的整体位置信息提供参考。

unnormalize(X)

  • 功能:将归一化后的坐标 X 还原到原始尺度。
  • 步骤
    1. 乘以标准差 std 后再加上均值 mean
    2. 通过逆归一化,X 的尺度回到原始数据的坐标范围,用于模型的输出预测和评估。

uncentering(X, batch_id, _type)

  • 功能:恢复经过 centering 操作后坐标的原始中心位置。
  • 步骤
    1. 根据 _type 参数选择去中心化方式:
      • 对抗原链和抗体链分别进行去中心化处理,即将先前减去的质心重新加回,以便恢复真实空间坐标。
      • 质心在 centering 中是通过 链的节点均值计算 得到的,因此在 uncentering 时加回该均值。
    2. 去中心化使得链的坐标返回到原始的实际空间位置,用于后续的损失计算和评估。

调用顺序总结

  • 前处理:通过 centering 获取质心后,将链坐标中心化,接着使用 normalize 归一化整个坐标集。
  • 消息传递中:在多轮迭代中,每轮会调用 update_globel_coordinates 动态更新全局节点坐标,保证消息传递中的链整体位置信息是最新的。
  • 后处理:消息传递后的预测坐标 pred_X 通过 unnormalizeuncentering 还原至原始空间位置和尺度,用于损失计算和评估。

在所有的中心化、去中心化以及全局节点更新过程中,均通过 均值计算 得到链的质心坐标。

update_globel_coordinates(X, S) 中,全局节点坐标的更新目的是为链(例如抗原、抗体的重链和轻链)的整体位置提供一个代表性的中心点。通过将全局节点坐标设为各链的质心,模型在消息传递过程中可以使用这个节点来表示整个链的位置和几何特征。这里的详细计算步骤如下:


update_globel_coordinates(X, S) 详细计算步骤

  1. 识别全局节点

    • S 中有特殊的标识,用于区分抗原链(E)、抗体的重链(H3)和轻链(L3)的 全局节点。这些全局节点分别表示抗原、重链和轻链的中心。
    • 例如,VOCAB.BOA 可能表示抗原的全局节点,VOCAB.BOH 表示抗体重链的全局节点,VOCAB.BOL 表示抗体轻链的全局节点。
  2. 计算质心

    • 对于每条链中的普通节点(非全局节点),取其坐标 X,计算所有节点的 坐标均值,以此作为该链的质心坐标。例如:
      • 对于抗原链中的所有普通节点,计算它们坐标的均值得到抗原的质心。
      • 对于抗体的重链和轻链,分别计算它们内部普通节点的坐标均值,得到各自的质心。
    • 这些质心反映了每条链的中心位置,表示链的整体几何中心。
  3. 更新全局节点的坐标

    • 将计算得到的质心坐标赋值给对应的全局节点。这使得这些全局节点的坐标总是跟随链的节点更新,动态表示当前链的中心位置。
  4. 作用

    • 全局节点的质心坐标用于下一轮消息传递,提供链的整体位置信息。
    • 通过更新这些全局节点的坐标,模型可以在消息传递过程中让每条链有一个代表其整体的“中心节点”。这个全局节点不仅包含链的中心位置,还能通过消息传递影响其他节点,增强链的整体一致性。

作用总结

update_globel_coordinates 的主要作用是确保每条链的全局节点始终反映链的中心位置。这个质心节点可以在消息传递过程中传递该链的整体几何信息,并在后续计算中作为链的代表点进行计算。

是的,正是这样!在 normalize 之后,update_globel_coordinates 会进一步更新全局节点的中心坐标。

以下是这两个步骤的主要流程和作用:

  1. normalize

    • 这一步骤将坐标进行归一化,使其均值接近零、标准差接近一,从而使整个数据在数值上更稳定,利于计算和模型训练。
    • normalize 操作是对每个坐标点独立进行的,与是否是全局节点无关。
  2. update_globel_coordinates

    • normalize 之后,update_globel_coordinates 基于归一化后的坐标,为每条链(抗原、重链、轻链)重新计算其质心,并将这些质心赋值给对应的全局节点。
    • 作用:确保在每一轮消息传递中,全局节点都能表示链的最新中心位置,使消息传递更具代表性,增强模型对每条链整体结构的理解。

这样设计的原因在于,normalize 调整了整个坐标空间的分布,但为了让模型始终能获得链的几何中心信息,update_globel_coordinates 必须在 normalize 之后重新计算质心并更新全局节点。这一步保证了链的全局节点在每一轮消息传递中都能提供链的整体中心信息。

interface_X = self.init_interface(X, S, paratope_mask, batch_id, init_noise) 这一步初始化接口(interface)坐标,是在 _forward 函数中的一部分,通常在中心化和归一化步骤后执行。它的主要作用是根据初始输入数据对接口节点的位置进行初始化。以下是该步骤的具体功能:

init_interface(X, S, paratope_mask, batch_id, init_noise) 的功能

  • 功能:在消息传递之前,生成抗体-抗原接口区域(即 paratope 和 epitope 的交互区域)的初始坐标 interface_X,为接下来的迭代提供起点。
  • 步骤
    1. 确定质心位置:首先根据抗原中心的坐标生成接口区域的位置,使得接口区域起始位置在抗原链的中心附近。
    2. 生成初始扰动:通过生成高斯噪声 init_noise,为接口区域的每个节点位置添加随机扰动,模拟实际空间位置的分布不确定性。
    3. 更新 paratope 的坐标:将生成的初始接口区域坐标 interface_X 赋值给 paratope 区域,确保在模型的初始推理阶段,paratope 区域的位置合理并带有一定随机性。

整体流程

  1. 位置参考:首先将接口的初始位置参考抗原链中心坐标,使 paratope 初始分布靠近抗原中心。
  2. 扰动生成:添加高斯扰动,使接口区域位置更加自然,不是完全均匀的坐标。
  3. 赋值和初始化:将生成的接口位置用于接下来的消息传递,以此为基础更新接口节点的最终预测坐标。

在整体流程中的作用

  • 初始化接口区域位置init_interface 提供了 paratope 区域合理的初始位置,帮助模型逐步优化接口区域的坐标分布。
  • 引入合理的随机性:添加的扰动确保每次初始化不会出现过于规律的接口分布,有助于提升模型的泛化能力。

在代码中,假设 paratope 包含 L3H3,而 epitope 区域为 E,那么 init_interface 函数的初始化操作执行了以下计算:

具体计算步骤

  1. 确定 epitope 中心坐标

    • 代码中首先找到 S 中属于 epitope 区域 E 的中心原子 CA 坐标,并计算 E 的平均位置坐标(质心)。这个坐标表示 epitope 的中心点。
  2. 初始化 paratope(L3 和 H3)的坐标

    • 代码将 interface_X 的初始位置设定为 epitope 中心,即 E 的质心坐标。这样做的目的是让 L3H3 的初始坐标点靠近 epitope 中心,表示一个合理的起始位置,模拟抗体和抗原之间的空间接触。
  3. 添加随机扰动

    • 为了模拟实际的空间位置分布,代码为 paratope 中的节点(L3H3)添加小幅的随机扰动。具体而言:
      • 为每个节点生成一个小的随机高斯噪声 init_noise
      • L3H3CA 原子坐标上应用较大幅度的噪声,确保 paratope 的整体结构保持完整。
      • 其他原子坐标上应用较小幅度的噪声,确保 paratope 的局部结构不失真。

初始化过程的目的

此初始化步骤完成了 paratope 的坐标设置,使其分布于 epitope 区域的中心附近。通过这样合理的初始化,后续的迭代和消息传递在优化过程中可以更好地预测抗体-抗原接口区域的最终结构。这种初始化方式还能帮助模型在迭代优化中更高效地收敛至合理的结构。

在前面的 centering 操作中,计算的是整个抗原或抗体链中所有原子坐标的均值,而不是针对残基中单独位置的原子。具体来说,centering 的实现步骤如下:

  1. 选取抗原(E)和抗体链(H3 和 L3)中的所有原子

    • 通过遍历每个链的所有原子,提取出整个抗原或抗体链中的所有原子坐标。
  2. 计算整条链的质心

    • 针对每个链(E、H3、L3),对所有原子的坐标计算均值。此均值坐标即为链的中心(质心)。
  3. 减去中心点坐标

    • 将每个原子的坐标减去链的质心坐标,完成“中心化”。
    • 这使得所有坐标以链的质心为参考点,便于标准化和后续操作。

因此,centering 是在链级别上计算中心坐标(质心),并不是针对残基或具体位置的原子。

根据代码的设计,init_interface 函数中的初始化仅针对 paratope 区域进行,也就是在您的设置中,仅对 L3H3 进行初始化,而没有包括所有的 CDR 区域。

分析 init_interface 代码逻辑:

  1. 选择特定区域init_interface 函数通过 paratope_mask 参数,只选择 L3H3 中的坐标进行操作,不会涉及其他 CDR 区域(如 H1H2L1L2 等)。

  2. 定位 epitope 中心:代码计算 epitope 区域 E 的中心点作为质心,并在初始化时,将 paratope 区域(即 L3H3)的坐标分布在该中心附近。

  3. 添加随机扰动:该扰动也只针对 paratope 区域的坐标,使 L3H3 的初始位置随机分布在 epitope 中心的附近。

结论

init_interface 中,仅初始化 paratope 区域(L3H3),而其他 CDR 区域则不会被此函数操作到。因此,此函数的作用是对预测接口区域的 paratope 提供一个合理的初始坐标分布,而非对所有的 CDR 区域进行初始化。

关于坐标的更新

是的,根据代码的逻辑,可以总结如下:

  1. Global节点(全局残基)

    • 大多数时候,global 节点的坐标会仅保留CA原子的坐标。这是因为global节点的质心计算只需CA原子,不需要完整的14个坐标。
    • 在EGCL模块的计算过程中(如在 update_globel_coordinates 调用时),可能会更新其他位置的坐标,以反映最新的质心或分布情况。
  2. E节点(抗原残基)

    • 抗原节点在大多数情况下会使用真实坐标。这是因为抗原的坐标通常在初始化时基于真实的结构数据。
    • forward 计算时,抗原节点可能会受到一些更新影响,但其坐标变化不会频繁发生,大部分情况下仍然保持原始的真实坐标。
  3. 抗体残基(paratope 和其他CDR区域)

    • 抗体残基通常会有完整的14个坐标(包括主链和侧链原子)。初始化时会从模板得到完整的14个原子坐标,并在消息传递过程中更新。
    • 其中 paratope 区域会通过噪声初始化靠近 epitope 区域,后续迭代更新中则进一步优化其坐标,以匹配抗原接口的空间布局。

总结而言,global 节点一般只需CA坐标,其它坐标只在特定运算中更新。抗原(E)多保持真实坐标,只有在 forward 计算时发生少量变化,而抗体区域(如 paratope 和 CDR)则始终包含完整的14个原子坐标,并在更新过程中进一步优化。

既然有两种坐标,评估的时候,使用的是哪种坐标

感谢您提供截图。我会重新检查代码,特别关注 RMSD(H3) 的计算过程,确认在评估时到底是使用 true_X 的 H3 部分,还是 interface_X 的 H3 坐标。

让我仔细检查后再为您更新解释。

我已复查代码,并从 cal_metrics 函数中的逻辑推断 RMSD(H3) 的具体使用。

评估代码中的 RMSD(H3) 坐标选择

cal_metrics 中:

  • RMSD(CA) 的计算是针对 pred_X(即整个抗体结构的坐标)与 true_X 比较得到的,通常用于对齐和未对齐的 RMSD。
  • CDR 区域 RMSD(包括 RMSD(H3))的计算涉及提取 pred_X 中的 CDR 区域(如 H3),并与 true_X 中相应区域的坐标进行比对。

结论

在代码的 RMSD(H3) 计算部分:

  • 使用的是 pred_X 中的 H3 部分与 true_X 中的 H3 真实坐标进行比较。
  • 并没有使用 interface_X 来替代 pred_X,即评估时是基于预测出的完整抗体结构(pred_X)的部分坐标,而非界面局部坐标。

因此,最终确认 RMSD(H3) 计算确实是基于 pred_X 的 H3 部分坐标,而不是 interface_X。希望这能清晰回答您的问题!

关于每部分loss是针对哪个区间

感谢您的澄清。如果 cmask 是针对整条抗体链,而 smask 是专门用于 CDR 区域,那么在计算 structure_loss 时的预测是针对 整条抗体链 的坐标,包括 CDR 和非 CDR 区域。具体来说:

  • structure_loss 中使用的是 cmask,这意味着模型在训练时会预测并计算 整条抗体链 的坐标损失。
  • smask 仅限于 CDR 部分,所以如果 CDR 区域的损失单独计算,则会使用 smask 掩码,但在 structure_loss 中并没有用到 smask,因此整个链条都会参与损失计算。

结论

在当前代码配置中,structure_loss 会计算整个抗体链的坐标损失,而不仅仅是 CDR 区域。

是的,残基种类(序列)预测的 loss 通常是针对 CDR 区域的。这是因为:

  • CDR 区域包含抗体的高变区,是特异性识别抗原的关键部分,因此对 CDR 序列的预测尤为重要。
  • 在代码中,通常会使用 smask 掩码来限制序列预测的 loss 计算,只对 CDR 区域的残基种类进行监督。smask 的作用是只覆盖 CDR 区域,从而屏蔽非 CDR 区域的残基,避免对这些区域进行不必要的序列预测。

总结

残基种类的 loss 确实主要针对 CDR 区域,而不是整条抗体链。这与 structure_loss 不同,后者则对整个链条的坐标进行监督。

posted @   GraphL  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示