整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

css布局的em的使用方法

么是弹性布局?

用户的文字大小与弹性布局

用户的浏览器默认渲染的文字大小是“16px”,换句话说,Web页面中“body”的文字大小在用户浏览器下默认渲染是“16px”。当然,如果用户愿意他可以改变这种字体大小的设置,用户可以通过UI控件来改变浏览器默认的字体大小。

弹性设计有一个关键地方Web页面中所有元素都使用“em”单位值。“em”是一个相对的大小,我们可以这样来设置1em,0.5em,1.5em等,而且“em”还可以指定到小数点后三位,比如“1.365em”。而其中“相对”的意思是:

1.相对的计算必然会一个参考物,那么这里相对所指的是相对于元素父元素的font-size。比如说:如果在一个<div>设置字体大小为“16px”,此时这个<div>的后代元素教程了是将继承他的字体大小,除非重新在其后代元素中进行过显示的设置。此时,如果你将其子元素的字体大小设置为“0.75em”,那么其字体大小计算出来后就相当于“0.75 X 16px = 12px”;

2.如果用户通过浏览器的UI控件改变了文字的大小,那么我们整个页面也会进行放大(或缩小),不至于用户改变了浏览器的字体后会致使整个页面崩溃(我想这种现像大家都有碰到过,不信你就试试你自己制作过的项目,你会觉得很恐怖)。

大家可以查看这个弹性布局样例。此时你使用浏览器的UI控件改变了文字的大小或者直接“ctrl + ”和“ctrl - ”,你会发现这个弹性布局实例,在浏览器改变字体大小浏览会做出相应的放大和缩小,并不会影响整个页面的布局。注:这个实例的所有HTML和CSS在本教程中教程了都会使用到。

至于其他的弹性布局的实例,大家可以浏览Dan Cederholm的Simplebites,并改变文字的大小去浏览。

体验后,是不是觉得弹性布局的页面很灵活呀,而且也像“px”一样的精确。因此,只要我们掌握了“font-size”、“px”和“em”之间的基本关系,我们就可以民以食快速使用CSS创建精确的布局。

CSS的Elastigirl引进EM

Elastigirl的“em”是极其强大和灵活的,他不管字体大小是什么,是12px,16或60,他都可以计算出其值。

em其实就是一种排版的测试单位,而且他的由来还有一段小故事,关于这段小故事我就不和大家说了,因为大家都不是来听我讲故事的,我想大还是喜欢知道他在CSS中的那些事。

在CSS中,“em”实际上是一个垂直测量。一个em等于任何字体中的字母所需要的垂直空间,而和它所占据的水平空间没有任何的关系,因此:

如果字体大小是16px,那么1em=16px。

入门

在我们开始来了解CSS中的这个“em”之前,我们需要知道在浏览器下,他的默认字体大小。正好我们前面也这样做了,在所有现代浏览器中,其默认的字体大小就是“16px”。因此在浏览器下默认的设置将是:

1em = 16px

因此,在一个CSS选择器被写入时,浏览器就有了一个“16px”大小的默认字体。此时我们Web页面中的<body>就继承了这个“font-size:16px;”,除非你在CSS样式中显式的设置<body>的“font-size”值,来改变其继承的值。这样一来,“1em = 16px”、“0.5em = 8px”、“10em = 160px”等等,那么我们也可以使用“em”来指定任何元素的大小。

设置Body的font-size

很多前辈在多年的实践中得出一个经验,他们建议我们在<body>中设置一个正文文本所需的字体大小,或者设置为“10px”,相当于(“0.625em或62.5%”),这样为了方便其子元素计算。这两种都是可取的。但是我们都知道,<body>的默认字体是“16px”,同时我们也很清楚了,我们改变了他的默认值,要让弹性布局不被打破,就需要重新进行计算,重新进行调整。所以完美的设置是:

body {font-size:1em;}

可是在那个没人爱的IE底下,“em”会有一个问题存在。调整字体大小的时候,同样会打破我们的弹性布局,不过还好,有一个方法可以解决:

html {font-size: 100%;}

公式转换——PXtoEM

如果你是第一创建弹性布局的,最好在身边准备一个计算器,因为我们一开始少不了很多的计算,有了他放心。

