关于ADMM的研究(二)

时间:2022-12-17 23:19:49

关于ADMM的研究(二)

4. Consensus and Sharing

本节讲述的两个优化问题,是非常常见的优化问题,也非常重要,我认为是ADMM算法通往并行和分布式计算的一个途径:consensus和sharing,即一致性优化问题与共享优化问题。

Consensus

4.1 全局变量一致性优化(Global variable consensus optimization)(切割数据,参数(变量)维数相同)

所谓全局变量一致性优化问题,即目标函数根据数据分解成N子目标函数(子系统),每个子系统和子数据都可以获得一个参数解xi,但是全局解只有一个z,于是就可以写成如下优化命题:

mins.t.∑i=1Nfi(xi),xi∈Rnxi−z=0

注意,此时fi:Rn→R⋃+∞仍是凸函数,而xi并不是对参数空间进行划分,这里是对数据而言,所以xi维度一样xi,z∈Rn,与之前的问题并不太一样。这种问题其实就是所谓的并行化处理,或分布式处理,希望从多个分块的数据集中获取相同的全局参数解。

在ADMM算法框架下(先返回最初从扩增lagrangian导出的ADMM),这种问题解法相当明确:

Lρ(x1,…,xN,z,y)=∑i=1N(fi(xi)+yTi(xi−z)+(ρ/2)∥xi−z∥22)s.t.C={(x1,…,xN)|x1=…=xN}
⟹xk+1izk+1yk+1i=argminx(fi(xi)+(yki)T(xi−zk)+(ρ/2)∥xi−z∥22))=1N∑i=1N(xk+1i+(1ρyki))=yki+ρ(xk+1i−zk+1)

对y-update和z-update的yk+1i和zk+1i分别求个平均,易得y¯k+1=0,于是可以知道z-update步其实可以简化为zk+1=x¯k+1,于是上述ADMM其实可以进一步化简为如下形式:

xk+1iyk+1i=argminx(fi(xi)+(yki)T(xi−x¯k)+(ρ/2)∥xi−x¯k∥22))=yki+ρ(xk+1i−x¯k+1)

这种迭代算法写出来了,并行化那么就是轻而易举了,各个子数据分别并行求最小化,然后将各个子数据的解汇集起来求均值,整体更新对偶变量yk,然后再继续回带求最小值至收敛。当然也可以分布式部署(hadoop化),但是说起来容易,真正工程实施起来又是另外一回事,各个子节点机器间的通信更新是一个需要细细揣摩的问题。

另外,对于全局一致性优化,也需要给出相应的终止迭代准则,与一般的ADMM类似,看primal和dual的residuals即可

∥rk∥22=∑i=1N∥xki−x¯k∥22,∥sk∥22=Nρ∥x¯ki−x¯k−1∥22

4.2 带正则项的全局一致性问题

下面就是要将之前所谈到的经典的机器学习算法并行化起来。想法很简单,就是对全局变量加上正则项即可,因此ADMM算法只需要改变下z-update步即可

mins.t.∑i=1Nfi(xi)+g(z),xi∈Rnxi−z=0⟹xk+1izk+1yk+1i=argminx+i(fi(xi)+(yki)T(xi−zk)(ρ/2)∥xi−z∥22))=argminz(g(z)+∑i=1N(−(yki)Tz+(ρ/2)∥xk+1i−z∥22))=yki+ρ(xk+1i−zk+1)

同样的,我们仍对z做一个平均处理,于是就有

zk+1=argminz(g(z)+(Nρ/2)∥z−x¯k+1−(1/ρ)y¯k∥22)

上述形式都取得是最原始的ADMM形式,简化处理,写成scaled形式即有

xk+1izk+1uk+1i=argminx(fi(xi)+(ρ/2)∥xi−zk+uki∥22))=argminz(g(z)+(Nρ/2)∥z−xk+1i−u¯k∥22)=uki+xk+1i−zk+1

这样对于后续处理问题就清晰明了多了。可以看到如果g(z)=λ|z|1,即lasso问题,那么z-update步就用软阈值operator即可。因此,对于大规模数据,要想用lasso等算法,只需要对数据做切块(切块也最好切均匀点),纳入到全局变量一致性的ADMM框架中,即可并行化处理。下面给出一些实例。

