指数滑动平均(EMA:exponential moving average)[转]

2023-10-14 16:20

本文主要是介绍指数滑动平均(EMA:exponential moving average)[转],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

摘自:https://www.cnblogs.com/wuliytTaotao/p/9479958.html

参考:https://www.investopedia.com/terms/e/ema.asp

https://www.investopedia.com/terms/s/sma.asp

 

 

1. 用滑动平均估计局部均

  滑动平均(exponential moving average),或者叫做指数加权平均(exponentially weighted moving average),可以用来估计变量的局部均值,使得变量的更新与一段时间内的历史取值有关。

       变量vt时刻记为 为变量 vt 时刻的取值,即在不使用滑动平均模型时=,在使用滑动平均模型后,的更新公式如下:

, 其中FiltFreq为目标频率系数(具体叫法目前尚不清楚,有待深入研究),SampleFreq为信号采样频率,例如FiltFreq=20Hz, SampleFreq=16000Hz.

 

  上式中,β∈[0,1)。β=0相当于没有使用滑动平均。假设起始 ==0,β=0.9,之后每个时刻,依次对变量 v进行赋值,不使用滑动平均和使用滑动平均结果如下:

                             表 1  三种变量更新方式

https://img2018.cnblogs.com/blog/1351564/201906/1351564-20190615000526560-254363648.png

                   图 1:三种变量更新方式

 

  Andrew Ng在Course 2 Improving Deep Neural Networks中讲到,t时刻变量 v 的滑动平均值大致等于过去 1/(1−β) 个时刻 θ 值的平均。这个结论在滑动平均起始时相差比较大,所以有了Bias correction,将 vt 除以 (1−βt)修正对均值的估计。

加入了Bias correction后,v_biasedt的更新公式如下:

 

t越大,1 - 越接近 1,则公式(1)和(2)得到的结果 (和v_biase)将越来越近,如图 1 所示。

  当 β越大时,滑动平均得到的值越和 θ 的历史值相关。如果 β=0.9,则大致等于过去 10 个 θ 值的平均;如果 β=0.99,则大致等于过去 100 个 θ值的平均。

  滑动平均的好处:占内存少,不需要保存过去10个或者100个历史 θ值,就能够估计其均值。(当然,滑动平均不如将历史值全保存下来计算均值准确,但后者占用更多内存和计算成本更高)。

 