像素对于我们来说太密切了,因此我们也将从这开始。首先需要计算出1px和em之间的比例,然后是知道我们需要的px值。通过前面的介绍,大家都知道1em总是等于父元素的字体大小,因此我们完全可以通过下面的工式来计算:

1 ÷ 父元素的font-size × 需要转换的像素值 = em值

大家可以参考一下面这张转换表(body字体为16px时的值)

接下来我们一起看一个很简单的实例“使用CSS的EM制作一个960px宽度的弹性布局”

HTML Markup

<body>

<div id="container">…</div>

</body>

将960px转换为em

1 ÷ 16px × 960px = 60em

这个计算值的前提条件是<body>的“font-size:16px”。

CSS Code

html {

font-size: 100%;

}

body {

font-size: 1em;

}

#container {

width: 60em;

}

通过上面的实例,我想大家更能形像化的理解了,因为有例可询,其实我们可以把上面的计算公式转换一下,将更方便你的计算:

需要转换的像素值 ÷ 父元素的font-size = em值

那么我们上面的实例“960px”就可以这样来转换成“em”值

960px ÷ 16px = 60em

上面我们一起见证了“px”转换成“em”的计算方式,接下来我们一起来动看制作上面展示过的弹性布局样例。下面我们主要一起来一步一步的实现他。

构建一个弹性的容器

要创建弹性布局样例那样的居中效果,我们首先需要创建一个HTML结构,我在此给创建一个<div>并且取名叫“wrap”

<body>

<div id="wrap"> content here</div>

</body>

我们希望这个容器是一个“740px”宽,适合一个“800px × 600px”显屏的实例。那么“740px”会等于多少“em”呢?这就是我们需要关心的问题,大家一起来看吧:

1、将“740px”转换成“em”设置到我们的容器“div#wrap”:我们都知道“div#wrap”的父元素<body>设置了字体为“16px”,那么此时在没有进行另外显示的设置时,他的子元素<div id="wrap">将继承“font-size”值,这样我们就可以轻意得到:“1px和1em之间的关系”

1em = 16px 也就是 1px = 1 ÷ 16 = 0.0625em

这样一来,我们的“740px”就很容易的能转换成“em” 0.0625em × 740 = 46.25em

当然大家也可以按照我们前面所列出的计算公式来进行转换,这样你心中更具有一个概念性,也不容易弄错:

1 ÷ 16 × 740 = 46.25em (1 ÷ 父元素的font-size × 需要转换的像素值 = em值)

这样一来,您可以使用上面的公式计算出您需要的任何宽度或高度的“em”值,你只需要知道“1px等于多少em”,另外就是你要转换的“px”值是多少,具备这几个参数你就能得到你想要的“em”值了。

2、创建CSS样式:现在我们可以给“div#wrap”写样式了,弹性布局样例很明显的告诉我们,给“div#wrap”设置了一个宽度为“740px”居中,带有上下“margin”为“24px”,而且带有“1px”的边框效果,那么我们首先根据上面的公式计算出相应的“em值”,然后在写到CSS样式中:

html {font-size: 100%;}

body {font-size: 1em;}

#wrap {

width: 46.25em;/*740px ÷ 16 = 46.25em */

margin: 1.5em auto;/*24px ÷ 16 = 1.5em*/

border: 0.0625em solid #ccc;/*1px ÷ 16 = 0.0625em*/

}

现在我们就轻松的创建了一个包含内容的弹性容器:弹性布局样例。

文本样式与em

首先我们在前面那个创建的<div id="wrap"></div>中插入一个<h1>和一个<p>:

<div id="wrap">

<h1>...</h1>

<p>...</p>

</div>

在弹性布局样例实例中,我们标题使用了“18px”,而段落设置的是“12px”字体,同时其行高是“18px”。18px将是我们实现弹性布局的一个重要值,可以使用他们都按正比变化。(有关于标题和段落的排版介绍,大家感兴趣可以点击Richard Rutter的basic leading和vertical rhythm以及chapter on vertical motion的相关介绍)。

根据CSS继承一说,我们在“div#wrap”的内容容器中没有显式的设置字体大小,这样整个“div#wrap”将继承了其父元素“body”的字体——“16px”。

1、给段落设置样式:——“12px”的字体,“18px”的行高以及margin值

