激活函数

fx5H4.png
$$
y=f(\sum_{i=1}^nw_ix_i+b)
$$
此f()为激活函数,输入为前一层所有输出的加权和再加上一个偏执b

sigmoid

$$
f(x)=\sigma(x)=\frac{1}{1+ e^x}\
$$

$$
\frac{\partial f(x)}{\partial x}=f(x)(1-f(x))
$$

优点:求导简单,数据可压缩到(0,1)

缺点:梯度离散,输入很大时输出太平缓

调用指令torch.sigmoid()

Tanh

$$
f(x)=tanh(x)=\frac{(e^x-e^{-x})}{(e^x+e^{-x})}
=2sigmoid(2x)-1
$$

$$
\frac{\partial f(x)}{\partial x}=1-tanh^2(x)
$$

调用指令torch.tanh()

ReLU

$$
f(x)=\begin{cases}0\ for\ x<0 \\
x\ for\ x\geq0\end{cases}
$$

调用指令torch.relu()

Loss函数

MSE

$$
loss_i=\sum(y_i-\bar y_i)^2=norm((y_i-\hat y_i),2)^2
$$

调用指令 torch.nn.functional.mse_loss($y,\hat y$')

自动求导:

方法一
1. 首先对需要求导的参数使用requires_grad_()方法标明需要求导
2. 计算mse:torch.nn.functional.mse_loss($y$,$\hat y$)
3. 使用torch.autograd.grad(mse,[w])对其进行求导

方法二

  1. 首先对需要求导的参数使用requires_grad_()方法标明需要求导

  2. 计算mse:torch.nn.functional.mse_loss($y,\hat y$)

  3. 调用mse.backward该指令会计算mse对所有已设置需要求导变量的梯度

  4. 调用w.grad显示梯度

    backward设置(retain_graph=True)才可以再一次调用,不设置则会报错

import torch.nn.functional as F
x=torch.ones(1)
w=torch.Tensor([2])
w.requires_grad_()
mse=F.mse_loss(torch.ones(1),x*w)
#torch.autograd.grad(mse,[w])
mse.backward()
print(w.grad)

#tensor([2.])

Softmax

$$
softmax(y_i)=\frac{e^{y_i}}{\sum_ je^{y_j}} \
$$

$$
\frac{\partial softmax(y_i)}{\partial y_j}=\begin{cases}softmax(y_i)(1-softmax(y_j))\ \ if\ i=j\\
-softmax(y_i)softmax(y_j)\ \ \ \ \ \ \ \ \ if\ i\neq j\end{cases}
$$

优点:将输出label的probability压缩到(0,1),且所有probability之和为1,原数据间隔拉大

调用指令 torch.nn.functional.mse_loss(y,dim=x)

交叉熵

$$
H(P,Q)=-\sum_{i=1}^nP(i)logQ(i)
$$

通常用于分类问题

调用指令 torch.nn.functional.cross_entropy(logits,y)

或者

pred=torch.nn.functional.softmax(logits,dim=1)
pred_log=torch.nn.functional.log(pred)
torch.nn.functional.nll_loss(pred_log,y)

cross_entropy=softmax→log→nll_loss

#一个二元二次函数梯度下降求极值算法

#一个二元二次函数梯度下降求极值算法
import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt
def himmelblau(x):
return(x[0]**2+x[1]-11)**2+(x[0]+x[1]**2-7)**2
x=np.arange(-6,6,0.1)
y=np.arange(-6,6,0.1)
X,Y=np.meshgrid(x,y)
Z=himmelblau([X,Y])

fig=plt.figure("himelblau")
ax=fig.gca(projection='3d')
ax.plot_surface(X,Y,Z)
ax.view_init(60,-30)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()#画出图像
x=torch.tensor([4.,0.],requires_grad=True)
optimizer=torch.optim.Adam([x],lr=1e-3)#lr:learning rate 实例化反向传播算法优化器
for step in range(20000):
pred=himmelblau(x)
optimizer.zero_grad()#参数梯度置为0
pred.backward()
optimizer.step()#执行梯度下降
if step%2000==0:
print('step{}:x={},f(x)={}'.format(step,x.tolist(),pred.item()))

fP7Oi.png

#运算结果
step0:x=[3.999000072479248, -0.0009999999310821295],f(x)=34.0
step2000:x=[3.5741987228393555, -1.764183521270752],f(x)=0.09904692322015762
step4000:x=[3.5844225883483887, -1.8481197357177734],f(x)=2.1100277081131935e-09
step6000:x=[3.5844264030456543, -1.8481241464614868],f(x)=2.41016095969826e-10
step8000:x=[3.58442759513855, -1.848125696182251],f(x)=2.9103830456733704e-11
step10000:x=[3.584428310394287, -1.8481262922286987],f(x)=9.094947017729282e-13
step12000:x=[3.584428310394287, -1.8481265306472778],f(x)=0.0
step14000:x=[3.584428310394287, -1.8481265306472778],f(x)=0.0
step16000:x=[3.584428310394287, -1.8481265306472778],f(x)=0.0
step18000:x=[3.584428310394287, -1.8481265306472778],f(x)=0.0

##一个交叉熵多分类问题

网络结构

##一个交叉熵多分类问题