第4章 第3节 深度学习(三)

推荐给朋友

● 神经网络为啥用交叉熵。

参考回答:

通过神经网络解决多分类问题时,最常用的一种方式就是在最后一层设置n个输出节点,无论在浅层神经网络还是在CNN中都是如此,比如,在AlexNet中最后的输出层有1000个节点,而即便是ResNet取消了全连接层,也会在最后有一个1000个节点的输出层。

一般情况下,最后一个输出层的节点个数与分类任务的目标数相等。假设最后的节点数为N,那么对于每一个样例,神经网络可以得到一个N维的数组作为输出结果,数组中每一个维度会对应一个类别。在最理想的情况下,如果一个样本属于k,那么这个类别所对应的的输出节点的输出值应该为1,而其他节点的输出都为0,即[0,0,1,0,….0,0],这个数组也就是样本的Label,是神经网络最期望的输出结果,交叉熵就是用来判定实际的输出与期望的输出的接近程度。

● 注意力公式

参考回答:

Soft attention、global attention、动态attention

Hard attention

静态attention“半软半硬”的attention (local attention)


强制前向attention

● 论文flow情况

参考回答:

谈谈自己投稿的论文,论文投稿级别,论文内容,用到的方法,对比方法等

● Flappy.Bird开发者,怎么利用DNQ方法强化学习你的游戏AI

参考回答:

强化学习是机器学习里面的一个分支。它强调如何基于环境而行动,以取得最大化的预期收益。其灵感来源于心理学中的行为主义理论,既有机体如何在环境给予的奖励或者惩罚的刺激下,逐步形成对刺激的预期,产生能够最大利益的习惯性行为。结构简图如下:

因为强化学习考虑到了自主个体、环境、奖励等因素,所以很多人包括强化学习的研究者Richard Sutton 都认为它是人工智能中最高层的模型,其它深度学习、机器学习模型都是它的子系统。在围棋界先后打败世界冠军的李世乭和柯洁额alphaGo就使用了强化学习模型,也正是这两次比赛,把人工智能这个概念传递给了大众。使用的是卷积神经网络结构。

● LeNet-5结构

参考回答:

输入层:32∗3232∗32的图片,也就是相当于10241024个神经元

C1层:选取66个特征卷积核,大小为5∗55∗5(不包含偏置),得到66个特征图,每个特征图的大小为32−5+1=2832−5+1=28,也就是神经元的个数由10241024减小到了28∗28=78428∗28=784。

输入层与C1层之间的参数:6∗(5∗5+1)6∗(5∗5+1),对于卷积层C1,每个像素都与前一层的5∗55∗5个像素和11个bias有连接,有6∗(5∗5+1)∗(28∗28)6∗(5∗5+1)∗(28∗28)个连接

S2层:池化,是一个下采样层(为什么是下采样?利用图像局部相关性的原理,对图像进行子抽样,可以减少数据处理量同时保留有用信息),有66个14∗1414∗14的特征图,特征图中的每个单元与C1中相对应特征图的2∗22∗2邻域相连接。S2S2层每个单元对应C1C1中44个求和,乘以一个可训练参数,再加上一个可训练偏置。

C1与S2之间的参数:每一个2∗22∗2求和,然后乘以一个参数,加上一个偏置,共计2∗6=122∗6=12个参数。S2S2中的每个像素都与C1C1中的2∗22∗2个像素和11个偏置相连接,所以有6∗5∗14∗14=58806∗5∗14∗14=5880个连接

C3层:选取卷积核大小为5∗55∗5,得到新的图片大小为10∗1010∗10我们知道S2包含:6张14∗146张14∗14大小的图片,我们希望这一层得到的结果是:16张10∗1016张10∗10的图片。这1616张图片的每一张,是通过S2S2的66张图片进行加权组合得到的,具体是怎么组合的呢?

S2与C3之间的组合

前66个feature map与S2S2层相连的33个feature map相连接,后面66个feature map与S2层相连的4个S2层相连的4个feature map相连接,后面33个feature map与S2S2层部分不相连的44个feature map相连接,最后一个与S2S2层的所有feature map相连。卷积核大小依然为5∗55∗5,总共有6∗(3∗5∗5+1)6∗(3∗5∗5+1)+6∗(4∗5∗5+1)6∗(4∗5∗5+1)+3∗(4∗5∗5+1)3∗(4∗5∗5+1)+1∗(6∗5∗5+1)=15161∗(6∗5∗5+1)=1516个参数。而图像大小为10∗1010∗10,所以共有151600151600个连接。

S4层

池化,窗口大小为2∗22∗2,有1616个特征图,总共有3232个参数

C3与S4之间的参数

16∗(25∗4+25)=200016∗(25∗4+25)=2000个连接

