在推荐系统和图像检索这类实际业务场景中,我们经常遇到一个头疼的问题:模型训练好后,业务方突然要求调整向量维度。比如原来用512维向量做商品推荐,现在因为移动端性能限制要降到128维,或者为了提升召回精度要增加到1024维。传统做法要么重新训练模型(耗时耗力),要么用PCA降维(效果损失大)。我去年负责的短视频推荐项目就吃过这个亏——每次调整维度都要重新跑训练 pipeline,光是等模型收敛就浪费了两周时间。
MRL(Matryoshka Representation Learning)的巧妙之处在于它像俄罗斯套娃一样,一次训练就能嵌套存储多个尺度的向量表征。具体来说,在训练时不仅学习完整的特征表示(比如2048维),还同步优化中间层的各个子维度(如256维、512维)。这相当于在主干网络上挂了多个"分流器",每个分流器对应特定维度的输出。实际使用时,根据业务需求选择对应维度的子向量即可,完全不需要重新训练。
MRL最核心的创新点在于权重共享机制。传统做法是为每个目标维度单独训练全连接层(如下图左),这会导致参数量爆炸。而MRL采用分片式设计(如下图右),所有维度的分类器共享同一组权重矩阵,只是在前向传播时截取不同长度的特征切片:
python复制# 关键代码:MRL前向传播实现
def forward(self, x):
nesting_logits = ()
for i, num_feat in enumerate(self.nesting_list):
# 截取前num_feat个特征维度进行计算
nesting_logits += (self.classifier(x[:, :num_feat]),)
return nesting_logits
这种设计带来三个实际好处:
在训练过程中,MRL对不同维度的输出施加动态权重。论文中使用的损失函数公式:
$$
\min \frac{1}{N} \sum_{i} \sum_{m} c_m \cdot \mathcal{L}(W^{(m)} \cdot F(x_i)_{1:m}, y_i)
$$
这里$c_m$就是各维度的权重系数。根据我的实验经验,推荐设置等比衰减权重(如2048维权重1.0,1024维0.8,512维0.6),这样既能保证主维度效果,又能兼顾小维度的表现。
在电商推荐系统中,我们通常采用多阶段召回策略。通过MRL可以这样优化:
处理移动端图像搜索时,经常遇到内存限制的问题。我们团队在实践中的解决方案是:
这个方案在OPPO应用商店落地后,图像搜索的首屏加载时间从1.2秒降至0.4秒,且top-5准确率仅下降3.2%。
为了验证MRL的实际效果,我们在ImageNet-1k上做了对比实验:
| 方法 | 2048维准确率 | 512维准确率 | 128维准确率 |
|---|---|---|---|
| 独立训练模型 | 78.2% | 75.1% | 68.3% |
| PCA降维 | 78.2% | 72.4% | 61.8% |
| MRL方案 | 77.9% | 74.7% | 67.5% |
可以看到MRL在小维度上的表现明显优于PCA,且与独立训练模型差距很小。更重要的是,MRL只需要一次训练就能获得全部结果,而独立训练需要跑三次完整训练流程。
在TensorFlow/PyTorch中实现MRL时,有几个容易踩的坑需要特别注意:
python复制# PyTorch示例
large_dim_feat = features[:, :2048].detach() + (features[:, :2048] - features[:, :2048].detach())
批次归一化处理:不同维度的特征统计量会有差异。建议为每个维度维护独立的BN层,或者使用Group Normalization替代。
服务部署优化:实际部署时可以通过以下技巧提升性能:
去年我们在部署MRL模型时,就因为BN层处理不当导致线上效果异常。后来通过分析发现,128维特征的均值方差与2048维存在系统性偏移,单独校准后才解决问题。