目录
熵的公式为:
假设 事件X 共有n种可能,发生 xi 的概率为 p(xi) ,那么该事件的熵 H(X) 为:
信息量:
任何事件都会承载着一定的信息量,包括已经发生的事件和未发生的事件,只是它们承载的信息量会有所不同。如昨天下雨这个已知事件,因为已经发生,既定事实,那么它的信息量就为0。如明天会下雨这个事件,因为未有发生,那么这个事件的信息量就大。
熵(Entropy)
混乱程度,不确定性,还是信息量?
不同的人对熵有不同的解释:混乱程度,不确定性,惊奇程度,不可预测性,信息量等等,面对如此多的解释,第一次接触时难免困惑。
信息论中熵的概念首次被香农提出,目的是寻找一种高效/无损地编码信息的方法:以编码后数据的平均长度来衡量高效性,平均长度越小越高效;同时还需满足“无损”的条件,即编码后不能有原始信息的丢失。这样,香农提出了熵的定义:无损编码事件信息的最小平均编码长度。
熵如何计算
已知男女所占比率各为50%,所有人群中抽烟占40%,不抽烟占60%,而在抽烟人群中95%都是男性,不抽烟人群中80%是女性。如果我们已知一个人抽烟,那么我们可以很有信心的说该烟民为男性,但是我们如何去度量这种信心呢?因此,我们引入了熵,熵是用来度量该系统的不确定性,我们有多大的把握说出该烟民为男性。试想一下,当烟民中男女比例各占50%的时候,这是最不容易确定该烟民性别的情况,所以这个时候熵很高(信息很混乱)。
当男女烟民各占50%时,熵的计算过程为(以2为底):
我们令事件X不抽烟为a,抽烟为b,则X:{a=No-smoking, b=smoking}。
可以看到烟民中性别分布要比非烟民更加不均衡,在这种情况下如果我们知道ta抽烟,则我们对ta的性别的判断更加准确。
抽烟事件整体的熵为:
我们在知道了烟民和非烟民中男女比例后要比瞎猜要准确多少如何度量呢,这时候引入新的概念,信息增益:
我们有10个球,5个白的,5个黑的,那么设随机变量X为取一个球,颜色的概率分布
P(白) = p(黑) = 0.5
H(X) = -0.5log(0.5) - 0.5log(0.5) = 1
联合熵(Joint Entropy)
两个随机变量X,Y的联合分布,可以形成联合熵(Joint Entropy),用H(X, Y)表示。
即:H(X, Y) = -Σ p(x, y) log(x, y)
还是上面的列子,这次我们弄A和B两个盒子,把10个球先放进去。记随机变量X为取到某种颜色球的概率分布,随机变量Y为取到某个盒子的概率分布
第一次我们把5个黑球放进A盒子,5个白球放进B盒子,联合概率分布如下:
第二次我们把2个黑球3个白球放入A盒,3个黑球2个白球放入B盒,联合概率分布如下:
根据熵和联合熵的公式计算一下:
第一次的:
H(X,Y) = -0.5log(0.5) - 0.5log(0.5) - 0log(0) - 0log(0)= 1
H(X) = -0.5log(0.5) - 0.5log(0.5)= 1
H(Y) = -0.5log(0.5) - 0.5log(0.5)= 1
第二次的,不管取的哪个盒子,取到黑球和白球的概率还是一样的0.5:
H(X,Y) = -0.2log(0.2) - 0.3log(0.3) -0.2log(0.2) - 0.3log(0.3)= 1.97
H(X) = -0.5log(0.5) - 0.5log(0.5)= 1
H(Y) = -0.5log(0.5) - 0.5log(0.5)= 1
于是可以看出来,单论X和Y的不确定性,其实两种分类是一样的,信息熵都是1,但是联合熵就不同了,一个是1,一个是1.97。第一个分类为什么是1呢,因为我们确定了盒子就确定了球的颜色,整个系统是非常有序的,需要表达的信息量和表达盒子的信息量是一样的。但第二种分法,我们抽出一个盒子以后,对球的颜色还是不太知道,不过已经比原来不分盒子要好点,最少我们知道哪种颜色多一个,于是联合熵就没有等于两个随机变量的信息熵之和,而是小了一点。
这里再说联合熵所表达的物理含义是,对一个两个随机变量组成的随机系统,我们可以先观察一个随机变量获取信息量,观察完后,我们可以在拥有这个信息量的基础上观察第二个随机变量的信息量。如果两个随机变量毫无关系,那么H(X, Y) = H(X) + H(Y)
条件熵
条件熵(Conditional entropy)
条件熵 H(Y|X) 表示在已知随机变量 X 的条件下随机变量 Y 的不确定性。条件熵 H(Y|X) 定义为 X 给定条件下 Y 的条件概率分布的熵对 X 的数学期望:
我们再对上面的两种分类计算一下条件熵:
第一次的:
H(Y|X) = -0.5log(1) - 0log(0) - 0log(0) - 0.5log(1) = 0
第二次的:
H(Y|X) = -0.2log(0.4) - 0.3log(0.6) - 0.3log(0.6) - 0.2log(0.4) = 0.97
惊奇的发现:
H(Y|X) = H(X,Y) - H(X)
其实条件熵就是在X确定了的情况下,我们要知道Y还需要多少信息量
第一种分法,盒子一确定我们就知道球的颜色了,于是条件熵是0
第二种分法,确定了盒子我们还是得接着猜,于是条件熵接近于H(Y),第一次分类没啥用。。。这里就回想起了之前看得决策树算法ID3,其实就是做了一次分类之后,再看确定分类还需要多少信息量——条件熵
交叉熵(Cross Entropy)
其实交叉熵应该放在相对熵前面讲。
相对熵用来衡量在给定的真实分布下,使用非真实分布所指定的策略消除系统的不确定性所需要付出的努力的大小,也就是需要的信息量。
最低的交叉熵就是原分布的信息熵,此时p(x) = q(x)
那么这个交叉熵到底好不好呢,得跟原来的真实分布做比较,于是有了下面的相对熵。
具体例子也在下面一起说。
交叉熵损失函数计算
有三种可预测类别:猫、狗、猪。假设我们当前有两个模型(参数不同),这两个模型都是通过sigmoid/softmax的方式得到对于每个预测结果的概率值:
模型1:
预测 | 真实 | 是否正确 |
---|---|---|
0.3 0.3 0.4 | 0 0 1 (猪) | 正确 |
0.3 0.4 0.3 | 0 1 0 (狗) | 正确 |
0.1 0.2 0.7 | 1 0 0 (猫) | 错误 |
模型1对于样本1和样本2以非常微弱的优势判断正确,对于样本3的判断则彻底错误。
模型2:
预测 | 真实 | 是否正确 |
---|---|---|
0.1 0.2 0.7 | 0 0 1 (猪) | 正确 |
0.1 0.7 0.2 | 0 1 0 (狗) | 正确 |
0.3 0.4 0.3 | 1 0 0 (猫) | 错误 |
模型2对于样本1和样本2判断非常准确,对于样本3判断错误,但是相对来说没有错得太离谱。
现在我们利用这个表达式计算上面例子中的损失函数值:
模型1:
对所有样本的loss求平均:
模型2:
对所有样本的loss求平均:
FL的关键概念
数据隐私:适用于敏感或隐私数据应用。
数据分布:训练分布在大量设备或服务器上;模型应该能够泛化到新的数据。
模型聚合:跨不同客户端更新的模型并且聚合生成单一的全局模型,模型的聚合方式如下:
-
简单平均:对所有客户端进行平均
-
加权平均:在平均每个模型之前,根据模型的质量,或其训练数据的数量进行加权。
-
联邦平均:这在减少通信开销方面很有用,并有助于提高考虑模型更新和使用的本地数据差异的全局模型的收敛性。
-
混合方法:结合上面多种模型聚合技术。
通信开销:客户端与服务器之间模型更新的传输,需要考虑通信协议和模型更新的频率。
收敛性:FL中的一个关键因素是模型收敛到一个关于数据的分布式性质的良好解决方案。
实现FL的简单步骤
-
定义模型体系结构
-
将数据划分为客户端数据集
-
在客户端数据集上训练模型
-
更新全局模型
-
重复上面的学习过程
Tensorflow代码示例
首先我们先建立一个简单的服务端:
import tensorflow as tf
# Set up a server and some client devices
server = tf.keras.server.Server()
devices = [tf.keras.server.ClientDevice(worker_id=i) for i in range(4)]
# Define a simple model and compile it
inputs = tf.keras.Input(shape=(10,))
outputs = tf.keras.layers.Dense(2, activation='softmax')(inputs)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Define a federated dataset and iterate over it
federated_dataset = tf.keras.experimental.get_federated_dataset(devices, model, x=X, y=y)
for x, y in federated_dataset:
# Train the model on the client data
model.fit(x, y)
然后我们实现模型聚合步骤:
1、简单平均
# Average the updated model weights
model_weights = model.get_weights()
for device in devices:
device_weights = device.get_weights()
for i, (model_weight, device_weight) in enumerate(zip(model_weights, device_weights)):
model_weights[i] = (model_weight + device_weight) / len(devices)
# Update the model with the averaged weights
model.set_weights(model_weights)
2、加权平均
# Average the updated model weights using weights based on the quality of the model or the amount of data used to train it
model_weights = model.get_weights()
total_weight = 0
for device in devices:
device_weights = device.get_weights()
weight = compute_weight(device) # Replace this with a function that returns the weight for the device
total_weight += weight
for i, (model_weight, device_weight) in enumerate(zip(model_weights, device_weights)):
model_weights[i] = model_weight + (device_weight - model_weight) * (weight / total_weight)
# Update the model with the averaged weights
model.set_weights(model_weights)
3、联邦平均
# Use federated averaging to aggregate the updated models
model_weights = model.get_weights()
client_weights = []
for device in devices:
client_weights.append(device.get_weights())
server_weights = model_weights
for _ in range(num_rounds):
for i, device in enumerate(devices):
device.set_weights(server_weights)
model.fit(x[i], y[i])
client_weights[i] = model.get_weights()
server_weights = server.federated_average(client_weights)
# Update the model with the averaged weights
model.set_weights(server_weights)
数学符号正三角和倒三角
正三角形是在高中物理上经常出现的一个符号,它是希腊字母,读作:delta,它表示的是某个物理量的变化。例如:Δv=v2-v1,Δt=t2-t1
而倒三角形是在高等数学和物理学里面才有的一个符号,它表示的是物理量:梯度。▽ 是梯度算子(在空间各方向上的全微分),比如电场强度E=-▽U,就表示电场强度E是电势U的负梯度,它是矢量,方向指向电势降落(梯度求增量,故负号表示降落)最快的方向。
在数学公式中U表示
在特定情况下,所讨论的所有集合是一个给定的全集 U 的子集