C5层

总共120120个feature map,每个feature map与S4S4层所有的feature map相连接,卷积核大小是5∗55∗5,而S4S4层的feature map的大小也是5∗55∗5,所以C5C5的feature map就变成了1个点,共计有120(25∗16+1)=48120120(25∗16+1)=48120个参数。

F6层

全连接

F6F6相当于MLP中的隐含层,有8484个节点,所以有84∗(120+1)=1016484∗(120+1)=10164个参数。F6F6层采用了正切函数。

输出层

采用了RBF函数,即径向欧式距离函数

● 推导LSTM正向传播和单向传播过程

参考回答:

前向推导过程:

反向推导过程:


● LSTM原理,与GRU区别

参考回答:

LSTM算法全称为Long short-term memory,是一种特定形式的RNN(Recurrent neural network,循环神经网络),而RNN是一系列能够处理序列数据的神经网络的总称。

RNN在处理长期依赖(时间序列上距离较远的节点)时会遇到巨大的困难,因为计算距离较远的节点之间的联系时会涉及雅可比矩阵的多次相乘,这会带来梯度消失(经常发生)或者梯度膨胀(较少发生)的问题,这样的现象被许多学者观察到并独立研究。为了解决该问题,研究人员提出LSTM。

LSTM是门限RNN,其单一节点的结构如下图1所示。LSTM的巧妙之处在于通过增加输入门限,遗忘门限和输出门限,使得自循环的权重是变化的,这样一来在模型参数固定的情况下,不同时刻的积分尺度可以动态改变,从而避免了梯度消失或者梯度膨胀的问题。

图1 LSTM的CELL示意图

根据LSTM网络的结构,每个LSTM单元的计算公式如下图2所示,其中Ft表示遗忘门限,It表示输入门限,Ct表示前一时刻cell状态、Ct表示cell状态(这里就是循环发生的地方),Ot表示输出门限,Ht表示当前单元的输出,Ht-1表示前一时刻单元的输出。

图2 LSTM计算公式

与GRU区别:1)GRU和LSTM的性能在很多任务上不分伯仲。2)GRU 参数更少因此更容易收敛,但是数据集很大的情况下,LSTM表达性能更好。3)从结构上来说,GRU只有两个门(update和reset),LSTM有三个门(forget,input,output),GRU直接将hidden state 传给下一个单元,而LSTM则用memory cell 把hidden state 包装起来。

● DNN的梯度更新方式

参考回答:

1)批量梯度下降法BGD

批量梯度下降法(Batch Gradient Descent,简称BGD)是梯度下降法最原始的形式,它的具体思路是在更新每一参数时都使用所有的样本来进行更新,其数学形式如下:

(1) 对上述的能量函数求偏导:

(2) 由于是最小化风险函数,所以按照每个参数的梯度负方向来更新每个:

2)随机梯度下降法SGD

由于批量梯度下降法在更新每一个参数时,都需要所有的训练样本,所以训练过程会随着样本数量的加大而变得异常的缓慢。随机梯度下降法(Stochastic Gradient Descent,简称SGD)正是为了解决批量梯度下降法这一弊端而提出的。

将上面的能量函数写为如下形式:

利用每个样本的损失函数对求偏导得到对应的梯度,来更新:

3)小批量梯度下降法MBGD

有上述的两种梯度下降法可以看出,其各自均有优缺点,那么能不能在两种方法的性能之间取得一个折衷呢?即,算法的训练过程比较快,而且也要保证最终参数训练的准确率,而这正是小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD)的初衷

● CNN为什么比DNN在图像识别上更好

参考回答:

DNN的输入是向量形式,并未考虑到平面的结构信息,在图像和NLP领域这一结构信息尤为重要,例如识别图像中的数字,同一数字与所在位置无关(换句话说任一位置的权重都应相同),CNN的输入可以是tensor,例如二维矩阵,通过filter获得局部特征,较好的保留了平面结构信息。

● 现场用collabedit写代码,一个怪异的归并算法。。。之前没遇到过,直接把归并写出来,但是说复杂度太高,优化了三遍还不行,最后说出用小顶堆解决了。。。

参考回答:

归并算法:
#include <iostream>
using namespace std;

//将有二个有序数列a[first...mid]和a[mid...last]合并。