从CSS继承中,我们可以得知我们所有段落继承了其父元素“div#wrap”的“font-size:16px”。同时我们通过前面的介绍得知1px = 1 ÷ 16 = 0.0625em,这样一来我们就很轻松的知道“12px”等于多少个“em”

0.0625em × 12 = 0.750em

这样我们就可以给段落p设置样式:

p {font-size: 0.75em;/*0.0625em × 12 = 0.750em */}

要计算出段落所需的行高和“margin”为“18px”,来满足Richard Rutter说的basic leading,那我们就需要像下面的方法和来计算:

18 ÷ 12 = 1.5em

使用所需的行高值“18px”直接除以“字体大小12px”,这样就得到了段落“p”的“line-height”值。在本例中行高就等于字体的“1.5”倍,接着我们把“line-height”和“margin”样式加到段落“p”中

p{

font-size: 0.75em;/*0.625em × 12 = 0.750em */

line-height: 1.5em;/*18px(line-height) ÷ 12(font-size) = 1.5em */

margin: 1.5em;/*18px(margin) ÷ 12(font-size) = 1.5em */

}

2、给标题设置一个18px的字号

标题“h1”和段落“p”一样的原理,他也是继承他父元素“div#wrap”的“16px”的“font-size”,所以我们也是按同样的方法可以计处出他的“em”

0.0625em × 18 = 1.125em

我们可以把得出的值写到CSS样式表中

h1 {

font-size: 1.125em;/*0.625em × 18 = 1.125em*/

}

同样为了保留Richard Rutter所说的vertical rhythm,我们同样将标题“h1”的“line-height”和“margin”都设置为“18px”,使用方法前面介绍的方法。很容易得到他们的“em”值为“1em”:

h1 {

font-size: 1.125em; /*0.625em × 18 = 1.125em*/

line-height: 1em; /*18px(line-height) ÷ 18px(font-size) = 1em */

margin: 1em; /*18px(margin) ÷ 18px(font-size) = 1em */

}

设置图片大小——使用em

要做出弹性布局样例这样的果,我们也需要在html中插入一张图片:

<body>

<div id="wrap">

<h1>....</h1>

<p><img src="90.png" alt="" /> Lorem...</p>

</div>

</body>

我们这张图片具有“90px”的宽和高,同时具有一个右边距和底边距为“18px”设置,而且还进行左浮动。下面我们就一起来看其如何实现图片这几个样式效果:

从HTML结构中,我们很清楚的知道,图片是段落“p”的子元素,通过前面的介绍,你们知道这个段落“p”的“font-size”值被得定义为“12px”,因此我们计算图片的属性值时,不能在按“1px = 0.0625em”或者“1em=16px”来计算,我们需要使用最老的公式计算:

1 ÷ 父元素的font-size × 需要转换的像素值 = em值

这样一来,按上面所示的公式,我们就可以计算出图片的大小:

1 ÷ 12 × 90 = 7.5em

现在你就可以将计算出来的值写到样式中去:

p img {

width: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的宽度) = 7.5em */

height: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的高度) = 7.5em */

}

我们在段落中知道了“18px”刚好是“1em”,现在我们也把他使用到图片的样式中:

p img {

width: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的宽度) = 7.5em */

height: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的高度) = 7.5em */

margin: 0 1.5em 1.5em 0;

float: left;

}

这样我们就制作出一个和弹性布局样例一样的效果。希望通过这样的一个实例能帮助大家了解如何使用“em”来创建一个弹性布局的方法。当然大家可能还在担心使用“em”来制作一个弹性布局,不能像“px”一样的的精确,如果你真正理解了这篇教程后,我想你不会在有这样的想法。

弹性布局的公式总结

最后我想大家肯定和我会有同一种想法,就是相关参数是的“px”值如何成功而且正确的转换成“em”值,经过上面的学习,我最后将公式总结一下:

元素自身没有设置字号大小时,元素的width、height、line-height、margin、padding、border等值转换都按下面公式转换:

1 ÷ 父元素的font-size × 需要转换的像素值 = em值

我们来看一个实例:

<body>

<div id="wrapper">test</div>

</body>

我们在body默认字体大小为“16px”,此时需要“div#wrapper”的相关参数值为:

#wrapper {

width: 200px;

height: 100px;

border: 5px solid red;

margin: 15px;

padding: 10px;