切割大样本数据,并行化计算

在经典的统计估计中,我们处理的多半是大样本低维度的数据,现在则多是是大样本高维度的数据。对于经典的大样本低维度数据,如果机器不够好,那么就抽样部分数据亦可以实现较好估计,不过如果没有很好的信息,就是想要对大样本进行处理,那么切割数据,并行计算是一个好的选择。现在的社交网络、网络日志、无线感应网络等都可以这么实施。下面的具体模型都在受约束的凸优化问题中以及ℓ1-norm问题中提过,此处只不过切割数据,做成分布式模型,思想很简单,与带正则项的global consensus问题一样的处理。经典问题lasso、sparse logistic lasso、SVM都可以纳入如下框架处理。

有观测阵A∈Rm×n和响应值b∈Rm,可以对应切分,即对矩阵A和向量b横着切,

A=⎛⎝⎜⎜A1⋮AN⎞⎠⎟⎟b=⎛⎝⎜⎜b1⋮bN⎞⎠⎟⎟

于是原来带正则项的优化问题就可以按照数据分解到多个子系统上去分别优化,然后汇集起来,形成一个global consensus问题。

mins.t.∑i=1Nli(Aixi−bi)+r(z)xi−z=0,i=1,…,Nxi,z∈Rn

结合受约束的凸优化问题时所给出来的具体的ADMM算法解的形式,下面直接给出这些问题的ADMM迭代算法公式

(1)Lasso

xk+1izk+1uk+1i=(ATiAi+ρI)−1(ATibi+ρ(zk−uki))=S1/ρN(x¯k+1−b+u¯k)=uki+xk+1i−zk+1

如果切割的数据量小于维数mi<n,那么求解时分解小的矩阵AiATi+ρI即可;其他求逆采用矩阵加速技巧即可。

(2)Sparse Logistic Regression

xk+1izk+1uk+1i=argminxi(li(Aixi−bi)+(ρ/2)∥xi−zk+uki∥22=S1/ρN(x¯k+1−b¯+u¯k)=uki+xk+1i−zk+1

在x-update步是需要用一些有效的算法来解决ℓ2正则的logistic回归,比如L-BFGS,其他的优化算法应该问题不大吧。

(3)SVM

注意分类问题和回归问题的损失函数不同,一般都是用l(sign(t)y)形式来寻求最优的分类权重使得分类正确。SVM使用Hinge Loss:ℓ(y)=max(0,1−t⋅y),即将预测类别与实际分类符号相反的损失给凸显出来。分布式的ADMM形式

xk+1izk+1uk+1i=argminxi(1T(Aixi+1)++(ρ/2)∥xi−zk+uki∥22=ρ(1/λ)+Nρ(x¯k+1+u¯k)=uki+xk+1i−zk+1

4.3 一般形式的一致性优化问题(切割参数到各子系统,但各子系统目标函数参数维度不同,可能部分重合)

上述全局一致性优化问题,我们可以看到,所做的处理不过是对数据分块,然后并行化处理。但是更一般的优化问题是,参数空间也是分块的,即每个子目标函数fi(xi)的参数维度不同xi,∈Rni,我们称之为局部变量。而局部变量所对应的的也将不再是全局变量z,而是全局变量中的一部分zg,并且不是像之前的顺序对应,而可能是随便对应到z的某个位置。可令g=G(i,⋅),即将xi映射到z的某部位

(xi)j=zG(i,j)=z^i

如果对所有i有G(i,j)=j,那么xi与z就是顺序映射,也就是全局一致性优化问题,否则就不是。结合下图就比较好理解

关于ADMM的研究(二)

虽然如果用其他方法来做感觉会复杂,但是纳入到上述ADMM框架,其实只不过是全局一致性优化问题的一个局部化变形,不过此时不是对数据进行分块,是对参数空间进行分块

mins.t.∑i=1Nfi(xi)+g(z),xi∈Rnixi−z^i=0,i=1,…N⟹xk+1izk+1yk+1i=argminx(fi(xi)+(yki)Txi(ρ/2)∥xi−z^ki∥22))=argminz(∑i=1N(−(yki)Tz^i+(ρ/2)∥xk+1i−z^i∥22)))=yki+ρ(xk+1i−z^k+1i)