void __merge(int a[], int first, int mid, int last, int temp[])
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
void __merge_sort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
__merge_sort(a, first, mid, temp);
__merge_sort(a, mid + 1, last, temp);
__merge(a, first, mid, last, temp);
}
}
bool MergeSort(int a[], int n)
{
int *p = new int[n];
if (p == NULL)
{
return false;
}
else
{
__merge_sort(a, 0, n - 1, p);
delete[] p;
return true;
}
}
int main()
{
const int LEN = 10;
int a[LEN] = { 23, 40, 45, 19, 12, 16, 90, 39, 87, 71 };
cout<<"Before the merge sort, the Array is:"<<endl;
for(int i = 0; i < LEN; ++i)
{
cout<<a[i]<<" ";
}
cout<<endl;
cout<<endl;
MergeSort(a, LEN);
cout<<"After the merge sort, the Array is:"<<endl;
for(int i = 0; i < LEN; ++i)
{
cout<<a[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}

小顶堆:

import java.util.Arrays;
public class SmallHeap {
public static int[] topN(int[] arr, int n) {
int[] list = new int[n];
System.arraycopy(arr, 0, list, 0, n);
for (int i = 0; i < n; i++) {
int t = i;
while (t != 0 && list[parent(t)] > list[t]) {
swap(list, t, t = parent(t));
}
}
for (int i = n, len = arr.length; i < len; i++) {
if (arr[i] >= list[0]) {

// 置换栈顶

list[0] = arr[i];

// 调整栈顶

int t = 0;
while((left(t)<n&&list[t]>list[left(t)])||(right(t)<n&& list[t]>list[right(t)])) {
if (right(t) < n && list[right(t)] < list[left(t)]) {
swap(list, t, t = right(t));
} else {
swap(list, t, t = left(t));
}
}
}
}
return list;
}
private static void swap(int[] list, int i, int j) {
int tmp = list[i];
list[i] = list[j];
list[j] = tmp;
}
private static int parent(int i) {
return (i - 1) / 2;
}
private static int left(int i) {
return 2 * i + 1;
}
private static int right(int i) {
return 2 * i + 2;
}
public static void main(String[] args) {
int[] arr = new int[]{56, 30, 71, 18, 29, 93, 44, 75, 20, 65, 68, 34};

System.out.println("原始数组: ");

System.out.println(Arrays.toString(arr));

System.out.println("调整后数组: ");

System.out.println(Arrays.toString(SmallHeap.topN(arr, 5)));

}

}

● LSTM和Naive RNN的区别

参考回答:

RNN和LSTM内部结构的不同:

RNN

LSTM

由上面两幅图可以观察到,LSTM结构更为复杂,在RNN中,将过去的输出和当前的输入concatenate到一起,通过tanh来控制两者的输出,它只考虑最近时刻的状态。在RNN中有两个输入和一个输出。

而LSTM为了能记住长期的状态,在RNN的基础上增加了一路输入和一路输出,增加的这一路就是细胞状态,也就是途中最上面的一条通路。事实上整个LSTM分成了三个部分:

1)哪些细胞状态应该被遗忘

2)哪些新的状态应该被加入

3)根据当前的状态和现在的输入,输出应该是什么

下面来分别讨论:

1)哪些细胞状态应该被遗忘

这部分功能是通过sigmoid函数实现的,也就是最左边的通路。根据输入和上一时刻的输出来决定当前细胞状态是否有需要被遗忘的内容。举个例子,如果之前细胞状态中有主语,而输入中又有了主语,那么原来存在的主语就应该被遗忘。concatenate的输入和上一时刻的输出经过sigmoid函数后,越接近于0被遗忘的越多,越接近于1被遗忘的越少。

2)哪些新的状态应该被加入

继续上面的例子,新进来的主语自然就是应该被加入到细胞状态的内容,同理也是靠sigmoid函数来决定应该记住哪些内容。但是值得一提的是,需要被记住的内容并不是直接concatenate的输入和上一时刻的输出,还要经过tanh,这点应该也是和RNN保持一致。并且需要注意,此处的sigmoid和前一步的sigmoid层的w和b不同,是分别训练的层。细胞状态在忘记了该忘记的,记住了该记住的之后,就可以作为下一时刻的细胞状态输入了。

3)根据当前的状态和现在的输入,输出应该是什么

这是最右侧的通路,也是通过sigmoid函数做门,对第二步求得的状态做tanh后的结果过滤,从而得到最终的预测结果。事实上,LSTM就是在RNN的基础上,增加了对过去状态的过滤,从而可以选择哪些状态对当前更有影响,而不是简单的选择最近的状态。

● 神经网络为啥用交叉熵。

参考回答:

通过神经网络解决多分类问题时,最常用的一种方式就是在最后一层设置n个输出节点,无论在浅层神经网络还是在CNN中都是如此,比如,在AlexNet中最后的输出层有1000个节点,而即便是ResNet取消了全连接层,也会在最后有一个1000个节点的输出层。