line-height: 18px;

}

那么我们按照上面的公式,将所在参数进行转换:

#wrapper {

width: 12.5em;/*1 ÷ 16 × 200 = 12.5em值*/

height: 6.25em;/*1 ÷ 16 × 100 = 6.25em值*/

border: 0.3125em solid red;/*1 ÷ 16 × 5 = 0.3125em值*/

margin: 0.9375em;/*1 ÷ 16 × 15 = 0.9375em值*/

padding: 0.625em;/*1 ÷ 16 × 10 = 0.625em值*/

line-height: 1.125em;/*1 ÷ 16 × 18 = 1.125em值*/

}

我们一起来看计算出来的值:

接下来我需要大家在来看一个效果,这一点很关键哟,仔细看好,在同样的参数基础上稍加一条元素本身设置字体大小为:14px;,大家可以会说很简单的呀,按前面的公式计算出来加上就是了,那么我现在就按大家说的计算加上:

#wrapper {

font-size: 0.875em;/*1 ÷ 16 × 14= 0.875em值*/

width: 12.5em;/*1 ÷ 16 × 200 = 12.5em值*/

height: 6.25em;/*1 ÷ 16 × 100 = 6.25em值*/

border: 0.3125em solid red;/*1 ÷ 16 × 5 = 0.3125em值*/

margin: 0.9375em;/*1 ÷ 16 × 15 = 0.9375em值*/

padding: 0.625em;/*1 ÷ 16 × 10 = 0.625em值*/

line-height: 1.125em;/*1 ÷ 16 × 18 = 1.125em值*/

}

此进我们在firebug下看计算出来的layout值

为了更好的说明问题,我把元素自身没有设置字体大小和元素自身设置了字体大小,两者在firebug计算出来值:

我截这个图的主要意图是,说明一个问题就是元素自身要是设置了字体大小后,其计算公式就不在是前面所说的,我们需要做一下修改:

1、字体计算公式依旧

1 ÷ 父元素的font-size × 需要转换的像素值 = em值

2、其它属性的计算公式需要换成

1 ÷ 元素的font-size × 需要转换的像素值 = em值

那么我们现在来计算一回:

#wrapper {

font-size: 0.875em;/*1 ÷ 16 × 14= 0.875em值*/

width: 14.2857em;/*1 ÷ 14 × 200 = 14.2857em值*/

height: 7.1429em;/*1 ÷ 14 × 100 = 7.1429em值*/

border: 0.357em solid red;/*1 ÷ 14 × 5 = 0.357em值*/

margin: 1.071em;/*1 ÷ 14 × 15 = 1.071em值*/

padding: 0.714em;/*1 ÷ 14 × 10 = 0.714em值*/

line-height: 1.2857em;/*1 ÷ 14 × 18 = 1.2857em值*/

}

我们在来看一次计算出来的值:

总结

长篇介绍了一大堆,唯一想告诉大家的是以下几点

1、浏览器的默认字体大小是16px

2、如果元素自身没有设置字体大小,那么元素自身上的所有属性值如“boder、width、height、padding、margin、line-height”等值,我们都可以按下面的公式来计算

1 ÷ 父元素的font-size × 需要转换的像素值 = em值

3、这一种千万要慢慢理解,不然很容易与第二点混了。如果元素设置了字体大小,那么字体大小的转换依旧按第二条公式计算,也就是下面的:

1 ÷ 父元素的font-size × 需要转换的像素值 = em值

那么元素设置了字体大小,此元素的其他属性,如“border、width、height、padding、margin、line-height”计算就需要按照下面的公式来计算:

1 ÷ 元素自身的font-size × 需要转换的像素值 = em值

这样说,不知道大家理解了整明白了没有,如果没有整明白,可以回过头来看上面的一个实例。转自:http://www.uml.org.cn/html/201207311.asp

智元专栏

人工智能很火,人工智能大神很火。大神们的神器是什么?有人说找到了,就是EM算法。 请看这篇:

但是最近网上引人关注的另一传闻是,一位人工智能论文获奖者在获奖感言中说深度学习方法是炼金术,从而引起大神家族成员反驳。报道见:NIPS机器学习炼金术之争

看到上面两篇,使我想到:EM算法是炼金术吗?