后续想做平均化处理,即中间会发生重合的参数zi取值一样的,那么z-update将只能找他对应的那些x进行平均化,也就是变成局部了,因为不是所有值都是要全局保持一致的。比如上面那个图中的z1,z2,z3,z4都分别只要求在部分xi发生了共享需要保持一样,而不是像之前全局要求每个xi对应的都是z。即

zk+1g=∑G(i,j)=g((xk+1i)j+(1/ρ)(yki)j)∑G(x,y)=g1

该式子表示就是z的第g个变量的平均值来源于所有映射到该变量的x与y的平均值。与之前的global类似,此时对于y的取均值会为0,因此z-update就变成了更简单的形式

zk+1g=1kg∑G(i,j)=g(xk+1i)

同全局一致性优化问题一样,我们可以加上正则项,然后也可以变成带正则项的一般形式的一致性优化问题。此处不赘述,与全局基本类似。

Sharing

4.4 共享问题(sharing)(横向切割数据,也可纵向切变量)

与之前的全局变量一致性优化问题类似,共享问题也是一个非常一般而且常见的问题。他的形式如下:

min∑i=1Nfi(xi)+g(∑i=1Nxi)

这里的第一部*部损失fi(xi)与全局一致性优化是一样的,即所有的xi∈Rn,i=1,…,N同维度,而对于一个共享的目标函数g则是新加入的。在实际中,我们常常需要优化每个子数据集上的损失函数,同时还要加上全局数据所带来的损失;或者需要优化每个子系统的部分变量,同时还要优化整个变量。共享问题是一个非常重要而灵活的问题,它也可以纳入到ADMM框架中,形式如下:

mins.t.∑i=1Nfi(xi)+g(∑i=1Nzi)xi−zi=0,zi∈Rn,i=1,…,N,⟹xk+1izk+1uk+1i=argminxi(fi(xi)+(ρ/2)∥xi−zki+uki∥22))=argminz(g(∑i=1Nzi)+ρ/2∑i=1N∥zi−xk+1i−uki∥22)=uki+xk+1i−zk+1i

上述形式当然还不够简洁,需要进一步化简。因为x-update可以不用担心,分机并行处理优化求解即可,而对于z-update这里面需要对Nn个变量求解,想加快速度,就减少变量个数。于是想办法通过和之前那种平均方式一样来简化形式解。

对于z-update步,令ai=uki+xk+1i,于是z-update步优化问题转化为

mins.t.g(Nz¯)+(ρ/2)∑i=1N∥zi−ai∥22z¯=1N∑i=1Nzi

当z¯固定时,那么后面的最优解(类似回归)为zi=ai+z¯−a¯,带入上式后于是后续优化就开始整体更新(均值化)

xk+1izk+1uk+1=argminxi(fi(xi)+(ρ/2)∥xi−xki+x¯k−z¯k+uk∥22))=argminz(g(Nz¯)+Nρ/2∥z¯−x¯k+1−uk∥22)=uki+x¯k+1−z¯k+1

另外,有证明如果强对偶性存在,那么global consensus问题与sharing问题是可以相互转化的,可以同时达到最优,两者存在着很紧密的对偶关系。

本节开头提过,sharing问题用来切分数据做并行化,也可以切分参数空间做并行化。这对于高维、超高维问题是非常有好处的。因为高维统计中,大样本是一方面问题,而高维度才是重中之重,如果能切分特征到低纬度中去求解,然后在合并起来,那么这将是一个很美妙的事情。上面利用regularized global consensus问题解决了切分大样本数据的并行化问题,下面利用sharing思想解决常见的高维数据并行化问题

切割变量(特征)空间,并行化处理

同样假设面对还是一个观测阵A∈Rm×n和响应观测b∈Rn,此时有n»m,那么要么就降维处理,要么就切分维度去处理,或者对于超高维矩阵,切分维度后再降维。此时A矩阵就不是像之前横着切分,而是竖着切分,这样对应着参数空间的切分:

A=[A1,…,AN],Ai∈Rm×ni,x=(x1,…,xN),x∈Rni,→Ax=∑i=1NAixi

于是正则项也可以切分为r(x)=∑Ni=1ri(xi)。那么最初的minl(Ax−b)+r(x)形式就变成了