一般情况下,最后一个输出层的节点个数与分类任务的目标数相等。假设最后的节点数为N,那么对于每一个样例,神经网络可以得到一个N维的数组作为输出结果,数组中每一个维度会对应一个类别。在最理想的情况下,如果一个样本属于k,那么这个类别所对应的的输出节点的输出值应该为1,而其他节点的输出都为0,即[0,0,1,0,….0,0],这个数组也就是样本的Label,是神经网络最期望的输出结果,交叉熵就是用来判定实际的输出与期望的输出的接近程度。

● 注意力公式

参考回答:

Soft attention、global attention、动态attention

Hard attention

“半软半硬”的attention (local attention)

静态attention

强制前向attention


● Inception Score 评价指标介绍

参考回答:

定义:

推导出上式的意义:

故要使得生成图像的inception score高,就需要

1.最大化H(y);也就是对于输入的样本,通过inception_v3模型后的类别要均衡,衡量模式坍塌。

2.最小化H(y|x);说明对于输入的样本,通过inception_v3模型后预测某类别的置信度要高,衡量图片生成的质量。

● 使用的 CNN 模型权重之间有关联吗?

参考回答:

权重之间有关联。CNN是权重共享,减少了参数的数量。

简单来说就是用一个卷积核来和一个图像来进行卷积,记住是同一个卷积核,不改变卷积核的值。这样可以减少权值参数。共享就是一个图片对卷积核是共同享有的。对于一个100*100像素的图像,如果我们用一个神经元来对图像进行操作,这个神经元大小就是100*100=10000,单如果我们使用10*10的卷积核,我们虽然需要计算多次,但我们需要的参数只有10*10=100个,加上一个偏向b,一共只需要101个参数。我们取得图像大小还是100*100。如果我们取得图像比较大,它的参数将会更加多。我们通过10*10的卷积核对图像进行特征提取,这样我们就得到一个Feature Map。

一个卷积核只能提取一个特征,所以我们需要多几个卷积核,假设我们有6个卷积核,我们就会得到6个Feature Map,将这6个Feature Map组成一起就是一个神经元。这6个Feature Map我们需要101*6=606个参数。这个值和10000比还是比较小的。如果像之前的神经网络, 两两相连, 需要 28x28 = 784 输入层, 加上第一个隐藏层30个神经元, 则需要784x30再加上30个b, 总共23,550个参数! 多了40倍的参数。

5、百度实习:1)模型压缩方法;2)CPM 模型压缩用了哪些方法;3)压缩效果(体积、指标、部署);4)Kaggle 比赛,比赛背景,怎么进行数据清洗,类别平衡,相近类别重分类,最终成绩是多少,觉得跟前几名差距在哪,有没有尝试过集成的方法;5)人脸项目,大概流程,GPU 加速的地方,两个网络的训练过程,级联网络的 inference 过程,能同时检测多个人脸吗?多尺度缩放怎么处理,resize 自己写?只是检测吗,有没有识别?或者其他

● CycleGAN 原理介绍一下

参考回答:

CycleGAN其实就是一个A→B单向GAN加上一个B→A单向GAN。两个GAN共享两个生成器,然后各自带一个判别器,所以加起来总共有两个判别器和两个生成器。一个单向GAN有两个loss,而CycleGAN加起来总共有四个loss。CycleGAN论文的原版原理图和公式如下,其实理解了单向GAN那么CycleGAN已经很好理解。

下面放一张网友们自制的CycleGAN示意图,比论文原版的更加直观,出处见水印。

● 训练 GAN 的时候有没有遇到什么问题

参考回答:

遇到GAN训练不稳定问题。通过Wasserstein GAN来解决这个问题。WGAN前作分析了Ian Goodfellow提出的原始GAN两种形式各自的问题,第一种形式等价在最优判别器下等价于最小化生成分布与真实分布之间的JS散度,由于随机生成分布很难与真实分布有不可忽略的重叠以及JS散度的突变特性,使得生成器面临梯度消失的问题;第二种形式在最优判别器下等价于既要最小化生成分布与真实分布直接的KL散度,又要最大化其JS散度,相互矛盾,导致梯度不稳定,而且KL散度的不对称性使得生成器宁可丧失多样性也不愿丧失准确性,导致collapse mode现象。

WGAN前作针对分布重叠问题提出了一个过渡解决方案,通过对生成样本和真实样本加噪声使得两个分布产生重叠,理论上可以解决训练不稳定的问题,可以放心训练判别器到接近最优,但是未能提供一个指示训练进程的可靠指标,也未做实验验证。

