计算机系统应用教程网站

网站首页 > 技术文章 正文

如何在深度学习模型内部做特征选择?

btikc 2024-10-12 11:01:23 技术文章 14 ℃ 0 评论


背景

在实际生产环境中,由于个性化业务的特殊性,我们要求模型既要为用户推荐出心意的物品,又要保证我们能够实时响应用户的请求,即对于用户的请求我们要立即响应,如果延时太长的话只能补一些通用商品或非个性化排序的结果。对此,如何让我们的模型能够兼顾上述的两种需求呢?本文将讲述一种在模型内部做特征选择的方法,用以在一定程度上缓解上述问题。

怎么做?

在个性化推荐业务中,通常我们的特征工程是非常庞大的一块数据开发业务。这就会导致我们的特征维度会急剧升高,显然特征维度的升高会带来我们模型处理这些特征的耗时,也就是延长了我们的打分时间。一种做法是我们将对特征进行一定程度的"阉割",即我们人为地对特征进行分析,将与业务目标关联度不大的特征进行删减,以加快我们的模型打分速度。

但是这种粗暴的处理方式,会削弱我们模型的效果,因为我们认为,凡是已经做了的特征在某种程度上都会对最终的业务目标产生影响的,并且人为分析的结果在一定程度上式有"偏差"的,因此这种方式我们一般是不建议使用的。

另外一种方式就是在模型内部做特征取舍,这样我们可以让模型自动选择重要的特征进行学习(这里有点类似于"attention"机制,但却有所不同,"attention"机制是将特征按照重要性学习其权重大小,但是我们这里的特征选择是为了减小我们模型的大小,使其能够满足线上打分需求)。

那么,我们该如何做呢?

其实很简单,我们只需要以下三步就可以搞得定:

1、 为特征矩阵加上权重矩阵

2、 对权重矩阵进行排序,取topk个权重值的索引

3、 利用索引对特征矩阵进行取值

详细代码示例如下:

# 特征矩阵
features # None * F
features = tf.reshape(features, shape = [-1, F, 1])
# 权重矩阵初始化
wgts = tf.get_variable(name='weights',
shape=[feature_size, 1],
initializer=tf.glorot_normal_initializer()) # F * 1
features = tf.multiply(features, wgts) # None * F * E
# kmaxpooling
# 对attention权重进行topK排序,选取重要性特征
wgts = tf.reshape(wgts, shape=[1, feature_size])
top_k_index = tf.nn.top_k(wgts, k=dimention_reduce_size, sorted=True)[1] # 1 * dimention_reduce_size
top_k_index = tf.reshape(top_k_index, shape=[dimention_reduce_size,])
reduce_features = tf.gather(features, indices=top_k_index, axis=1) # None * dimention_reduce_size * E

以上就是示例代码,大家有时间的时候可以去试下。

推荐场景中的特征维度巨大,假如我们想要使用一些较为复杂的模型,例如xDeepFM,那么在模型中的CIN模块,可能由于特征维度太大,而导致GPU的显存"爆掉"。因此,我们这时就可以借助上述方法来缓解这种显存危机的问题了。


如果你喜欢我的文章,欢迎关注我的微信公众号【软客圈】(ID:recoquan)

纯手工打造,实属不易,欢迎大家分享和转发~

原创内容,转载需注明出处,否则视为侵权并将被追诉!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表