2. TensorFlow中使用滑动平均来更新变量(参数

  滑动平均可以看作是变量的过去一段时间取值的均值,相比对变量直接赋值而言,滑动平均得到的值在图像上更加平缓光滑,抖动性更小,不会因为某次的异常取值而使得滑动平均值波动很大,如图 1所示。

  TensorFlow 提供了 tf.train.ExponentialMovingAverage 来实现滑动平均。在初始化 ExponentialMovingAverage 时,需要提供一个衰减率(decay),即公式(1)(2)中的 β

。这个衰减率将用于控制模型的更新速度。ExponentialMovingAverage 对每一个变量(variable)会维护一个影子变量(shadow_variable),这个影子变量的初始值就是相应变量的初始值,而每次运行变量更新时,影子变量的值会更新为:

 

shadow_variable=decay⋅shadow_variable+(1−decay)⋅variable             (3)

 

公式(3)中的 shadow_variable 就是公式(1)中的 vt,公式(3)中的 variable 就是公式(1)中的 θt,公式(3)中的 decay 就是公式(1)中的 β

公式(3)中,decay 决定了影子变量的更新速度,decay 越大影子变量越趋于稳定。在实际运用中,decay一般会设成非常接近 1 的数(比如0.999或0.9999)。为了使得影子变量在训练前期可以更新更快,ExponentialMovingAverage 还提供了 num_updates 参数动态设置 decay 的大小。如果在初始化 ExponentialMovingAverage 时提供了 num_updates 参数,那么每次使用的衰减率将是:

 

min{decay,1+num_updates10+num_updates}              (4)

 

这一点其实和 Bias correction 很像。

TensorFlow 中使用 ExponentialMovingAverage 的例子:code 

(如果 GitHub 无法加载 .ipynb 文件,则将 .ipynb 文件的 URL 复制到网站 https://nbviewer.jupyter.org/)

 

3. 滑动平均为什么在测试过程中被使用

  滑动平均可以使模型在测试数据上更健壮(robust)。“采用随机梯度下降算法训练神经网络时,使用滑动平均在很多应用中都可以在一定程度上提高最终模型在测试数据上的表现。” 

  对神经网络边的权重 weights 使用滑动平均,得到对应的影子变量 shadow_weights。在训练过程仍然使用原来不带滑动平均的权重 weights,不然无法得到 weights 下一步更新的值,又怎么求下一步 weights 的影子变量 shadow_weights。之后在测试过程中使用 shadow_weights 来代替 weights 作为神经网络边的权重,这样在测试数据上效果更好。因为 shadow_weights 的更新更加平滑,对于随机梯度下降而言,更平滑的更新说明不会偏离最优点很远;对于梯度下降 batch gradient decent,我感觉影子变量作用不大,因为梯度下降的方向已经是最优的了,loss 一定减小;对于 mini-batch gradient decent,可以尝试滑动平均,毕竟 mini-batch gradient decent 对参数的更新也存在抖动。

设 decay=0.999,一个更直观的理解,在最后的 1000 次训练过程中,模型早已经训练完成,正处于抖动阶段,而滑动平均相当于将最后的 1000 次抖动进行了平均,这样得到的权重会更加 robust。

 

 

Python实例:

# -*- coding: utf-8 -*-
"""
Created on Sun Apr  8 22:16:57 2018
"""
import numpy as np
from matplotlib import pyplot as plt
#from scipy.signal import medfilt#%% Generage data
N = 10000
w = 501 # median filter window sizesigma = 0.1
data = np.random.random(N)*sigma + 1
#data[0] += sigma # make the first point biasedbreak_idx = int(N/2)
data[break_idx] += -sigma
data[break_idx:] += 1#%% median filter
def medfilt(data, w):# one-sided median filter for 1-D array# w - windows size, needs to be oddassert(w%2 == 1)L = len(data)data_filtered = np.zeros(L)startp = 0endp = 0for i in range(L):if i - w + 1 < 0:startp = 0else:startp = i - w + 1endp = i+1data_filtered[i] = np.median(data[startp:endp])return data_filtered#%% Exponentially weighted average with bias correction
beta = 1 - 1.0/w
data_filtered = np.zeros(len(data) + 1)
data_filtered_corrected = np.copy(data_filtered)
bias_correction_idx = 0data_filtered[0] = 0
for i in range(N):if (data[i] - data[i-1]) > 0.5:data_filtered[i+1] = 0 + (1 - beta) * data[i]bias_correction_idx = ielse:data_filtered[i+1] = beta * data_filtered[i] + (1 - beta) * data[i]# bias correction   data_filtered_corrected[i+1] = data_filtered[i+1] / (1 - beta ** (i+1 - bias_correction_idx))data_median = medfilt(data, w)plt.plot(data, label = 'raw')
#plt.plot(data_filtered[1:], label = 'filtered')
plt.plot(data_filtered_corrected[1:], label = 'filtered corrected')
plt.plot(data_median, label = 'median filter')
plt.legend()
plt.show()

生成的图形如下:

  

References

Course 2 Improving Deep Neural Networks by Andrew Ng

《TensorFlow实战Google深度学习框架》 4.4.3

 

这篇关于指数滑动平均(EMA:exponential moving average)[转]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/211677

相关文章

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

HumanNeRF:Free-viewpoint Rendering of Moving People from Monocular Video 翻译

HumanNeRF:单目视频中运动人物的自由视点绘制 引言。我们介绍了一种自由视点渲染方法- HumanNeRF -它适用于一个给定的单眼视频ofa人类执行复杂的身体运动,例如,从YouTube的视频。我们的方法可以在任何帧暂停视频,并从任意新的摄像机视点或甚至针对该特定帧和身体姿势的完整360度摄像机路径渲染主体。这项任务特别具有挑战性,因为它需要合成身体的照片级真实感细节,如从输入视频中可能

【leetcode详解】考试的最大困扰度(滑动窗口典例)

实战总结: sum += answerKey[right] == c; 经典操作,将判断语句转化为0, 1接收来计数//大问题分解: 对'T'还是'F'做修改, 传参为c//滑动窗口: 遍历, 维护left& right指向 及 c的个数, 更新不知从何下手写代码时:考虑先写好第一次的,然后以此为基础补充代码以适后续情况 题面: 解题感受: 思路总体好想, 实现略有挑战。 思路分析:

【每日一题】LeetCode 2379.得到K个黑块的最少涂色次数(字符串、滑动窗口)

【每日一题】LeetCode 2379.得到K个黑块的最少涂色次数(字符串、滑动窗口) 题目描述 给定一个字符串 blocks,其中每个字符代表一个颜色块,可以是 ‘W’(白色)或 ‘B’(黑色)。你需要找到一个至少包含 k 个连续黑色块的子串。每次操作可以将一个白色块变成黑色块。你的任务是找到至少出现一次连续 k 个黑色块的最少操作次数。 和该题目类似:【每日一题】LeetCode 202

【视频教程】手把手AppWizard轻松制作一个emWin滑动主界面控制框架,任意跳转控制(2024-09-06)

现在的新版AppWizard已经比较好用,用户可以轻松的创建各种项目常规界面。 比如早期创建一个支持滑动的主界面框架,并且可以跳转各种子界面,仅仅界面布局和各种图片格式转换都要花不少时间,而现在使用AppWizard,可以说轻轻松松,毫不费力。 用户唯一要做的就是根据自己的芯片性能做一定的速度优化。 视频: https://www.bilibili.com/video/BV17Rp3eLE

Flutter-listview的item左右滑动,删除item

import 'package:flutter/material.dart';//列表左右滑动删除void main() =>runApp(MaterialApp(home: HomePage(),));class HomePage extends StatelessWidget {final List<String> items = List.generate(20, (index) =>

【python 百度指数抓取】python 模拟登陆百度指数,图像识别百度指数

一、算法思想 目的奔着去抓取百度指数的搜索指数,搜索指数的爬虫不像是其他爬虫,难度系数很高,分析之后发现是图片,坑爹的狠,想了下,由于之前做过身份证号码识别,验证码识别之类,豁然开朗,不就是图像识别麽,图像识别我不怕你,于是就有了思路,果然有异曲同工之妙,最后成功被我攻破了,大致思路如下: 1、首先得模拟登陆百度账号(用selenium+PhantomJS模拟登陆百度,获取cookie) 2

滑动窗口——632. 最小区间

最近在抽时间写LC上的一个专栏——2024春招冲刺百题计划。挑着做,做了几道和滑动窗口相关的题目,632. 最小区间,LC上标记为困难,第一次写完全没有思考,参考了别人写的答案茅塞顿开,特此记录以鞭策自己学习。最近实习结束回到学校后,一边搞科研,自己本来想一天写一篇博客,以此鞭策自己学习,但自己研究方向和后端丝毫不沾边,自己最近又没有学习新的知识用以记录博客,也甚是悔已。人生如是,

【Android】NestedScrollView的简单用法与滚动冲突、滑动冲突

一、NestedScrollView 1. 什么是 NestedScrollView NestedScrollView 是 Android 中一个用于处理垂直方向滚动的布局组件,它继承自 FrameLayout,同时支持嵌套滑动(Nested Scrolling)机制。相比于传统的 ScrollView,NestedScrollView 专为解决嵌套滚动冲突问题设计,能够与其他支持嵌套滑动的子