WGAN本作引入了Wasserstein距离,由于它相对KL散度与JS散度具有优越的平滑特性,理论上可以解决梯度消失问题。接着通过数学变换将Wasserstein距离写成可求解的形式,利用一个参数数值范围受限的判别器神经网络来最大化这个形式,就可以近似Wasserstein距离。在此近似最优判别器下优化生成器使得Wasserstein距离缩小,就能有效拉近生成分布与真实分布。WGAN既解决了训练不稳定的问题,也提供了一个可靠的训练进程指标,而且该指标确实与生成样本的质量高度相关。

● CPM 模型压缩怎么做的?有压过 OpenPose 吗?

参考回答:

预测和图像特征计算模块可以被深度网络架构来取代,其中图像和组织特征的表达可以从数据中直接学习。卷积架构让全局可导,因此可以CPM所有阶段联合训练。CPM可以描述为在PM隐含空间模型框架下的卷积架构。

1)用局部图线索来进行关键定位

第一阶段只用局部图线索来预测部件信任度。figure 2c展示用本地图信息的部件检测的深度网络。先序哦是局部的因为第一阶段感知野只是输出像素附近的一小块。我们用5层卷机网络组成的结构(尾部是量个1x`1卷积层的全卷积架构)。实践中,为了得到一定精度,我们把图片标准化为368x368,感受野是160x160.网络可以看成让深度网络在图像上滑动,并将160x160中局部图像线索回归至代表了各个部件在各个位置的score的P+1大小输出向量。

2)基于空间环境信息的级联预测

对于性状稳定的头和肩膀,检测效果很好,然而人体骨架的连接处准确率就很低,因为形状差异很大。部件周围的信任映射,虽然有噪声,但是很有价值。figure 3中,当检测右手肘时,右肩膀的信任映射达到高峰,可以成为一个很强的线索。后续阶段的预测器(gt)可以用图位置z附近含有噪声的信任映射里的空间组织信息(fai),并且利用“部件的几何设定都是恒定的”这一事实来提高改善预测。

第二个阶段,分类器g2接收特征x2和前一阶段fai的输入。前一阶段不同部件的位置z附近的空间区域产生信任映射,特征方程是把信任映射出的特点编码。CPM不用显式方程来计算环境特征,而是定义含有前一阶段信任度的fai作为预测机的感受野。

这个网络的设计为了在第二阶段输出层得到一个足够大的感知野,可以学习复杂和长距离的部件关系。通过应用迁移阶段的输出层特征(而不是用图模型的显式方程),后续卷积层自由结合最有预测力的特征,来形成环境信息。第一阶段的信任映射来自用小感知野来检验局部图像的网络。第二阶段,我们设计了一个极大扩充的等价感知野。大感知野可以用两种方法实现:牺牲准确度的池化,增加参数为代价的加大卷积核大小,或者冒着可能让反传消失风险增加网络层数。我们选择增加卷积层,在8x降维热力图上达到大感知野,让我们尽可能减少参数数量。8步网络更容易获得大感知野,它和4步网络表现一样好(在高精确度区域也是)。我们也在PM之后图像特征上映射上重复了类似架构,让空间组织依赖图像而且允许错误关联。

我们发现,感受野变大,准确性也变大。通过一系列实验,figure 4的准确度随着感受野的变化曲线,改变感受野只通过改变结构而不是增加参数。准确度随着感受野变大而变大,在250像素饱和,这也大概是归一化物体的大小。这说明,网络确实让远距离物体关系编码,并且这是有益的。我们最好的数据集中,我们把图像归一化为368x368,基于第一级信任映射的第二级感知野输出是31x31,这和原始图片的400x400像素等价,其半径可以覆盖任何部件。当阶段增多,有效感知野就会变大。我们有6个阶段。

3)用CPM学习

这个深度架构可以有许多层。训练这个网可能让梯度消失,就是反向传播在中间层会减弱。pm级联预测框架有一个自然的解决这个问题的方法。我们不断激励这个网络,通过在每个阶段t的输出定义一个损失函数,让预测的和实际信任映射的距离最小化。部件p理想的信任映射是bp,通过把p部件的最可能点设定在ground truth位置。

压缩过OpenPose,效果还可以。

● 用过哪些 Optimizer,效果如何

参考回答:

1)SGD;2)Momentum;3)Nesterov;4)Adagrad;5)Adadelta;6)RMSprop;7)Adam;8)Adamax;9)Nadam。(1)对于稀疏数据,尽量使用学习率可自适应的算法,不用手动调节,而且最好采用默认参数。(2)SGD通常训练时间最长,但是在好的初始化和学习率调度方案下,结果往往更可靠。但SGD容易困在鞍点,这个缺点也不能忽略。(3)如果在意收敛的速度,并且需要训练比较深比较复杂的网络时,推荐使用学习率自适应的优化方法。(4)Adagrad,Adadelta和RMSprop是比较相近的算法,表现都差不多。(5)在能使用带动量的RMSprop或者Adam的地方,使用Nadam往往能取得更好的效果。

● 图像基础:传统图像处理方法知道哪些,图像对比度增强说一下

参考回答:

数字图像处理常用方法:

1)图像变换:由于图像阵列很大,直接在空间域中进行处理,涉及计算量很大。因此,往往采用各种图像变换的方法,如傅立叶变换、沃尔什变换、离散余弦变换等间接处理技术,将空间域的处理转换为变换域处理,不仅可减少计算量,而且可获得更有效的处理(如傅立叶变换可在频域中进行数字滤波处理)。目前新兴研究的小波变换在时域和频域中都具有良好的局部化特性,它在图像处理中也有着广泛而有效的应用。

2)图像编码压缩:图像编码压缩技术可减少描述图像的数据量(即比特数),以便节省图像传输、处理时间和减少所占用的存储器容量。压缩可以在不失真的前提下获得,也可以在允许的失真条件下进行。编码是压缩技术中最重要的方法,它在图像处理技术中是发展最早且比较成熟的技术。

3)图像增强和复原:图像增强和复原的目的是为了提高图像的质量,如去除噪声,提高图像的清晰度等。图像增强不考虑图像降质的原因,突出图像中所感兴趣的部分。如强化图像高频分量,可使图像中物体轮廓清晰,细节明显;如强化低频分量可减少图像中噪声影响。图像复原要求对图像降质的原因有一定的了解,一般讲应根据降质过程建立“降质模型”,再采用某种滤波方法,恢复或重建原来的图像。

4)图像分割:图像分割是数字图像处理中的关键技术之一。图像分割是将图像中有意义的特征部分提取出来,其有意义的特征有图像中的边缘、区域等,这是进一步进行图像识别、分析和理解的基础。虽然目前已研究出不少边缘提取、区域分割的方法,但还没有一种普遍适用于各种图像的有效方法。因此,对图像分割的研究还在不断深入之中,是目前图像处理中研究的热点之一。

5)图像描述:图像描述是图像识别和理解的必要前提。作为最简单的二值图像可采用其几何特性描述物体的特性,一般图像的描述方法采用二维形状描述,它有边界描述和区域描述两类方法。对于特殊的纹理图像可采用二维纹理特征描述。随着图像处理研究的深入发展,已经开始进行三维物体描述的研究,提出了体积描述、表面描述、广义圆柱体描述等方法。

6)图像分类(识别):图像分类(识别)属于模式识别的范畴,其主要内容是图像经过某些预处理(增强、复原、压缩)后,进行图像分割和特征提取,从而进行判决分类。图像分类常采用经典的模式识别方法,有统计模式分类和句法(结构)模式分类,近年来新发展起来的模糊模式识别和人工神经网络模式分类在图像识别中也越来越受到重视。

全局对比度增强

1. 直方图均衡化 Histogram Equalization

算法:

1)根据图像灰度计算灰度概率密度函数PDF

2)计算累积概率分布函数CDF

3)将CDF归一化到原图灰度取值范围,如[0,255]。

4)之后CDF四舍五入取整,得到灰度转换函数sk=T(rk)

5)将CDF作为转换函数,将灰度为rk的点转换为sk灰度

2. 直方图匹配 Histogram Matching

算法:

1)根据图像计算概率密度分布pr(r);

2)根据pr(r)计算累计分布函数sk=T(rk);

3)根据给定的目标分布pz(z)计算累计分布函数G(zq);

4)对于每一个k,找到一个q,使得G(zq)约等于sk;

5)将原图中灰度为k的点变为灰度q;

局部对比度增强

1. 邻域直方图均衡:将全局直方图均衡的思想应用于邻域直方图处理中。

2. 邻域直方图匹配:将全局直方图匹配的思想应用于邻域直方图处理中。

3. 邻域统计方法

算法

1)初始化:增强常数E,灰度下阈值k0,标准差下阈值k1,标准差上阈值k2,窗口半宽s;

2)计算图像灰度均值MG和灰度标准差σG;

3)对于每一个像素,计算邻域(大小为2∗step+1的方块)内灰度均值ML和标准差σL;

4)如果ML<=k0∗MGML<=k0∗MG并且k1∗σG<=σL<=k2∗σG,将像素灰度乘以E。

● 介绍一下图像的高频、低频部分,知道哪些图像补全的方法

参考回答:

图像的频率:灰度值变化剧烈程度的指标,是灰度在平面空间上的梯度。

(1)什么是低频?

低频就是颜色缓慢地变化,也就是灰度缓慢地变化,就代表着那是连续渐变的一块区域,这部分就是低频. 对于一幅图像来说,除去高频的就是低频了,也就是边缘以内的内容为低频,而边缘内的内容就是图像的大部分信息,即图像的大致概貌和轮廓,是图像的近似信息。

(2)什么是高频?

反过来, 高频就是频率变化快.图像中什么时候灰度变化快?就是相邻区域之间灰度相差很大,这就是变化得快.图像中,一个影像与背景的边缘部位,通常会有明显的差别,也就是说变化那条边线那里,灰度变化很快,也即是变化频率高的部位.因此,图像边缘的灰度值变化快,就对应着频率高,即高频显示图像边缘。图像的细节处也是属于灰度值急剧变化的区域,正是因为灰度值的急剧变化,才会出现细节。

另外噪声(即噪点)也是这样,在一个像素所在的位置,之所以是噪点,就是因为它与正常的点颜色不一样了,也就是说该像素点灰度值明显不一样了,,也就是灰度有快速地变化了,所以是高频部分,因此有噪声在高频这么一说。

图像补全的方法:

Region Filling and Object Removal by Exemplar-Based Image Inpainting

算法的流程大致如下:

1)对待补全区域边界的像素依次计算补全的优先度(priority),这个优先度主要考虑2个因素。一个是周围像素可信度高的位置要优先补,另一个是位于图像梯度变化剧烈的位置要优先补。综合二者得到所有优先度之后,挑选优先度最高的像素来补

2)对于上一步找到的待补全像素,考虑它周围的一个小patch(比如3*3)。在图像已知部分搜索所有的patch,找到最相似的patch

3)用找到的best match来补全未知部分,并更新相关数值

但是我们也不难发现这个方法存在的问题:如果图像已知部分找不到相似的patch,那算法将无法进行;这个方法只适用于补全背景以低频信息和重复性纹理为主的图像;搜索相似的patch计算复杂度非常高,算法运行效率低。

Scene Completion Using Millions of Photographs

算法的大致流程如下:

1)从Flickr上下载两百万图片构建数据库,以”landscape””city””park”等关键词搜索户外场景的图片。

2)对于一张待补全图像,从数据库中挑选200个场景最相似的图片,这里使用gist scene descriptor和图像下采样到4*4作为匹配的特征向量。

3)将补全区域边界外80个pixel的区域作为context。对于每一张匹配的图像,搜索所有的平移空间和3个尺度的scale空间,根据context部分的匹配误差,选择最佳的补全位置;之后利用graph-cut算法求解最佳的融合边界。

4)利用标准的泊松融合处理融合边界。

5)将前几步的匹配cost和graph-cut的cost加起来,返回cost最小的20的结果供用户挑选。

Context Encoders: Feature Learning by Inpainting

文章提出的网络结构如下,包括3个部分:Encoder, Channel-wise fully-connected layer, Decoder。Encoder的结构直接借鉴了AlexNet前5层的卷积层结构,具体结构如下。输入的crop尺寸是227Í227,卷积之后得到的feature map结构是256层6 Í 6。所有的weight都随机初始化。

Channel-wise fully-connected layer是对普通fc层的一种改进。之所以加入fc层是为了使feature map每一层的信息可以在内部交流。但传统的fc层参数太多,因此作者提出可以在fc中去掉feature map层间的信息交流,从而减少参数规模。在fc之后会接一个stride为1的卷积层,来实现层间的信息交流。

Decoder的目的是将压缩的feature map一步步放大,恢复到原始图片的尺寸。文章提出采用5个up-convolutional层,每层后接一个RELU。上采样的结构如下。

● 百度实习:模型压缩的大方向。CPM 模型怎么压缩的,做了哪些工作?

参考回答:

预测和图像特征计算模块可以被深度网络架构来取代,其中图像和组织特征的表达可以从数据中直接学习。卷积架构让全局可导,因此可以CPM所有阶段联合训练。CPM可以描述为在PM隐含空间模型框架下的卷积架构。

1)用局部图线索来进行关键定位

第一阶段只用局部图线索来预测部件信任度。figure 2c展示用本地图信息的部件检测的深度网络。先序哦是局部的因为第一阶段感知野只是输出像素附近的一小块。我们用5层卷机网络组成的结构(尾部是量个1x`1卷积层的全卷积架构)。实践中,为了得到一定精度,我们把图片标准化为368x368,感受野是160x160.网络可以看成让深度网络在图像上滑动,并将160x160中局部图像线索回归至代表了各个部件在各个位置的score的P+1大小输出向量。

