RNN-LSTM 机器学习 准确度很低

&figure&&img src=&https://pic4.zhimg.com/v2-c1ce5cbcdda97b0c05cdc20_b.jpg& data-rawwidth=&1007& data-rawheight=&316& class=&origin_image zh-lightbox-thumb& width=&1007& data-original=&https://pic4.zhimg.com/v2-c1ce5cbcdda97b0c05cdc20_r.jpg&&&/figure&&p&上篇日志&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&人脸特征向量用整数存储精度损失多少?&/a&里面写到把浮点特征向量转成整型,可以提速几倍,今天做了一番实验。&/p&&p&&br&&/p&&p&&b&摘要:&/b&&/p&&p&如果你对性能一无所知,把计算相似度的代码写成下面这样&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&float dot_float(int len, const float* v1, const float* v2)
float sumf = 0;
for (int i = 0; i & i++)
sumf += v1[i] * v2[i];
&/code&&/pre&&/div&&p&然后在外层这样调用&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&for (int pp = 0; pp & person_ pp++)
scoresf[pp] = dot_float(N, valf1, valf2 + pp*N);
&/code&&/pre&&/div&&p&与这种最粗糙的写法相比,本文介绍的写法最终可以提速&b&12.6倍&/b&左右。&/p&&p&&br&&/p&&p&&b&基本思路:&/b&&/p&&p&1.float转short, 相似度损失小于万分之五(见最上面的链接),位宽缩小一半,定点比浮点要快。&/p&&p&2.利用SSE加速。&/p&&p&3.批量处理减少函数调用次数。&/p&&p&4. 展开循环&/p&&p&&br&&/p&&p&&b&第一部分:数据准备&/b&&/p&&p&注意不用SSE时,两short相乘会溢出,因此直接用int存储。如果用short存储,相乘时才转成int,应该会更慢。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&float scale = (int)0x7
void init()
person_num = total_elements / N;
printf(&N = %d, person_num = %d\n&, N, person_num);
valf1 = new float[N];
valf2 = new float[N*person_num];
vali1 = new int[N];
vali2 = new int[N*person_num];
valshort1 = new short[N];
valshort2 = new short[N*person_num];
scoresf = new float[person_num];
scoresi = new int[person_num];
float len1 = 0;
for (int i = 0; i & N; i++)
valf1[i] =
len1 += valf1[i] * valf1[i];
len1 = sqrt(len1);
for (int i = 0; i & N; i++)
valf1[i] /= len1;
vali1[i] = __min(scale, valf1[i] * scale + 0.5f);
valshort1[i] = vali1[i];
for (int pp = 0; pp & person_ pp++)
double len2 = 0;
for (int i = 0; i & N; i++)
int tmp = rand() % N;
valf2[pp*N + i] =
len2 += tmp*
len2 = sqrt(len2);
for (int i = 0; i & N; i++)
valf2[pp*N + i] /= len2;
vali2[pp*N + i] = __min(scale, valf2[pp*N + i] * scale + 0.5f);
valshort2[pp*N + i] = vali2[pp*N + i];
&/code&&/pre&&/div&&p&&br&&/p&&p&&b&第二部分: 不用SSE时浮点点积和整型点积&/b&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&float dot_float(int len, const float* v1, const float* v2)
float sumf = 0;
for (int i = 0; i & i++)
sumf += v1[i] * v2[i];
int dot_int(int len, const int* v1, const int* v2)
int sumi = 0;
for (int i = 0; i & i++)
sumi += v1[i] * v2[i];
&/code&&/pre&&/div&&p&len =128, 256, 512, 时,整型比浮点大概快2.3-2.9倍&/p&&p&&br&&/p&&p&&b&第三部分:使用SSE (位宽256,头文件在#include &immintrin.h&),浮点与short&/b&&/p&&p&注意地址对齐,否则会慢很多,包括前面申请数组内存的时候也要,我是因为测试的都是整16倍的,所以没有加对齐代码,对齐方式参照float tmp[8 + 8], *q = (float*)(((long long)tmp+8)&&5&&5),请读者自己琢磨。&/p&&p&浮点改SSE加速更明显,浮点改SSE后加速2倍左右,整型改SSE之后加速1.5倍左右。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&#ifdef use_aligned
#define my_mm256_load_ps _mm256_load_ps
#define my_mm256_store_ps _mm256_store_ps
#define my_mm256_load_si256 _mm256_load_si256
#define my_mm256_store_si256 _mm256_store_si256
#define my_mm256_load_ps _mm256_loadu_ps
#define my_mm256_store_ps _mm256_storeu_ps
#define my_mm256_load_si256 _mm256_loadu_si256
#define my_mm256_store_si256 _mm256_storeu_si256
float dot_float_SSE(int len, const float* v1, const float* v2)
__m256 result = _mm256_setzero_ps();
__m256 val1, val2;
#ifdef use_aligned
float tmp[8 + 8], *q = (float*)(((long long)tmp+8)&&5&&5);
float q[8];
int i = 0;
for (; i & i += 8)
val1 = my_mm256_load_ps(v1 + i);
val2 = my_mm256_load_ps(v2 + i);
val1 = _mm256_mul_ps(val1, val2);
result = _mm256_add_ps(result, val1);
my_mm256_store_ps(q, result);
sumf = q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7];
for (; i & i++)
sumf += v1[i] * v2[i];
int dot_short_SSE(int len, const short* v1, const short* v2)
#ifdef use_aligned
int tmp[8 + 8], *q = (int*)(((long long)tmp + 8) && 5 && 5);
__m256i result = _mm256_setzero_si256();
__m256i val1, val2;
int i = 0;
const __m256i* vv1 = (const __m256i*)v1;
const __m256i* vv2 = (const __m256i*)v2;
for (; i & i += 16)
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
my_mm256_store_si256((__m256i*)q, result);
sumi = q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7];
for (; i & i++)
sumi += (int)v1[i] * (int)v2[i];
&/code&&/pre&&/div&&p&&br&&/p&&p&&b&第四部分:SSE批量计算与SSE不批量&/b&&/p&&p&看下面这个函数意思意思一下,就是尽量少调用函数。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&void dot_float_batch(int len, const float* v1, const float* v2, int num, float* scores)
for (int pp = 0; pp & pp++)
float sumf = 0;
for (int i = 0; i & i++)
sumf += v1[i] * v2[pp*N+i];
scores[pp] =
&/code&&/pre&&/div&&p&SSE批量比不批量提速较为明显,维度越低越明显。&/p&&p&&br&&/p&&p&&b&第五部分:展开循环&/b&&/p&&p&只展开了256维。为什么选256维,不防看看这里&a href=&https://link.zhihu.com/?target=https%3A//github.com/wy1iu/sphereface/issues/81& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SpherefaceNet-04, SpherefaceNet-06 Release · Issue #81 · wy1iu/sphereface&/a&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&void dot_short_SSE_batch_dim256(const short* v1, const short* v2, int num, int* scores)
#ifdef use_aligned
int tmp[8 + 8], *q = (int*)(((long long)tmp + 8) && 5 && 5);
for (int nn = 0; nn & nn++)
__m256i result = _mm256_setzero_si256();
__m256i val1, val2;
int i = 0;
const __m256i* vv1 = (const __m256i*)v1;
const __m256i* vv2 = (const __m256i*)v2;
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
val1 = my_mm256_load_si256(vv1++);
val2 = my_mm256_load_si256(vv2++);
val1 = _mm256_madd_epi16(val1, val2);
result = _mm256_add_epi32(result, val1);
my_mm256_store_si256((__m256i*)q, result);
sumi = q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7];
scores[nn] =
&/code&&/pre&&/div&&p&展开之后性能得到意想不到的提升。&/p&&p&&br&&/p&&p&&b&实验:维度*人脸数=25.6百万,外层循环10次,每次随机生成向量,依次统计各种方法时间,每次执行100次,相当于维度*人脸数=2560百万。&/b&&/p&&p&符号说明:&/p&&p&
浮点:不使用SSE的float点积&/p&&p&
浮点*:批量float点积&/p&&p&
浮点SSE:SSE float点积&/p&&p&
浮点SSE*:SSE批量float点积&/p&&p&
浮点SSE**:展开循环的SSE批量float点积&/p&&p&
整型:不使用SSE的int点积&/p&&p&
整型*:批量int点积&/p&&p&
整型SSE:SSE short点积&/p&&p&
整型SSE*: SSE批量short点积&/p&&p&
整型SSE**:展开循环的SSE批量short点积&/p&&p&时间表&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&维度 人数 浮点 浮点* 浮点SSE 浮点SSE* 浮点SSE** 整型 整型* 整型SSE 整型SSE* 整型SSE**
128 20M 1.927
256 10M 2.166
512 5M 2.205
&/code&&/pre&&/div&&p&加速表&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&维度 人数 浮点 浮点* 浮点SSE 浮点SSE* 浮点SSE** 整型 整型* 整型SSE 整型SSE* 整型SSE**
128 20M 1.000
256 10M 1.000
512 5M 1.000
&/code&&/pre&&/div&&p&可以看到,与最粗糙的写法相比,&b&不展开&/b&的时候也能得到&b&5.5-7.0&/b&倍加速,&b&展开&/b&的时候达到&b&12.6倍&/b&加速&/p&&p&&br&&/p&&p&&b&结论:&/b&&/p&&p&将浮点特征向量转为short型存储,并使用SSE加速,对特定维数展开循环,可以获得一个量级的性能提升。同时,存储空间也减半。其代价只是不到万分之五的精度损失。&/p&
上篇日志里面写到把浮点特征向量转成整型,可以提速几倍,今天做了一番实验。 摘要:如果你对性能一无所知,把计算相似度的代码写成下面这样float dot_float(int len, const float* v1, const float* v2)
float sum…
&figure&&img src=&https://pic4.zhimg.com/v2-a09dd633d49c05d5453ac_b.jpg& data-rawwidth=&460& data-rawheight=&302& class=&origin_image zh-lightbox-thumb& width=&460& data-original=&https://pic4.zhimg.com/v2-a09dd633d49c05d5453ac_r.jpg&&&/figure&&blockquote&安妮 编译整理&br&量子位 出品 | 公众号 QbitAI&/blockquote&&p&今天有三件事挺有意思。&/p&&p&一是以“&b&快到没朋友&/b&”著称的流行目标检测模型YOLO推出全新v3版,新版本又双叒叕提升了精度和速度。在实现相近性能时,YOLOv3比SSD速度提高3倍,比RetinaNet速度提高近4倍。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-5e781f695d22aa61ab1a24_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1080& data-rawheight=&553& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic1.zhimg.com/v2-5e781f695d22aa61ab1a24_r.jpg&&&/figure&&p&二是有细心网友发现,模型一作在arXiv上发布研究论文时,脑回路清奇地将自己这篇论文自引自用了一下。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-ef0b96b11d5b680b5a79_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&933& data-rawheight=&137& class=&origin_image zh-lightbox-thumb& width=&933& data-original=&https://pic2.zhimg.com/v2-ef0b96b11d5b680b5a79_r.jpg&&&/figure&&p&三是……在小哥自引自用后没多久,arXiv官方账号宣布服务器由于不明原因挂掉了……&/p&&figure&&img src=&https://pic1.zhimg.com/v2-a1dee71464_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&872& data-rawheight=&181& class=&origin_image zh-lightbox-thumb& width=&872& data-original=&https://pic1.zhimg.com/v2-a1dee71464_r.jpg&&&/figure&&h2&&b&更快更强&/b&&/h2&&p&先说更新这件正经事~&/p&&p&通过调整YOLO模型中的一些细节,v3模型增大了一些准确率也有所提升,速度依旧非常快。&/p&&p&对于320x320的图像,YOLOv3的检测速度可达22ms,mAP值可达28.2,与SSD的准确率相当但速度快3倍。&/p&&p&当用旧版.5 IOU mAP检测指标时,YOLOv3在英伟达TitanX显卡上51ms达到57.9AP50的性能。相比之下,RetinaNet则用198ms达到57.5AP50的性能,两者性能相近但速度相差近4倍。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-0dcb8d867c7e832fcd769_b.jpg& data-size=&normal& data-rawwidth=&549& data-rawheight=&326& class=&origin_image zh-lightbox-thumb& width=&549& data-original=&https://pic2.zhimg.com/v2-0dcb8d867c7e832fcd769_r.jpg&&&figcaption&△ 在实现相同准确度情况下,YOLOv3速度明显优于其他检测方法(单一变量实验)&/figcaption&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-b6e906ceb0a5c343ec6679_b.jpg& data-size=&normal& data-rawwidth=&1029& data-rawheight=&732& class=&origin_image zh-lightbox-thumb& width=&1029& data-original=&https://pic2.zhimg.com/v2-b6e906ceb0a5c343ec6679_r.jpg&&&figcaption&△ 在COCO数据集上不同模型的运行情况对比&/figcaption&&/figure&&h2&&b&作者,和他的少女心&/b&&/h2&&p&YOLOv3出自华盛顿大学的Joseph Redmon和Ali Farhadi之手。&/p&&p&Ali Farhadi是华盛顿大学的副教授,一作Joseph Redmon是他的博士生,曾在IBM实习,其实还当过电台DJ。Redmon是一个少女心有点爆棚的程序员,这里有一份他的简历,可以自行感受下。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-b789ae85dffaa_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&577& data-rawheight=&747& class=&origin_image zh-lightbox-thumb& width=&577& data-original=&https://pic2.zhimg.com/v2-b789ae85dffaa_r.jpg&&&/figure&&p&处于不知名的原因,小哥有一些“独角兽情结”,可以再次感受下个人网站的画风——&/p&&figure&&img src=&https://pic4.zhimg.com/v2-71afa80fc18f69a34a2f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1080& data-rawheight=&396& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic4.zhimg.com/v2-71afa80fc18f69a34a2f_r.jpg&&&/figure&&h2&&b&“论文就该实在点”&/b&&/h2&&p&如果单单是YOLOv3发布新版本,可能在Reddit上还达不到热度200的水平。有意思在,论文从头到尾都透露着“不太正经”的气息,比如作者自引自用论文,比如这个Introduction的开头——&/p&&blockquote&自己今年没怎么做研究,花了很多时间在Twitter上,捣鼓了一下GAN。&/blockquote&&p&没错,这真的是一篇arXiv上的论文。Redmon还在论文中写了写自己尝试但失败了的方法。结尾,也不忘调侃一下热点。&/p&&p&“还有一个更好地问题:‘我们如何使用检测器?’Facebook和Google的很多研究员也在做相关研究啊。我认为,我们至少能知道技术被应用在了有利的方面,并且不会被恶意利用并将它们卖给…等一下,&b&你说这就是它的用途??&/b&Oh!”&/p&&p&Reddit上网友的称赞每篇论文都应该这样实在,小哥在Reddit已收获大批粉丝……&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e246a1e23ce2f729f458a357f3bf5f99_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&198& data-rawheight=&195& class=&content_image& width=&198&&&/figure&&h2&&b&相关资料&/b&&/h2&&p&对了,对论文有疑问还是不要去@作者了,反正对方也&b&不会回&/b&,论文中都说了~&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-02fabe5c84b8802fac975d69acdc2be6_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&489& data-rawheight=&26& class=&origin_image zh-lightbox-thumb& width=&489& data-original=&https://pic3.zhimg.com/v2-02fabe5c84b8802fac975d69acdc2be6_r.jpg&&&/figure&&p&&br&&/p&&p&你可以选择冒险再回看研读一下论文和代码。&/p&&p&论文下载地址:&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//pjreddie.com/media/files/papers/YOLOv3.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&pjreddie.com/media/file&/span&&span class=&invisible&&s/papers/YOLOv3.pdf&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&项目地址:&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//pjreddie.com/darknet/yolo/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&pjreddie.com/darknet/yo&/span&&span class=&invisible&&lo/&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&相关代码:&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//github.com/pjreddie/darknet& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&github.com/pjreddie/dar&/span&&span class=&invisible&&knet&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&不过你得&b&小心&/b&。&/p&&p&毕竟……YOLO模型的全称可是&b&You Only Look Once&/b&(只能看一眼),再看可能会被吃掉!&/p&&figure&&img src=&https://pic1.zhimg.com/v2-8af114dec3dd1e73ccd70_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&460& data-rawheight=&302& class=&origin_image zh-lightbox-thumb& width=&460& data-original=&https://pic1.zhimg.com/v2-8af114dec3dd1e73ccd70_r.jpg&&&/figure&&p&— &b&完&/b& —&/p&&p&欢迎大家关注我们的专栏:&a href=&https://zhuanlan.zhihu.com/qbitai& class=&internal&&量子位 - 知乎专栏&/a&&/p&&p&诚挚招聘&/p&&p&量子位正在招募编辑/记者,工作地点在北京中关村。期待有才气、有热情的同学加入我们!相关细节,请在量子位公众号(QbitAI)对话界面,回复“招聘”两个字。&/p&&p&&a href=&https://zhuanlan.zhihu.com/qbitai& class=&internal&&量子位 QbitAI&/a& · 头条号签约作者&/p&&p&?'?' ? 追踪AI技术和产品新动态&/p&
安妮 编译整理 量子位 出品 | 公众号 QbitAI今天有三件事挺有意思。一是以“快到没朋友”著称的流行目标检测模型YOLO推出全新v3版,新版本又双叒叕提升了精度和速度。在实现相近性能时,YOLOv3比SSD速度提高3倍,比RetinaNet速度提高近4倍。二是有细心网友…
&figure&&img src=&https://pic2.zhimg.com/v2-d8efaee033036_b.jpg& data-rawwidth=&909& data-rawheight=&502& class=&origin_image zh-lightbox-thumb& width=&909& data-original=&https://pic2.zhimg.com/v2-d8efaee033036_r.jpg&&&/figure&&p&很久没有更文章了,主要是没有找到zero-shot learning(ZSL)方面我特别想要分享的文章,且中间有一段时间在考虑要不要继续做这个题目,再加上我懒 (¬_¬),所以一直拖到了现在。&/p&&p&最近科研没什么进展,就想着写一个ZSL的入门性的文章,目的是为了帮助完全没有接触过这方面,并有些兴趣的同学,能在较短的时间对ZSL有一定的认识,并且对目前的发展情况有一定的把握。&/p&&p&在此之前,需要提到的是:&b&无论是论文笔记,还是总结性的读物,都包含了作者自己的理解和二次加工,想要做出好的工作必定需要自己看论文和总结。&/b&&/p&&h2&零次学习(zero-shot learning)基本概念&/h2&&p&每次在实验室做工作汇报的时候,总会把ZSL的基本概念讲一遍,但是每次的效果都不是很好,工作都讲完了,提的第一个问题依然是:ZSL到底是什么?这让我一度认为我的表达能力有问题。。。。。。不过回忆起我第一次接触这个题目的时候,也花了挺长的时间才搞清楚到底在做一件什么事情,那篇入门的文章[1]看了很久才基本看懂。因此,我尽量用最简单的,不带任何公式的方式来讲一下这到底是个什么问题。&/p&&p&假设小暗(纯粹因为不想用小明)和爸爸,到了动物园,看到了马,然后爸爸告诉他,这就是马;之后,又看到了老虎,告诉他:“看,这种身上有条纹的动物就是老虎。”;最后,又带他去看了熊猫,对他说:“你看这熊猫是黑白色的。”然后,爸爸给小暗安排了一个任务,让他在动物园里找一种他从没见过的动物,叫斑马,并告诉了小暗有关于斑马的信息:“斑马有着马的轮廓,身上有像老虎一样的条纹,而且它像熊猫一样是黑白色的。”最后,小暗根据爸爸的提示,在动物园里找到了斑马(意料之中的结局。。。)。&/p&&p&上述例子中包含了一个人类的推理过程,就是利用过去的知识(马,老虎,熊猫和斑马的描述),在脑海中推理出新对象的具体形态,从而能对新对象进行辨认。(如图1所示)ZSL就是希望能够模仿人类的这个推理过程,使得计算机具有识别新事物的能力。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-d8efaee033036_b.jpg& data-size=&normal& data-rawwidth=&909& data-rawheight=&502& class=&origin_image zh-lightbox-thumb& width=&909& data-original=&https://pic2.zhimg.com/v2-d8efaee033036_r.jpg&&&figcaption&图1 ZSL概念图[17]&/figcaption&&/figure&&p&如今深度学习非常火热,使得纯监督学习在很多任务上都达到了让人惊叹的结果,但其限制是:往往需要足够多的样本才能训练出足够好的模型,并且利用猫狗训练出来的分类器,就只能对猫狗进行分类,其他的物种它都无法识别。这样的模型显然并不符合我们对人工智能的终极想象,我们希望机器能够像上文中的小暗一样,具有通过推理,识别新类别的能力。&/p&&p&ZSL就是希望我们的模型能够对其从没见过的类别进行分类,让机器具有推理能力,实现真正的智能。其中零次(Zero-shot)是指对于要分类的类别对象,一次也不学习。这样的能力听上去很具有吸引力,那么到底是怎么实现的呢?&/p&&p&假设我们的模型已经能够识别马,老虎和熊猫了,现在需要该模型也识别斑马,那么我们需要像爸爸一样告诉模型,怎样的对象才是斑马,但是并不能直接让模型看见斑马。所以模型需要知道的信息是马的样本、老虎的样本、熊猫的样本和样本的标签,以及关于前三种动物和斑马的描述。将其转换为常规的机器学习,这里我们只讨论一般的图片分类问题:&/p&&p&(1)训练集数据&img src=&https://www.zhihu.com/equation?tex=X_%7Btr%7D& alt=&X_{tr}& eeimg=&1&& 及其标签 &img src=&https://www.zhihu.com/equation?tex=Y_%7Btr%7D& alt=&Y_{tr}& eeimg=&1&& ,包含了模型需要学习的类别(马、老虎和熊猫),这里和传统的监督学习中的定义一致;&/p&&p&(2)测试集数据 &img src=&https://www.zhihu.com/equation?tex=X_%7Bte%7D& alt=&X_{te}& eeimg=&1&& 及其标签 &img src=&https://www.zhihu.com/equation?tex=Y_%7Bte%7D& alt=&Y_{te}& eeimg=&1&& ,包含了模型需要辨识的类别(斑马),这里和传统的监督学习中也定义一直;&/p&&p&(3)训练集类别的描述 &img src=&https://www.zhihu.com/equation?tex=A_%7Btr%7D& alt=&A_{tr}& eeimg=&1&& ,以及测试集类别的描述 &img src=&https://www.zhihu.com/equation?tex=A_%7Bte%7D& alt=&A_{te}& eeimg=&1&& ;我们将每一个类别 &img src=&https://www.zhihu.com/equation?tex=y_%7Bi%7D%5Cin+Y& alt=&y_{i}\in Y& eeimg=&1&& ,都表示成一个语义向量 &img src=&https://www.zhihu.com/equation?tex=a_%7Bi%7D%5Cin+A& alt=&a_{i}\in A& eeimg=&1&& 的形式,而这个语义向量的每一个维度都表示一种高级的属性,比如“黑白色”、“有尾巴”、“有羽毛”等等,当这个类别包含这种属性时,那在其维度上被设置为非零值。对于一个数据集来说,语义向量的维度是固定的,它包含了能够较充分描述数据集中类别的属性。&/p&&p&在ZSL中,我们希望利用 &img src=&https://www.zhihu.com/equation?tex=X_%7Btr%7D& alt=&X_{tr}& eeimg=&1&& 和 &img src=&https://www.zhihu.com/equation?tex=Y_%7Btr%7D& alt=&Y_{tr}& eeimg=&1&& 来训练模型,而模型能够具有识别 &img src=&https://www.zhihu.com/equation?tex=X_%7Bte%7D& alt=&X_{te}& eeimg=&1&& 的能力,因此模型需要知道所有类别的描述 &img src=&https://www.zhihu.com/equation?tex=A_%7Btr%7D& alt=&A_{tr}& eeimg=&1&& 和 &img src=&https://www.zhihu.com/equation?tex=A_%7Bte%7D& alt=&A_{te}& eeimg=&1&& 。ZSL这样的设置其实就是上文中小暗识别斑马的过程中,爸爸为他提供的条件。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-33aeedce07dd_b.jpg& data-size=&normal& data-rawwidth=&894& data-rawheight=&286& class=&origin_image zh-lightbox-thumb& width=&894& data-original=&https://pic2.zhimg.com/v2-33aeedce07dd_r.jpg&&&figcaption&图2 ZSL设置图[16]&/figcaption&&/figure&&p&如图2,可以较为直观地了解ZSL的设置。&/p&&p&讲到这,很多同学可能会问:&/p&&p&(1)类别的描述 &img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& 到底是怎么获取的?&/p&&p&答:有人工专家定义的,也有通过海量的附加数据集自动学习出来的,但前者的效果目前要好很多。&/p&&p&(2)这样做让人觉得有点失望呀!我希望模型能够在没有斑马样本的情况下,识别斑马,而现在,虽然我不需要为模型提供斑马的样本,但是却要为每一个类别添加一种描述,更离谱的是我还需要斑马(测试集)的描述,这个过程并没有想象中智能诶!&/p&&p&答:的确,在我们的想象中,我们期待的智能是:只给机器马、老虎和熊猫,然后它就可以识别斑马了,这样多爽,多神奇。但我们回过头去,再想想小暗的思考过程,如果爸爸不告诉小暗关于斑马的任何信息,那么当小暗看见斑马的时候,并不会知道它是什么,只是小暗能够描述它:“这是一匹有着黑白颜色条纹的马。”这里,有同学可能又会说:至少我们可以不用告诉小暗类别的描述呀,但是ZSL就不行。其实,我们是需要告诉小暗类别描述的,或者说小暗在之前就学习到了类别描述,比如怎样的图案是“条纹”,怎样的颜色称为“黑白色”,这样的属性定义。对于一个模型来说,它就像刚出生的婴儿,我们需要教会它这些属性的定义。&/p&&p&(3)就算是这样,需要实现定义这个描述 &img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& 还是很蛋疼的一件事情。&/p&&p&答:(1)中就有提到,描述 &img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& 可以自动学习,我们将小暗已经掌握的知识描述为一个知识库,这个知识库里就有对各种属性的定义;而能够模仿人类知识库的最好东西就是“百度百科”,“维基百科”等等各种百科,我们可以利用百科中的各种定义,生成类别的定义,这方面侧重于NLP,因此不进一步讨论。&/p&&p&在此,我们小小总结一下ZSL问题的定义。&b&利用训练集数据训练模型,使得模型能够对测试集的对象进行分类,但是训练集类别和测试集类别之间没有交集;期间需要借助类别的描述,来建立训练集和测试集之间的联系,从而使得模型有效&/b&。&/p&&h2&目前的研究方式&/h2&&p&在上文中提到,要实现ZSL功能似乎需要解决两个部分的问题:第一个问题是获取合适的类别描述 &img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& ;第二个问题是建立一个合适的分类模型。&/p&&p&目前大部分工作都集中在第二个问题上,而第一个问题的研究进展比较缓慢。个人认为的原因是, 目前&img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& 的获取主要集中于一些NLP的方法,而且难度较大;而第二个问题能够用的方法较多,比较容易出成果。&/p&&p&因此,接下来的算法部分,也只介绍研究分类模型的方法。&/p&&h2&数据集介绍&/h2&&p&先介绍数据集,是因为希望在算法介绍部分,直接给出实例,让大家能够直接上手,这里顺便插个沐神 &a class=&member_mention& href=&https://www.zhihu.com/people/13fd0fce2affd948bfd821a8f7ed10f3& data-hash=&13fd0fce2affd948bfd821a8f7ed10f3& data-hovercard=&p$b$13fd0fce2affd948bfd821a8f7ed10f3&&@李沐&/a& 的感悟。&/p&&blockquote&虽然在我认识的人里,好些人能够读一篇论文或者听一个报告后就能问出很好的问题,然后就基本弄懂了。但我在这个上笨很多。读过的论文就像喝过的水,第二天就不记得了。一定是需要静下心来,从头到尾实现一篇,跑上几个数据,调些参数,才能心安地觉得懂了。例如在港科大的两年读了很多论文,但现在反过来看,仍然记得可能就是那两个老老实实动手实现过写过论文的模型了。即使后来在机器学习这个方向又走了五年,学习任何新东西仍然是要靠动手。——李沐(MXNet开发者)&/blockquote&&p&(1)&b&Animal with Attributes(AwA)&/b&官网:&a href=&https://link.zhihu.com/?target=https%3A//cvml.ist.ac.at/AwA/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Animals with Attributes&/a&&/p&&p&提出ZSL定义的作者,给出的数据集,都是动物的图片,包括50个类别的图片,其中40个类别作为训练集,10个类别作为测试集,每个类别的语义为85维,总共有30475张图片。但是目前由于版权问题,已经无法获取这个数据集的图片了,作者便提出了AwA2,与前者类似,总共37322张图片。&/p&&p&(2)&b&Caltech-UCSD-Birds-200-2011(CUB)&/b&官网:&a href=&https://link.zhihu.com/?target=http%3A//www.vision.caltech.edu/visipedia/CUB-200-2011.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Caltech-UCSD Birds-200-2011&/a&&/p&&p&全部都是鸟类的图片,总共200类,150类为训练集,50类为测试集,类别的语义为312维,有11788张图片。&/p&&p&(3)&b&Sun database(SUN)&/b&官网:&a href=&https://link.zhihu.com/?target=http%3A//groups.csail.mit.edu/vision/SUN/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SUN Database&/a&&/p&&p&总共有717个类别,每个类别20张图片,类别语义为102维。传统的分法是训练集707类,测试集10类。&/p&&p&(4)&b&Attribute Pascal and Yahoo dataset(aPY)&/b&官网:&a href=&https://link.zhihu.com/?target=http%3A//vision.cs.uiuc.edu/attributes/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Describing Objects by their Attributes&/a&&/p&&p&共有32个类,其中20个类作为训练集,12个类作为测试集,类别语义为64维,共有15339张图片。&/p&&p&(5)&b&ILSVRC2012/ILSVRC2010(ImNet-2)&/b&&/p&&p&利用ImageNet做成的数据集,由ILSVRC个类作为训练集,ILSVRC个类作为测试集,有254000张图片。它由 4.6M 的Wikipedia数据集训练而得到,共1000维。&/p&&p&上述数据集中(1)-(4)都是较小型(small-scale)的数据集,(5)是大型(large-scale)数据集。虽然(1)-(4)已经提供了人工定义的类别语义,但是有些作者也会从维基语料库中自动提取出类别的语义表示,来检测自己的模型。&/p&&p&这里给大家提供一些已经用GoogleNet提取好的数据集图片特征,大家可以比较方便地使用。&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&Zero-Shot Learing问题数据集分享(GoogleNet 提取)&/a&&/p&&h2&基础算法介绍&/h2&&p&在此,只具体介绍最简单的方法,让大家可以快速上手。我们面对的是一个图片分类问题,即对测试集的样本 &img src=&https://www.zhihu.com/equation?tex=X_%7Bte%7D& alt=&X_{te}& eeimg=&1&& 进行分类,而我们分类时需要借助类别的描述 &img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& ,由于每一个类别 &img src=&https://www.zhihu.com/equation?tex=y_%7Bi%7D%5Cin+Y& alt=&y_{i}\in Y& eeimg=&1&& ,都对应一个语义向量 &img src=&https://www.zhihu.com/equation?tex=a_%7Bi%7D%5Cin+A& alt=&a_{i}\in A& eeimg=&1&& ,因此我们现在可以忘掉 &img src=&https://www.zhihu.com/equation?tex=Y& alt=&Y& eeimg=&1&& ,直接使用 &img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& 。我们把 &img src=&https://www.zhihu.com/equation?tex=X& alt=&X& eeimg=&1&& (利用深度网络提取的图片特征,比如GoogleNet提取为1024维)称为特征空间(visual feature space),把类别的语义表示 &img src=&https://www.zhihu.com/equation?tex=A& alt=&A& eeimg=&1&& ,称为语义空间。&b&我们要做的,其实就是建立特征空间与语义空间之间的映射&/b&。&/p&&p&对于分类,我们能想到的最简单的形式就是岭回归(ridge regression),俗称均方误差加范数约束,具体形式为:&/p&&p&&img src=&https://www.zhihu.com/equation?tex=min%7C%7CX_%7Btr%7DW+-+A_%7Btr%7D%7C%7C%5E%7B2%7D%2B%5Ceta%5COmega%28W%29& alt=&min||X_{tr}W - A_{tr}||^{2}+\eta\Omega(W)& eeimg=&1&&
(1)&/p&&p&其中, &img src=&https://www.zhihu.com/equation?tex=%5COmega%28%29& alt=&\Omega()& eeimg=&1&& 通常为2范数约束, &img src=&https://www.zhihu.com/equation?tex=%5Ceta& alt=&\eta& eeimg=&1&& 为超参,对 &img src=&https://www.zhihu.com/equation?tex=W& alt=&W& eeimg=&1&& 求导,并让导为0,即可求出 &img src=&https://www.zhihu.com/equation?tex=W& alt=&W& eeimg=&1&& 的值。测试时,利用 &img src=&https://www.zhihu.com/equation?tex=W& alt=&W& eeimg=&1&& 将 &img src=&https://www.zhihu.com/equation?tex=x_%7Bi%7D%5Cin+X_%7Bte%7D& alt=&x_{i}\in X_{te}& eeimg=&1&& 投影到语义空间中,并在该空间中寻找到离它最近的 &img src=&https://www.zhihu.com/equation?tex=a_%7Bi%7D%5Cin+A_%7Bte%7D& alt=&a_{i}\in A_{te}& eeimg=&1&& ,则样本的类别为 &img src=&https://www.zhihu.com/equation?tex=a_%7Bi%7D& alt=&a_{i}& eeimg=&1&& 所对应的标签 &img src=&https://www.zhihu.com/equation?tex=y_%7Bi%7D%5Cin+Y_%7Btr%7D& alt=&y_{i}\in Y_{tr}& eeimg=&1&& 。&/p&&p&简单写一个matlab实现。&/p&&div class=&highlight&&&pre&&code class=&language-matlab&&&span&&/span&&span class=&n&&regression_lambda&/span& &span class=&p&&=&/span& &span class=&mf&&1.0&/span&&span class=&p&&;&/span&
&span class=&n&&W&/span& &span class=&p&&=&/span& &span class=&n&&ridge_regression&/span&&span class=&p&&(&/span&&span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&train_set&/span&&span class=&p&&,&/span& &span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&train_class_attributes&/span&&span class=&p&&,&/span& &span class=&n&&regression_lambda&/span& &span class=&p&&,&/span& &span class=&mi&&1024&/span&&span class=&p&&);&/span&
&span class=&n&&S_test&/span& &span class=&p&&=&/span& &span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&test_set&/span& &span class=&o&&*&/span& &span class=&n&&W&/span&&span class=&p&&;&/span&
&span class=&p&&[&/span&&span class=&n&&zsl_accuracy&/span&&span class=&p&&]=&/span& &span class=&n&&zsl_el&/span&&span class=&p&&(&/span&&span class=&n&&S_test&/span&&span class=&p&&,&/span& &span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&S_te&/span&&span class=&p&&,&/span& &span class=&n&&param&/span&&span class=&p&&);&/span&
&span class=&n&&fprintf&/span&&span class=&p&&(&/span&&span class=&s&&'AwA ZSL accuracy on test set: %.1f%%\n'&/span&&span class=&p&&,&/span& &span class=&n&&zsl_accuracy&/span&&span class=&o&&*&/span&&span class=&mi&&100&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&我们使用AwA数据集,图片事先利用GoogleNet提取了特征(1024维),在测试集上可以得到59.1%的准确率。&/p&&p&这样一个岭回归之所以有效,是因为训练集类别语义 &img src=&https://www.zhihu.com/equation?tex=A_%7Btr%7D& alt=&A_{tr}& eeimg=&1&& 与测试集类别语义 &img src=&https://www.zhihu.com/equation?tex=A_%7Bte%7D& alt=&A_{te}& eeimg=&1&& 之间存在的密切联系。其实任何ZSL方法有效的基础,都是因为这两者之间具体的联系。&/p&&p&仅仅利用如此naive的方式,得到的结果显然不能满足我们的要求,那么建立更好的模型,则需要进一步了解ZSL问题中,存在着哪些和传统监督分类的差异。&/p&&h2&ZSL中存在的问题&/h2&&p&在此,介绍一些目前ZSL中主要存在的问题,以便让大家了解目前ZS领域有哪些研究点。&/p&&p&&b&领域漂移问题(domain shift problem)&/b&&/p&&p&该问题的正式定义首先由[2]提出。简单来说,就是同一种属性,在不同的类别中,视觉特征的表现可能很大。如图3所示,斑马和猪都有尾巴,因此在它的类别语义表示中,“有尾巴”这一项都是非0值,但是两者尾巴的视觉特征却相差很远。如果斑马是训练集,而猪是测试集,那么利用斑马训练出来的模型,则很难正确地对猪进行分类。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-733de891fa7f28dad776c2_b.jpg& data-size=&normal& data-rawwidth=&451& data-rawheight=&343& class=&origin_image zh-lightbox-thumb& width=&451& data-original=&https://pic3.zhimg.com/v2-733de891fa7f28dad776c2_r.jpg&&&figcaption&图3 domain shift示意图,图中的prototype表示类别在语义空间中的位置[2]&/figcaption&&/figure&&p&&b&枢纽点问题(Hubness problem)&/b&&/p&&p&这其实是高维空间中固有的问题:在高维空间中,某些点会成为大多数点的最近邻点。这听上去有些反直观,细节方面可以参考[3]。由于ZSL在计算最终的正确率时,使用的是K-NN,所以会受到hubness problem的影响,并且[4]中,证明了基于岭回归的方法会加重hubness problem问题。&/p&&p&&b&语义间隔(semantic gap)&/b&&/p&&p&样本的特征往往是视觉特征,比如用深度网络提取到的特征,而语义表示却是非视觉的,这直接反应到数据上其实就是:样本在特征空间中所构成的流型与语义空间中类别构成的流型是不一致的。(如图4所示)&/p&&figure&&img src=&https://pic1.zhimg.com/v2-869ec7e6e0f97ce59123a_b.jpg& data-size=&normal& data-rawwidth=&587& data-rawheight=&295& class=&origin_image zh-lightbox-thumb& width=&587& data-original=&https://pic1.zhimg.com/v2-869ec7e6e0f97ce59123a_r.jpg&&&figcaption&图4 流型不一致示意图[8]&/figcaption&&/figure&&p&这使得直接学习两者之间的映射变得困难。&/p&&p&还有其他的,比如semantic loss[5]问题,样本通过映射坍塌到一点[6]等,由于还不常研究,在此就不再讨论。&/p&&p&在此,我们给出解决上述三个问题的基本方法,从而更加深度地了解这三个问题。&/p&&p&(1)领域漂移&/p&&p&由于样本的特征维度往往比语义的维度大,所以建立从 &img src=&https://www.zhihu.com/equation?tex=X& alt=&X& eeimg=&1&& 到 &img src=&https://www.zhihu.com/equation?tex=S& alt=&S& eeimg=&1&& 的映射往往会丢失信息,为了保留更多的信息,保持更多的丰富性,最流行的做法是将映射到语义空间中的样本,再重建回去,这样学习到的映射就能够得到保留更多的信息。因此,在原来简单岭回归[1]的基础上,可以将目标函数改为:[7]&/p&&p&&img src=&https://www.zhihu.com/equation?tex=min%7C%7CX_%7Btr%7D+-+W%5E%7BT%7DA_%7Btr%7D%7C%7C%5E%7B2%7D%2B%5Clambda+%7C%7CWX_%7Btr%7D+-+A_%7Btr%7D%7C%7C%5E%7B2%7D& alt=&min||X_{tr} - W^{T}A_{tr}||^{2}+\lambda ||WX_{tr} - A_{tr}||^{2}& eeimg=&1&& (2)&/p&&p&从目标函数可以看出,这其实完成的是一个简易的自编码器过程,我们简称这个算法为SAE,利用matlab可以轻松对其实现。&/p&&div class=&highlight&&&pre&&code class=&language-matlab&&&span&&/span&&span class=&n&&lambda1&/span& &span class=&p&&=&/span& &span class=&mi&&800000&/span&&span class=&p&&;&/span&
&span class=&n&&W&/span& &span class=&p&&=&/span& &span class=&n&&SAE&/span&&span class=&p&&(&/span&&span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&train_set&/span&&span class=&o&&'&/span&&span class=&p&&,&/span& &span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&train_class_attributes&/span&&span class=&o&&'&/span&&span class=&p&&,&/span& &span class=&n&&lambda1&/span&&span class=&p&&);&/span&
&span class=&n&&S_test&/span& &span class=&p&&=&/span& &span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&test_set&/span& &span class=&o&&*&/span& &span class=&n&&NormalizeFea&/span&&span class=&p&&(&/span&&span class=&n&&W&/span&&span class=&o&&'&/span&&span class=&p&&);&/span&
&span class=&p&&[&/span&&span class=&n&&zsl_accuracy&/span&&span class=&p&&]=&/span& &span class=&n&&zsl_el&/span&&span class=&p&&(&/span&&span class=&n&&S_test&/span&&span class=&p&&,&/span& &span class=&n&&param&/span&&span class=&p&&.&/span&&span class=&n&&S_te&/span&&span class=&p&&,&/span& &span class=&n&&param&/span&&span class=&p&&);&/span&
&span class=&n&&fprintf&/span&&span class=&p&&(&/span&&span class=&s&&'AwA ZSL accuracy on test set: %.1f%%\n'&/span&&span class=&p&&,&/span& &span class=&n&&zsl_accuracy&/span&&span class=&o&&*&/span&&span class=&mi&&100&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&依然是在AwA上进行测试,可以得到83.2%的准确率,比简单的岭回归(1)提高了24.1%。自编码器的这个结构目前在ZSL方法中非常流行,稍后我们还会提到。&/p&&p&(2)枢纽点问题&/p&&p&目前对于枢纽点问题的解决主要有两种方法:&/p&&p&a. 如果模型建立的方式为岭回归,那么可以建立从语义空间到特征空间的映射,从而不加深hubness problem对结果的影响[4],也就是说将目标函数(1)改为:&/p&&p&&img src=&https://www.zhihu.com/equation?tex=min%7C%7CX_%7Btr%7D+-+A_%7Btr%7DW%7C%7C%5E%7B2%7D%2B%5Ceta%5COmega%28W%29& alt=&min||X_{tr} - A_{tr}W||^{2}+\eta\Omega(W)& eeimg=&1&& (3)&/p&&p&在AwA数据集上,这种简单的改变能够得到76.5%的正确率,比原本提高了17.4%。&/p&&p&b.可以使用生成模型,比如自编码器、GAN等,生成测试集的样本,这样就变成了一个传统的监督分类问题,不存在K-NN的操作,所以不存在hubness problem的影响。&/p&&p&(3)语义间隔问题&/p&&p&语义间隔问题的本质是二者的流形结构不一致,因此,解决此问题的着手点就在于将两者的流形调整到一致,再学习两者之间的映射[8]。最简单的方法自然是将类别的语义表示调整到样本的流型上,即用类别语义表示的K近邻样本点,重新表示类别语义即可。&/p&&h2&有关ZSL的一些其他的概念&/h2&&p&这里将提到一些ZSL涉及到的其他概念。&/p&&p&(1)直推式学习(Transductive setting)&/p&&p&这里的直推式学习其实是指在训练模型的时候,我们可以拿到测试集的数据,只是不能拿到测试集的样本的标签,因此我们可以利用测试集数据,得到一些测试集类别的先验知识。这种设置在迁移学习中很常见。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-7a2f3465bcf020ccb2f43_b.jpg& data-size=&normal& data-rawwidth=&600& data-rawheight=&424& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic4.zhimg.com/v2-7a2f3465bcf020ccb2f43_r.jpg&&&figcaption&图5 非直推式(inductive)和直推式学习的区别[16]&/figcaption&&/figure&&p&(2)泛化的ZSL(generalized ZSL)&/p&&p&上文中提到的ZSL,在测试时使用K-NN进行正确率的评估时,只在测试类别中找最近邻的类别,但是在现实的问题中,拿到的样本也可能属于训练集类别,因此在测试时,同时加入训练集类别。[9]现在的很多方法都开始测试模型在这种设置下的能力。&/p&&h2&推荐阅读的论文&/h2&&p&我一直不想写ZSL的发展史,因为据我的经验,写了一大段发展史之后,往往大家的兴致不高,而且看完之后一般都不会有什么特别的感觉,基本也记不得什么东西。所以倒不如给大家推荐一些论文,从最早的到目前最新的,使得大家在短时间内能对ZSL的发展有一个大概的概念。&/p&&p&(1)Learning To Detect Unseen Object Classes by Between-Class Attribute Transfer[1]&/p&&p&ZSL问题的开创性文章,当然是必读的喽,而且可以顺便看看别人是如何阐述一个新问题(挖坑)的。&/p&&p&(2)An embarrassingly simple approach to zero-shot learning[10]&/p&&p&有着很强的理论基础,算法简单、有效,虽然已经过去很多年了,但还是目前新工作需要进行对比的方法之一。&/p&&p&(3)Transductive Multi-View Zero-Shot Learning[2]&/p&&p&第一次定义了domain shift问题。&/p&&p&(4)Zero-shot recognition using dual visualsemantic mapping paths[11]&/p&&p&解决semantic gap问题的简单做法。&/p&&p&(5)Predicting visual exemplars of unseen classes for zero-shot learning[12]&/p&&p&从本质的角度出发,将ZSL问题,看作聚类问题,用最简单的方法直接建立映射。&/p&&p&(6)Semantic Autoencoder for Zero-Shot Learning[7]&/p&&p&引入自编码器结构的第一篇文章,直接导致现在出现的新方法大都具有这种结构。&/p&&p&(7)Zero-Shot Learning - A Comprehensive Evaluation of the Good, the Bad and the Ugly[14]&/p&&p&综述性的文章,总结了17年底以前的方法,提出了新的评价标准,对当时领域发展比较混乱的地方做出了一些更标准的评估。&/p&&p&(8)Zero-Shot Learning via Class-Conditioned Deep Generative Models[6]&/p&&p&将[7]改造为深度模型,并加上一些其他的约束。&/p&&p&(9)Preserving Semantic Relations for Zero-Shot Learning[13]&/p&&p&在自编码器结构的基础上,显示地加入语义类别之间的关系约束。&/p&&p&(10)Recent Advances in Zero-shot Recognition[15]&/p&&p&综述性的文章,读起来很顺畅,可以看看别人是怎么写综述,中顶刊的。&/p&&p&以上几篇文章,是我认为较有代表性,比较值得读的工作。&/p&&h2&代码&/h2&&p&有很多工作,作者都是提供代码的,我自己也实现了一些工作,如果有时间我会将其整理在一起,方便大家使用。&/p&&h2&我自己的看法&/h2&&p&我当初做这个课题,纯粹是因为项目的需要,再加上当时并没有想清楚自己要做什么,所以就做着试试了。目前这个领域属于很好发论文的阶段,而且并不需要十分深刻的理解,就能发不错等级的文章,比较容易能够看到它的发展趋势及下一步大家扎堆的地方,很多时候是在拼速度,而不是拼想法。但好发论文,并不代表它发展迅速,在我看来,真正有贡献的工作少之又少,且其对本质的研究发展缓慢。并且,该问题离实际应用还太远,很可能并不属于这个时代。基于这些原因,之前有一段时间很不想再继续这个课题。。。&/p&&h2&总结&/h2&&p&稍微总结一下,其实我也不知道要总结什么,只是习惯了每篇文章最后都要写个总结。花了大概一天的时间,写了这篇ZSL入门文章。写它一方面是因为希望能够有一篇ZSL的入门性质的读物,为大家提供便利;另一方面就是近期科研不顺,总是怀疑自己不是读书的料,写写文章让自己心情好些。希望大家阅读之后,能够得到一定的帮助吧!&/p&&h2&其他&/h2&&p&文章仓促之下写的,没有经过什么构思,就是想到哪,写到哪。后面我应该还会修改,添加一些其他的内容,如果大家有什么问题,欢迎评论或者私信。&/p&&p&祝大家科研顺利!为人类理解这个世界做一点点贡献!&/p&&h2&参考文献&/h2&&p&[1]Learning To Detect Unseen Object Classes by Between-Class Attribute Transfer&/p&&p&[2]Transductive Multi-View Zero-Shot Learning.&/p&&p&[3]Hubness and Pollution: Delving into Class-Space Mapping for Zero-Shot Learning.&/p&&p&[4]Ridge Regression, Hubness, and Zero-Shot Learning.&/p&&p&[5]Zero-Shot Visual Recognition using Semantics-Preserving Adversarial Embedding Network.&/p&&p&[6]Zero-Shot Learning via Class-Conditioned Deep Generative Models.&/p&&p&[7]Semantic Autoencoder for Zero-Shot Learning.&/p&&p&[8]Zero-Shot Recognition using Dual Visual-Semantic Mapping Paths.&/p&&p&[9]An Empirical Study and Analysis of Generalized Zero-Shot Learning for Object Recognition in the Wild.&/p&&p&[10]An embarrassingly simple approach to zero-shot learning&/p&&p&[11]Zero-shot recognition using dual visualsemantic mapping paths&/p&&p&[12]Predicting visual exemplars of unseen classes for zero-shot learning&/p&&p&[13]Preserving Semantic Relations for Zero-Shot Learning&/p&&p&[14]Zero-Shot Learning - A Comprehensive Evaluation of the Good, the Bad and the Ugly&/p&&p&[15]Recent Advances in Zero-shot Recognition&/p&&p&[16]&a href=&https://link.zhihu.com/?target=http%3A//people.duke.edu/%7Eww107/material/ZSL.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&people.duke.edu/~ww107/&/span&&span class=&invisible&&material/ZSL.pdf&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&[17]Attribute-Based Synthetic Network (ABS-Net): Learning More From Pseudo Feature Representation&/p&
很久没有更文章了,主要是没有找到zero-shot learning(ZSL)方面我特别想要分享的文章,且中间有一段时间在考虑要不要继续做这个题目,再加上我懒 (¬_¬),所以一直拖到了现在。最近科研没什么进展,就想着写一个ZSL的入门性的文章,目的是为了帮助完全没有…
&figure&&img src=&https://pic3.zhimg.com/v2-794d6d75f8f662ba4aa6ff_b.jpg& data-rawwidth=&1280& data-rawheight=&853& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic3.zhimg.com/v2-794d6d75f8f662ba4aa6ff_r.jpg&&&/figure&&p&机器学习(machine learning)是一个正在快速发展的学科领域,新的概念层出不穷。突发奇想,我想稍微总结一下我听过的以 “xxx learning” 为命名形式的概念,并尽量简短的加以解释、说明。对我自己,算是一种知识的简单梳理。希望对于不太熟悉机器学习的人,这也能是一个快速的科普。&/p&&hr&&h2&&b&1. Machine learning&/b&&/h2&&p&机器学习(machine learning)是指计算机科学人工智能分类下的一门学科领域。它关注的是如何构建和改善算法使得计算机能够自动的从数据中习得经验,并完成一些特定的任务。这些任务包括:分类、聚类、回归、降维、推荐、密度估计等等。&/p&&p&&br&&/p&&h2&&b&2. lifelong machine learning、lifelong learning&/b&&/h2&&p&终身机器学习(lifelong machine learning or lifelong learning)是机器学习里的一个研究主题。它关注的是构建一套算法或者系统,使之能持续不断的学习,并能从过去的学习任务中积累经验和知识,来帮助解决新任务。&/p&&p&&br&&/p&&h2&&b&3. Deep learning&/b&&/h2&&p&深度学习(deep learning)是指一类使用包含多个处理层(layer)的复杂模型对数据进行高层抽象的算法,每一层通常都包含一些非线性变换的处理单元,模型前一层的输出是后一层的输入,不同的处理层代表了不同的抽象层次。现在说的深度学习最主要的模型结构就是深度神经网络。&/p&&p&&br&&/p&&h2&&b&4. Supervised learning、unsupervised learning 、semi-supervised learning&/b&&/h2&&p&监督学习(supervised learning)、无监督学习(unsupervised learning)和 半监督学习(semi-supervised learning)是机器学习方法的主要分类,依据主要是看算法有无利用训练数据中的标签信息。&/p&&p&监督学习(supervised learning)类算法要求训练数据中明确包含所要预测的标签信息,比如分类问题的类别标签信息,并利用这些标签信息来训练生成模型。&/p&&p&无监督学习(unsupervised learning)类算法的训练数据中不包含任何标签信息,只包含无标签信息的训练数据。&/p&&p&半监督学习(semi-supervised learning)类算法的训练数据中既有包含标签信息的数据,也有不包含标签信息的无标签数据,即这类算法只利用了部分标签信息。&/p&&p&&br&&/p&&h2&&b&5. Transfer learning&/b&&/h2&&p&迁移学习(transfer learning)的目标是从源任务(source tasks)学习提炼一些知识然后应用在跟源任务相似但是不同的目标任务(target task)上,帮助目标任务完成的更好。&/p&&p&迁移学习的概念跟先前提到的终身机器学习的概念非常相似,区别是终身机器学习还想强调(1)持续不断的学习;(2)“知识”的提炼、存储和共享。&/p&&p&&br&&/p&&h2&&b&6. Meta learning&/b&&/h2&&p&元学习(meta learning)的另一个更简单直观的说法叫让机器 “学会学习(learning to learn)”,目标是让机器可以从过往的任务中学习出某些知识、模式、或者算法的性质,可以灵活快速的指导新任务的学习,类似像人一样学会根据历史经验“举一反三”。&/p&&p&先前介绍的迁移学习可以作为 meta learning 中实施的具体方法。&/p&&p&&br&&/p&&h2&&b&7. Reinforcement learning、deep reinforcement learning&/b&&/h2&&p&强化学习(reinforcement learning)的目标是让机器(agent)在特定的环境下,感知自己所处的状态,并根据当前状态做出行动,每个行动会获得一些奖励,通过跟环境的不断交互最终找到使得长期累积奖励最大化的策略。&/p&&p&深度强化学习(deep reinforcement learning)是指应用了深度学习技术的强化学习。&/p&&p&&br&&/p&&h2&&b&8. PU learning&/b&&/h2&&p&正样本和无标签样本学习(PU learning)是指从只有正样本和无标签样本的训练数据中学习得到一个二分类模型,这里的无标签样本可能是正样本,也可能是负样本。PU learning 属于半监督学习中的一类算法。&/p&&p&&br&&/p&&h2&&b&9. One-shot learning、few-shot learning、zero-shot learning&/b&&/h2&&p&单样本学习、少样本学习或者零样本学习(one-shot learning、few-shot learning、zero-shot learning)是指每个要预测的类别只有一个、少数几个、或者甚至没有训练样本,它们都是迁移学习的极端特例。一般的,这三类学习先有一个在大量源数据上学习得到的一个模型,在迁移学习阶段,利用少量训练样本对模型进行更新,快速的适应新的任务。&/p&&p&&br&&/p&&h2&&b&10. Online learning&/b&&/h2&&p&在线学习(online learning)是指新的数据不断的过来情况下,原有的模型只需要利用新数据实时修正、优化,不需要抛弃老模型之后再重新训练。&/p&&p&相对应的,传统的模型训练是在所有离线训练数据上训练一个模型,如果有新的数据来的话,需要将新数据和老数据合到一起,然后重新训练模型。&/p&&p&&br&&/p&&h2&&b&11. Ensemble Learning&/b&&/h2&&p&集成学习(ensemble learning)指的是用某种策略或者方法将多个弱模型(比如,弱分类器)综合起来,输出一个最终的结果,提高整体模型的泛化能力。常见的集成学习的方法包括 bagging、boosting 和 stacking。&/p&&p&&br&&/p&&h2&&b&12. Representation learning、feature learning&/b&&/h2&&p&表征学习(representation learning、feature learning)是指自动的从原始数据中学习、提炼数据特征的一类技术或者方法。比如,深度学习就是表征学习的一种方法,深度神经网络中间隐层的输出结果就是原始数据的抽象特征。再比如,PCA 可以将高维数据映射到低维空间,也可以作为表征学习的一种方法。&/p&&p&&br&&/p&&h2&&b&13. Active learning&/b&&/h2&&p&主动学习(active learning)属于半监督学习(semi-supervised learning)中的一类算法,适用于训练样本中标签信息比较少的情况。这类算法先使用有标记的样本数据训练出一个分类器,并对未标记的训练样本进行预测,从中挑选出最不确定的样本来咨询用户并进行打标,最后使用扩充后的训练集重新训练分类器,从而提高模型性能,整个过程是重复迭代式进行的。&/p&&p&&br&&/p&&h2&&b&14. Multi-task learning&/b&&/h2&&p&多任务学习(multi-task learning)是指将多个相关的任务放在一起训练,通过不同任务之间的特征或者参数等信息共享来提升模型的性能,让多个任务彼此受益。&/p&&p&&br&&/p&&h2&&b&15. Dual learning&/b&&/h2&&p&对偶学习(dual learning)是一种比较有意思的模型训练方式。在对偶学习中存在互为对偶的两个任务:原任务和对偶任务。这样的对偶任务例子包括:机器翻译中的中译英和英译中,语音处理中的语音合成和语音识别,问答系统中的回答问题和生成问题。互为对偶的任务,可以在训练过程中互相提供反馈,共同提高,从而降低对于标签数据的依赖。&/p&&p&&br&&/p&&h2&&b&16. Adversarial machine learning&/b&&/h2&&p&对抗机器学习(adversarial machine learning)研究的是如果存在一个对安全系统进行恶意攻击的对手,通过污染训练数据等方式对安全系统中的机器学习模型进行攻击的情况下,如何设计更有效、更稳健的算法来抵御类似攻击。&/p&&hr&&p&上面的介绍是暂时我能想到的以“xxx learning”的形式命名的概念,未能覆盖全部,后续还会不定期的补充、更新。同时,一些概念的介绍也相对简单,如果有偏差或者错误,欢迎提醒纠正。&/p&&p&&/p&
机器学习(machine learning)是一个正在快速发展的学科领域,新的概念层出不穷。突发奇想,我想稍微总结一下我听过的以 “xxx learning” 为命名形式的概念,并尽量简短的加以解释、说明。对我自己,算是一种知识的简单梳理。希望对于不太熟悉机器学习的人…
&figure&&img src=&https://pic1.zhimg.com/v2-a721e9efb75_b.jpg& data-rawwidth=&908& data-rawheight=&383& class=&origin_image zh-lightbox-thumb& width=&908& data-original=&https://pic1.zhimg.com/v2-a721e9efb75_r.jpg&&&/figure&&p&接上文&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&说一说最近很火的离线跟踪&/a&&/p&&p&&br&&/p&&p&在SiamFC提出以后,各种改良工作有了爆发式发展的趋势,去年ICCV就有3篇基于SiamFC结构来改进的。&/p&&h2&&b&3.CREST,EAST,DSiam(ICCV2017)&/b&&/h2&&p&这三篇中,CREST(&a href=&https://link.zhihu.com/?target=http%3A//openaccess.thecvf.com/content_ICCV_2017/papers/Song_CREST_Convolutional_Residual_ICCV_2017_paper.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CREST: Convolutional Residual Learning for Visual Tracking&/a&)和DSiam(&a href=&https://link.zhihu.com/?target=http%3A//openaccess.thecvf.com/content_ICCV_2017/papers/Guo_Learning_Dynamic_Siamese_ICCV_2017_paper.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Learning Dynamic Siamese Network for Visual Object Tracking&/a&)是改进SiamFC判别效果的,EAST(&a href=&https://link.zhihu.com/?target=http%3A//openaccess.thecvf.com/content_ICCV_2017/papers/Huang_Learning_Policies_for_ICCV_2017_paper.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Learning Policies for Adaptive Tracking with Deep Feature Cascades&/a&)则主要针对速度提升。&/p&&p&&br&&/p&&p&先来说说CREST,还是上次说到的问题,DCFNet虽然避免了空域卷积,但是很不稳定判别力不够。只用一个DCF Layer直接把score map回归到groundtruth label是很困难的,这时候最简单的想法就是stacking more layers,但是这样做会产生model degradation。所以文章很自然的把Residual Learning的思想借用到了这里。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-d6cebad4d8d3ca9c0ad5a08f2125936f_b.jpg& data-size=&normal& data-rawwidth=&880& data-rawheight=&380& class=&origin_image zh-lightbox-thumb& width=&880& data-original=&https://pic2.zhimg.com/v2-d6cebad4d8d3ca9c0ad5a08f2125936f_r.jpg&&&figcaption&CREST&/figcaption&&/figure&&p&具体是怎么做Residual Learning的呢?看上图CREST的整体框架。左半部分就是SiamFC,主要区别在右半部分。最上面的橙色框,展示的是DCFNet里的DCF过程,输入T帧的feature map,输出Response Map,但是此时的Response Map并不准确。所以CREST就增加了两个可学习的残差:空间残差和时间残差。&/p&&p&空间残差用了三层网络,使用小尺寸的卷积核,输入T帧的feature map,输出Response Map。从原理上看,空间残差可以看做当目标受外部因素(光照,遮挡,复杂背景等)影响造成DCF无法回归到groundtruth时,通过图片空间域的信息估计一个残差,去修正base mapping的结果。&/p&&p&时间残差的输入是起始帧(object appearance)的特征,输出是Response Map。时间残差适用于空间残差+DCF无法回归到groundtruth的情况,当然不可否认这种情况是会存在的。计算T帧的图像完全没用了,那我们只能用起始帧了,所以他编码的是起始帧。为什么叫空间残差可能就是因为取自不同帧吧。&/p&&p&神奇的是,虽然参照了SiamFC,这篇文章用VGG权值做初始化后,其余部分的权值是online update的。&/p&&p&&br&&/p&&p&接下来DSiam,天津大学做的,应该不是有名的组,但是这个工作我很喜欢。首先展示一张图&/p&&figure&&img src=&https://pic2.zhimg.com/v2-df3ff4cf81c3933acd8d29577efcf5a9_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&624& data-rawheight=&718& class=&origin_image zh-lightbox-thumb& width=&624& data-original=&https://pic2.zhimg.com/v2-df3ff4cf81c3933acd8d29577efcf5a9_r.jpg&&&/figure&&p&这张图显示了不同tracker在序列上的IoU变化情况,我们可以很清楚的看到,SiamFC在跟踪跑道上人的时候,经常会跟偏到另外一个跑道上,这个问题对deep tracking很致命,同时也是非常重要的一个问题。原因是我们基于深度特征来跟踪时,其实已经失去了物体的细节表达,所以deep tracking只能区分“人”在哪,无法区分两个人之间的差别,所以一旦目标周围有相似物体出现很容易跟丢。&/p&&p&在这种情况下,用目标的appearance去匹配可能不是最佳的,而是需要在线学习目标的形态变化(一个有意思的细节:CREST和DSiam都用到了在线训练来改善DCF,从这里我们看到其实视频的前后帧先验还是很有用的,一旦抛弃online完全offline,正确率也会大打折扣)。文中定义了两个transformations,V学习起始帧到t-1帧的特征变换&/p&&figure&&img src=&https://pic4.zhimg.com/v2-e6ad14c7ba_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&510& data-rawheight=&63& class=&origin_image zh-lightbox-thumb& width=&510& data-original=&https://pic4.zhimg.com/v2-e6ad14c7ba_r.jpg&&&/figure&&p&这样有一个好处,我们将起始帧变换成t-1帧后,用t-1帧的appearance去预测t帧的位置,会很大程度上减小appearance variation。另外一个transformation W用来抑制无关背景特征&/p&&figure&&img src=&https://pic4.zhimg.com/v2-a6ac6f7afcc93_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&558& data-rawheight=&66& class=&origin_image zh-lightbox-thumb& width=&558& data-original=&https://pic4.zhimg.com/v2-a6ac6f7afcc93_r.jpg&&&/figure&&p&上述 &img src=&https://www.zhihu.com/equation?tex=%5Cbar%7BG%7D_%7Bt-1%7D& alt=&\bar{G}_{t-1}& eeimg=&1&& 就是手工加余弦窗的图,用一张图表示以上过程&/p&&figure&&img src=&https://pic2.zhimg.com/v2-4b413d580f42d9ff3e29_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&582& data-rawheight=&305& class=&origin_image zh-lightbox-thumb& width=&582& data-original=&https://pic2.zhimg.com/v2-4b413d580f42d9ff3e29_r.jpg&&&/figure&&p&求解V和W都是FFT循环卷积假设,到傅里叶域快速求解的,保证了速度。最后输出就是两个经过transform的特征的互相关&/p&&figure&&img src=&https://pic4.zhimg.com/v2-aed107bdc8cb18ff579b2cedc6c42f42_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&581& data-rawheight=&413& class=&origin_image zh-lightbox-thumb& width=&581& data-original=&https://pic4.zhimg.com/v2-aed107bdc8cb18ff579b2cedc6c42f42_r.jpg&&&/figure&&p&&br&&/p&&p&最后一个加速SiamFC的工作EAST,EAST的思想就很简单易懂了,对于简单帧(目标外观没发生很大变化的帧),用底层卷积特征甚至是pixel value就可以精确跟踪,而对于困难帧则需要深度特征,于是文章通过每一层特征对应预测位置的精确程度来判断是否early stop,一旦浅层特征就可以达到很精确,那就不必计算深度的了。这一方法大大减小计算量,提升跟踪速度。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-19f036fdd9aa3fb72aa298d69abf1e88_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1296& data-rawheight=&389& class=&origin_image zh-lightbox-thumb& width=&1296& data-original=&https://pic2.zhimg.com/v2-19f036fdd9aa3fb72aa298d69abf1e88_r.jpg&&&/figure&&p&说说简单,但是训练这么一个决策的Agent还是很复杂的。文中定义了8个action作为决策结果(见如上图右半部分)。从上到下,前两个是Global scaling,用于全局缩放,中间四个Local scaling,用来调整宽和高,最后俩分别是不缩放和停止。&/p&&p&然后把score map和历史action作为当前节点的状态,根据IoU来设计奖惩函数,最后通过Deep Q-learning来训练Agent,这是我见过第一篇用强化学习来enhance跟踪的文章,可谓创意十足,而且这篇文章的Agent是offline训练的。&/p&
接上文 在SiamFC提出以后,各种改良工作有了爆发式发展的趋势,去年ICCV就有3篇基于SiamFC结构来改进的。3.CREST,EAST,DSiam(ICCV2017)这三篇中,CREST()和DSiam(
&figure&&img src=&https://pic3.zhimg.com/v2-37b5ef59e42863ecf2cb_b.jpg& data-rawwidth=&600& data-rawheight=&456& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic3.zhimg.com/v2-37b5ef59e42863ecf2cb_r.jpg&&&/figure&&p&作为现代机器学习基石的深度神经网络,虽然模仿的是生物神经网络,但其实这两者之间有着极大的区别。抛开仅有的一些相似处,有些重要的机器学习机制没有任何自然界的版本,而这两者学习过程之间也有着大量的不同。&/p&&p&&b&这些区别很有可能解释了为什么机器学习系统在某些领域中的表现远逊于自然系统&/b&。就拿昆虫来说,昆虫仅需接触几次新的气味就能学会如何识别这些新气味。而机器则需要海量的数据集才能学会。因此,计算机科学家希望通过加深对自然学习方式的了解来减少这两者之间的距离。&/p&&p&为了进一步找出自然与机器学习之间的差距,华盛顿大学研究科学家Charles Delahunt与他的团队创造出了一款&b&模仿烟草天蛾(学名:Manduca sexta)嗅觉学习系统的结构与行为的人工神经网络&/b&。他们表示,他们的系统可以对自然神经网络的学习方式提供一些重要的见解,为机器学习带来突破。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-37b5ef59e42863ecf2cb_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&600& data-rawheight=&456& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic3.zhimg.com/v2-37b5ef59e42863ecf2cb_r.jpg&&&/figure&&p&与其他动物相比,飞蛾的嗅觉系统比较简单,并已被神经科学家们很好地绘制出来。&b&它是由5个独特的网络组成,由每个网络向下一个网络一层一层的传输信息。&/b&&/p&&p&&b&飞蛾嗅觉系统的首层网络&/b&,是一个由3万多个用于检测气味的化学受体所组成的系统。它会把一套嘈杂的数据传输到下一层:天线叶(antenna lobe)。天线叶含有大约60个叫Glomeruli的单元,每一个单元都会专注于一种气味。&/p&&p&天线叶会把分析过一边的气味数据传输给含有4000个kenyon细胞的蘑菇体(Mushroom Body),把它编成记忆。&/p&&p&作为记忆,这些关于气味的信息最终会被一层仅有两位数的外在神经元读取。它们将把来自蘑菇体的信号转化为行为,比如“向上飞”。&/p&&p&这个系统在多个方面与机器学习网络完全不同。就拿天线叶来说,它会把信息编码到低维参数空间中,把信息传输给蘑菇体;但蘑菇体却会把信息编码到高维参数空间中。相比之下,人工神经网络每层的维度都十分相似。&/p&&p&此外,一旦飞蛾成功的识别一种气味,这将出发一个奖励机制,&b&导致神经元向天线叶与蘑菇体喷射一种叫“章鱼胺”(octopamine)的化学神经递质。&/b&&/p&&p&这种奖励机制在学习过程中起到了至关重要的作用。在飞蛾脑中,章鱼胺可以帮助加强产生成功的神经线路。&b&这也是赫布学习(Hebbian learning)中最重要的理论之一&/b&,即“一起激发的神经元也会连在一起”(Cells that fire together, wire together)。确实,神经科学家早就知道去掉章鱼胺的飞蛾是无法学习的。我们只是不知道章鱼胺的具体工作方式。&/p&&p&而机器的学习方式则十分不同。它依赖的是一种叫“反向传播”(backpropagation)的过程,通过调整每个神经元之间的连接来提高结果。但是在这个过程中,信息是在神经网络中进行反向流动的,而它在自然中也没有任何相似的存在。&/p&&p&为了更好地了解飞蛾学习的方式,Delahunt的团队创造出了一款模仿自然神经网络的工作方式的人工神经网络。“我们创造出来一款端到端的计算模型来模仿烟草天蛾的嗅觉系统,包括天线叶与蘑菇体在章鱼胺刺激之下的互动行为”,他们说道。&/p&&p&&b&这款模型的设计理念就是在每一层百分百重现自然系统的一切行为&/b&。比如由气味受体所产生的嘈杂信号,以及数据从天线叶传输到蘑菇体时所产生的维度变化。它甚至还包含了一个模仿章鱼胺作用的机制。&/p&&p&最终的结果十分有意思,这款模型显示,气味受体所产生的嘈杂信号会受到天线叶的前置放大。但是,这些信号在传输到蘑菇体时所经历的维度变化可以有效的排除一切噪声。因此,这些干净的信号可以让该系统输出“向上飞”这种明确的指令。&/p&&p&而章鱼胺所起到的作用也更明确了。这款模仿系统显示,在没有章鱼胺的情况下其实也可以实现学习,&b&但由于它的速度极慢,相当于不存在&/b&。这意味着章鱼胺是一种强效学习加速剂。&/p&&p&但是章鱼胺具体是如何实现加速功能的呢?Delahunt与团队认为“这可能是一种让飞蛾绕开新增突触在赫布生长时固有的有机约束的方式,否则这种约束可能将飞蛾学习的速度限制在一个难以接受的速度。”&/p&&p&此外,章鱼胺还有另外一个作用。赫布学习只能加强现有的神经连接,因此无法解释新的神经线路是如何产生的。Delahunt表示章鱼胺还可以打开新的传输通道来形成连接:“这会扩展系统学习时能够探索的解空间”。&/p&&p&总体来说,&b&这款模仿自然神经网络的人工神经网络系统完美的实现了它的设计目标&/b&,以一个自然的方式学会了分别气味。“我们的模型可以学习新的气味,通过模仿出来的整合-激发神经元也与飞蛾体内激发率的统计特征一致”,Delahunt说道。&/p&&p&广泛来说,此项研究成果可能给人工神经网络领域带来极大的影响。“从一个机器学习角度来看,该模型提供了一个由自然启发的机制,并将十分利于建设需要用极少样本实现迅速学习的神经网络”,该团队总结道。&/p&&p&所以,未来的机器学习网络很可能将会包含章鱼胺等神经递质的仿品。&/p&&p&当然,神经递质并不只在学习时有着重要的地位。神经科学家们十分了解它们在情绪与情绪调节等机制中的地位。而这,则可能成为机器学习研究者的下一个研究方向了。&/p&
作为现代机器学习基石的深度神经网络,虽然模仿的是生物神经网络,但其实这两者之间有着极大的区别。抛开仅有的一些相似处,有些重要的机器学习机制没有任何自然界的版本,而这两者学习过程之间也有着大量的不同。这些区别很有可能解释了为什么机器学习系统…
&figure&&img src=&https://pic3.zhimg.com/v2-8d34ac07d837fe07a462f1_b.jpg& data-rawwidth=&2804& data-rawheight=&1022& class=&origin_image zh-lightbox-thumb& width=&2804& data-original=&https://pic3.zhimg.com/v2-8d34ac07d837fe07a462f1_r.jpg&&&/figure&&p&因为本人现在待业在家玩耍,手上只有一台可怜的笔记本可以用来训练,所以这篇文章的更新会比较慢了,因为研究这些network有一些还只是一些想法,还没来得及验证(当然以目前的设备来说要验证也只能用MNIST和CIFAR-10)。不过既然是挖坑系列,所以也就不在意这么多了。&/p&&p&&br&&/p&&p&上次讲了一些关于人脸识别里面数据分布一些东西,这次想来探讨一下network,network是非常非常神奇的东西,虽然现在都说deep learning是data-driven的,但是毫无疑问,即使是有了像ImageNet这样庞大的数据集,每年能够取得top的都是一些新的network design,可见network在推动深度学习上起了多大的作用。&/p&&p&&br&&/p&&p&按照惯例,本文首先提出3个问题:&/p&&p&&b&1.Convolution的运作机制到底是什么样的?为什么会有后来的group&/b&&/p&&p&&b&convolution,depthwise convolution,shuffle?&/b&&/p&&p&&b&2.ResNet和Inception到底有没有区别?为什么ResNet的前后两个版本会不一样?&/b&&/p&&p&&b&3.为什么人脸识别没有专门的网络设计?人脸识别的最优网络应该是什么样的?&/b&&/p&&p&&br&&/p&&p&识别领域入门半年小白,望抛砖引玉。&/p&&hr&&h2&一.Convolution&/h2&&p&1.Convolution Layer&/p&&p&卷积大家肯定不陌生,卷积神经网络大家肯定也不陌生,就连二维卷积是怎么进行的,相信大家也有研究过,就是下面这样的:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-15fea61b768f7561648dbea164fcb75f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&543& data-rawheight=&544& data-thumbnail=&https://pic4.zhimg.com/v2-15fea61b768f7561648dbea164fcb75f_b.jpg& class=&origin_image zh-lightbox-thumb& width=&543& data-original=&https://pic4.zhimg.com/v2-15fea61b768f7561648dbea164fcb75f_r.jpg&&&/figure&&p&对于一个channel(左图),我们用一个filter(中间)去对这个channel进行卷积,就可以得到一个output(右边)。&/p&&p&一般来说,网上能够找到的教程一般都只会告诉我们上面那张图的过程即使卷积(convolution),没错,上面的那张图确确实实是convolution的过程,但不过却不是convolution layer的完整过程。&/p&&p&我们知道,一个convolution layer的输入是(NCHW),输出是(NKHW),也就是说,有C个channel,有K*C个filter,如果不考虑N,H,W。那么就变成了C个输入,K个输出,K*C个filter。&/p&&p&显然,按照上面的那种卷积方法,每个filter对应一个输出,那么会有K*C个输出,而之所以只有K个输出,就是做了所谓的一个channel merge操作,如下图:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-74bda42e4b439ac6a1c6c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1080& data-rawheight=&1440& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic4.zhimg.com/v2-74bda42e4b439ac6a1c6c_r.jpg&&&/figure&&p&这个,才是一个convolution layer所做的工作。&/p&&p&2.convolution中的参数冗余&/p&&p&当我们想用VGG网络go deeper的时候,会发现后面的channel数越来越多,相应的filter也越来越多,有时甚至可以达到个 3x3 的filter。&/p&&p&但是这样的话参数量和计算量都有了大幅度的增长,但是效果的提升却不大,人们开始思考这样的卷积是否是存在参数冗余的。&/p&&p&(1)Group Convolution&/p&&p&现在我每一个channel都需要输出k个output,那能不能不要输出这么多个output,我们输出k/m个怎么样?Group Convolution就抱着这样的目的。&/p&&p&Group Convolution过程如下所示,请自行比较与original convolution之间的区别。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-3e0fbea80eebae387ed644f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1080& data-rawheight=&1440& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic2.zhimg.com/v2-3e0fbea80eebae387ed644f_r.jpg&&&/figure&&p&我们在这里提出一个问题:如果最后的concat换成element wise会怎么样?我这里不做解答,但是理解concat确实是理解group convolution的关键。&/p&&p&&br&&/p&&p&(2)shuffleNet&/p&&p&Group Convolution虽然了将output变成了k/m,但是,却加入了group的限制。怎么说呢,可以从上面的图看到,group1 和 group2 之间是完全没有交流的,这与我们的初衷不一样,在我们最开始的设想中是不会出现group的。&/p&&p&Face++针对这一点提出了一个shuffleNet,意在加强各个group之间的交流,shuffleNet的基本结构如下:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-404ebbf5f1ffa1f6a32bdd_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1571& data-rawheight=&587& class=&origin_image zh-lightbox-thumb& width=&1571& data-original=&https://pic2.zhimg.com/v2-404ebbf5f1ffa1f6a32bdd_r.jpg&&&/figure&&p&可以看到,其操作就是在进行第二个group conv之前,将channel shuffle了一下。&/p&&p&&br&&/p&&p&我这里说得这么平淡无奇,真的不是我在diss Face++,只是,看了下面的几种方法,真的只能让人感叹国内外研究水平上的差距。&/p&&p&&br&&/p&&p&(3)Bottleneck&/p&&p&除了group之外,还有没有别的操作能够减少计算量,比如我们把CxK变成Cxm+mxm+mxK之类的?&/p&&p&Google研究者设计了Bottleneck结构,如下所示:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-f410d9c448d14e3e6c3dc5_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&600& data-rawheight=&514& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic2.zhimg.com/v2-f410d9c448d14e3e6c3dc5_r.jpg&&&/figure&&p&这样的意图也特别好理解,就是觉得256x256x3x3太多余了嘛,实际上我们只需要64x64x3x3就行了。
&/p&

我要回帖

 

随机推荐