• 原文地址:optimizing-gradient-descent。如果熟悉英文的话,强烈推荐阅读原文,毕竟翻译过程中因为个人理解有限,可能会有谬误,还望读者能不吝指出。另外,由于原文太长,分了两部分翻译,上篇主要是梯度下降优化算法的总结,本篇将会是随机梯度的并行和分布式,以及优化策略的总结。

    SGD 的并行和分布式

    由于大规模数据解决方案和低档集群的存在,使用分布式 SGD 进行进一步加速是明显的选择。

    SGD 本身属性是串行的:一步一步地,我们逐渐靠近最小值。运行它可以提供较好的收敛结果,但在大数据集上会非常慢。相反,异步运行 SGD 更快,但各个 worker 间的非优交互会导致收敛结果变差。而且,我们也可以在一台机器上,而无需大量的计算集群来并行化 SGD。接下来的部分就是已经提出来的优化并行和分布式 SGD 的算法和架构。

    Hogwild!

    Niu et al. [23] 引入了一个叫做 Hogwild! 的更新策略,可以使 SGD 可以在多 CPU 上并行更新。处理器在无需对参数加锁的情况下就可以访问共享内存。但仅在输入的是稀疏数据时才有效,因为每次更新仅修改所有参数的一小部分。他们展示了在这种情况下,更新策略几乎可以达到一个最优的收敛率,因为处理器不太可能覆盖掉有用的信息。

    - 阅读剩余部分 -

  • 原文地址:optimizing-gradient-descent。如果熟悉英文的话,强烈推荐阅读原文,毕竟翻译过程中因为个人理解有限,可能会有谬误,还望读者能不吝指出。另外,由于原文太长,分了两部分翻译,本篇主要是梯度下降优化算法的总结,下篇将会是随机梯度的并行和分布式,以及优化策略的总结。

    梯度下降是优化中最流行的算法之一,也是目前用于优化神经网络最常用到的方法。同时,每个优秀的深度学习库都包含了优化梯度下降的多种算法的实现(比如,lasagnecaffekeras 的文档)。然而,这些算法一般被封装成优化器,如黑盒一般,因此很难得到它们实际能力和缺点的解释。

    本篇博客的目标是为读者提供不同梯度下降优化算法的直观解释,希望读者可以学以致用。我们会先了解下梯度下降的不同变种。然后会对训练过程的问题进行简单总结。接着,我们会介绍最常用的优化算法,展示它们解决这些问题的动机,以及它们对应更新规则变化的原因。我们也就会简单回顾在并行和分布式的情况下,梯度下降优化的算法和架构。最后,我们也会聊聊有助于优化梯度下降的其他策略。

    梯度下降是最小化以模型参数 $\theta \in \mathbb{R}^d$ 构建的目标函数 $J(\theta)$ 的一种方法,它通过按目标函数 $\nabla_\theta J(\theta)$ 在参数梯度的相反方向更新参数。学习率 $\eta$ 决定了我们到达(局部)最小所需的步数的大小。换成通俗的话说,我们会沿着目标函数所构建的表面坡度的方向往下走,直到我们到达一个谷底。如果你还不熟悉梯度下降,你可以参考这篇优化神经网络的入门介绍

    - 阅读剩余部分 -

  • 背景

    最近我们组里有个服务接口,特点是读写量比较大,同时每次写入的内容一分钟后会过期,同时还要统计热门的频度。现在新增的需求是,查询返回的结果要按过期时间排序,这对我们已有的服务是个小小的挑战:因为读写更新逻辑都已经写死到业务逻辑中!

    这个服务的情况是:每个用户都有一个唯一的 userid,并会频繁请求服务端的文件,每次的 userid 请求,服务端会记录 userid 并设置一个过期时间,同时统计被请求文件的频次做热门统计。还有就是需要提供一个主动删除 userid 的接口。

    解藕

    因为刚接手这个服务,乍一看有过期时间,数据可以 KV 存储,貌似用 redis 非常合适,而且 redis 中也支持 top N 这种频次统计,唯一的问题在于如何获取按过期时间排序的结果。经过查阅资料,可以用sort by命令,依据未过期的数据进行排序,具体思路如下:

    LPUSH list userid        # 将 userid 放入列表中
    SET expired_userid 60    # 将 userid 加前缀 `expired_` 作为 key,设置其过期时间为 60s
    
    SORT list BY expired_* DESC  # 安装未过期的 userid 作为标准对 list 进行排序
    

    - 阅读剩余部分 -

  • 最近将上传接口从php+apache重构成nginx+lua,因为是多人协作的项目,在完成后进行测试时,总会出现上传时无法读取图片数据的问题。于是昨天晚上,我花了一些时间研究了一下,发现是ngx.req.socketngx.req.get_body_data混用导致。下面简单记录发现和解决这个问题的过程。

    背景简介

    图片上传时,除了图片数据,还需要一些参数,比如验证参数、图片处理参数等。而这些参数可以以两种方式传递到我们服务端:

    • application/x-www-form-urlencoded: 一般只POST比较短的参数
    • multipart/form-data: 一般用于POST比较大的二进制数据

    因此,我们需要解析这两种上传的方式,而坑就埋在了此处。

    问题初探

    这个问题的发现和定位还是很简单的。部署完测试环境进行测试时,发现测试没成功,返回的错误信息显示上传数据失败。因此,问题已经在解析参数和上传数据的那个库args.lua中。

    args.lua中,有三个函数: - 读取并解析完整请求参数; - 获取上传所需要的参数,用于验证和处理图片; - 获取上传的图片数据。

    - 阅读剩余部分 -

  • 如今视频直播非常火热,就需要对视频格式的知识做些储备,FLV(即Flash Video)这一视频格式是最简单的,通过对它的文件格式的研究,可以对这些应用于网络传输的视频格式,也即流媒体有一些基本的了解。

    FLV

    流媒体简介

    流式媒体是按照时间顺序依次下载播放的媒体形式,依托于Flash这一强大播放器插件,可以实现边下载边播放,比如在优酷等视频平台观看节目时,并不需要把视频完整下载下来就可以播放,而这些视频网站都有Flash插件的支持;与之对应的是BT下载的视频,很难做到_顺序下载_,另外还要看播放器是否支持解码部分视频,来达到边下载边播放的目的,你可以尝试播放一个没有下载完的视频,拖动进度条是可以找到能看的片段,但很少能从视频开头开始。

    从上面可以看出,流媒体传输最重要的特性是要按时间顺序传输。打个比方,如果流媒体是一列火车,火车进站就必须严格按照“火车头-第一节车厢-第二节车厢…”的方式进站,乱了顺序可不行 :P

    - 阅读剩余部分 -