我近两年碰巧在研究用以改进EM算法的新算法:http://survivor99.com/lcg/CM/Recent.html,对EM算法存在的问题比较清楚。我的初步结论是:EM算法虽然在理论上有问题,但是确实炼出金子了。反过来也可以说,虽然EM算法练出金子了,但是收敛很不可靠,流行的解释EM算法的收敛理由更是似是而非。有人使之神秘化,使得它是有炼金术之嫌。论据何在?下面我首先以混合模型为例,简单介绍EM算法,并证明流行的EM算法收敛证明是错的(没说算法是错的)。

假设n个高斯分布函数是:

P(X|θj)=Kexp[-(X-cj)2/(2dj2)],j=1,2,…,n

其中K是系数,cj是中心,dj是标准差。假设一个数据分布P(X)是两个高斯分布的混合

P(X)=P*(y1)P(X|θ*1)+P(y2)P(X|θ*2)

其中P*(y1),P*(y2)是真的混合比例,θ*1θ*2表示真的模型参数。我们只知道模型是高斯分布且n=2。现在我们猜测5个参数P(y1),c1c2d1d2。不是6个参数,是因为p(y2)=1-P(y1)。根据猜测得到的分布是

Q(X)=P(y1)P(X|θ1)+P(y2)P(X|θ2)

如果Q(X)非常接近P(X),相对熵或 Kullback-leibler 距离

H(Q||P)=∑iP(xi)log[P(xi)/P(xi)]

就接近0,比如小于0.001比特,那么就算我们猜对了。参看下图:

混合模型问题之所以重要,是因为它是限制分布类型而不是分布范围的模糊聚类,是无监督学习的一个典型。

EM算法起源于这篇文章:Dempster, A.P., Laird, N.M., Rubin,D. B.: Maximum Likelihood from Incomplete Datavia the EM Algorithm. Journal of the Royal Statistical Society, Series B39, 1–38(1977)。通过这个网站http://www.sciencedirect.com/搜索可见,光是标题有EM算法的英文文章就有6.8万篇(有似然度的文章将近76万篇),可见研究和应用EM算法的人何其多。

Wiki百科上的EM算法介绍见这里:

https://en.wikipedia.org/wiki/Expectation%E2%80%93maximization_algorithm

一篇中文介绍见这里:

http://www.cnblogs.com/mindpuzzle/archive/2013/04/05/2998746.html

EM算法的基本思想是:

目的是改变预测模型参数求似然度logP(XN)或logP(X)达最大(N表示有N个样本点,黑体X表示矢量),样本和θ之间的似然度就是负的预测熵(或交叉熵,广义熵的一种):

Hθ’(X)=∑iP(xi)logP(xi)

其中P(xi)就是上面的曲线Q(X)上的一个点(X是变量,xi是常量),即P(xi)=Q(xi)。我们用X的概率分布P(X)取代X序列。则EM算法的基本公式如下(下面y就是wiki百科中的z):

其中θt表示M步优化前的θ。这里的Q和上面的Q(X)中的Q含义不同,下面我们用Q(.)表示这里的Q(θ|θt)。

从语义信息论(http://survivor99.com/lcg/books/GIT/)看,我们可以得到

[Q(θ|θt)-H]/N=Hθ’(XY)-Hθ’(Y|X)=-Hθ(XY)+Hθ(Y|X)

右边是两个负的广义熵或负的交叉熵,和参数有关。为了讨论方便,后面忽略左边的N。

EM算法分两步:

E-step:写出预测的yj的条件概率

M-step:最大化Q(θ|θt),也就是最大化负的联合熵Hθ’(XY),或最小化联合交叉熵Hθ(XY)。

为什么这样能收敛呢?wiki百科这样说:

  1. Expectation-maximization works to improve Q(θ|θt) rather than directly improving log(X|θ). Here is shown that improvements to the former imply improvements to the latter.[13]

这就是说,只要Q(.)达最大,log(X|θ)就达到最大。

2)M-step可以增大Q(.),E-step也不减少Q(.),所以反复迭代就能收敛。

这篇证明文章比较出名:Wu, C.F.J.: On the Convergence Properties of the EM Algorithm. Annals of Statistics11, 95–10(1983)。

这等于说,真模型在山顶上,爬山人每一步只上不下就能到达山顶。M步只上,E步不下,所以能到达山顶。