2)基于空间环境信息的级联预测

对于性状稳定的头和肩膀,检测效果很好,然而人体骨架的连接处准确率就很低,因为形状差异很大。部件周围的信任映射,虽然有噪声,但是很有价值。figure 3中,当检测右手肘时,右肩膀的信任映射达到高峰,可以成为一个很强的线索。后续阶段的预测器(gt)可以用图位置z附近含有噪声的信任映射里的空间组织信息(fai),并且利用“部件的几何设定都是恒定的”这一事实来提高改善预测。

第二个阶段,分类器g2接收特征x2和前一阶段fai的输入。前一阶段不同部件的位置z附近的空间区域产生信任映射,特征方程是把信任映射出的特点编码。CPM不用显式方程来计算环境特征,而是定义含有前一阶段信任度的fai作为预测机的感受野。

这个网络的设计为了在第二阶段输出层得到一个足够大的感知野,可以学习复杂和长距离的部件关系。通过应用迁移阶段的输出层特征(而不是用图模型的显式方程),后续卷积层自由结合最有预测力的特征,来形成环境信息。第一阶段的信任映射来自用小感知野来检验局部图像的网络。第二阶段,我们设计了一个极大扩充的等价感知野。大感知野可以用两种方法实现:牺牲准确度的池化,增加参数为代价的加大卷积核大小,或者冒着可能让反传消失风险增加网络层数。我们选择增加卷积层,在8x降维热力图上达到大感知野,让我们尽可能减少参数数量。8步网络更容易获得大感知野,它和4步网络表现一样好(在高精确度区域也是)。我们也在PM之后图像特征上映射上重复了类似架构,让空间组织依赖图像而且允许错误关联。

