姿态估计1-10:FSA-Net(头部姿态估算)-源码无死角讲解(5)-Feature aggregation

以下链接是个人关于FSA-Net(头部姿态估算) 所有见解,如有错误欢迎大家指出,我会第一时间纠正。有兴趣的朋友可以加微信:a944284742相互讨论技术。若是帮助到了你什么,一定要记得点赞!因为这是对我最大的鼓励。
姿态估计1-00:FSA-Net(头部姿态估算)-目录-史上最新无死角讲解

前言

通过前面的博客,网络构建的组件中,我们只剩下Feature aggregation没有讲解了,也就是对应论文的如下部分:
在这里插入图片描述
首先我们回到training_and_testing/run_fsanet_train.sh文件,可以看到如下代码:

# FSANET_Capsule
KERAS_BACKEND=tensorflow python FSANET_train.py --batch_size 16 --nb_epochs 90 --model_type 2 --db_name '300W_LP'
KERAS_BACKEND=tensorflow python FSANET_train.py --batch_size 16 --nb_epochs 90 --model_type 3 --db_name '300W_LP'
KERAS_BACKEND=tensorflow python FSANET_train.py --batch_size 16 --nb_epochs 90 --model_type 4 --db_name '300W_LP'


# FSANET_Netvlad
KERAS_BACKEND=tensorflow python FSANET_train.py --batch_size 16 --nb_epochs 90 --model_type 5 --db_name '300W_LP'
KERAS_BACKEND=tensorflow python FSANET_train.py --batch_size 16 --nb_epochs 90 --model_type 6 --db_name '300W_LP'
KERAS_BACKEND=tensorflow python FSANET_train.py --batch_size 16 --nb_epochs 90 --model_type 7 --db_name '300W_LP'

可以知道,以上的六种类型都是使用了Feature aggregation,但是这分成Capsule和Netvlad两种方式,我们在通过
training_and_testing/FSANET_train.py对:

FSA_net_Capsule()
FSA_net_Var_Capsule()
FSA_net_noS_Capsule()
FSA_net_NetVLAD()
FSA_net_Var_NetVLAD()
FSA_net_noS_NetVLAD()

可以发现这些中类中的父类BaseCapsuleFSANet以及BaseNetVLADFSANet都实现ssr_aggregation_model_build函数,在讲解其之前,我先把class BaseFSANet(object)的如下部分粘贴一下:

        # 构建特征压缩模型,或者说胶囊网络,论文中的Feature aggregation操作
        # 可以看到,这个函数是没有实现的,也就是由子类去实现,为什么呢?
        # 前面的ssr_S_model模型,根据配置不一样,输出结果有两种可能,分别为[b,192,64]与[b,21,64]
        # 继承该类的子类在构建网络的的时候,会根据is_noS_model参数实现合适的该函数
        # 输出为3个[b,16]的特征向量
        ssr_aggregation_model = self.ssr_aggregation_model_build((self.num_primcaps,64))

下面我们就来看看def ssr_aggregation_model_build(self, shape_primcaps):的实现。

AggregatedFeatureExtractionLayer注释

在源码中搜索ssr_aggregation_model_build,我们可以发现其实现的过程各不相同,但是他们都调用了AggregatedFeatureExtractionLayer方法。为了方便大家查看,我把3中ssr_aggregation_model_build的实现都复制一下:

# Capsule FSANetworks,压缩网络
class BaseCapsuleFSANet(BaseFSANet):
    def __init__(self, image_size,num_classes,stage_num,lambda_d, S_set):
        super(BaseCapsuleFSANet, self).__init__(image_size,num_classes,stage_num,lambda_d, S_set)         

    def ssr_aggregation_model_build(self, shape_primcaps):
        input_primcaps = Input(shape_primcaps)        
        capsule = CapsuleLayer(self.num_capsule, self.dim_capsule, routings=self.routings, name='caps')(input_primcaps)        

        feat_s1_div, feat_s2_div, feat_s3_div = AggregatedFeatureExtractionLayer(num_capsule=self.num_capsule)(capsule)

        feat_s1_div = Reshape((-1,))(feat_s1_div)
        feat_s2_div = Reshape((-1,))(feat_s2_div)
        feat_s3_div = Reshape((-1,))(feat_s3_div)        
        
        return Model(inputs=input_primcaps,outputs=[feat_s1_div,feat_s2_div,feat_s3_div], name='ssr_Cap_model')


