《PyTorch深度学习建模与应用(参考用书)》(一)——基础函数
《PyTorch深度学习建模与应用(参考用书)》(一)——基础函数
函数是数学中重要的概念,纵观300年来函数的发展,众多数学家从几何、代数,直至对应、集合的角度不断赋予函数概念以新的思想,从而推动了整个数学的发展。
1.什么是函数
函数在数学中是两个不为空的集合间的一种对应关系。下面首先介绍集合的概念。
1.1 集合
一般我们把研究对象统称为元素,把一些元素组成的总体叫集合(简称集),集合具有确定性(即给定集合中的元素必须是确定的)和互相性(即给定集合中的元素是互不相同的)。例如“身材较高的人”不能构成集合,因为其元素不是确定的。
通常,用大写拉丁字母A、B、C、
…
\dots
…表示集合,用小写拉丁字母a、b、c、
…
\dots
…表示集合中的元素,如果a是集合A中的元素,就说a属于A,记作:
a
∈
A
a \in A
a∈A
在观察某一现象的过程适,常常会遇到各种不同的量,其中有的量在过程中不会变化,我们称其常量;有的量在过程中是变化的,也就是取不同的数值,则称其为变量。
如果变量的变化是连续的,则常用区间来表示其变化范围,在数轴上来说,区间是指介于某两点之间上的线段上点的全体。区间主要有如下7种类型:
- (a,b):表示大于a、小于b的实数全体,也可记为: a < x < b a < x <b a<x<b
- [a,b):表示大于等于a、小于b的实数全体,也可记为: a ≤ x < b a \leq x <b a≤x<b
- (a,b]:表示大于等于a、小于b的实数全体,也可记为: a < x ≤ b a <x \leq b a<x≤b
- [a,b]:表示大于等于a、小于b的实数全体,也可记为: a ≤ x ≤ b a \leq x \leq b a≤x≤b
- [a, + ∞ \infty ∞]:表示不小于a的实数的全体,也可记为: a ≤ x < + ∞ a \leq x <+ \infty a≤x<+∞
- [- ∞ \infty ∞, b]:表示小于b的实数的全体,也可记为:- ∞ ≤ x < b \infty \leq x <b ∞≤x<b
- [- ∞ \infty ∞, + ∞ \infty ∞]:表示小于b的实数的全体,也可记为:- ∞ ≤ x < + ∞ \infty \leq x <+\infty ∞≤x<+∞
1.2 函数
设D与B是两个非空实数集,如果存在一个对应规则f,使得对D中任何一个实数x,在B中都有唯一确定的实数y与x第一,则对应规则f称为D上的函数,记为:
f
:
x
−
>
y
或
f
:
D
−
>
B
f:x->y或f:D->B
f:x−>y或f:D−>B
y称为x对应的函数值,记为:
y
=
f
(
x
)
,
x
∈
D
y=f(x),x \in D
y=f(x),x∈D
其中,x称为自变量,y称为因变量、
由函数定义可以看出,函数是一种对应规则,在函数
y
=
f
(
x
)
y=f(x)
y=f(x)中,f表示对应规则,
f
(
x
)
f(x)
f(x)是对应自变量x的函数值,但在研究函数时,这种对应关系总是通过函数值的形式表示表现出来的,所以习惯上常把x处的函数值y称为函数,并用y=f(x)的形式表示y是x的函数,但是应正确理解,函数的本质是指对应规则f。
函数y=f(x)的定义域D是自变量x的取值范围,而函数值y又是由对应规则f来确定的,所以函数实质上是由其定义域D和对应规则f所确定的。因此,通常称函数的定义域和对应规则为函数的两个要素。也就是说,只要两个函数的定义域相同,对应规则也相同,就称这两个函数为相同的函数,与变量用什么符号表示无关,如
y
=
∣
x
∣
y=|x|
y=∣x∣与
z
=
v
2
z = \sqrt{v^2}
z=v2,就是相同的函数。
掌握函数的基本性质对于解决相关问题很有帮助,函数通常具有奇偶性、单调性、有界性、周期性等特性。
(1)奇偶性
设函数y=f(x)的定义域D关于原点对称,若对任意
x
∈
D
x \in D
x∈D满足
f
(
−
x
)
=
f
(
x
)
f(-x)=f(x)
f(−x)=f(x),则称f(x)在D上的偶函数;若对任意
x
∈
D
x \in D
x∈D满足
f
(
−
x
)
=
−
f
(
x
)
f(-x)=-f(x)
f(−x)=−f(x),则称f(x)在D上的奇函数。
偶函数的图像关于y轴对称,奇函数的图像关于原点对称。
(2)单调性
若对任意
x
1
,
x
2
∈
(
a
,
b
)
x_1,x_2 \in (a,b)
x1,x2∈(a,b),当
x
1
<
x
2
x_1<x_2
x1<x2时,有
f
(
x
1
)
<
f
(
x
2
)
f(x_1)<f(x_2)
f(x1)<f(x2),则称函数y=f(x)是区间(a,b)上的单调增加函数;当
x
1
<
x
2
x_1<x_2
x1<x2时,有
f
(
x
1
)
>
f
(
x
2
)
f(x_1)>f(x_2)
f(x1)>f(x2),则称函数y=f(x)是区间(a,b)上的单调减少函数,单调增加函数和单调减少函数统称为单调函数。若函数y=f(x)是区间(a,b)上的单调函数,则称区间(a,b)为单调区间。
单调增加的函数图像表现为从左向右是单调上升的曲线,单调下降的函数图像表现为从左向右是单调下降的曲线。
(3)有界性
如果存在M>0,使对于任意
x
∈
D
x \in D
x∈D满足
∣
f
(
x
)
∣
≤
M
|f(x)| \leq M
∣f(x)∣≤M,则称函数y=f(x)是有界的,图像在直线y=-M与y=M之间。
(4)周期性
如果存在常数T,使对于任意
x
∈
D
,
x
+
T
∈
D
x \in D,x+T \in D
x∈D,x+T∈D,有
f
(
x
+
T
)
=
f
(
x
)
f(x+T) = f(x)
f(x+T)=f(x),则称函数y=f(x)是周期函数,通过所说的周期函数的周期是指它的最小周期。
对于周期性函数,在每一个周期内的图像是相同的。
1.3 极限
当自变量无限增大或自变量无线接近某一定点时,函数值无线接近某一常数A,这时就叫作函数存在极值。
(1)自变量趋向无穷大时函数的极限
设函数y=f(x),若对于任意给定的正数
θ
\theta
θ(不论其多么小),总存在着正数X,使得对于适合不等式
∣
x
∣
>
X
|x|>X
∣x∣>X的一切x,所对应的函数值f(x)都满足不等式
∣
f
(
x
)
−
A
∣
<
θ
|f(x)-A|<\theta
∣f(x)−A∣<θ,那么常数A就叫作函数y=f(x)当
x
−
>
∞
x-> \infty
x−>∞,记作:
lim
x
−
>
∞
f
(
x
)
=
A
\lim_{x->\infty}f(x)=A
limx−>∞f(x)=A。
函数极限的运算规则:若已知
x
−
>
x
0
(
x
−
>
∞
)
x->x_0(x->\infty)
x−>x0(x−>∞),
f
(
x
)
−
>
A
,
g
(
x
)
−
>
B
f(x)->A,g(x)->B
f(x)−>A,g(x)−>B,那么:
lim
x
−
>
x
0
(
f
(
x
)
+
g
(
x
)
)
=
A
+
B
\lim_{x->x_0}(f(x)+g(x))=A+B
x−>x0lim(f(x)+g(x))=A+B
lim
x
−
>
x
0
(
f
(
x
)
.
g
(
x
)
)
=
A
.
B
\lim_{x->x_0}(f(x) . g(x))=A.B
x−>x0lim(f(x).g(x))=A.B
lim
x
−
>
x
0
f
(
x
)
g
(
x
)
=
A
B
\lim_{x->x_0}\frac{f(x)}{g(x)}=\frac{A}{B}
x−>x0limg(x)f(x)=BA
lim
x
−
>
x
0
k
.
f
(
x
)
=
k
.
A
(
k
为常数
)
\lim_{x->x_0}k.f(x)=k.A (k为常数)
x−>x0limk.f(x)=k.A(k为常数)
lim
x
−
>
x
0
[
f
(
x
)
]
m
=
A
m
(
m
为正整数
)
\lim_{x->x_0}[f(x)]^m=A^m (m为正整数)
x−>x0lim[f(x)]m=Am(m为正整数)
在计算复杂函数的极限时,可以利用上述的预算规则把一个复杂的函数转化为若干个简单的函数来求极限。
(2)无穷小量与无穷大量
在自变量的某个变化过程中,以零为极限的变量称为该极限过程中的无穷小量,简称无穷小。例如,如果
lim
x
−
>
x
0
f
(
x
)
=
0
\lim_{x->x_0}f(x)=0
limx−>x0f(x)=0,当x->
x
0
x_0
x0时,f(x)是无穷小量。一般说来,无穷小表达的是变量的变化状态,而不是变量的大小,一个变量无论多么小,都不能是无穷小量,数值0是唯一可以作为无穷小的常熟。
在自变量的某个变化过程中,绝对值可以无限增大的变量称为这个变化过程中的无穷大量,简称无穷大,无穷大量是极限不存在的一种情形。例如,如果
lim
x
−
>
x
0
f
(
x
)
=
∞
\lim_{x->x_0}f(x)=\infty
limx−>x0f(x)=∞,当x->
x
0
x_0
x0时,f(x)是无穷大量。
在自变量的变化过程中,无穷大量的倒数是无穷小量,不为零的无穷小量的倒数是无穷大量。
2. PyTorch中的主要函数
| API名称 | 说明 | 作用 |
|---|---|---|
| torch.seed() | 参数:无 | 用于生成不确定的随机数,返回一个64位的数值 |
| torch.manual_seed(seed) | 参数:种子seed为int类型或long类型 | 设定生成随机数的种子,并返回一个torch.Generator对象 |
| torch.inital_seed() | 参数:无 | 返回生成随机数的原始种子值 |
| torch.get_rng_state() | 参数:无 | 返回随机生成器状态(Byte Tensor) |
| torch.set_rng_state(new_state) | 参数:无 | 设定一个随机生成器状态 |
3. 微分基础
微分是数学中的一个重要概念,它是对函数的局部变化率的一种线性描述。
3.1微分及其公式
如果函数y=f(x)在点x处的改变量
δ
y
=
f
(
x
+
δ
x
)
−
f
(
x
)
\delta y=f(x+ \delta x)-f(x)
δy=f(x+δx)−f(x),可以表示为:
δ
y
=
A
δ
x
+
O
(
δ
x
)
\delta y =A \delta x +O(\delta x)
δy=Aδx+O(δx)
其中,
O
(
δ
x
)
O(\delta x)
O(δx)是比
δ
x
\delta x
δx(
δ
x
\delta x
δx->0)高阶的无穷小,则称函数
y
=
f
(
x
)
y=f(x)
y=f(x)在点x处可微,称
A
δ
x
A \delta x
Aδx为
δ
y
\delta y
δy的线性主部,又称
A
δ
y
A \delta y
Aδy为函数
y
=
f
(
x
)
y=f(x)
y=f(x)在点x处的微分,记作dy或者df(x),即dy=A
δ
x
\delta x
δx。
3.2微分公式
基本初等函数的求导公式及微分goon故事如表2-1所示。
| 求导公式 | 微分公式 |
|---|---|
| c’=0(c为常数) | dc=0(c为常数) |
| ( x u x^u xu)'=u x u − 1 ( u 为实数 ) x^{u-1}(u为实数) xu−1(u为实数) | d( x u x^u xu)=u x u − 1 d x ( u 为实数 ) x^{u-1}dx(u为实数) xu−1dx(u为实数) |
| ( a x a^x ax)'=lna a x ( a 为实数 ) a^{x}(a为实数) ax(a为实数) | d( a x a^x ax)=lna a x d x ( a 为实数 ) a^{x}dx(a为实数) axdx(a为实数) |
| ( e x e^x ex)'= e x e^{x} ex | d( e x e^x ex)= e x d x e^{x}dx exdx |
| ( l n x lnx lnx)'= 1 x \frac{1}{x} x1 | d( l n x lnx lnx)= 1 x \frac{1}{x} x1dx |
| (sinx)'=cosx | d(sinx)=cosx dx |
| (cosx)'=-sinx | d(cosx)=-sinx dx |
| (tanx)'= s e c 2 x sec^2x sec2x | d(tanx)= s e c 2 x sec^2x sec2xdx |
| (cotx)'=- c s c 2 csc^2 csc2x | d(cotx)=- c s c 2 csc^2 csc2xdx |
| (arcsinx)'= 1 1 − x 2 \frac{1}{\sqrt{1-x^2}} 1−x21 | d(arcsinx)= 1 1 − x 2 \frac{1}{\sqrt{1-x^2}} 1−x21dx |
| (arccosx)'=- 1 1 − x 2 \frac{1}{\sqrt{1-x^2}} 1−x21 | d(arccosx)=- 1 1 − x 2 \frac{1}{\sqrt{1-x^2}} 1−x21dx |
| (arctanx)'= 1 1 + x 2 \frac{1}{1+x^2} 1+x21 | d(arctanx)= 1 1 + x 2 \frac{1}{1+x^2} 1+x21dx |
| (arccotx)'=- 1 1 + x 2 \frac{1}{1+x^2} 1+x21 | d(arccotx)=- 1 1 + x 2 \frac{1}{1+x^2} 1+x21dx |
对于一般形式的函数,求导与微分法则如下表所示:
| 求导公式 | 微分公式 |
|---|---|
| [u(x)+v(x)]‘=u’(x)+v’(x) | d[u(x)+v(x)]=du(x)+dv(x) |
| [u(x)-v(x)]‘=u’(x)-v’(x) | d[u(x)-v(x)]=du(x)-dv(x) |
| [u(x)v(x)]‘=u’(x)v(x)+u(x)v’(x) | d[u(x)v(x)]=du(x)v(x)+u(x)dv(x) |
| [cu(x)]‘=cu’(x) | d[cu(x)]=cdu(x) |
| [ u ( x ) v ( x ) \frac{u(x)}{v(x)} v(x)u(x)]'= u ′ ( x ) v ( x ) − u ( x ) v ′ ( x ) v 2 ( x ) \frac{u'(x)v(x)-u(x)v'(x)}{v^2(x)} v2(x)u′(x)v(x)−u(x)v′(x) | d[ u ( x ) v ( x ) \frac{u(x)}{v(x)} v(x)u(x)]= d u ( x ) v ( x ) − u ( x ) d v ( x ) v 2 ( x ) \frac{du(x)v(x)-u(x)dv(x)}{v^2(x)} v2(x)du(x)v(x)−u(x)dv(x) |
| [ 1 v ( x ) ] ′ = − v ′ ( x ) v 2 ( x ) \frac{1}{v(x)} ]'=-\frac{v'(x)}{v^2(x)} v(x)1]′=−v2(x)v′(x) | d [ 1 v ( x ) ] = − d v ( x ) v 2 ( x ) d[\frac{1}{v(x)}]=-\frac{dv(x)}{v^2(x)} d[v(x)1]=−v2(x)dv(x) |
| d y d x = d y d u d u d x \frac{dy}{dx}=\frac{dy}{du}\frac{du}{dx} dxdy=dudydxdu | dy=f’(u)du |
3.3函数的极值与最值
设函数f(x)在点
x
0
x_0
x0的某邻域内有定义,如果对于该邻域内任意一点x,都有
f
(
x
)
<
f
(
x
0
)
f(x)<f(x_0)
f(x)<f(x0),则称
f
(
x
0
)
f(x_0)
f(x0)是函数f(x)的极大值;如果对于该邻域内任一点x,都有
f
(
x
)
>
f
(
x
0
)
f(x)>f(x_0)
f(x)>f(x0),则称
f
(
x
0
)
f(x_0)
f(x0)是函数f(x)的极小值。函数的极大值与极小值统称为函数的极值,使函数取得极值的点称为函数的极值点。
单变量函数的极值问题较为简单,那么它的极值可能是函数的边界点或驻点,使得
f
(
x
0
)
=
0
f(x_0)=0
f(x0)=0的点x称为函数f(x)的驻点。
对于多变量函数的极值,与单变量函数类似,极值点只能在函数不可导的点或导数为0的点上取得。
此外,对于最值问题,在闭区间上连续函数一定存在最大值和最小值。连续函数在闭区间上的最大值和最小值只能在区间内的驻点,不可导点或闭区间的断点处取得。
3.4Pytorch自动微分
几乎所有机器学习算法在训练或预测时都归结为求解最优化问题,如果目标函数可导,那么问题变为训练函数的驻点。自动微分也称自动求导,算法能够计算可导函数在某点处的导数值,是反向传播算法的一般化。
自动微分技术在深度学习库中处于重要地位,是整个训练算法的核心组件之一。深度学习模型的训练就是不断更新权值,权值的更新需要求解梯度,求解梯度十分烦琐,Pytorch提供自动求导系统,我们只要搭建好前向传播的计算图,就能获取所有张量的梯度。
Pytorch中自动求导模块中的相关函数有torch.autograd.backward()和torch.autograd.gard()。
3.4.1 torch.autograd.backward()
该函数实现自动求取梯度,函数参数如下所示:
torch.autograd.backward(tensors,grad_tensor=None,retain_graph=None,create_graph=False)
- Tensor:用于求导的张量
- retain_graph:保存计算图,由于Pytorch采用动态图极值,在每次反向传播之后计算图都会释放掉,如果还想继续使用,就要设置此参数为True
- create_graph:创建导数计算图,用于高阶求导
- grad_tensor:多梯度权重,当有多个loss需要计算梯度时,需要设置每个loss的权值
例如,线性的一阶求导的代码如下:
import torch
w = torch.tensor([1.],requires_grad=True)
x = torch.tensor([2.],requires_grad=True)
a = torch.add(x,w)
b = torch.add(w,1)
y0 = torch.mul(a,b)
y1 = torch.add(a,b)
loss = torch.cat([y0,y1],dim=0)
grad_t = torch.tensor([1.,2.])
loss.backward(gradient=grad_t)
print(w.grad)
输出如下:
torch.tensor([9.])
3.4.2torch.autograd.gard()
torch.autograd.gard(outputs,inputs,grad_outputs=None,retain_graph=None,create_graph=Falese)
参数说明:
- outputs:用于求导的张量
- inputs:需要梯度的张量
- create_graph:创建导数计算图
- retain_graph:保存计算图
- grad_outputs:多梯度权重
例如,计算 y = x 2 y=x^2 y=x2的二阶导数的代码如下:
import torch
x = torch.tensor([3.], requires_grad=True)
y = torch.pow(x,2)
grad1 = torch.autograd.gard(y,x,create_graph=True)
print(grad1)
grad2 = torch.autograd.gard(grad1[0],x)
print(grad2)
输出如下:
(tensor([6.],grad_fn=),)
(tensor([2.],)
注意事项:
1)梯度不能自动清零,在每次反向传播中会叠加,代码如下:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
for i in range(3):
a = torch.add(x,w)
b = torch.add(w,1)
y = torch.mul(a,b)
y.backward()
print(w.grad)
输出如下:
(tensor([5.],)
(tensor([10.],)
(tensor([15.],)
这会导致我们得不到正确的结果,所以需要手动清零,代码如下:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
for i in range(3):
a = torch.add(x,w)
b = torch.add(w,1)
y = torch.mul(a,b)
y.backward()
print(w.grad)
w.grad_zero_()#梯度清零
输出如下:
(tensor([5.],)
(tensor([5.],)
(tensor([5.],)
2)依赖于也i节点的节点,requires_grad默认为True,代码如下:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
for i in range(3):
a = torch.add(x,w)
b = torch.add(w,1)
y = torch.mul(a,b)
print(a.requires_grad,b.requires_grad,y.requires_grad)
输出如下:
True True True
3)叶子节点不可以执行in-place,因为前向传播记录了叶子节点的地址,反向传播需要用到叶子节点的数据时,要根据地址寻找数据,执行in-place操作改变了地址中的数据,梯度求解也会发生错误,代码如下:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(x,w)
b = torch.add(w,1)
y = torch.mul(a,b)
w.add_(1)
输出如下:
RuntimeError: a leaf Variable that requires grad has been used in an in-palce opreation
in-place操作即原为操作,在原始内存中改变这个数据,代码如下:
a = torch.tensor([1])
print(id(a),a)
#开辟新的内存地址
a = a + torch.tensor([1])
print(id(a),a)
#in-palce操作,地址不变
a += torch.tensor([1])
print(id(a),a)
输出如下:
2638883967360 tensor([1])
2638883967362 tensor([2])
2638883967362 tensor([3])
4.数理统计基础
数理统计是数学一个分支,它以概率论为基础,研究大量随机现象的统计规律性。本节介绍数据统计基础知识,以及Pytorch中的主要统计函数及其案例。
4.1数理统计及其指标
概率论与数理统计是从数量化的角度来研究现实世界中一类不确定现象(随机现象)规律性的一门应用数学学科。下面分别介绍概率论与数理统计的基础知识。
4.1.1概率论基础
(1)必然现象与随机现象
在生活和工作中,人们会观察到各种各样的现象,归纳起来,分为两大类:
一类是可语言其结果的,即在保持条件不变的情况下,重复进行试验,其结果总是确定的,必然发生。这类现象称为必然现象或确定性现象。
另一类是事前不可预言其结果的,即在保持条件不变的情况下,重复进行试验,其结果未必相同。这类在个别试验中其结果呈现偶然性、不确定性的现象,称为随机现象或不确定性现象。
(2)概率
研究随机试验,仅知道可能发生哪些随机事件是不够的,还需要了解各种随机事件发生的可能性大小,以揭示这些事件内在的统计规律性。
这就要求有一个能够衡量事件发生可能性大小的数量指标,这个指标应该是事件本身固有的,且不随忍的主观意志改变,称之为概率。事件A的概率记为P(A)
(3)统计概率
在相同条件下进行n次重复试验,如果随机事件A发生的次数为m,那么m/n称为事件A的频率;当试验重复数n逐渐增大时,随机事件A的频率越来越稳定地接近某一个数值p,那么就把p称为随机事件A地概率。这样定义地概率称为统计概率。
(4)正态分布
若连续型随机变量x的概率密度函数为:
f
(
x
)
=
1
σ
2
π
e
−
(
x
−
u
)
2
2
σ
2
f(x)=\frac{1}{\sigma \sqrt{2 \pi}}e^{-\frac{(x-u)^2}{2 \sigma^2}}
f(x)=σ2π1e−2σ2(x−u)2
其中u为平均数,
σ
2
\sigma ^2
σ2为方差,则称随机变量x服从正态分布,记为x~
N
(
u
,
σ
2
)
N(u,\sigma^2)
N(u,σ2)。相应的概率分布函数为:
F
(
x
)
=
1
σ
2
π
∫
−
∞
x
e
−
(
x
−
u
)
2
2
σ
2
d
x
F(x)=\frac{1}{\sigma \sqrt{2 \pi} }\int_{- \infty}^{x}e^{-\frac{(x-u)^2}{2 \sigma^2}}dx
F(x)=σ2π1∫−∞xe−2σ2(x−u)2dx
(5)标准正态分布
称u=0,
σ
2
\sigma^2
σ2=1的正态分布,标准正态分布的概率密度函数及分布函数为:
f
(
x
)
=
1
2
π
e
−
x
2
2
f(x)=\frac{1}{ \sqrt{2 \pi}}e^{-\frac{x^2}{2}}
f(x)=2π1e−2x2
F
(
x
)
=
1
2
π
∫
−
∞
u
e
−
u
2
2
d
u
F(x)=\frac{1}{\sqrt{2 \pi} }\int_{- \infty}^{u}e^{-\frac{u^2}{2}}du
F(x)=2π1∫−∞ue−2u2du
(6)卡方分布
若n个相互独立的随机变量
X
1
X_1
X1,
X
2
X_2
X2,
…
\dots
…,
X
n
X_n
Xn均服从标准正态分布(也称独立同分布于标准正态分布),则这n个服从标准正态分布的随机变量的平方和构成一新的随机变量,其分布规律称为卡方分布。
X
2
=
X
1
2
+
X
2
2
+
⋯
+
X
n
2
X^2=X_1^2+X_2^2+\dots+X_n^2
X2=X12+X22+⋯+Xn2
(7)T分布
T分布用于根据小样本来估计呈正态分布且方差未知的总体的均值。设随机变量X服从标准正态分布,变量Y服从卡方分布且独立,则称:
T
=
X
Y
n
T=\frac{X}{\sqrt{\frac{Y}{n}}}
T=nYX
为自由度为n的分布。
(8)F分布
设X和Y分别服从自由度
n
1
n_1
n1和
n
2
n_2
n2的卡方分布,则称统计量F服从F分布。
自由度(df)指的是计算某一统计量时,取值不受限制的变量个数,通常df=n-k,其中n为样本数量,k为被限制的条件数或样本个数。
F
=
X
n
1
Y
n
2
F=\frac{\frac{X}{n_1}}{\frac{Y}{n_2}}
F=n2Yn1X
(9)显著性水平
抽样指标值随机样本的变动而变动,因而抽样指标和总体指标的误差仍然是一个随机变量,不能保证误差不超过一定范围的这件事是必然的,而只能以一定程度的概率保证(置信度)。
对于总体的被估计指标X,找出样本的两个估计量
x
1
x_1
x1和
x
2
x_2
x2,使被估计指标X落在区间
(
x
1
,
x
2
)
(x_1,x_2)
(x1,x2)内的概率
1
−
α
1-\alpha
1−α,
(
0
<
α
<
1
)
(0<\alpha<1)
(0<α<1)为已知的。我们称区间
(
x
1
,
x
2
)
(x_1,x_2)
(x1,x2)为总体指标X的置信区间,其估计置信度为
1
−
α
1-\alpha
1−α,称
α
\alpha
α为显著性水平,
x
1
x_1
x1是置信下限,
x
2
x_2
x2是置信上限。
4.1.2数量统计指标
(1)平均值
平均值(均值)是集中趋势中最常用、最重要的测度值,根据数据的表现形式不同,平均值有简单平均值和加权平均值两种。
简单平均值是将总体各单位每一个值加总得到的总量除以单位总量而求出的平均指标,其计算公式如下:
X
=
X
1
+
X
2
+
⋯
+
X
n
n
=
∑
X
n
X=\frac{X_1+X_2+\dots+X_n}{n}=\frac{\sum X}{n}
X=nX1+X2+⋯+Xn=n∑X
简单平均值适用于总体单位数较少的未分组数据。如果所给的资料是已经分组的数据,则平均值的计算应采用加权平均值的形式。
加权平均值是首先用各组的值乘以相应的各组单位数求出各组总量,并加总求得总体总量,而后再将总体总量和总体单位总量对比,其计算公式如下:
X
=
f
1
X
1
+
f
2
X
2
+
⋯
+
f
n
X
n
f
1
+
f
2
+
⋯
+
f
n
=
∑
f
X
∑
f
X=\frac{f_1X_1+f_2X_2+\dots+f_nX_n}{f_1+f_2+\dots+f_n}=\frac{\sum fX}{\sum f}
X=f1+f2+⋯+fnf1X1+f2X2+⋯+fnXn=∑f∑fX
其中f表示各组的单位数,或者说是频数或权数。
(2)中位数
中位数是将总体单位某一变量的各个变量值按大小顺序排序,处于数列中间位置的那个变量值就是中位值。
将各变量按大小顺序排序后,首先确定中位数的位置,可以公式
n
+
1
2
\frac{n+1}{2}
2n+1确定,n代表总体单位的项数;然后根据中点位置确定中位数。有两种情况:当n为奇数项时,则中位数就是居于中间位置的那个变量值;当n为偶数项时,则中位数是位于中间位置的两个变量值的平均数。
(3)众数
众数是总体中出现次数最多的值,即最普遍、最常见的值。众数只有在中体单位较多而又有明确的集中趋势的资料中才有意义。在单项数列中,出现最多的那个组的值就是众数。若在数列中有两组的次数是相同的,且次数最多,则就是双众数。
(4)百分位数
如果将一组数据排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数。常用的有四分数,指的是将数据分为4等份,分别位于25%、50%、75%处的百分数。百分位数的优点是不受极端值的影响,但是不能用于定类数据。
(5)方差与标准差
方差是总体各单位变量值与其平均数的离差平方的平均数,用
σ
2
\sigma^2
σ2表示,方差的平方根是标准差
σ
\sigma
σ。与方差不同的是,标准差是具有量纲(即单位)的,它与变量值的计量大碗内相同,其实际意义要比方差清楚。因此,在对社会经济现象进行分析时,往往更多地使用标准差。
根据数据不同,方差和标准差的计算有两种形式:简单平均式和加权平均式。在数据未分组的情况下,采用简单平均式,公式如下:
σ
2
=
∑
(
X
−
X
^
)
2
n
\sigma^2=\frac{\sum (X-\hat{X})^2}{n}
σ2=n∑(X−X^)2
σ
=
∑
(
X
−
X
^
)
2
n
\sigma=\sqrt{\frac{\sum (X-\hat{X})^2}{n}}
σ=n∑(X−X^)2
在数据分组的情况下,采用加权平均式,公式如下:
σ
2
=
∑
f
(
X
−
X
^
)
2
∑
f
\sigma^2=\frac{\sum f(X-\hat{X})^2}{\sum f}
σ2=∑f∑f(X−X^)2
σ
=
∑
f
(
X
−
X
^
)
2
∑
f
\sigma=\sqrt{\frac{\sum f(X-\hat{X})^2}{\sum f}}
σ=∑f∑f(X−X^)2
(6)极差
极差又称全距或范围,它是总体单位中最大变量值和最小变量值之差,即两极之差,以R表示。根据全距的大小来说明变量值变动范围的大小,公式如下:
R
=
x
m
a
x
−
x
m
i
n
R=x_{max}-x_{min}
R=xmax−xmin
极差只是利用率一组数据两端的信息,不能反映出中间数据的分散情况,因而不能准确描述出数据的分散程度,且容易受极端值的影响。
(7)最大值
顾名思义,最大值即样本数据中取得最大的数据。
(8)最小值
顾名思义,最小值即样本数据中取得最小的数据。
(9)变异系数
变异系数是将标准差与其平均数对比所得的比值,又称离散系统,公式如下:
V
σ
=
σ
X
^
V_{\sigma}=\frac{\sigma}{\hat{X}}
Vσ=X^σ
变异系数是衡量数据中各观测值变异程度的统计量。当进行两个或多个资料变异程度的比较时,如果平均数相同,则可以直接利用标准差来比较。如果平均数不同,则比较其变异程度不能采用标准差,则需要采用标准差与平均值的比值(相对值)来比较。
(10)偏度
偏度是对分布偏斜方向及程度的测度。测量偏斜的程度需要计算偏态。常用三阶中心矩除以标准差的三次方,表示数据分布的相对偏斜程度。其计算公式如下:
a
3
=
∑
f
(
x
−
x
^
)
3
σ
3
∑
f
a_3=\frac{\sum f(x-\hat{x})^3}{\sigma^3 \sum f}
a3=σ3∑f∑f(x−x^)3
在公式中,
a
3
a_3
a3为正,表示分布为右偏;
a
3
a_3
a3为负,表示分布为左偏。
(11)峰度
峰度是频数分布曲线与正态分布相比较,顶端的尖峭程度。统计上常用四阶中心矩测定峰度。其计算公式如下:
a
4
=
∑
f
(
x
−
x
^
)
4
σ
4
∑
f
a_4=\frac{\sum f(x-\hat{x})^4}{\sigma^4 \sum f}
a4=σ4∑f∑f(x−x^)4
当
a
4
=
3
a_4=3
a4=3,分布曲线为正态分布;
当
a
4
<
3
a_4<3
a4<3,分布曲线为平峰分布;
当
a
4
>
3
a_4>3
a4>3,分布曲线为尖峰分布;
(12)Z标准化得分
Z标准化得分是某一数据与平均数的距离以标准差为单位的测量值、其计算公式如下:
Z
i
=
X
i
−
X
^
σ
Z_i=\frac{X_i-\hat{X}}{\sigma}
Zi=σXi−X^
在公式中,
Z
i
Z_i
Zi即为
X
i
X_i
Xi的Z标准化得分。Z标准化的绝对值越大,说明它离平均数越远。
标准化后的数值能表目各原始数据在一组数据分布中的相对位置,而且还能不同分布的各组原始数据间进行比较。因此,标准化值在统计分析中起着十分重要的作用。
4.2Pytorch统计函数
Pytorch与其它统计软件一样,也内置了丰富的统计函数。下面结合案例重点介绍求和、求均值、求方差、求标准差、求中位数等一些常用的统计函数。
(1)所有元素的积
torch.prob()函数返回所有元素的积,用法如下:
torch.prob(input,dtype=None)
(2)求和
torch.sum()函数对输入的tensor数据的某一维度求和,一共有两种用法,代码如下:
torch.sum(input,dtype=None)
torch.sum(input,dim,keepdim=False,dtype=None)
参数说明:
- Input:输入一个tensor
- dim:要求和的维度,可以是一个列表,当dim=0时,即第0个维度会缩减,也就是将N行压缩成一行,故相当于列进行求和;当dim=1时,对行进行求和。
- keepdim:求和之后这个dim元素个数为1,所以要被去掉,如果要保留这个维度,则应当让keepdim=True
首先,创建初始张量,代码如下:
import torch
a = torch.rand(2,2)
print(a)
##输出如下:
##tensor([[0.0528,0.3420],[0.5011,0.4264]])
a1 = torch.sum(a)
a2 = torch.sum(a,dim=(0,1))
a3 = torch.sum(a,dim=0)
a4 = torch.sum(a,dim=1)
print(a1)
print(a2)
print(a3)
print(a4)
##a1输出tensor(1.3223)
##a2输出tensor(1.3223)
##a3输出tensor([0.5539,0.7684])
##a3输出tensor([0.3948,0.9275])
a5=torch.sum(a,dim=(0,1),keepdim=True)
a6=torch.sum(a,dim=(0,),keepdim=True)
a7=torch.sum(a,dim=(1,),keepdim=True)
print(a5)
print(a6)
print(a7)
##a5输出tensor(1.3223)
##a6输出tensor([0.5539,0.7684])
##a7输出tensor([[0.3948],[0.9275]])
(3)平均值
torch.mean()函数对输入的tensor数据的某一维度求平均值,参数与torch.sum()函数类似,也有两种用法:
torch.mean(input,dtype=None)
torch.mean(input,dim,keepdim=False,dtype=None)
设置参数input和dim,代码如下:
a8=torch.mean(a)
a9=torch.mean(a,dim=(0,1))
a10=torch.mean(a,dim=0)
a11=torch.mean(a,dim=1)
print(a8)
print(a9)
print(a10)
print(a11)
##a8输出tensor(0.3306)
##a9输出tensor(0.3306)
##a10输出tensor[0.2770,0.3842]
##a11输出tensor[0.1974,0.4638]
设置参数keepdim,代码如下:
a12=torch.mean(a,dim=(0,1),keepdim=True)
a13=torch.mean(a,dim=0,keepdim=True)
a14=torch.mean(a,dim=1,keepdim=True)
print(a12)
print(a13)
print(a14)
##a12输出tensor(0.3306)
##a13输出tensor[0.2770,0.3842]
##a12输出tensor[[0.1974],[0.4638]]
(4)最大值
torch.max()函数返回最大值,参数与torch.sum()函数类似,但是参数dim需要是整数,也有两种用法,代码如下:
torch.max(input,dtype=None)
torch.max(input,dim,keepdim=False,dtype=None)
设置参数input和dim,代码如下:
a15 = torch.max(a)
a16 = torch.max(a,dim=0)
a17 = torch.max(a,dim=1)
print(a15)
print(a16)
print(a17)
##a12输出tensor(0.5011)
##torch.return_types.max(values=tensor([0.5011,0.4264])),
##indices=tensor([1,1])
##torch.return_types.max(values=tensor([0.3420,0.5011])),
##indices=tensor([1,0])
设置参数keepdim,代码如下:
a18 = torch.max(a,0,keepdim=True)
a19 = torch.max(a,1,keepdim=True)
print(a18)
print(a19)
结果同之前。
(5)最小值
torch.min()函数返回最小值,参数与torch.max()函数类似,但是参数dim需要是整数,也有两种用法。
(6)中位值
torch.median()函数返回中位数,参数与torch.max()函数类似,也有两种用法。
(7)众数
torch.mode()函数返回中位数,参数与torch.max()函数类似,也有两种用法。
(8)方差
torch.var()函数返回方差,参数与torch.max()函数类似,也有两种用法。
torch.var(input,unbiased=True)
torch.var(input,dim,unbiased=True,keepdim=False,*,out=None)
参数说明:
- input:输入一个tensor
- dim:求和的维度,可以是一个列表,当dim=0时,即第0个维度会缩减,也就是说将N行压缩成一行,故相当于对列进行求和;当dim=1,对行进行求和
- unbiased:是否使用无偏估计。布尔型。如果unbiased为False,则通过有偏估计量计算方差,否则将使用贝塞尔校正更正。
- keepdim:求和之后这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则应当让keepdim=True
(9)标准差
torch.std()函数返回标准,参数与torch.var()函数类似,也有两种用法。
torch.std(input,unbiased=True)
torch.std(input,dim,unbiased=True,keepdim=False,*,out=None)
5.矩阵
5.1矩阵的运算
(1)矩阵的加法
如果
A
=
(
A
i
j
)
m
n
A=(A_{ij})_{mn}
A=(Aij)mn,
B
=
(
B
i
j
)
m
n
B=(B_{ij})_{mn}
B=(Bij)mn,
C
=
A
+
B
=
(
A
i
j
+
b
i
j
)
m
n
C=A+B=(A_{ij}+b_{ij})_{mn}
C=A+B=(Aij+bij)mn
(2)矩阵的减法
如果
A
=
(
A
i
j
)
m
n
A=(A_{ij})_{mn}
A=(Aij)mn,
B
=
(
B
i
j
)
m
n
B=(B_{ij})_{mn}
B=(Bij)mn,
C
=
A
−
B
=
(
A
i
j
−
b
i
j
)
m
n
C=A-B=(A_{ij}-b_{ij})_{mn}
C=A−B=(Aij−bij)mn
(3)矩阵的乘法
如果
A
=
(
A
i
j
)
m
n
A=(A_{ij})_{mn}
A=(Aij)mn,
B
=
(
B
i
j
)
n
p
B=(B_{ij})_{np}
B=(Bij)np,
A
B
=
C
=
(
C
i
j
)
m
p
AB=C=(C_{ij})_{mp}
AB=C=(Cij)mp,其中,
c
i
j
=
∑
k
=
1
n
a
i
k
×
b
k
j
c_{ij}=\sum_{k=1}^na_{ik} \times b_{kj}
cij=∑k=1naik×bkj
(4)矩阵的除法
如果
A
=
(
A
i
j
)
m
n
A=(A_{ij})_{mn}
A=(Aij)mn,
B
=
(
B
i
j
)
n
p
B=(B_{ij})_{np}
B=(Bij)np,
A
B
−
1
=
C
=
(
C
i
j
)
m
p
AB^{-1}=C=(C_{ij})_{mp}
AB−1=C=(Cij)mp,其中,
c
i
j
=
∑
k
=
1
n
a
i
k
/
b
k
j
c_{ij}=\sum_{k=1}^na_{ik} / b_{kj}
cij=∑k=1naik/bkj
(5)矩阵的转置
设矩阵
A
=
(
a
i
j
)
m
n
A=(a_{ij})_{mn}
A=(aij)mn,将A的行与列的元素位置交换,称为矩阵A的转置,
A
T
=
(
a
i
j
)
n
m
A^T=(a_{ij})_{nm}
AT=(aij)nm
(6)矩阵的特征值与特征向量
设A为n阶矩阵,若存在常数
λ
\lambda
λ和非零n维向量
α
\alpha
α,使得
A
α
=
λ
α
A \alpha=\lambda \alpha
Aα=λα,则称
λ
\lambda
λ为A的特征值
α
\alpha
α是A的属于特征值
λ
\lambda
λ的特征向量。称
∣
λ
E
−
A
∣
=
f
A
(
λ
)
|\lambda E-A|=f_A(\lambda)
∣λE−A∣=fA(λ)为A的特征多项式,
∣
λ
E
−
A
∣
=
0
|\lambda E-A|=0
∣λE−A∣=0为A的特征方程。
5.2Pytorch矩阵运算
张量的基本运算方式,一种为逐元素之间的运算,例如add(加)、sub(减)、mul(乘)、div(除)四则运算,以及幂运算、平方根、对数等矩阵运算。
(1)矩阵的加法
在Pytorch中,矩阵的加法运算有5种实现方法。
import torch
a = torch.rand(3,4)
b = torch.rand(4)
print(a)
print(b)
输出如下:
tensor([[0.5675,0.7567,0.4230,0.5616],
[0.7795,0.4334,0.3138,0.7730],
[0.4122,0.7436,0.1173,0.9017]])
tensor([0.3944,0.3240,0.4609,0.7860])
从输出可以看出,张量a和张量b的维度不一样,在进行矩阵运算时,会隐式把一个张量的维度调整到与另一个张量相匹配1维度以实现维度兼容,从而进行运算。
与Numpy的广播机制一致,这里的张量b会调整为如下的项式,维度与张量a一样。
tensor([[0.3944,0.3240,0.4609,0.7860],
[0.3944,0.3240,0.4609,0.7860],
[0.3944,0.3240,0.4609,0.7860]])
方法1:使用+运算符实现加法
print(a+b)
方法2:使用函数torch.add()实现加法
print(torch.add(a,b))
方法3:输出到一个向量
c=torch.Tensor(3,4)
print(torch.add(a,b,out=c))
方法4:把一个张量加到另一个张量上
print(b.add(a))
(2)矩阵的减法
方法1:使用-运算符实现减法
print(a-b)
方法2:使用函数torch.sub()实现减法
print(torch.sub(a,b))
方法3:输出到一个向量
c=torch.Tensor(3,4)
print(torch.sub(a,b,out=c))
方法4:把一个张量加到另一个张量上
print(b.sub(a))
(3)矩阵的乘法
方法1:使用*运算符实现乘法
print(a*b)
方法2:使用函数torch.mul()实现乘法
print(torch.mul(a,b))
方法3:输出到一个向量
c=torch.Tensor(3,4)
print(torch.mul(a,b,out=c))
方法4:把一个张量加到另一个张量上
print(b.mul(a))
(4)矩阵的除法
方法1:使用/运算符实现除法
print(a/b)
方法2:使用函数torch.mul()实现除法
print(torch.div(a,b))
方法3:输出到一个向量
c=torch.Tensor(3,4)
print(torch.div(a,b,out=c))
方法4:把一个张量加到另一个张量上
print(b.div(a))
(5)矩阵的幂运算
方法1:使用**运算符实现幂运算
print(a**2)
方法2:使用函数torch.pow()实现幂运算
print(a.pow(2))
(6)矩阵的平方根
方法1:使用函数torch.sqrt()实现减法
print(a.sqrt())
方法2:使用函数torch.rsqrt()实现减法
print(a.rsqrt())
(7)矩阵的对数
方法1:使用函数torch.log2()实现减法
print(torch.log2(a))
方法2:使用函数torch.log10()实现减法
print(torch.log10(a))
6.其他运算
(1)向下取整
print(a.floor())
(2)向上取整
print(a.ceil())
(3)四舍五入
print(a.round())
(4)提取整数部分
print(a.trunc())
(5)提取小数部分
print(a.frac())
7.拟合余弦函数曲线
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torch.utils.data import TensorDataset
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
x = np.linspace(-2*np.pi,2*np.pi,400)
y = np.cos(x)
X = np.expand_dim(x,axis=1)
Y = y.reshape(400,-1)
dataset = TensorDataset(torch.tensor(X,dtype=torch.float),torch.tensor(Y,dtype=torch.float))
dataloader=DataLoader(dataset,batch_size=10,shuffle=True)
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.net=nn.Sequential(
nn.Linear(in_features=1,out_features=10),nn.ReLU(),
nn.Linear(10,100),nn.ReLU(),
nn.Linear(100,10),nn.ReLU(),
nn.Linear(10,1)
)
def forward(self, input:torch.FloatTensor):
return self.net(input)
net = Net()
optim = torch.optim.Adam(Net.parameters(net),lr=0.001)
Loss = nn.MSELoss()
for epoch in range(100):
loss = None
for batch_x,batch_y in dataloader:
y_predict = net(batch_x)
loss = Loss(y_predict,batch_y)
optim.zero_grad()
loss.backward()
optim.step()
if (epoch+1)%10==0:
print("训练步骤 : {0} ,模型损失 {1}".format(epoch+1,loss.item()))
predict=net(torch.tensor(X,dtype=torch.float))
plt.figure(figsize=(12,7),dpi=160)
plt.plot(x,y,label='实际值',marker="X")
plt.plot(x,predict.detach().numpy(),label="预测值",marker='o')
plt.xlabel("x",size=15)
plt.ylabel("cos(x)",size=15)
plt.xticks(size=15)
plt.yticks(size=15)
plt.legend(fontsize=15)
plt.show()
更多推荐
所有评论(0)