但是,使用EM算法时,往往在预测分布P(X|θ)和实际分布P(X)不重合就停下来了。流行的解释是:那叫局部收敛(其实就是收错了地方);因为大山周围有一些小山,出发点不对就上到小山顶上了。所以起始点很重要。于是有人专门研究如何通过测试找到较好的出发点,比如随机选多点测试看哪个好。

EM有时虽然能收敛,但是常常收敛很慢。为了提高速度,于是又有很多人提出很多改进办法。其中比较出名的一个就是上面《九层境界》中提到的VBEM算法(详见Neal, R.,Hinton, G.: A view of the EM algorithm that justifies incremental, sparse, and other variants. in: Michael I. Jordan(ed.) Learning in Graphical Models,pp355–368. MITPress,Cambridge,MA(1999)),就是用

F(θq)=Q(θ|θt)+H(Y)

取代Q(θ|θt)(上面忽略了系数N),不断最大化F(θq)(q=P(Y))。在M步最大化F(.),在E步也最大化F(.)。据说这样收敛更快。但是VBEM的收敛证明是不是一样有问题呢?我的结论是:算法好一些,但是收敛证明问题还是存在。

首先我们看EM算法(包括VBEM算法)的收敛证明错在哪里。

在Shannon信息论中有公式:

H(XY)=H(X)+H(Y|X)

由于引进似然函数,Shannon熵变成预测熵或交叉熵,但是基本关系还是成立

Hθ(XY)=Hθ(X)+Hθ(Y|X)=-logP(X)+Hθ(Y|X)

写成负熵的形式是:

H’θ(XY)=logP(X|θ)+H’θ(Y|X)

后面这一项Hθ(Y|X)和Y的熵有关,P(y1)=P(y2)=0.5的时候H(Y)最大,负熵就最小,H’θ(Y|X)也比较小。如果真的比例P*(Y)是接近等概率的,起步时P(y1)=0.1,P(y2)=0.9,Y的负熵较大,我们不断最大化H’θ(XY),就会阻止P(Y)向真比例P*(Y)靠近。这是EM算法收敛慢甚至不收敛的一个原因。这也是为什么VBEM方法要用F(.)取代Q(.)。上式两边加上H(Y)以后就有

H’θ(XY)+H(Y)=logP(X|θ)+H’θ(Y|X)+H(Y)

H(Y)-Hθ(XY)=-Hθ(X)+H(Y)-Hθ(Y|X)

近似得到(后面解释近似):

-Hθ(X|Y)=-Hθ(X)+Iθ(X;Y)

也就是

F(θq)=-Hθ(X|Y)=-Hθ(X)+Iθ(X;Y)(3)

可见,F(θ,q)就是负的后验熵。两边加上P(X),左边就是预测互信息或语义互信息(我早在1993年的《广义信息论》一书中就提出):

F(θq)+H(X)=H(X)-Hθ(X|Y)=I(X;ϴ)(4)

从上面两个公式可以得到

H(Q||P)=H(X|θ)-H(X)=Iθ(X;Y)-I(X;ϴ)(5)

我们可以粗略理解,相对熵=Shannon互信息-预测互信息。后面我们将介绍这个公式的更加严格形式。

因为H(X)和模型无关,最大化F(.)就是最大化预测互信息,避免误改P(Y)。这样就好理解为什么VBEM比EM好。

但是,F(θ,q)最大化和logP(X|θ)最大化是否总是一致的?结论是否定的。证明很简单:

假设有一个真模型θ*和子模型比例P*(Y),它们产生P(X)。同时相应的Shannon联合熵是H*(X,Y),X的后验熵是H*(X|Y),互信息是I*(X;Y)。那么改变X和Y的概率分布,上面三个量都会变。

我们猜测的时候,如果联合概率分布P(Y,X|θ)P*(X,Y)更加集中,负熵log(XY|θ)=Hθ(XY)就会大于真模型的负熵-H*(X,Y),继续增大H’θ(XY)就会南辕北辙。

比如,下图例子中,第一轮优化参数前就可能有H’θ(XY)>-H*(XY)。它对于EM算法收敛证明来说就是反例。图中R=I(X;Y),R*=I*(X;Y)。其中真实的Q*(.)和互信息I*(X;Y)比较小。

