精华内容
下载资源
问答
  • 浅谈测量的系统误差与偶然误差 测量工作中的仪器无论多么精良,观测者如何仔细地操作,仍不可 能得到绝对准确的测量成果,测量成果中,总是不可避免地存在误差。 例如,往、返丈量某段距离若干次,观测结果总不一致...
  • 利用AIS进行雷达标校在军事领域已得到广泛应用。但在标校过程中发现,校后雷达精度很多时候没有得到显著提高。...通过实测数据证明,所提出的方法能够得到较准确的系统误差估计值,对雷达的系统误差进行了有效的校准。
  • 引入时间信号误差分析方法及对应滤波技术,其以激光信号计时原理为基础,对信号测量过程中可能出现的误差因素进行分析,并基于时间序列统计理论对时间序列信号进行预处理、时域特征分析以及频域特征分析,发现时间...
  • 由于这个积分项会将前面若干次的误差进行累计,所以可以很好的消除稳态误差(假设在仅有比例项的情况下,系统卡在稳态误差了,即上例中的0.8,由于加入了积分项的存在,会让输入增大,从而使得水缸的水位可以大于0.8...

    一文读懂PID控制算法(抛弃公式,从原理上真正理解PID控制)

    PID控制应该算是应用非常广泛的控制算法了。小到控制一个元件的温度,大到控制无人机的飞行姿态和飞行速度等等,都可以使用PID控制。这里我们从原理上来理解PID控制。
    PID(proportion integration differentiation)其实就是指比例,积分,微分控制。先把图片和公式摆出来,看不懂没关系。(一开始看这个算法,公式能看懂,具体怎么用怎么写代码也知道,但是就是不知道原理,不知道为什么要用比例,微分,积分这3个项才能实现最好的控制,用其中两个为什么不行,用了3个项能好在哪里,每一个项各有什么作用

    PID控制算法原理

    PID控制算法公式

    总的来说,当得到系统的输出后,将输出经过比例,积分,微分3种运算方式,叠加到输入中,从而控制系统的行为,下面用一个简单的实例来说明。

    比例控制算法

    我们先说PID中最简单的比例控制,抛开其他两个不谈。还是用一个经典的例子吧。假设我有一个水缸,最终的控制目的是要保证水缸里的水位永远的维持在1米的高度。假设初试时刻,水缸里的水位是0.2米,那么当前时刻的水位和目标水位之间是存在一个误差的error,且error为0.8.这个时候,假设旁边站着一个人,这个人通过往缸里加水的方式来控制水位。如果单纯的用比例控制算法,就是指加入的水量u和误差error是成正比的。即
    u=kp*error
    假设kp取0.5,
    那么t=1时(表示第1次加水,也就是第一次对系统施加控制),那么u=0.5*0.8=0.4,所以这一次加入的水量会使水位在0.2的基础上上升0.4,达到0.6.
    接着,t=2时刻(第2次施加控制),当前水位是0.6,所以error是0.4。u=0.5*0.4=0.2,会使水位再次上升0.2,达到0.8.
    如此这么循环下去,就是比例控制算法的运行方法。
    可以看到,最终水位会达到我们需要的1米。
    但是,单单的比例控制存在着一些不足,其中一点就是 –稳态误差!(我也是看了很多,并且想了好久才想通什么是稳态误差以及为什么有稳态误差)。
    像上述的例子,根据kp取值不同,系统最后都会达到1米,不会有稳态误差。但是,考虑另外一种情况,假设这个水缸在加水的过程中,存在漏水的情况,假设每次加水的过程,都会漏掉0.1米高度的水。仍然假设kp取0.5,那么会存在着某种情况,假设经过几次加水,水缸中的水位到0.8时,水位将不会再变换!!!因为,水位为0.8,则误差error=0.2. 所以每次往水缸中加水的量为u=0.5*0.2=0.1.同时,每次加水缸里又会流出去0.1米的水!!!加入的水和流出的水相抵消,水位将不再变化!!
    也就是说,我的目标是1米,但是最后系统达到0.8米的水位就不在变化了,且系统已经达到稳定。由此产生的误差就是稳态误差了。
    (在实际情况中,这种类似水缸漏水的情况往往更加常见,比如控制汽车运动,摩擦阻力就相当于是“漏水”,控制机械臂、无人机的飞行,各类阻力和消耗都可以理解为本例中的“漏水”)
    所以,单独的比例控制,在很多时候并不能满足要求。

    积分控制算法

    还是用上面的例子,如果仅仅用比例,可以发现存在暂态误差,最后的水位就卡在0.8了。于是,在控制中,我们再引入一个分量,该分量和误差的积分是正比关系。所以,比例+积分控制算法为:
    u=kp*error+ ki ∗ ∫ error
    还是用上面的例子来说明,第一次的误差error是0.8,第二次的误差是0.4,至此,误差的积分(离散情况下积分其实就是做累加), error=0.8+0.4=1.2. 这个时候的控制量,除了比例的那一部分,还有一部分就是一个系数ki乘以这个积分项。由于这个积分项会将前面若干次的误差进行累计,所以可以很好的消除稳态误差(假设在仅有比例项的情况下,系统卡在稳态误差了,即上例中的0.8,由于加入了积分项的存在,会让输入增大,从而使得水缸的水位可以大于0.8,渐渐到达目标的1.0.)这就是积分项的作用。

    微分控制算法

    换一个另外的例子,考虑刹车情况。平稳的驾驶车辆,当发现前面有红灯时,为了使得行车平稳,基本上提前几十米就放松油门并踩刹车了。当车辆离停车线非常近的时候,则使劲踩刹车,使车辆停下来。整个过程可以看做一个加入微分的控制策略。
    微分,说白了在离散情况下,就是error的差值,就是t时刻和t-1时刻error的差,即u=kd*(error(t)-error(t-1)),其中的kd是一个系数项。可以看到,在刹车过程中,因为error是越来越小的,所以这个微分控制项一定是负数,在控制中加入一个负数项,他存在的作用就是为了防止汽车由于刹车不及时而闯过了线。从常识上可以理解,越是靠近停车线,越是应该注意踩刹车,不能让车过线,所以这个微分项的作用,就可以理解为刹车,当车离停车线很近并且车速还很快时,这个微分项的绝对值(实际上是一个负数)就会很大,从而表示应该用力踩刹车才能让车停下来。
    切换到上面给水缸加水的例子,就是当发现水缸里的水快要接近1的时候,加入微分项,可以防止给水缸里的水加到超过1米的高度,说白了就是减少控制过程中的震荡。

    现在在回头看这个公式,就很清楚了
    这里写图片描述
    括号内第一项是比例项,第二项是积分项,第三项是微分项,前面仅仅是一个系数。很多情况下,仅仅需要在离散的时候使用,则控制可以化为
    这里写图片描述
    这里写图片描述
    每一项前面都有系数,这些系数都是需要实验中去尝试然后确定的,为了方便起见,将这些系数进行统一一下:
    这里写图片描述
    这样看就清晰很多了,且比例,微分,积分每个项前面都有一个系数,且离散化的公式,很适合编程实现。
    讲到这里,PID的原理和方法就说完了,剩下的就是实践了。在真正的工程实践中,最难的是如果确定三个项的系数,这就需要大量的实验以及经验来决定了。通过不断的尝试和正确的思考,就能选取合适的系数,实现优良的控制器。

    展开全文
  • 在频率扫描干涉法绝对距离测量过程中,目标的运动会对测量结果引入误差,经推导发现运动误差与激光扫频终点频率以及扫频过程中的光程差位移量有关。前者可直接通过高精度波长计测量,对于后者,提出了外差干涉频分...
  • OFDM完整仿真过程及解释(MATLAB)

    万次阅读 多人点赞 2019-04-19 17:03:45
    看书上ofdm介绍挺简单的,自己来仿真才发现很多知识点都不知道; 2.花了很长时间才理清整个ofdm过程,网上的程序都是一段一段的,不能直接理解整个过程。所以想着自己来做一个完整过程的仿真,加深理解; 3.基带信号...

    因为是复制过来,如果出现图片显示不完整以及需要源程序请点击下面链接查看原文:

    OFDM完整仿真过程及解释(MATLAB) - 子木的文章 - 知乎

    点击这里访问原文

    后面的更新没有同步,点上面链接可以看更新部分。

     

    目录:

    一、说明

    二、ofdm总体概述

    三、基本原理

    四、过程中涉及的技术

    五、OFDM基本参数的选择

    六、OFDM的MATLAB仿真程序

     

    一、说明

    0.能找到这篇文章,说明对ofdm已经有一点了解,所以其原理就不再赘述,这篇代码的目的只是希望能对ofdm整个过程有一个理解;

    1.看书上ofdm介绍挺简单的,自己来仿真才发现很多知识点都不知道;

    2.花了很长时间才理清整个ofdm过程,网上的程序都是一段一段的,不能直接理解整个过程。所以想着自己来做一个完整过程的仿真,加深理解;

    3.基带信号能完成整个过程,但是想加进频带传输这一部分,就完整了;

    4.信道部分想用瑞利信道的,程序写出来了,但是误差和信道估计这一块还不是很明白,所以就先用的高斯信道;

    5.不足之处欢迎指正。。。。

    二、概述

    OFDM是一种特殊的多载波传输方案,它可以被看作是一种调制技术,也可以被当作一种复用技术。

    简单来说:OFDM是一种多载波的传输方法,它将频带划分为多个子信道并行传输数据,将高速数据流分成多个并行的低速数据流,然后调制到每个信道的子载波上进行传输。由于它将非平坦衰落无线信道转化成多个正交平坦衰落的子信道,从而可消除信道波形间的干扰,达到对抗多径衰落的目的。

    正交频分复用(OFDM)是对多载波调制(MCM)的一种改进,在。它的特点是:各子载波相互正交,所以扩频调制后的频谱可以相互重叠,不但减少了子载波间的相互干扰,还大大提高了频谱利用率。

    选择OFDM的一个很大的原因是该系统能够很好的对抗频率选择性衰落和窄带干扰。在单载波系统中,一次衰落或者干扰会导致整个链路失效,但是在多载波系统中,某一时刻只会有少部分的子信道受到深衰落的影响。

    三、基本原理

    3.1 OFDM系统收发机的典型(根据实际需要可添/删部分)框图如下:

    OFDM收发机框图

    其中,上半部分对应于发射机链路,下半部分对应于接收机链路。

    发送端将被传输的数字信号转换成子载波幅度和相位的映射,并进行离散傅里叶变换(IDFT),将数据的频谱表达式变到时域上。IFFT和IDFT变换的作用相同,只是有更高的计算效率,所以适用于所有的应用系统。接收端进行与发送端相反的操作,用FFT变换分解,子载波的幅度和相位最终转换回数字信号。

    这里理解为传输的频域信号是因为IFFT是从频域到时域,实际上这里IFFT充当的是一个实现子载波正交的作用,具体可以推导其DFT公式。知乎里公式编辑太麻烦了。

     

    3.2 OFDM调制与解调

    一个OFDM符号之内包括多个经过调制的子载波的合成信号,其中每个子载波都可以收到psk(相移键控)和qam(正交幅度调制)的调制。

    OFDM发射机将信息比特流映射成一个psk或qam符号序列,之后将串行的符号序列转换为并行符号流。每N个经过串并转换的符号被不同的子载波调制。

    OFDM符号是N个并行符号的复合信号,若单个串行符号的传输时间(周期)是Ts,则一个OFDM符号的持续时间(周期)Tsym=N*Ts。

    频域调制信号X[k]的频率为:fk=k/Tsym,子载波数量为N,则k=0,1,2.....N-1。(由DFT原理推导)

    四、过程中涉及的技术

    为什么要用?怎么用?

    4.1 保护间隔

    多径信道会对OFDM符号造成ISI影响,破坏了子载波间的正交性。故需要采取一些方法来消除多径信道带来的符号间干扰(ISI)影响,即插入保护间隔。

    保护间隔有两种插入方法:一种是补零(zp),即在保护间隔中填充0;另一种是插入循环前缀(cp)或循环后缀(cs)实现OFDM的循环扩展(为了某种连续性)。

    zp是在保护间隔内不插入任何信号,但是在这种情况下,由于多径传播的影响,会产生载波间干扰(ICI),即不同的子载波间会产生干扰。

    一般采用cp。cp是将OFDM后部的采样复制到前面,长度为Tcp,故每个符号的长度为Tsym=Tsub+Tcp,Tsub为数据部分子载波数。Tcp大于或等于多径时延,符号间的ISI影响将被限制在保护间隔中,因此不会影响下一个OFDM的FFT变换。

    4.2交织

    交织的作用是将突发错误转换为随机错误,有利于前向纠错码的译码,提高了整个通信系统的可靠性。交织由两个变换过程组成。第一次变换保证了相邻的编码比特被映射到不相邻的子载波上。第二次变换保证了相邻的编码比特被分别映射到星座图的重要和非重要比特上,避免出现长时间的低比特位映射。

    交织块的长度Ncbps,对qpsk、16qam、64qam分别为2、4、6,s=Ncbps/2,d=16。

    4.3信道编码

    由于移动通信存在干扰和衰落,在信号传输过程中将出现差错,故对数字信号必须采用纠、检错技术,即纠、检错编码技术,以增强数据在信道中传输时抵御各种干扰的能力,提高系统的可靠性。

    这里的信道编码一般采用卷积编码,Viterbi译码。

    卷积编码是现代数字通信系统中常见的一种前向纠错码,区别于常规的线性分组码,卷积编码的码字输出不仅与当前时刻的信息符号输入有关,还与之前输入的信息符号有关。

    4.4 扩频

    “扩频通信技术是一种信息传输方式,其信号所占有的频带宽度远大于所传信息必需的最小带宽;频带的扩展是通过一个独立的码序列来完成,用编码及调制的方法来实现的,与所传信息数据无关;在接收端则用同样的码进行相关同步接收、解扩及恢复所传信息数据”

    根据香农定理,带宽和信噪比可用互换,扩频扩展了带宽,则对信噪比的要求可降低。

    4.5 导频

    导频不携带信息,导频是双方已知的数据,是用来做信道估计的。

    在接收机中,虽然利用接收到的段训练序列、长训练序列可以进行信道均衡、频率偏差校正,但符号还会存在一定的剩余偏差,且偏差会随着时间的累积而累积,会造成所有子载波产生一定的相位偏移。因此,还需要不断地对参考相位进行跟踪。要能实现这个功能,需要在52个非0子载波中插入导频符号。

    4.6 RF(射频)调制

    OFDM调制器的输出产生了一个基带信号,将此基带信号与所需传输的频率进行混频操作,利用模拟技术或数字上变频可完成。由于数字调制技术提高了处理I、Q信道之间的匹配性和数字IQ调制器相位的准确性,将会更加精确。

    五、OFDM基本参数的选择

    5.1 各种OFDM参数的选择就是需要在多项要求冲突中进行折衷考虑。通常来说,首先要确认3个参数:带宽、比特率、及保护间隔。

    5.1.1 按照惯例,保护间隔的时间长度应该为应用移动环境信道的时延扩展均方根值的2~4倍。

    5.1.2 确定保护间隔之后,则OFDM符号周期长度就确定了。为了最大限度的减少由于插入保护比特所带来的信噪比的损失,OFDM符号周期长度远远大于保护间隔长度。但是符号周期又不能任意大,否则就需要更多的子载波,带宽不变,子载波间隔就变小,系统的实现复杂度就提高了,而且还加大了系统的峰值平均功率比,同时系统对频率偏差更加敏感。因此,一般选择符号周期长度是保护间隔的5倍,这样,由于插入保护比特所造成的信噪比损耗只有1dB左右。

    5.1.3 确定保护间隔和符号周期长度之后,子载波的数量可由-3dB带宽除以子载波间隔(即去掉保护间隔之后的符号周期的倒数)得到。或者可由所要求比特速率除以每个子信道的比特速率来确定子载波的数量。每个信道中所传输的比特速率可由调制类型、编码速率、和符号速率来确定。

    5.2 有用符号持续时间T

    T对子载波之间间隔、译码的等待周期都有影响,为了保持数据的吞吐量,子载波数目和FFT的长度要有相对较大的数量,这就导致符号持续时间变长。总之,符号周期长度的选择以保证信道的稳定为前提。

    5.3 子载波数

    N=1/T

    其数值与FFT处理过的复数点数相对应,需适应数据速率和保护间隔的要求。

    5.4 调制模式

    OFDM系统的调制模式基于功率和频谱利用率来选择,可采用qam、psk。

    为了使所有的点有相同的平均功率,二进制序列映射后的复数要归一化。(BPSK\QPSK\16QAM\64QAM分别对应乘以1、1/根号2、1/根号10、1/根号42),解调的时候再变回去。

    5.5 以具体实例说明;

    要求:(1)比特率为25Mbit/s(2)可容忍的时延扩展为200ns(3)带宽小于18MHz。

    1)由200ns时延扩展得保护间隔为800ns;

    2)由保护间隔800ns得符号周期长度6*800ns=4.8us;

    3)子载波的间隔选取4.8-0.8=4us的倒数,即250KHz;

    4)由所要求的比特速率与OFDM符号速率的比值,每个符号需要传送的比特:25Mbit/s)/(1/4.8us)=120bit。

    5)为了完成上面120bit/符号,有两种选择:利用16QAM和码率为1/2的编码方法,这样每个子载波携带2bit的有用信息,因此需要60个子载波;另一种是利用QPSK和码率为3/4的编码方法,每个子载波携带1.5bit信息。因此需要80个子载波,然而80个子载波意外着带宽:80*250KHz=20MHz,大于所给带宽要求,故取第一种,即60个子载波。可利用64点IFFT来实现,剩余4个子载波补0.

    六、OFDM的MATLAB仿真主程序

    clc;
    clear;
    
    %————————————————————————————————————————————————————————%
    %q1:ifft点数难道不是应该等于子载波数吗?子载波数与ifft点数的关系?
    %a:ifft点数等于子载波数
    %q2:对矩阵进行fft?
    %a:y可以是一向量或矩阵,若y为向量,则Y是y的FFT,并且与y具有相同的长度。若y为一矩阵,则Y是对矩阵的每一列向量进行FFT。
    %q3:怎么对ofdm信号上变频
    %————————————————————————————————————————————————————————%
    
    %% 参数设置
    
    N_sc=52;      %系统子载波数(不包括直流载波)、number of subcarrier
    N_fft=64;            % FFT 长度
    N_cp=16;             % 循环前缀长度、Cyclic prefix
    N_symbo=N_fft+N_cp;        % 1个完整OFDM符号长度
    N_c=53;             % 包含直流载波的总的子载波数、number of carriers
    M=4;               %4PSK调制
    SNR=0:1:25;         %仿真信噪比
    N_frm=10;            % 每种信噪比下的仿真帧数、frame
    Nd=6;               % 每帧包含的OFDM符号数
    P_f_inter=6;      %导频间隔
    data_station=[];    %导频位置
    L=7;                %卷积码约束长度
    tblen=6*L;          %Viterbi译码器回溯深度
    stage = 3;          % m序列的阶数
    ptap1 = [1 3];      % m序列的寄存器连接方式
    regi1 = [1 1 1];    % m序列的寄存器初始值
    
    
    %% 基带数据数据产生
    P_data=randi([0 1],1,N_sc*Nd*N_frm);
    
    
    %% 信道编码(卷积码、或交织器)
    %卷积码:前向纠错非线性码
    %交织:使突发错误最大限度的分散化
    trellis = poly2trellis(7,[133 171]);       %(2,1,7)卷积编码
    code_data=convenc(P_data,trellis);
    
    
    %% qpsk调制
    data_temp1= reshape(code_data,log2(M),[])';             %以每组2比特进行分组,M=4
    data_temp2= bi2de(data_temp1);                             %二进制转化为十进制
    modu_data=pskmod(data_temp2,M,pi/M);              % 4PSK调制
    % figure(1);
    scatterplot(modu_data),grid;                  %星座图(也可以取实部用plot函数)
    
    %% 扩频
    %————————————————————————————————————————————————————————%
    %扩频通信信号所占有的频带宽度远大于所传信息必需的最小带宽
    %根据香农定理,扩频通信就是用宽带传输技术来换取信噪比上的好处,这就是扩频通信的基本思想和理论依据。
    %扩频就是将一系列正交的码字与基带调制信号内积
    %扩频后数字频率变成了原来的m倍。码片数量 = 2(符号数)* m(扩频系数)
    %————————————————————————————————————————————————————————%
    
    code = mseq(stage,ptap1,regi1,N_sc);     % 扩频码的生成
    code = code * 2 - 1;         %将1、0变换为1、-1
    modu_data=reshape(modu_data,N_sc,length(modu_data)/N_sc);
    spread_data = spread(modu_data,code);        % 扩频
    spread_data=reshape(spread_data,[],1);
    
    %% 插入导频
    P_f=3+3*1i;                       %Pilot frequency
    P_f_station=[1:P_f_inter:N_fft];%导频位置(导频位置很重要,why?)
    pilot_num=length(P_f_station);%导频数量
    
    for img=1:N_fft                        %数据位置
        if mod(img,P_f_inter)~=1          %mod(a,b)就是求的是a除以b的余数
            data_station=[data_station,img];
        end
    end
    data_row=length(data_station);
    data_col=ceil(length(spread_data)/data_row);
    
    pilot_seq=ones(pilot_num,data_col)*P_f;%将导频放入矩阵
    data=zeros(N_fft,data_col);%预设整个矩阵
    data(P_f_station(1:end),:)=pilot_seq;%对pilot_seq按行取
    
    if data_row*data_col>length(spread_data)
        data2=[spread_data;zeros(data_row*data_col-length(spread_data),1)];%将数据矩阵补齐,补0是虚载频~
    end;
    
    %% 串并转换
    data_seq=reshape(data2,data_row,data_col);
    data(data_station(1:end),:)=data_seq;%将导频与数据合并
    
    %% IFFT
    ifft_data=ifft(data); 
    
    %% 插入保护间隔、循环前缀
    Tx_cd=[ifft_data(N_fft-N_cp+1:end,:);ifft_data];%把ifft的末尾N_cp个数补充到最前面
    
    %% 并串转换
    Tx_data=reshape(Tx_cd,[],1);%由于传输需要
    
    %% 信道(通过多经瑞利信道、或信号经过AWGN信道)
     Ber=zeros(1,length(SNR));
     Ber2=zeros(1,length(SNR));
    for jj=1:length(SNR)
        rx_channel=awgn(Tx_data,SNR(jj),'measured');%添加高斯白噪声
        
    %% 串并转换
        Rx_data1=reshape(rx_channel,N_fft+N_cp,[]);
        
    %% 去掉保护间隔、循环前缀
        Rx_data2=Rx_data1(N_cp+1:end,:);
    
    %% FFT
        fft_data=fft(Rx_data2);
        
    %% 信道估计与插值(均衡)
        data3=fft_data(1:N_fft,:); 
        Rx_pilot=data3(P_f_station(1:end),:); %接收到的导频
        h=Rx_pilot./pilot_seq; 
        H=interp1( P_f_station(1:end)',h,data_station(1:end)','linear','extrap');%分段线性插值:插值点处函数值由连接其最邻近的两侧点的线性函数预测。对超出已知点集的插值点用指定插值方法计算函数值
    
    %% 信道校正
        data_aftereq=data3(data_station(1:end),:)./H;
    %% 并串转换
        data_aftereq=reshape(data_aftereq,[],1);
        data_aftereq=data_aftereq(1:length(spread_data));
        data_aftereq=reshape(data_aftereq,N_sc,length(data_aftereq)/N_sc);
        
    %% 解扩
        demspread_data = despread(data_aftereq,code);       % 数据解扩
        
    %% QPSK解调
        demodulation_data=pskdemod(demspread_data,M,pi/M);    
        De_data1 = reshape(demodulation_data,[],1);
        De_data2 = de2bi(De_data1);
        De_Bit = reshape(De_data2',1,[]);
    
    %% (解交织)
    %% 信道译码(维特比译码)
        trellis = poly2trellis(7,[133 171]);
        rx_c_de = vitdec(De_Bit,trellis,tblen,'trunc','hard');   %硬判决
    
    %% 计算误码率
        [err,Ber2(jj)] = biterr(De_Bit(1:length(code_data)),code_data);%译码前的误码率
        [err, Ber(jj)] = biterr(rx_c_de(1:length(P_data)),P_data);%译码后的误码率
    
    end
     figure(2);
     semilogy(SNR,Ber2,'b-s');
     hold on;
     semilogy(SNR,Ber,'r-o');
     hold on;
     legend('4PSK调制、卷积码译码前(有扩频)','4PSK调制、卷积码译码后(有扩频)');
     hold on;
     xlabel('SNR');
     ylabel('BER');
     title('AWGN信道下误比特率曲线');
    
     figure(3)
     subplot(2,1,1);
     x=0:1:30;
     stem(x,P_data(1:31));
     ylabel('amplitude');
     title('发送数据(以前30个数据为例)');
     legend('4PSK调制、卷积译码、有扩频');
    
     subplot(2,1,2);
     x=0:1:30;
     stem(x,rx_c_de(1:31));
     ylabel('amplitude');
     title('接收数据(以前30个数据为例)');
     legend('4PSK调制、卷积译码、有扩频');
    

    七、能看到这里,如果有丢丢帮助的话,emmmm点个赞~呗

    原文:

    整个过程

    本来对每一步都有讲解注释的,但是程序编辑多了感觉不美观,就删掉了。比如扩频,其原理、作用、如何实现~

    三、代码及说明

    1.尽量把每一句程序都注释,能达到初学者拿到程序就能懂的程度;

    2.下面这段程序是上变频之前的,包含了画图,对ofdm信号有一个直观的感受(与上面图片中的流程可能冲突,这里仅仅是为了画图解释,所以这也是最开始学容易绕晕的地方)

    clear;
    %% 参数设置
    sub_carriers=2048;%子载波数
    T = 1 / sub_carriers;
    time = [0:T:1-T];% Nifft份,每份相隔T
    
    Lp=4984;
    P_Tx=(rand(1,Lp)>0.5);%(bits)%产生1个长为Lp的数据包:
    conv_out=convolutional_en(P_Tx);%(卷积编码):
    interleave_table = interleav_matrix(ones(1,2*(Lp+8)));
    interleav_out = interleaving(conv_out ,interleave_table);%(交织器)
    
    x=qpsk(interleav_out);%(4QAM 调制)
    L=length(x);%信号长度
    
    s=48;
    symbol_used_len=L/s;%把输入分为S个符号,每个符号长为symbol_used_len
    %循环前缀的长度
    cp=256;
    %每一个OFDM符号的抽样值应补‘0’个数zeros_pad
    zeros_pad=sub_carriers-symbol_used_len;
    %每一个OFDM符号一侧应该补‘0’个数zeros_pad_side
    zeros_pad_side=zeros_pad/2;
    
    %对输入信号进行分割,分割为s个符号,再对每个符号进行FFT运算,实现OFDM解调,并保证能量不变
    time_domain_x_link=[];
    for I=0:(s-1)
        %对输入进行分割 
        x_temp=x(I*symbol_used_len+1:I*symbol_used_len+symbol_used_len);
        %对每个分割的部分进行补零操作,使其长为sub_carriers
        x_temp_pad=[zeros(1,zeros_pad_side),x_temp,zeros(1,zeros_pad_side)];
        %对每个符号进行IFFT运算
        time_domain_x_temp=ifft(x_temp_pad)*sqrt(sub_carriers);
        %对每个符号添加循环前缀
        time_domain_x_cp_temp=[time_domain_x_temp(sub_carriers-cp+1:sub_carriers),time_domain_x_temp];
        %将符号连接成为串行数据流
        time_domain_x_link=[time_domain_x_link,time_domain_x_cp_temp];
    
    end
    sum_xI = real(time_domain_x_link);
    sum_xQ = imag(time_domain_x_link);
    
    figure;
    num=1000;%画出前num个点  
    xaxis   = zeros(length(time(1:num)));
    plot(time(1:num), sum_xI(1:num), 'b:', time(1:num), sum_xQ(1:num), 'g:', time(1:num), abs(sum_xI(1:num)+j*sum_xQ(1:num)), 'k-', time(1:num), xaxis, 'r-');
    ylabel('y'),xlabel('t'),
    title(['前', num2str(num),'个点经ifft的QAM符号实部之和虚部之和以及实部与虚部的绝对值波形']),
    legend('实部之和','虚部之和', '绝对值');

    3.与上面图片流程相符的代码

    代码前面的问题也是我在这个过程中遇到的,困扰了好久,可以带着问题看看。欢迎讨论。

    clc;
    clear;
    
    %————————————————————————————————————————————————————————%
    %q1:fft点数难道不是应该等于子载波数吗?子载波数与ifft点数的关系?
    %q2:对矩阵进行fft?
    %q3:怎么对ofdm信号上变频
    %q4:基带速率是多少?怎么实现?
    %q5传输频带是多少?怎么实现?
    %q6子载波间隔是多少?怎么实现?
    %q7符号周期是多少?怎么实现?
    %————————————————————————————————————————————————————————%
    
    %% 参数设置
    
    N_sc=52;      %系统子载波数(不包括直流载波)、number of subcarrier
    N_fft=64;            % FFT 长度
    N_cp=16;             % 循环前缀长度、Cyclic prefix
    N_symbo=N_fft+N_cp;        % 1个完整OFDM符号长度
    N_c=53;             % 包含直流载波的总的子载波数、number of carriers
    M=4;               %4PSK调制
    SNR=0:1:25;         %仿真信噪比
    N_frm=10;            % 每种信噪比下的仿真帧数、frame
    Nd=6;               % 每帧包含的OFDM符号数
    P_f_inter=6;      %导频间隔
    data_station=[];    %导频位置
    L=7;                %卷积码约束长度
    tblen=6*L;          %Viterbi译码器回溯深度
    stage = 3;          % m序列的阶数
    ptap1 = [1 3];      % m序列的寄存器连接方式
    regi1 = [1 1 1];    % m序列的寄存器初始值
    
    
    %% 基带数据数据产生
    P_data=randi([0 1],1,N_sc*Nd*N_frm);
    
    
    %% 信道编码(卷积码、或交织器)
    %卷积码:前向纠错非线性码
    %交织:使突发错误最大限度的分散化
    trellis = poly2trellis(7,[133 171]);       %(2,1,7)卷积编码
    code_data=convenc(P_data,trellis);
    
    
    %% qpsk调制
    data_temp1= reshape(code_data,log2(M),[])';             %以每组2比特进行分组,M=4
    data_temp2= bi2de(data_temp1);                             %二进制转化为十进制
    modu_data=pskmod(data_temp2,M,pi/M);              % 4PSK调制
    % figure(1);
    scatterplot(modu_data),grid;                  %星座图(也可以取实部用plot函数)
    
    %% 扩频
    %————————————————————————————————————————————————————————%
    %扩频通信信号所占有的频带宽度远大于所传信息必需的最小带宽
    %根据香农定理,扩频通信就是用宽带传输技术来换取信噪比上的好处,这就是扩频通信的基本思想和理论依据。
    %扩频就是将一系列正交的码字与基带调制信号内积
    %扩频后数字频率变成了原来的m倍。码片数量 = 2(符号数)* m(扩频系数)
    %————————————————————————————————————————————————————————%
    
    code = mseq(stage,ptap1,regi1,N_sc);     % 扩频码的生成
    code = code * 2 - 1;         %将1、0变换为1、-1
    modu_data=reshape(modu_data,N_sc,length(modu_data)/N_sc);
    spread_data = spread(modu_data,code);        % 扩频
    spread_data=reshape(spread_data,[],1);
    
    %% 插入导频
    P_f=3+3*1i;                       %Pilot frequency
    P_f_station=[1:P_f_inter:N_fft];%导频位置(导频位置很重要,why?)
    pilot_num=length(P_f_station);%导频数量
    
    for img=1:N_fft                        %数据位置
        if mod(img,P_f_inter)~=1          %mod(a,b)就是求的是a除以b的余数
            data_station=[data_station,img];
        end
    end
    data_row=length(data_station);
    data_col=ceil(length(spread_data)/data_row);
    
    pilot_seq=ones(pilot_num,data_col)*P_f;%将导频放入矩阵
    data=zeros(N_fft,data_col);%预设整个矩阵
    data(P_f_station(1:end),:)=pilot_seq;%对pilot_seq按行取
    
    if data_row*data_col>length(spread_data)
        data2=[spread_data;zeros(data_row*data_col-length(spread_data),1)];%将数据矩阵补齐,补0是虚载频~
    end;
    
    %% 串并转换
    data_seq=reshape(data2,data_row,data_col);
    data(data_station(1:end),:)=data_seq;%将导频与数据合并
    
    %% IFFT
    ifft_data=ifft(data); 
    
    %% 插入保护间隔、循环前缀
    Tx_cd=[ifft_data(N_fft-N_cp+1:end,:);ifft_data];%把ifft的末尾N_cp个数补充到最前面
    
    %% 并串转换
    Tx_data=reshape(Tx_cd,[],1);%由于传输需要
    
    %% 信道(通过多经瑞利信道、或信号经过AWGN信道)
     Ber=zeros(1,length(SNR));
     Ber2=zeros(1,length(SNR));
    for jj=1:length(SNR)
        rx_channel=awgn(Tx_data,SNR(jj),'measured');%添加高斯白噪声
        
    %% 串并转换
        Rx_data1=reshape(rx_channel,N_fft+N_cp,[]);
        
    %% 去掉保护间隔、循环前缀
        Rx_data2=Rx_data1(N_cp+1:end,:);
    
    %% FFT
        fft_data=fft(Rx_data2);
        
    %% 信道估计与插值(均衡)
        data3=fft_data(1:N_fft,:); 
        Rx_pilot=data3(P_f_station(1:end),:); %接收到的导频
        h=Rx_pilot./pilot_seq; 
        H=interp1( P_f_station(1:end)',h,data_station(1:end)','linear','extrap');%分段线性插值:插值点处函数值由连接其最邻近的两侧点的线性函数预测。对超出已知点集的插值点用指定插值方法计算函数值
    
    %% 信道校正
        data_aftereq=data3(data_station(1:end),:)./H;
    %% 并串转换
        data_aftereq=reshape(data_aftereq,[],1);
        data_aftereq=data_aftereq(1:length(spread_data));
        data_aftereq=reshape(data_aftereq,N_sc,length(data_aftereq)/N_sc);
        
    %% 解扩
        demspread_data = despread(data_aftereq,code);       % 数据解扩
        
    %% QPSK解调
        demodulation_data=pskdemod(demspread_data,M,pi/M);    
        De_data1 = reshape(demodulation_data,[],1);
        De_data2 = de2bi(De_data1);
        De_Bit = reshape(De_data2',1,[]);
    
    %% (解交织)
    %% 信道译码(维特比译码)
        trellis = poly2trellis(7,[133 171]);
        rx_c_de = vitdec(De_Bit,trellis,tblen,'trunc','hard');   %硬判决
    
    %% 计算误码率
        [err,Ber2(jj)] = biterr(De_Bit(1:length(code_data)),code_data);%译码前的误码率
        [err, Ber(jj)] = biterr(rx_c_de(1:length(P_data)),P_data);%译码后的误码率
    
    end
     figure(2);
     semilogy(SNR,Ber2,'b-s');
     hold on;
     semilogy(SNR,Ber,'r-o');
     hold on;
     legend('4PSK调制、卷积码译码前(有扩频)','4PSK调制、卷积码译码后(有扩频)');
     hold on;
     xlabel('SNR');
     ylabel('BER');
     title('AWGN信道下误比特率曲线');
    
     figure(3)
     subplot(2,1,1);
     x=0:1:30;
     stem(x,P_data(1:31));
     ylabel('amplitude');
     title('发送数据(以前30个数据为例)');
     legend('4PSK调制、卷积译码、有扩频');
    
     subplot(2,1,2);
     x=0:1:30;
     stem(x,rx_c_de(1:31));
     ylabel('amplitude');
     title('接收数据(以前30个数据为例)');
     legend('4PSK调制、卷积译码、有扩频');

    4.上面就是整个基带传输过程,其实上变频和下变频也很简单,将信号分为IQ路,分别乘cos和-sin即可,关于这一步,可以参考我另一篇8PSK调制的文章,在那篇文章里有相似的原理。链接:https://blog.csdn.net/qq_41687938/article/details/89514982和贼详细的8PSK调制与解调详细过程 - 子木的文章 - 知乎 https://zhuanlan.zhihu.com/p/47258287

    5.本来打算解释解释原理的,但是想着网上资料很多,就不献丑了,想打王者了~

    展开全文
  • 从理论上分析方形四探针和直线四探针薄层电阻测试方法中探针游移所造成的系统偏差,推导出计算游移偏差的公式,并作图展示探针游移后的电阻与理想值之比的分布情况,分析了两种四探针测试方法出现最大误差的情况。...
  • docker容器的时间和系统时间存在8小时误差,容器使用UTC时区,系统使用CST时区时间 原因分析及解决方法 创建容器的时候就应该使用-v /etc/localtime [容器名称或者id]:/etc/localtime和-v /etc/timezone [容器名称...

    问题描述:
    docker容器的时间和系统时间存在8小时误差,容器使用UTC时区,系统使用CST时区时间

    原因分析及解决方法
    创建容器的时候就应该使用-v /etc/localtime [容器名称或者id]:/etc/localtime-v /etc/timezone [容器名称或者id]:/etc/timezone指定容器的时间和时区,但是由于容器已经创建完项目也部署上去了,不想再换重新创建换容器,解决方法就是直接把系统的localtime文件和timezone替换到容器里。

    注意:发现仅替换localtime文件,docker容器的时间同步了,但是jvm中的时间还是存在8小时时差,重启也不管用,直到替换timezone文件即生效

    原文地址:https://blog.csdn.net/thousa_ho/article/details/80242653

    展开全文
  • variance:方差 -> 实际上对应着物理实验中系统误差和随机误差的概念,假设有n组数据,每一组数据都会产生一个相应的 f∗f^*f∗,此时bias表示所有 f∗f^*f∗的平均落靶位置和真值靶心的距离,variance表示这些 f∗f...

    Where does the error come from?

    如果本文对你有帮助,请给我的github打个star叭,上面附有全系列目录和内容!
    更多优质内容欢迎关注我的微信公众号“Sakura的知识库”:
    在这里插入图片描述

    Review

    之前有提到说,不同的function set,也就是不同的model,它对应的error是不同的;越复杂的model,也许performance会越差,所以今天要讨论的问题是,这个error来自什么地方

    • error due to bias
    • error due to variance

    了解error的来源其实是很重要的,因为我们可以针对它挑选适当的方法来improve自己的model,提高model的准确率,而不会毫无头绪

    抽样分布

    y ^ \widehat{y} y y ∗ y^* y 真值和估测值

    y ^ \widehat{y} y 表示那个真正的function,而 f ∗ f^* f表示这个 f ^ \widehat{f} f 的估测值estimator

    就好像在打靶, f ^ \widehat{f} f 是靶的中心点,收集到一些data做training以后,你会得到一个你觉得最好的function即 f ∗ f^* f,这个 f ∗ f^* f落在靶上的某个位置,它跟靶中心有一段距离,这段距离就是由Bias和variance决定的

    bias:偏差;variance:方差 -> 实际上对应着物理实验中系统误差和随机误差的概念,假设有n组数据,每一组数据都会产生一个相应的 f ∗ f^* f,此时bias表示所有 f ∗ f^* f的平均落靶位置和真值靶心的距离,variance表示这些 f ∗ f^* f的集中程度

    抽样分布的理论(概率论与数理统计)

    假设独立变量为x(这里的x代表每次独立地从不同的training data里训练找到的 f ∗ f^* f),那么

    总体期望 E ( x ) = u E(x)=u E(x)=u ;总体方差 V a r ( x ) = σ 2 Var(x)=\sigma^2 Var(x)=σ2

    用样本均值 x ‾ \overline{x} x估测总体期望 u u u

    由于我们只有有限组样本 S a m p l e   N   p o i n t s : { x 1 , x 2 , . . . , x N } Sample \ N \ points:\{x^1,x^2,...,x^N\} Sample N points:{x1,x2,...,xN},故

    样本均值 x ‾ = 1 N ∑ i = 1 N x i \overline{x}=\frac{1}{N}\sum\limits_{i=1}^{N}x^i x=N1i=1Nxi ;样本均值的期望 E ( x ‾ ) = E ( 1 N ∑ i = 1 N x i ) = u E(\overline{x})=E(\frac{1}{N}\sum\limits_{i=1}^{N}x^i)=u E(x)=E(N1i=1Nxi)=u ; 样本均值的方差 V a r ( x ‾ ) = σ 2 N Var(\overline{x})=\frac{\sigma^2}{N} Var(x)=Nσ2

    样本均值 x ‾ \overline{x} x的期望是总体期望 u u u,也就是说 x ‾ \overline{x} x是按概率对称地分布在总体期望 u u u的两侧的;而 x ‾ \overline{x} x分布的密集程度取决于N,即数据量的大小,如果N比较大, x ‾ \overline{x} x就会比较集中,如果N比较小, x ‾ \overline{x} x就会以 u u u为中心分散开来

    综上,样本均值 x ‾ \overline{x} x以总体期望 u u u为中心对称分布,可以用来估测总体期望 u u u

    用样本方差 s 2 s^2 s2估测总体方差 σ 2 \sigma^2 σ2

    由于我们只有有限组样本 S a m p l e   N   p o i n t s : { x 1 , x 2 , . . . , x N } Sample \ N \ points:\{x^1,x^2,...,x^N\} Sample N points:{x1,x2,...,xN},故

    样本均值 x ‾ = 1 N ∑ i = 1 N x i \overline{x}=\frac{1}{N}\sum\limits_{i=1}^{N}x^i x=N1i=1Nxi ;样本方差 s 2 = 1 N − 1 ∑ i = 1 N ( x i − x ‾ ) 2 s^2=\frac{1}{N-1}\sum\limits_{i=1}^N(x^i-\overline{x})^2 s2=N11i=1N(xix)2 ;样本方差的期望 E ( s 2 ) = σ 2 E(s^2)=\sigma^2 E(s2)=σ2 ; 样本方差的方差 V a r ( s 2 ) = 2 σ 4 N − 1 Var(s^2)=\frac{2\sigma^4}{N-1} Var(s2)=N12σ4

    样本方差 s 2 s^2 s2的期望是总体方差 σ 2 \sigma^2 σ2,而 s 2 s^2 s2分布的密集程度也取决于N

    同理,样本方差 s 2 s^2 s2以总体方差 σ 2 \sigma^2 σ2为中心对称分布,可以用来估测总体方差 σ 2 \sigma^2 σ2

    回到regression的问题上来

    现在我们要估测的是靶的中心 f ^ \widehat{f} f ,每次collect data训练出来的 f ∗ f^* f是打在靶上的某个点;产生的error取决于:

    • 多次实验得到的 f ∗ f^* f的期望 f ‾ \overline{f} f与靶心 f ^ \widehat{f} f 之间的bias—— E ( f ∗ ) E(f^*) E(f),可以形象地理解为瞄准的位置和靶心的距离的偏差
    • 多次实验的 f ∗ f^* f之间的variance—— V a r ( f ∗ ) Var(f^*) Var(f),可以形象地理解为多次打在靶上的点的集中程度

    说到这里,可能会产生一个疑惑:我们之前不就只做了一次实验吗?我们就collect了十笔data,然后training出来了一个 f ∗ f^* f,然后就结束了。那怎么找很多个 f ∗ f^* f呢?怎么知道它的bias和variance有多大呢?

    f ∗ f^* f取决于model的复杂程度以及data的数量

    假设这里有多个平行宇宙,每个空间里都在用10只宝可梦的data去找 f ∗ f^* f,由于不同宇宙中宝可梦的data是不同的,因此即使使用的是同一个model,最终获得的 f ∗ f^* f都会是不同的

    于是我们做100次相同的实验,把这100次实验找出来的100条 f ∗ f^* f的分布画出来

    f ∗ f^* f的variance取决于model的复杂程度和data的数量

    f ∗ f^* f的variance是由model决定的,一个简单的model在不同的training data下可以获得比较稳定分布的 f ∗ f^* f,而复杂的model在不同的training data下的分布比较杂乱(如果data足够多,那复杂的model也可以得到比较稳定的分布)

    如果采用比较简单的model,那么每次在不同data下的实验所得到的不同的 f ∗ f^* f之间的variance是比较小的,就好像说,你在射击的时候,每次击中的位置是差不多的,就如同下图中的linear model,100次实验找出来的 f ∗ f^* f都是差不多的

    但是如果model比较复杂,那么每次在不同data下的实验所得到的不同的 f ∗ f^* f之间的variance是比较大的,它的散布就会比较开,就如同下图中含有高次项的model,每一条 f ∗ f^* f都长得不太像,并且散布得很开

    那为什么比较复杂的model,它的散布就比较开呢?比较简单的model,它的散布就比较密集呢?

    原因其实很简单,其实前面在讲regularization正规化的时候也提到了部分原因。简单的model实际上就是没有高次项的model,或者高次项的系数非常小的model,这样的model表现得相当平滑,受到不同的data的影响是比较小的

    举一个很极端的例子,我们的整个model(function set)里面,就一个function:f=c,这个function只有一个常数项,因此无论training data怎么变化,从这个最简单的model里找出来的 f ∗ f^* f都是一样的,它的variance就是等于0

    f ∗ f^* f的bias只取决于model的复杂程度

    bias是说,我们把所有的 f ∗ f^* f平均起来得到 E ( f ∗ ) = f ∗ ‾ E(f^*)=\overline{f^*} E(f)=f,这个 f ∗ ‾ \overline{f^*} f与真值 f ^ \widehat{f} f 有多接近

    当然这里会有一个问题是说,总体的真值 f ^ \widehat{f} f 我们根本就没有办法知道,因此这里只是假定了一个 f ^ \widehat{f} f

    下面的图示中,红色线条部分代表5000次实验分别得到的 f ∗ f^* f黑色线条部分代表真实值 f ^ \widehat{f} f 蓝色线条部分代表5000次实验得到的 f ∗ f^* f的平均值 f ‾ \overline{f} f

    根据上图我们发现,当model比较简单的时候,每次实验得到的 f ∗ f^* f之间的variance会比较小,这些 f ∗ f^* f会稳定在一个范围内,但是它们的平均值 f ‾ \overline{f} f距离真实值 f ^ \widehat{f} f 会有比较大的偏差;而当model比较复杂的时候,每次实验得到的 f ∗ f^* f之间的variance会比较大,实际体现出来就是每次重新实验得到的 f ∗ f^* f都会与之前得到的有较大差距,但是这些差距较大的 f ∗ f^* f的平均值 f ‾ \overline{f} f却和真实值 f ^ \widehat{f} f 比较接近

    上图分别是含有一次项、三次项和五次项的model做了5000次实验后的结果,你会发现model越复杂,比如含有5次项的model那一幅图,每一次实验得到的 f ∗ f^* f几乎是杂乱无章,遍布整幅图的;但是他们的平均值却和真实值 f ^ \widehat{f} f 吻合的很好。也就是说,复杂的model,单次实验的结果是没有太大参考价值的,但是如果把考虑多次实验的结果的平均值,也许会对最终的结果有帮助

    注:这里的单次实验指的是,用一组training data训练出model的一组有效参数以构成 f ∗ f^* f(每次独立实验使用的training data都是不同的)

    因此:
    • 如果是一个比较简单的model,那它有比较小的variance和比较大的bias。就像下图中左下角的打靶模型,每次实验的 f ∗ f^* f都比较集中,但是他们平均起来距离靶心会有一段距离(比较适合实验次数少甚至只有单次实验的情况)
    • 如果是一个比较复杂的model,每次实验找出来的 f ∗ f^* f都不一样,它有比较大的variance但是却有比较小的bias。就像下图中右下角的打靶模型,每次实验的 f ∗ f^* f都比较分散,但是他们平均起来的位置与靶心比较接近(比较适合多次实验的情况)
    为什么会这样?

    实际上我们的model就是一个function set,当你定好一个model的时候,实际上就已经定好这个function set的范围了,那个最好的function只能从这个function set里面挑出来

    如果是一个简单的model,它的function set的space是比较小的,这个范围可能根本就没有包含你的target;如果这个function set没有包含target,那么不管怎么sample,平均起来永远不可能是target(这里的space指上图中左下角那个被model圈起来的空间)

    如果这个model比较复杂,那么这个model所代表的function set的space是比较大的(简单的model实际上就是复杂model的子集),那它就很有可能包含target,只是它没有办法找到那个target在哪,因为你给的training data不够,你给的training data每一次都不一样,所以他每一次找出来的 f ∗ f^* f都不一样,但是如果他们是散布在这个target附近的,那平均起来,实际上就可以得到和target比较接近的位置(这里的space指上图中右下角那个被model圈起来的空间)

    Bias vs Variance

    由前面的讨论可知,比较简单的model,variance比较小,bias比较大;而比较复杂的model,bias比较小,variance比较大

    bias和variance对error的影响

    因此下图中(也就是之前我们得到的从最高项为一次项到五次项的五个model的error表现),绿色的线代表variance造成的error,红色的线代表bias造成的error,蓝色的线代表这个model实际观测到的error

    e r r o r 实 际 = e r r o r v a r i a n c e + e r r o r b i a s — — 蓝 线 为 红 线 和 绿 线 之 和 error_{实际}=error_{variance}+error_{bias}——蓝线为红线和绿线之和 error=errorvariance+errorbias线线绿线

    可以发现,随着model的逐渐复杂:

    • bias逐渐减小,bias所造成的error也逐渐下降,也就是打靶的时候瞄得越来越准,体现为图中的红线
    • variance逐渐变大,variance所造成的error也逐渐增大,也就是虽然瞄得越来越准,但是每次射出去以后,你的误差是越来越大的,体现为图中的绿线
    • 当bias和variance这两项同时被考虑的时候,得到的就是图中的蓝线,也就是实际体现出来的error的变化;实际观测到的error先是减小然后又增大,因此实际error为最小值的那个点,即为bias和variance的error之和最小的点,就是表现最好的model
    • 如果实际error主要来自于variance很大,这个状况就是overfitting过拟合;如果实际error主要来自于bias很大,这个状况就是underfitting欠拟合(可以理解为,overfitting就是过分地包围了靶心所在的space,而underfitting则是还未曾包围到靶心所在的space)

    这就是为什么我们之前要先计算出每一个model对应的error(每一个model都有唯一对应的 f ∗ f^* f,因此也有唯一对应的error),再挑选error最小的model的原因,只有这样才能综合考虑bias和variance的影响,找到一个实际error最小的model

    必须要知道自己的error主要来自于哪里
    你现在的问题是bias大,还是variance大?

    当你自己在做research的时候,你必须要搞清楚,手头上的这个model,它目前主要的error是来源于哪里;你觉得你现在的问题是bias大,还是variance大

    你应该先知道这件事情,你才能知道你的future work,你要improve你的model的时候,你应该要走哪一个方向

    那怎么知道现在是bias大还是variance大呢?
    • 如果model没有办法fit training data的examples,代表bias比较大,这时是underfitting

      形象地说,就是该model找到的 f ∗ f^* f上面并没有training data的大部分样本点,如下图中的linear model,我们只是example抽样了这几个蓝色的样本点,而这个model甚至没有fit这少数几个蓝色的样本点(这几个样本点没有在 f ∗ f^* f上),代表说这个model跟正确的model是有一段差距的,所以这个时候是bias大的情况,是underfitting

    • 如果model可以fit training data,在training data上得到小的error,但是在testing data上,却得到一个大的error,代表variance比较大,这时是overfitting

    如何针对性地处理bias大 or variance大的情况呢?

    遇到bias大或variance大的时候,你其实是要用不同的方式来处理它们

    1、如果bias比较大

    bias大代表,你现在这个model里面可能根本没有包含你的target, f ^ \widehat{f} f 可能根本就不在你的function set里

    对于error主要来自于bias的情况,是由于该model(function set)本来就不好,collect更多的data是没有用的,必须要从model本身出发

    • redesign,重新设计你的model

      • 增加更多的features作为model的input输入变量

        比如pokemon的例子里,只考虑进化前cp值可能不够,还要考虑hp值、species种类…作为model新的input变量

      • 让model变得更复杂,增加高次项

        比如原本只是linear model,现在考虑增加二次项、三次项…

    2、如果variance比较大

    • 增加data
      • 如果是5次式,找100个 f ∗ f^* f,每次实验我们只用10只宝可梦的数据训练model,那我们找出来的100个 f ∗ f^* f的散布就会像下图一样杂乱无章;但如果每次实验我们用100只宝可梦的数据训练model,那我们找出来的100个 f ∗ f^* f的分布就会像下图所示一样,非常地集中
      • 增加data是一个很有效控制variance的方法,假设你variance太大的话,collect data几乎是一个万能丹一样的东西,并且它不会伤害你的bias
      • 但是它存在一个很大的问题是,实际上并没有办法去collect更多的data
      • 如果没有办法collect更多的data,其实有一招,根据你对这个问题的理解,自己去generate更多“假的”data
        • 比如手写数字识别,因为每个人手写数字的角度都不一样,那就把所有training data里面的数字都左转15°,右转15°
        • 比如做火车的影像辨识,只有从左边开过来的火车影像资料,没有从右边开过来的火车影像资料,该怎么办?实际上可以把每张图片都左右颠倒,就generate出右边的火车数据了,这样就多了一倍data出来
        • 比如做语音辨识的时候,只有男生说的“你好”,没有女生说的“你好”,那就用男生的声音用一个变声器把它转化一下,这样男女生的声音就可以互相转化,这样data就可以多出来
        • 比如现在你只有录音室里录下的声音,但是detection实际要在真实场景下使用的,那你就去真实场景下录一些噪音加到原本的声音里,就可以generate出符合条件的data了
    • Regularization(正规化)
      • 就是在loss function里面再加一个与model高次项系数相关的term,它会希望你的model里高次项的参数越小越好,也就是说希望你今天找出来的曲线越平滑越好;这个新加的term前面可以有一个weight,代表你希望你的曲线有多平滑
      • 下图中Regularization部分,左边第一幅图是没有加regularization的test;第二幅图是加了regularization后的情况,一些怪怪的、很不平滑的曲线就不会再出现,所有曲线都集中在比较平滑的区域;第三幅图是增加weight的情况,让曲线变得更平滑
      • 加了regularization以后,因为你强迫所有的曲线都要比较平滑,所以这个时候也会让你的variance变小;但regularization是可能会伤害bias的,因为它实际上调整了function set的space范围,变成它只包含那些比较平滑的曲线,这个缩小的space可能没有包含原先在更大space内的 f ^ \widehat{f} f ,因此伤害了bias,所以当你做regularization的时候,需要调整regularization的weight,在variance和bias之间取得平衡

    注:variance比较大的case,加以图例解释如下:(假设这里我们无法获得更多的data)

    1、蓝色区域代表最初的情况,此时model比较复杂,function set的space范围比较大,包含了target靶心,但由于data不够, f ∗ f^* f比较分散,variance比较大

    2、红色区域代表进行regularization之后的情况,此时model的function set范围被缩小成只包含平滑的曲线,space减小,variance当然也跟着变小,但这个缩小后的space实际上并没有包含原先已经包含的target靶心,因此该model的bias变大

    3、橙色区域代表增大regularization的weight的情况,增大weight实际上就是放大function set的space,慢慢调整至包含target靶心,此时该model的bias变小,而相较于一开始的case,由于限定了曲线的平滑度(由weight控制平滑度的阈值),该model的variance也比较小

    实际上,通过regularization优化model的过程就是上述的1、2、3步骤,不断地调整regularization的weight,使model的bias和variance达到一个最佳平衡的状态(可以通过error来评价状态的好坏,weight需要慢慢调参)

    Model Selection

    我们现在会遇到的问题往往是这样:我们有很多个model可以选择,还有很多参数可以调,比如regularization的weight,那通常我们是在bias和variance之间做一些trade-off权衡

    我们希望找一个model,它variance够小,bias也够小,这两个合起来给我们最小的testing data的error

    但是以下这些事情,是你不应该做的:

    你手上有training set,有testing set,接下来你想知道model1、model2、model3里面,应该选哪一个model,然后你就分别用这三个model去训练出 f 1 ∗ , f 2 ∗ , f 3 ∗ f_1^*,f_2^*,f_3^* f1,f2,f3,然后把它apply到testing set上面,分别得到三个error为0.9,0.7,0.5,这里很直觉地会认为是model3最好

    但是现在可能的问题是,这个testing set是你自己手上的testing set,是你自己拿来衡量model好坏的testing set,真正的testing set是你没有的;注意到你自己手上的这笔testing set,它有自己的一个bias(这里的bias跟之前提到的略有不同,可以理解为自己的testing data跟实际的testing data会有一定的偏差存在)

    所以你今天那这个testing set来选择最好的model的时候,它在真正的testing set上不见得是最好的model,通常是比较差的,所以你实际得到的error是会大于你在自己的testing set上估测到的0.5

    以PM2.5预测为例,提供的数据分为training set,public testing set和private testing set三部分,其中public的testing set是供你测试自己的model的,private的testing data是你暂且未知的真正测试数据,现在你的model3在public testing set上的error为0.5,已经成功beat baseline,但是在private的testing set上,你的model3也许根本就没有beat the baseline,反而是model1和model2可能会表现地更好

    怎样做才是可靠的呢?
    training data分成training set和validation set

    你要做的事情是,把你的training set分成两组:

    • 一组是真正拿来training model的,叫做training set(训练集)
    • 另外一组不拿它来training model,而是拿它来选model,叫做validation set(验证集)

    先在training set上找出每个model最好的function f ∗ f^* f,然后用validation set来选择你的model

    也就是说,你手头上有3个model,你先把这3个model用training set训练出三个 f ∗ f^* f,接下来看一下它们在validation set上的performance

    假设现在model3的performance最好,那你可以直接把这个model3的结果拿来apply在testing data上

    如果你担心现在把training set分成training和validation两部分,感觉training data变少的话,可以这样做:已经从validation决定model3是最好的model,那就定住model3不变(function的表达式不变),然后用全部的data在model3上面再训练一次(使用全部的data去更新model3表达式的参数)

    这个时候,如果你把这个训练好的model的 f ∗ f^* fapply到public testing set上面,你可能会得到一个大于0.5的error,虽然这么做,你得到的error表面上看起来是比较大的,但是这个时候你在public set上的error才能够真正反映你在private set上的error

    考虑真实的测试集

    实际上是这样一个关系:

    training data(训练集) -> 自己的testing data(测试集) -> 实际的testing data
    (该流程没有考虑自己的testing data的bias)

    training set(部分训练集) -> validation set(部分验证集) -> 自己的testing data(测试集) -> 实际的testing data
    (该流程使用自己的testing data和validation来模拟testing data的bias误差,可以真实地反映出在实际的data上出现的error)

    真正的error

    当你得到public set上的error的时候(尽管它可能会很大),不建议回过头去重新调整model的参数,因为当你再回去重新调整什么东西的时候,你就又会把public testing set的bias给考虑进去了,这就又回到了第一种关系,即围绕着有偏差的testing data做model的优化

    这样的话此时你在public set上看到的performance就没有办法反映实际在private set上的performance了,因为你的model是针对public set做过优化的,虽然public set上的error数据看起来可能会更好看,但是针对实际未知的private set,这个“优化”带来的可能是反作用,反而会使实际的error变大

    当然,你也许几乎没有办法忍住不去做这件事情,在发paper的时候,有时候你会propose一个方法,那你要attach在benchmark的corpus,如果你在testing set上得到一个差的结果,你也几乎没有办法把持自己不回头去调一下你的model,你肯定不会只是写一个paper说这个方法不work这样子(滑稽

    因此这里只是说,你要keep in mind,如果在那个benchmark corpus上面所看到的testing的performance,它的error,肯定是大于它在real的application上应该有的值

    比如说你现在常常会听到说,在image lab的那个corpus上面,error rate都降到3%,那个是超越人类了,但是真的是这样子吗?已经有这么多人玩过这个corpus,已经有这么多人告诉你说前面这些方法都不work,他们都帮你挑过model了,你已经用“testing” data调过参数了,所以如果你把那些model真的apply到现实生活中,它的error rate肯定是大于3%的

    如何划分training set和validation set?

    那如果training set和validation set分坏了怎么办?如果validation也有怪怪的bias,岂不是对结果很不利?那你要做下面这件事情:

    N-flod Cross Validation

    如果你不相信某一次分train和validation的结果的话,那你就分很多种不同的样子

    比如说,如果你做3-flod的validation,意思就是你把training set分成三份,你每一次拿其中一份当做validation set,另外两份当training;分别在每个情境下都计算一下3个model的error,然后计算一下它的average error;然后你会发现在这三个情境下的average error,是model1最好

    然后接下来,你就把用整个完整的training data重新训练一遍model1的参数;然后再去testing data上test

    原则上是,如果你少去根据public testing set上的error调整model的话,那你在private testing set上面得到的error往往是比较接近public testing set上的error的

    总结conclusion

    1、一般来说,error是bias和variance共同作用的结果

    2、model比较简单和比较复杂的情况:

    • 当model比较简单的时候,variance比较小,bias比较大,此时 f ∗ f^* f会比较集中,但是function set可能并没有包含真实值 f ^ \widehat{f} f ;此时model受bias影响较大
    • 当model比较复杂的时候,bias比较小,variance比较大,此时function set会包含真实值 f ^ \widehat{f} f ,但是 f ∗ f^* f会比较分散;此时model受variance影响较大

    3、区分bias大 or variance大的情况

    • 如果连采样的样本点都没有大部分在model训练出来的 f ∗ f^* f上,说明这个model太简单,bias比较大,是欠拟合

    • 如果样本点基本都在model训练出来的 f ∗ f^* f上,但是testing data上测试得到的error很大,说明这个model太复杂,variance比较大,是过拟合

    4、bias大 or variance大的情况下该如何处理

    • 当bias比较大时,需要做的是重新设计model,包括考虑添加新的input变量,考虑给model添加高次项;然后对每一个model对应的 f ∗ f^* f计算出error,选择error值最小的model(随model变复杂,bias会减小,variance会增加,因此这里分别计算error,取两者平衡点)

    • 当variance比较大时,一个很好的办法是增加data(可以凭借经验自己generate data),当data数量足够时,得到的 f ∗ f^* f实际上是比较集中的;如果现实中没有办法collect更多的data,那么就采用regularization正规化的方法,以曲线的平滑度为条件控制function set的范围,用weight控制平滑度阈值,使得最终的model既包含 f ^ \widehat{f} f ,variance又不会太大

    5、如何选择model

    • 选择model的时候呢,我们手头上的testing data与真实的testing data之间是存在偏差的,因此我们要将training data分成training set和validation set两部分,经过validation挑选出来的model再用全部的training data训练一遍参数,最后用testing data去测试error,这样得到的error是模拟过testing bias的error,与实际情况下的error会比较符合
      “GitAds”/
    展开全文
  • docker容器的时间和系统时间存在8小时误差,容器使用UTC时区,系统使用CST时区时间 原因分析及解决方法 创建容器的时候就应该使用-v /etc/localtime [容器名称或者id]:/etc/localtime和-v /etc/timezone [容器名称...
  • 在直接数字域设计中,我们常常需要用到PID算法,而PID算法投入单片机使用时,往往需要硬件的支持,在调试时非常麻烦。本文通过Matlab仿真的手段实现PID,方便了开发者对系统的设计和实时调试。
  • 基于物品的协同过滤算法实现图书推荐系统

    万次阅读 多人点赞 2019-09-14 21:20:24
    本文首先介绍了推荐系统的发展历史,及目前常用的几种推荐算法的介绍与比较,然后以基于物品的协同过滤算法为基础,详细介绍图书推荐系统的构建。在该系统中,主要功能分为用户功能和图书推荐功能...
  • matlab人脸识别论文

    万次阅读 多人点赞 2019-10-11 17:41:51
    摘 要 本文设计了一种基于BP神经网络的人脸识别系统,并对其进行了性能分析。该系统首先利用离散小波变换获取包含人脸图像大部分原始信息的低频分量,对图像数据进行降维;...通过系统仿真实验与分析发现:人脸特征的提...
  •  ... 摘要:许多工程师会在设计中遇到...本文介绍了如何根据系统需求合理选择ADC,列举了ADC测量中可能遇到的各种误差源。 采用12位分辨率的模数转换器(ADC)未必意味着你的系统将具有12位的精度。很多时候,令
  • 精密光测工程通常在室外进行,很难避免因大气扰动造成的系统误差。大气扰动可以分为高频扰动和低频扰动两部分,高频扰动部分可以通过滤波消扰等图像处理方法消除。通过搭建相机对视成像系统的约束条件来消除由大气低频...
  • 对由不同型号GPS-OEM板和不同型号天线所组成的GPS单点定位系统的定位误差时间序列进行了混沌特性分析,通过计算最大Lyapunov指数确定了其为混沌时间序列。在此基础上提出了基于混沌时间序列的GPS单点定位误差预测方法...
  • 利用蒙特卡罗(Monte-Carlo)方法对一端输入相干态,另一端输入真空态的马赫-曾德尔(Math-Zehnder)干涉仪的位相测量误差进行了研究.通过分析粒子数差的测量结果,验证该测量方法所测得的位相值的误差依赖于待测位相θ...
  • 模糊PID算法及其MATLAB仿真(2)

    万次阅读 多人点赞 2019-04-16 18:05:07
    上一篇写了模糊自整定PID的理论,这篇来做MATLAB仿真。 目录 补充内容:如何计算临界稳定下... 学过控制工程或者相关理论的同学应该比较了解,判断系统稳定性的条件一般用到劳斯表(劳斯判据)。而PID控制和模糊PI...
  • 图像分割综述

    万次阅读 多人点赞 2019-07-09 22:03:48
    近年来还提出了基于曲面拟合的方法、基于边界曲线拟合的方法、基于反应-扩散方程的方法、串行边界查找、基于变形模型的方法。 边缘检测的优缺点: (1)边缘定位准确; (2)速度快; (3)不能保证边缘的连续...
  • 压力测试工具

    万次阅读 多人点赞 2018-12-20 16:06:28
    目录 1 性能测试... 2 2 压力测试(Stress Test)... 2 2.1 网站测试... 2 2.2 系统测试要求... 3 3 测试工具... 3 3.1 Webbench. 4 3.1.1 Ubuntu 下载安装... 5 3.1.2 ...
  • 理解ADC误差系统性能的影响

    千次阅读 2018-10-06 22:29:18
    本文介绍了如何根据系统需求合理选择ADC,列举了ADC测量中可能遇到的各种误差源。  采用12位分辨率的模数转换器(ADC)未必意味着你的系统将具有12位的精度。很多时候,令工程师们吃惊和不解的是:数据采集系统所表现...
  • 测试开发笔记

    万次阅读 多人点赞 2019-11-14 17:11:58
    测试开发笔记 第一章 测试基础 7 什么是软件测试: 7 ...验收测试:(在系统测试之后) 11 回归测试: 11 4.测试过程(干什么,怎么干) 12 5.各阶段输入、输出标准以及入口、出口准则:(测试阶段过程要素) 1...
  • SPSS(十九)SPSS之时间序列模型(图文+数据集)

    万次阅读 多人点赞 2019-06-17 22:32:38
    Time domain(最为常见的方法):将时间序列看成是过去一些点的函数,或者认为序列具有随时间系统变化的趋势,它可以用不多的参数来加以描述,或者说可以通过差分、周期等还原成随机序列。 Frequency domain:...
  • 软件测试面试题汇总

    万次阅读 多人点赞 2018-09-27 12:31:09
    2、我现在有个程序,发现在Windows上运行得很慢,怎么判别是程序存在问题还是软硬件系统存在问题?   5 3、测试的策略有哪些? ................................................................................
  • 2.1 进行误差分析(carrying out error analysis) ...假设猫分类器准确率为90%,误差为10%,在错误分类的例子中我们发现有上图中的两类狗图片(乍一看觉得是猫),为了让你的猫分类器在狗图上做得更好,...
  • 深度学习入门

    万次阅读 多人点赞 2017-11-05 21:23:46
    在这种方法论中,有一种“追本溯源”的蕴意包含其内,即一个系统(或理论)无论多复杂,都可以分解、分解、再分解,直到能够还原到逻辑原点。   在意象上,还原主义就是“1+1=2”,也就是说,一个复杂的系统,...
  • PID的理解和应用

    万次阅读 多人点赞 2019-06-01 20:43:46
    也就是说,目标是1米 但是最后系统达到0.8米的水位就不再变化了,且系统已经达到稳定 由此产生的误差就是稳态误差了 在实际情况中,这种类似水缸漏水的情况往往更加常见 比如控制汽车运动,摩擦阻力就相当于是...
  • 复杂系统或过程参数优化问题往往采用建模发现其潜在规律,再通过优化方法利用该规律获取最佳工艺参数。而建模误差的存在,往往使优化解与实际最佳工艺参数存在差距,难以获得理想性能。为此提出一种基于误差补偿模型的...
  • 这样理解稳态误差

    千次阅读 2021-03-06 20:36:25
    稳态误差是控制系统的一个非常重要的指标。按字面意思理解,就是系统到达稳定状态后存在的误差,也就是说系统本身是稳定的才可以求解稳态误差。...下面以实例来说明求稳态误差的一般方法: 例1中省略了判断
  • RBF神经网络参考模型自适应MATLAB实现(分析)

    万次阅读 多人点赞 2018-12-06 17:22:48
    一般的神经网络的作用是去做一些分类,回归等工作,能够根据系统输入,在训练好的神经网络系统下分类或者预测出系统的输出,我主要的工作不是做分类器,这个方法主要运用在机器视觉上,我的研究生主要工作是逼近一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,242
精华内容 21,696
关键字:

发现系统误差的方法