minl(∑i=1NAixi−b)+∑i=1Nri(xi)

这个与sharing问题非常接近了,做点变化那就是sharing问题了

mins.t.l(∑i=1Nzi−b)+∑i=1Nri(xi)Aixi−zi=0,i=1,…,N⟹xk+1izk+1uk+1=argminxi(ri(xi)+(ρ/2)∥Aixi−Aixki+Ax¯¯¯¯¯k−z¯k+uk∥22))=argminz(l(Nz¯−b)+Nρ/2∥z¯−Ax¯¯¯¯¯k+1−uk∥22)=uki+Ax¯¯¯¯¯k+1−z¯k+1

与之前的global consensus问题相比,ADMM框架x-update与z-update似乎是反过来了。于是将此形式直接套到Lasso等高维问题即有很具体的形式解了。

(1)Lasso

xk+1iz¯k+1uk+1=argminxi(λ∥xi∥1+(ρ/2)∥Aixi−Aixki+Ax¯¯¯¯¯k−z¯k+uk∥22))=1N+ρ(b+ρAx¯¯¯¯¯k+1+ρuk)=uk+Ax¯¯¯¯¯k+1−z¯k+1

当|ATi(Aixki+z¯k−Ax¯¯¯¯¯k−uk)|2≤λ/ρ时xk+1i=0(第i块特征不需要用),这样加快了x-update速度,不过这个对串行更有效,对并行起来也没有多大用..

(2)Group Lasso 与lasso基本一样,只是在x-update上有一个正则项的不同,有ℓ1-norm变成了ℓ2-norm

xk+1i=argminxi(λ∥xi∥2+(ρ/2)∥Aixi−Aixki+Ax¯¯¯¯¯k−z¯k+uk∥22)

该问题其实就是按组最小化(ρ/2)|Aixi−v|22+λ|xi|2,解为

if∥ATiv∥2≤λ/ρ,otherwisethenxi=0xi=(ATiAi+vI)−1ATiv

涉及矩阵长短计算时,再看矩阵小技巧。

(3)Sparse Logstic Regression 也与lasso区别不大,只是z-update的损失函数不同,其余相同于是

z¯k+1=argminz¯(l(Nz¯)+(ρ/2)∥z¯−Ax¯¯¯¯¯k+1−uk∥22)

(4)SVM

SVM与之前的global consensus时候优化顺序反了过来,与logistic rgression只是在z-update步不同(损失函数不同):

xk+1iz¯k+1uk+1=argminxi(λ∥xi∥22+(ρ/2)∥Aixi−Aixki+Ax¯¯¯¯¯k−z¯k+uk∥22))=argminz¯(1T(Nz¯+1)++(ρ/2)∥z¯−Ax¯¯¯¯¯k+1−uk+1∥)=uk+Ax¯¯¯¯¯k+1−z¯k+1

z-update解析解可以写成软阈值算子

(z¯k+1)i=⎧⎩⎨⎪⎪vi−N/ρ,−1/N,vi,vi>−1/N+N/ρvi∈[−1/N,−1/N+N/ρ]vi<−1/Nvi=(Ax¯¯¯¯¯k+1+u¯k)i

(5)Generalized Additive Models

广义可加模型是一个很适合sharing框架的问题。它本身就是对各个各个特征做了变化后(非参方法),重新表示观测的方式

b≈∑j=1nfj(xj)

当fi是线性变化时,则退化成普通线性回归。此时我们目标优化的问题是

min∑i=1mli(∑j=1nfj(xij)−bi)+∑j=1nrj(fj)

其中有m个观测,n维特征(变量)。rj此时是对一个functional的正则,此时这个问题看起来似乎既可以对数据切分,也可以对特征切分,不过此时仍用sharing问题来做,相当于对特征切分为一个特征为一个子系统,于是有