这个例子中迭代用的是信道匹配算法,和VBEM算法比,主要差别是,在E步把继续增大F(.)改为调整P(Y)。其中红线就是EM算法中Q(θ|θt)的变化轨迹,第一个E步之后,Q(.)就大于真模型的Q*(.)。如果起始参数是随机的,那么它可能导致Q(.)出现在红线的任何位置,从而大于Q*(.)。

F(.)有类似情况,它和预测互信息(图示是G)走势完全一致,在每个E步是下降的。原来影响交叉熵有三个因素:

1)预测的分布和样本的分布是否符合,如果更符合,负熵Q(.)和F(.)就更大;

2)X和Y的分布是否集中,如果更集中负熵就更大;

3)X和Y是否相关,如果更相关负熵就更大。

流行的收敛证明只考虑了第一条。

到此有人会问,如果终点不在山顶上,起点很可能高于终点,那么为什么EM算法在大多数情况下是收敛的?

回答是:EM算法收敛证明中第二条,Q(.)只增不减也错了!原来在E步,Q(.)和F(.)是可能减小的!一般情况下都会使Q(.)向真模型的Q*=-H*(X,Y)靠拢,使F(.)向-H*(X|Y)靠拢。如果调整P(Y),收敛就更加可靠,EM算法就变为CM算法。

下面提供CM算法的粗略数学证明。

先看为什么需要调整P(Y)。在E步的公式(2)(计算Shannon信道的公式)中,P(yj|X)和P(X)及四个参数可能不匹配,导致

那样,上面计算出的Shannon信道就是一个不称职的Shannon信道。调整方法很简单,就是不断用左边的P+1(yj)代替右边的P(yj),直到两者相等。

下面介绍用信道匹配算法(CM算法)用到的公式:

上面第一行公式就是公式(5)的更加严格形式。其中用到子模型θjP(X|θj) 就等于前面方法中的P(X|yjθ)。RQ就近似于前面方法中Iθ(X;Y)。为什么说近似呢,因为这里用到Y的广义熵或交叉熵H(Y+1)=-∑jP+1(yj)logP(yj) 和相对熵H(Y+1||Y)。联合熵减去这个熵才是预测后验熵。而在VBEM方法中,增加的H(Y)是Shannon熵。

有了上面公式(6),我们就可以采用下面三步减小相对熵H(Q||P)——保证每一步都是减小的:

I:写出Shannon信道表达式,等于EM算法中的E步;

II:调整P(Y),使得P(Y+1)=P(Y);如果H(Q||P)<0.001,结束。

III:改变参数最大化语义互信息G。转到I。

详细讨论见这里:http://survivor99.com/lcg/CM.html

如果EM算法在M步先调整P(Y),固定P(Y)再优化参数,EM算法就和CM算法相同。如果在VBEM算法中添加的H(Y)改为交叉熵,E步调整P(Y)而不是最大化F(.),VBEM算法就和CM算法相同。

从语义互信息公式看

迭代就是轮流改变log左边(I和II)和右边(III)。改变右边是语义信道匹配Shannon信道,改变左边是Shannon信道匹配语义信道。所以该算法叫信道匹配(Channels’Matching)算法或CM算法(保留EM中的M)。我们也可以说CM算法是EM算法的改进版本。但是基本思想是不同的。CM算法也没用到Jensen不等式。

为什么CM算法会使Q(X)会收敛到P(X)呢?相对熵会不会表现为很多山洼,有高有低,我们不巧,落到一个较高的山洼里呢?

这要从Shannon的信息率失真理论谈起。Shannon在1948年发表经典文章《通信的数学理论之》,11年之后,他提出信息率失真函数R(D)——就是给定平均损失上限D求互信息I(X;Y)最小值R(D)。我在1993年的《广义信息论》中把它改造为R(G)函数。G是广义互信息或语义互信息(也就是平均log标准似然度)的下限。R(G)是给定G时的Shannon互信息I(X;Y)的最小值。可以证明,所有R(G)函数都是碗状的。R(D)函数像是半个碗,也是凹的。证明G是碗状的很简单,因为R(D)函数处处是凹的(已有结论),R(G)函数是它的自然扩展,也是处处是凹的。

