1. 参考资料:
paper:C3AE: Exploring the Limits of Compact Model for Age Estimation
code:https://github.com/StevenBanama/C3AE
2. 模型结构
- 原始图像裁剪为3个尺寸作为网络的输入,合并3个经过CNN提取后的特征向量,然后经过第一个全连接层(对应图中的 W 1 W_1 W1)得到区间概率分布,紧接着经过第二个全连接层(对应图中的 W 2 W2 W2)输出最终的年龄。
- 网络的约束为预测年龄与真实年龄的L1距离以及预测分布与真实分布的KL散度,具体如下:
KL损失中加入了一个关于 W 1 W_1 W1的L1正则项,主要是为了控制分布的稀疏性(由于年龄分布的gt是两点分布,即某两个区间端点的概率较高,其它端点的概率接近0,因此理想状态下预测的年龄分布也同gt一样稀疏)
3. 创新点
3.1 通过两点分布表示年龄
在C3AE模型提出之前,有不少年龄估计模型采用正态分布作为额外的约束信息,看到C3AE提出的使用两点分布来表示年龄,顿时眼前一亮,不禁感叹一句:妙啊~
论文中的图对两点分布解释得很清晰,也很容易理解:
论文中给出了计算两点分布的步骤:
① 任意年龄 y n y_n yn可以表示为:
y n = λ 1 ⋅ z n 1 + λ 2 ⋅ z n 2 y_n=\lambda_1\cdot z_n^1+\lambda_2 \cdot z_n^2 yn=λ1⋅zn1+λ2⋅zn2② 根据 y n y_n yn和区间大小计算端点值 z n 1 z_n^1 zn1和 z n 2 z_n^2 zn2: z n 1 = f l o o r ( y n K ) ⋅ K z_n^1=floor(\frac{y_n}{K})\cdot K zn1=floor(Kyn)⋅K z n 2 = c e i l ( y n K ) ⋅ K z_n^2=ceil(\frac{y_n}{K})\cdot K zn2=ceil(Kyn)⋅K③ 计算两点对应的概率 λ 1 \lambda_1 λ1和 λ 2 \lambda_2 λ2: λ 1 = 1 − y n − z n 1 K \lambda_1=1 - \frac{y_n-z_n^1}{K} λ1=1−Kyn−zn1 λ 2 = 1 − z n 2 − y n K \lambda_2=1 - \frac{z_n^2-y_n}{K} λ2=1−Kzn2−yn
对应的代码如下(代码来源于参考资料中的code):
def label_to_vector(label, num_points=11, interval=10):
""" label = lambda1 * z1 + lambda2 * z2"""
# calculate which two points the label is located between
z1 = np.floor(label / interval) * interval
z2 = np.ceil(label / interval) * interval
# calculate the probability of two points
lambda1 = 1 - (label - z1) / interval
lambda2 = 1 - (z2 - label) / interval
vector = [0] * num_points
vector[int(z1 // interval)] = lambda1
vector[int(z2 // interval)] = lambda2
return vector
3.2 轻量级网络
作者抛弃了如MobileNet之类的成熟的轻量级网络结构,而是重新设计了一个适用于小尺寸输入的普通的小型CNN网络,一共只有5个卷积层,但是取得了优于MobileNet和ShuffleNet的结果。
那么作者为啥不用现成的轻量级网络,非得自己设计一个呢?作者在文中是这样解释的:对于小尺寸图像,深度可分离卷积需要更多的卷积核数量才能取得与标准卷积相当的表征能力,因此使用标准卷积能够节省更多的计算开销。
4. 启发
对于连续值回归任务,除了L1距离外,还可以采用两点分布的形式增加约束,通过“分类+回归”级联的方式构建模型,应该能取得更加稳定的回归结果。