fk+1jz¯k+1uk+1=argminfi∈Fj(rj(fj)+(ρ/2)∑i=1m(fj(xij)−fkj(xij)+z¯ki+f¯ki)+uki=argminz¯(∑i=1mli(Nz¯−bi)+ρ/2∑j=1n∥z¯−f¯k+1−uk∥,f¯k=1n∑j=1nfkj(xij)=uk+f¯k+1−z¯k+1

fj是一个ℓ2正则的损失,有直接求解的算法求解,z可以一块一块的求解?

最后再说一个经济学中很重要的sharing问题的特例,即交换问题(exchange problem):

mins.t.∑i=1Nfi(xi)∑i=1Nxi=0,xi∈Rn,i=1,…N

此时共享目标函数g=0。xi可以表示不同物品在N个系统上的交换数量,(xi)j可以表示物品j从子系统i上收到的交换数目,约束条件就可以看做在这些系统中物品交换是保持均衡稳定的。于是转化为sharing问题,就有很简单的ADMM解法(或者当做之前讲过的受约束的凸优化问题来解,做投影):

xk+1iuk+1=argminxi(fi(xi)+(ρ/2)∥xi−xki+x¯k+uk∥22))=uki+x¯k+1

4.4 应用小总结

感觉上通过consensus problem和general consensus problem,我们可以看到并行和分布式部署优化方案的可行性。我们可以切分数据以及相应的目标函数,也可以切分变量到各个子系统上去,分别作优化,甚至我们可以大胆想象对不同类型数据块用不同的优化算法,结合consensus问题和ADMM算法,达到同一个global variable的优化目的;或者对不同变量在不同类型数据块上优化,即使有重叠,也可以结合general consensus思想和ADMM算法来解决这个问题。当然前提是能够定义好需要估计的参数和优化的目标函数!大规模部署的前景还是很不错的。下面具体分布式统计模型的构建便是ADMM算法非常好的应用。切分数据、切分变量(不过每个子系统的目标函数基本都是一样的,其实应该可以不同)

5. Nonconvex问题

5.1 变量选择(Regressor Selection)

5.2 因子模型(Factor Model Fitting)

5.3 双凸优化(Bi-convex Problem)

非负矩阵分解(Nonnegative Matrix Factorization)

6. 具体实施与实际计算结果

这块真的很实际,需要明白MPI的机理和Mapreduce、Graphlab等通信运作的机理,这样才好部署ADMM算法,因为中间有很多迭代,需要做好子节点间参数与整体参数的通信,保持迭代时能同步更新参数。看实际运作,MPI和GraphLab可能更适合这种框架,Hadoop也是可以的,不过毕竟不是为迭代算法所生,要做好需要进行一些优化。Boyd提到Hadoop其中的Hbase更适合这种框架,因为Hbase是一种大表格,带有时间戳,适合记录迭代的记录,这样就不容易导致分布计算时候搞不清是哪一步的迭代结果了,导致通信调整比较复杂。不过在MapReduce框架下实施ADMM算法是没有什么问题的,只要熟稔Hadoop的一些细节部分,基本没有太大问题。

8. 总结

一个好的一般性算法,我个人觉得是易实施,并可大规模应用许多问题。可以让统计学家卡在搞算法的瓶颈中解放出来,使得他们能快速用模拟,验证自己构建可能较为复杂的模型。只有当看到一个令人感到欣慰的结果时,那些模型的统计性质的证明才可能是有意义的,如果事先连希望都看不到,那证明起来都可能底气不足,让人难以信服,更难以大规模应用统计学家所构建的模型。现在是一个高维数据、海量数据的年代,算法的重要性更会凸显出来,一个好的模型如果没有一个有效的算法支撑,那么他将可能什么都不是,Lasso头几年所遭遇的冷遇也充分证明了这一点,再比如在没有计算机年代,Pearson的矩估计应用反而远多于Fisher的MLE估计方法也是一个道理。好的一般性的解决方案,我想这不管是优化理论,还是统计等其他应用学科,虽然知道没有最牛最终极的方法,但是能涌现一些大范围适用的方法,那就是再好不过了。一招鲜吃遍天,人还都是喜欢简单、安逸爱偷懒的嘛..

原文出处:http://joegaotao.github.io/cn/2014/02/admm/

关于ADMM的研究(二)的更多相关文章

  1. 关于ADMM的研究(一)

    关于ADMM的研究(一) 最近在研究正则化框架如何应用在大数据平台上.找到了<Distributed Optimization and Statistical Learning via the ...

  2. Fiddler实战深入研究&lpar;二&rpar;

    Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...

  3. &lpar;转载&rpar;Fiddler实战深入研究&lpar;二&rpar;

    原文来源于:http://www.cnblogs.com/tugenhua0707/p/4637771.html,作者:涂根华 !个人觉得文章写的特别好,故收藏于此,感谢原作者的分享 Fiddler实 ...

  4. Fiddler实战深入研究&lpar;二&rpar;&lbrack;转载&rsqb;

    Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...

  5. Nginx源码研究二:NGINX的事件处理概论

    NGINX作为服务端的应用程序,在客户端发出数据后,服务端在做着这样一些处理,数据先会经过网卡,网卡会和操作系统做交互,经过操作系统的协议栈处理,再和不同的应用程序交互. 在这里面涉及两个概念,一个是 ...

  6. tomcat 组件研究二--请求过程

    上一篇博客大概总结了tomcat 的组件以及其组织方式,对于tomcat 的启动过程也进行进行了简单的总结,下面这篇博客,继续研究tomcat 处理请求的相关组件,其实就是主要研究Connectors ...

  7. &lbrack;转&rsqb; Java se 7新特性研究&lpar;二&rpar;

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp82   今天主要研究Java se 7中异常处理的新功能.从今天开始正在 ...

  8. android&lowbar;activity&lowbar;研究&lpar;二&rpar;

    这次开始玩玩活动的生命周期.废话不说,先搞个小应用,大体思路是:主界面有两个按钮,一个按钮按下后,出现第二个界面:另一个按钮按下后,出现第三个界面,真他妈简单. 一.主界面: 1. 主界面布局xml文 ...

  9. dedecms代码研究二

    dedecms代码研究(2)从index开始现在继续,今天讲的主要是dedecms的入口代码.先打开index.PHP看看里面是什么吧.打开根目录下的index.php嗯映入眼帘的是一个if语句.检查 ...

随机推荐

  1. 网络天荒地老之UIWebView&amp&semi;WebKit

    UIWebView 是苹果提供的用来展示网页的UI控件,它也是最占内存的控件. iOS8.0之后出现了webkit框架,WKWebView相比UIWebView节省了1/4~1/3的内存,速度快,但是 ...

  2. PHP易混淆函数的区分方法及意义

    1.echo和print的区别   PHP中echo和print的功能基本相同(输出),但是两者之间还是有细微差别的.echo输出后没有返回值,但print有返回值,当其执行失败时返回flase.因此 ...

  3. android项目的结构和布局

    一.res文件夹 1.res文件夹用于存放Android的资源.包括:动画.静态图片.字符串.菜单.布局.视频.文件等. 1.drawable-ldpi:低分辨率图形(120像素/英寸) 2.draw ...

  4. jquery点击图片选中特效

    jquery点击图片选中特效 点击在线预览效果

  5. Apache Log4j使用实例

    Apache Log4j使用实例  原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.  Blog:  1.Logger类 通过Logger类的静 ...

  6. getting start with storm 翻译 第八章 part-1

    转载请注明出处:http://blog.csdn.net/lonelytrooper/article/details/12434915 第八章 事务性Topologies 在Storm中,正如本书前边 ...

  7. Asp&period;net Repeater控件

    Repeater控件和DataList控件,可以用来一次显示一组数据项.比如,可以用它们显示一个数据表中的所有行.     Repeater控件完全由模板驱动,提供了最大的灵活性,可以任意设置它的输出 ...

  8. Chapter 4&period;开放-封闭原则

    开放-封闭原则:是说软件实体应该可以扩展,但不可修改. 设计人员必须对于他设计的模块应该对哪种变化封闭做出选择,先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化. 面对需求,对程序的改动是通 ...

  9. ThoughtWorks 面试

    ThoughtWorks 面试备忘录   ThoughtWorks 面试备忘录 前言 前段时间 ThoughtWorks 在网上和拉勾网合作搞了一次网络招聘,名为抛弃简历!让代码说话!可谓赚足了眼球, ...

  10. android 第三次作业

    android studio音乐播放器 一.实现功能: 1.读取本地SD中的所有音频文件 2.歌单列表展示,并显示音频具体信息 3.进度条显示当前播放进度,可滑动加速 4.点击歌单进行播放 5.实现暂 ...