我们发现,感受野变大,准确性也变大。通过一系列实验,figure 4的准确度随着感受野的变化曲线,改变感受野只通过改变结构而不是增加参数。准确度随着感受野变大而变大,在250像素饱和,这也大概是归一化物体的大小。这说明,网络确实让远距离物体关系编码,并且这是有益的。我们最好的数据集中,我们把图像归一化为368x368,基于第一级信任映射的第二级感知野输出是31x31,这和原始图片的400x400像素等价,其半径可以覆盖任何部件。当阶段增多,有效感知野就会变大。我们有6个阶段。

3)用CPM学习

这个深度架构可以有许多层。训练这个网可能让梯度消失,就是反向传播在中间层会减弱。pm级联预测框架有一个自然的解决这个问题的方法。我们不断激励这个网络,通过在每个阶段t的输出定义一个损失函数,让预测的和实际信任映射的距离最小化。部件p理想的信任映射是bp,通过把p部件的最可能点设定在ground truth位置。

● Depthwise 卷积实际速度与理论速度差距较大,解释原因。

参考回答:

首先,caffe原先的gpu实现group convolution很糟糕,用for循环每次算一个卷积,速度极慢。第二,cudnn7.0及之后直接支持group convolution,但本人实测,速度比github上几个直接写cuda kernel计算的dw convolution速度慢。例如对于n=128, c=512, h=32, w=32, group=512的卷积跑100次,cudnn 7.0里的group convolution需要4秒多,而DepthwiseConvolution大概只需要1秒。

