(Tensorflow之六)滑动平均模型ExponentialMovingAverage

本文详细介绍了衰减平均算法的计算方法及应用,通过数学公式展示了如何动态调整衰减率以提高模型收敛速度,并提供了TensorFlow实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、计算方法

{a1,a2,a3,...,an},其衰减率为decay,对应的影子变量为:
{m1,m2,m3,...,mn},则:

mn=decaymn1+(1decay)an

可以展开来分析:
m1=a1

m2=decaya1+(1decay)a2

m3=decaym2+(1decay)a3=decay2a1+(1decay)decaya2+(1decay)a3

m4=decaym3+(1decay)a4=decay3a1+(1decay)decay2a2+(1decay)decaya3+(1decay)a4

......

以其类推
mn=decaymn1+(1decay)an=decayn1a1+decayn2(1decay)+...+(1decay)an

一般而言,为了使模型趋于收敛,会选择decay为接近1的数,例如:
decay = 0.99;
那么:
m1=a1

m2=0.99a1+0.01a2

m3=0.99m2+0.01a3=0.992a1+0.010.99a2+0.01a3

我们发现初始值对后面影响非常大,若初始值与真实值偏差较大时,函数收敛速度非常慢;为了解决该问题,tensorflow提供了num_updates参数来动态设置decay的大小;
decay=min{DECAY,1+num_updates10+num_updates}

例:
DECAY = 0.99
第一轮,先设num_updates = 0;
那么:

decay=min{0.99,1+010+0}=0.1

则:
m1=a1

m2=0.1a1+0.9a2

第二轮,可设num_updates = 100
那么:
decay=min{0.99,1+10110+100}=0.91

则:
m3=0.91m2+0.09a3

以此类推,从而可以动态调整decay值大小。
import tensorflow as tf

test1 = tf.Variable(0,dtype=tf.float32)
num_updates = tf.Variable(0,dtype=tf.float32)
DECAY = 0.99

Moving_average = tf.train.ExponentialMovingAverage(DECAY,num_updates)

#跟新test1
Moving_average_op = Moving_average.apply([test1])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    #第一次打印出初始值,滑动平均值,输出值应该为[0,0]
    print(sess.run([test1,Moving_average.average(test1)]))

    #更新test1
    sess.run(tf.assign(test1,3))
    sess.run(Moving_average_op)
    #第二次打印初始值,滑动平均值,输出值应该为[3,0],滑动平均值计算0*0.1+0.9*3=2.7
    print(sess.run([test1,Moving_average.average(test1)]))

    #更新test2与num_updates
    sess.run(tf.assign(test1,5))
    sess.run(tf.assign(num_updates,90))
    sess.run(Moving_average_op)
    #第三次打印初始值,滑动平均值,输出值应该为[3,0],滑动平均值计算2.7*0.91+5*0.09
    print(sess.run([test1,Moving_average.average(test1)]))   

输出值

[0.0, 0.0]
[3.0, 2.6999998]
[5.0, 2.9069998]
### 滑动平均算法的实现与原理 滑动平均算法是一种常用的滤波方法,其核心思想是通过对一系列数据点进行平均处理,从而平滑掉数据中的噪声[^1]。具体而言,该算法的目标是在一个采样周期内寻找一个值 \( \overline{y} \),使得该值与各测量值 \( y(i) \) 之间的误差平方和最小化。 在实际应用中,滑动平均算法通常分为两种形式:**简单滑动平均**和**指数滑动平均**。 #### 简单滑动平均(Simple Moving Average, SMA) 简单滑动平均的基本公式为: \[ \overline{y}_n = \frac{1}{N} \sum_{i=1}^{N} y(i) \] 其中,\( \overline{y}_n \) 表示当前窗口内的平均值,\( N \) 是窗口大小,\( y(i) \) 是第 \( i \) 个采样值。这种方法通过计算固定窗口内所有采样值的算术平均来实现平滑效果[^1]。 以下是使用 Java 实现简单滑动平均的一个示例代码: ```java import java.util.LinkedList; import java.util.Queue; public class SimpleMovingAverage { private Queue<Double> window; private int size; private double sum; public SimpleMovingAverage(int size) { this.size = size; this.window = new LinkedList<>(); this.sum = 0.0; } public void addData(double data) { if (window.size() == size) { sum -= window.poll(); } window.offer(data); sum += data; } public double getAverage() { if (window.isEmpty()) return 0.0; return sum / window.size(); } public static void main(String[] args) { int windowSize = 5; SimpleMovingAverage sma = new SimpleMovingAverage(windowSize); for (int i = 0; i < 10; i++) { double data = Math.random() * 100.0; sma.addData(data); System.out.println("原始数据: " + data + ", 平均值: " + sma.getAverage()); } } } ``` #### 指数滑动平均(Exponential Moving Average, EMA) 相比于简单滑动平均,指数滑动平均赋予不同时间点的数据不同的权重,最近的数据点权重更大,而较早的数据点权重逐渐减小。其公式为: \[ Y_n = \alpha Y_{n-1} + (1 - \alpha) X_n \] 其中,\( Y_n \) 是本次滤波结果,\( Y_{n-1} \) 是上次滤波结果,\( X_n \) 是本次采样值,\( \alpha \) 是滤波系数,取值范围为 [0, 1]。较小的 \( \alpha \) 值表示更倾向于保留历史数据的影响,而较大的 \( \alpha \) 值则更关注当前数据的变化[^3]。 以下是一个 Python 实现指数滑动平均的示例代码: ```python class ExponentialMovingAverage: def __init__(self, alpha): self.alpha = alpha self.filtered_value = None def filter(self, value): if self.filtered_value is None: self.filtered_value = value else: self.filtered_value = self.alpha * self.filtered_value + (1 - self.alpha) * value return self.filtered_value # 示例运行 ema = ExponentialMovingAverage(alpha=0.9) for i in range(10): data = i ** 2 # 模拟输入数据 filtered_data = ema.filter(data) print(f"原始数据: {data}, 滤波结果: {filtered_data}") ``` ### 总结 滑动平均算法的核心在于通过对数据进行加权或非加权平均来减少噪声的影响。简单滑动平均适用于对等权重数据的场景,而指数滑动平均更适合需要动态调整权重的应用场合[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值