进一步结论:R(G)-G也是处处是凹的。所以山洼只有一个。求相对熵最小,就是求R(G)-G最小,就是找R=G的点,也就是上图中45度斜线和碗状曲线相切的点。

像E步那样,用公式(2)求Shannon信道,并调整P(Y),就能得到R(G)。原来求信息率失真函数也用到迭代算法,也用到和公式(2)类似的公式。EM和VBEM算法之所以慢,除了因为没有调整P(Y),还和指导思想有关。因为认为增大负熵就能达到目的,所以设置初始参数时就想把负熵弄得小一点,比如把两个标准差d1和d2设得大一点,防止漏掉真模型。但是在计算试验中我发现,有时候选择较小的偏差,收敛反而更快。从文献数字和我的计算实验看,CM算法迭代5次收敛比较常见,而EM算法(包括改进的)达到收敛的迭代次数大多超过10次。

诚然,CM算法也不是完美无缺的。在少数极端情况下(比如两个分布重叠较多,两个分量比例相差较大时),初始值选择不当收敛也很慢。结合已有的EM算法研究中关于初始参数的研究成果,应该还能改进。

我上面只是证明了流行的EM算法收敛证明是错的,是否还有其他对的证明?我不能肯定。北大的马尽文教授是EM算法专家,做过很多推广和应用。他说有,我很期待。我以为如果有,可能和我的证明异途同归。我和VBEM的第一作者Neal教授通过信,他说要是E步减小Q(.)或F(.),那就太震动了。看来他一直相信流行的负熵只增不减证明。

现在回到“炼金术”话题。

实际上,把深度学习和炼金术联系起来的AliRahimi教授演讲标题是:

《从“炼金术”到“电力”的机器学习》,他并没有否定深度学习,只是说要加强理论研究,也不排除先有实践再有理论。

根据上面分析,可以说EM算法正在从“炼金术”向“冶金术”过渡。如过它在理论上停滞不前,如果我们把它神话,它就真像是炼金术了。反之,正视已有问题,寻找更简洁更有说服力理论,才能使“炼金术”成为可靠“冶金”工具。

作者简介:

鲁晨光,男,南京航空航天大学毕业(77级). 当过长沙市青年学术带头人,赴加拿访问学者,北师大数学系访问学者(汪培庄教授指导)…研究兴趣是:语义信息论,统计学习,色觉的数学和哲学, 美学和进化论,投资组合。专著有:《广义信息论》,《投资组合的熵理论和信息价值》,《色觉奥妙和哲学基本问题》,《美感奥妙和需求进化》。于《光学学报》,《机器人》,《通信学报》,《现代哲学》,《Int. J. of General System》等杂志上发表论文多篇。最近主要工作是把语义信息论用到统计学习,用以解决最大似然估计,贝叶斯推理, 多标签分类, 混合模型等问题。个人网站:http://survivor99.com/lcg/ 信箱:lcguang@foxmail.com。

前端开发中,单位的使用,有很多种,em、px等,本文主要讲解em。不过在做对比之前,我们还是先了解em的一些基础知识,

1、 浏览器的字体的默认大小是16px

2、如果元素设置字体大小(有,有,有设了字体大小……)

1 ÷ 父元素的font-size × 需要转换的像素值 = em值

3、如果元素没有设计字体大小(没有,没有没有设了字体大小……)

1 ÷ 元素自身的font-size × 需要转换的像素值 = em值

写下如下的代码:


初始显示效果

加一段css代码

从代码中我可以看,

1、p1没设置字体大小,p1的父级是浏览器的<html>,p1字体显示为16px; border的em值为1,宽度就为16px

2、p2设置了字体大小为20px,自然而然显示20px;border的em值为1,显示的宽度为20px;

3、p3给设置了一个字体大小为2em;p3_1的em就是相对于p3,p3_1的字体大小32px;border的em值为1,显示的宽度为32px;

如下图显示的效果:


进行对比可以得出以下结论:

一、从1和2对比可以看出,浏览器的默认字体大小是16px,em的是相对了父级的

二、从2和3看出,不管是设置em、还是设置像素px。都代表是:设置了字体大小

三、从1、2、3可以看出,元素width,height,border-weight等属性的em,相对元素自身字体的大小而言而言

做一个有博客的web前端自媒体人,专注web前端开发,关注用户体验,加我qq/微信交流:6135833