分析了一下dw convolution与普通convolution的理论计算复杂度,举例如下:

卷积1:普通卷积,输入为64*64*256,输出为64*64*256,卷积核大小为3*3。参数为3*3*256*256=590K,计算量为64*64*256*3*3*256=2.42G,计算过程的工作集内存总量(输入输出数据+参数)为64*64*256*2 + 3*3*256*256 = 2.69M。

卷积2:dw卷积,输入为64*64*256,输出为64*64*256,卷积核大小为3*3。参数为3*3*256=2.3K个,计算量为64*64*256*3*3=9.44M,计算过程的工作集内存总量为64*64*256*2 + 3*3*256=2.10M。

卷积3:普通卷积,输入为64*64*16,输出为64*64*16,卷积核大小为3*3。参数为3*3*16*16=2.3K个,计算量为64*64*16*3*3*16=9.44M,计算过程的工作集内存总量为64*64*16*2 + 3*3*16*16=133K。

可以看到卷积2肯定比卷积1快,因为计算量下降到1/256了,但卷积2实际上无法达到卷积1的256倍速度(我记得我测得结果大概是快10倍左右),因为工作集内存大小并没有显著降低。卷积2也无法达到卷积3的速度,因为虽然FLOPS相同,但工作集内存大小相差了很多倍,因此单位数据的计算密度小很多,很难充分利用GPU上的计算单元。

● RetinaNet 的大致结构画一下

参考回答:

● RetinaNet为什么比SSD效果好

参考回答:

SSD 在训练期间重新采样目标类和背景类的比率,这样它就不会被图像背景淹没。RetinaNet采用另一种方法来减少训练良好的类的损失。因此,只要该模型能够很好地检测背景,就可以减少其损失并重新增强对目标类的训练。所以RetinaNet比SSD 效果好。