class BaseNetVLADFSANet(BaseFSANet):
    def __init__(self, image_size,num_classes,stage_num,lambda_d, S_set):
        super(BaseNetVLADFSANet, self).__init__(image_size,num_classes,stage_num,lambda_d, S_set)         

    def ssr_aggregation_model_build(self, shape_primcaps):
        input_primcaps = Input(shape_primcaps)
        
        agg_feat = NetVLAD(feature_size=64, max_samples=self.num_primcaps, cluster_size=self.num_capsule, output_dim=self.num_capsule*self.dim_capsule)(input_primcaps)
        agg_feat = Reshape((self.num_capsule,self.dim_capsule))(agg_feat)

        feat_s1_div, feat_s2_div, feat_s3_div = AggregatedFeatureExtractionLayer(num_capsule=self.num_capsule)(agg_feat)        

        feat_s1_div = Reshape((-1,))(feat_s1_div)
        feat_s2_div = Reshape((-1,))(feat_s2_div)
        feat_s3_div = Reshape((-1,))(feat_s3_div)
        
        return Model(inputs=input_primcaps,outputs=[feat_s1_div,feat_s2_div,feat_s3_div], name='ssr_Agg_model')



class BaseMetricFSANet(BaseFSANet):
    def __init__(self, image_size,num_classes,stage_num,lambda_d, S_set):
        super(BaseMetricFSANet, self).__init__(image_size,num_classes,stage_num,lambda_d, S_set) 
        
    def ssr_aggregation_model_build(self, shape_primcaps):
        input_primcaps = Input(shape_primcaps)

        metric_feat = MatMulLayer(16,type=1)(input_primcaps)
        metric_feat = MatMulLayer(3,type=2)(metric_feat)

        feat_s1_div, feat_s2_div, feat_s3_div = AggregatedFeatureExtractionLayer(num_capsule=self.num_capsule)(metric_feat)        

        feat_s1_div = Reshape((-1,))(feat_s1_div)
        feat_s2_div = Reshape((-1,))(feat_s2_div)
        feat_s3_div = Reshape((-1,))(feat_s3_div)
        
        return Model(inputs=input_primcaps,outputs=[feat_s1_div,feat_s2_div,feat_s3_div], name='ssr_Metric_model')    

可以看到,其都调用了AggregatedFeatureExtractionLayer类扯coll方法,该类很好理解,输入一个[b,3,16]的特征,然后分割成3个[b,16]的特征。既然如此,那么看来重点,还是在调用AggregatedFeatureExtractionLayer方法之前的处理,那么我们就来分析一下吧。

BaseCapsuleFSANet

首先我们来看看BaseCapsuleFSANet,其实现过程如下如下:
在这里插入图片描述
输入有两种可能,[b,192,64]与[b,21,64],前者为不使用Scoring function获得的特征向量,那么后者当然就是使用Scoring function获得的特征向量。但是经过ssr_aggregation_model_build函数之后,其都是输出3个[b,16]的特征向量。那么通过结构,可以看到,其重点就是在于CapsuleLayer的实现了,但是CapsuleLayer在源码中已经有了很详细的介绍,我这里就不班门弄斧了。

BaseNetVLADFSANet

和BaseCapsuleFSANet长得真的好像,几乎是双胞胎了,其中不同点仅仅在于其调用了:

agg_feat = NetVLAD(feature_size=64, max_samples=self.num_primcaps, cluster_size=self.num_capsule, output_dim=self.num_capsule*self.dim_capsule)(input_primcaps)

其输入输出形状CapsuleLayer是一样的,不行看下图BaseNetVLADFSANet结构:
在这里插入图片描述
该图存在于pre-trained\300W_LP_models\fsanet_netvlad_3_16_2_21_5/ssr_Agg_model.png。那么不用多说,其核心就在于NetVLAD的实现了。其中也有比较详细的注释,我也不再啰嗦了,

结语

到这里为止,我们的训练代码,都讲解完成了,谢谢大家,下面会讲解测试代码,以及几个实用的demol使用。

发布了219 篇原创文章 · 获赞 687 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/103716627