塞进裤子ヾ(≧O≦)〃嗷~

0%

神经网络基础(一)

神经网络基础

感知器 perceptron

感知器

$$y=f(wx+b)$$

激活函数

sigmoid

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

值域(0,1), torch.sigmoid()

导数f(x)’= $f(x)(1-f(x))$

mark

容易导致梯度消失vanishing gradient和梯度爆炸exploding gradient问题,所以一般只用于输出,将输出解释成概率

1
2
3
4
5
6
7
import torch
import matplotlib.pyplot as plt

x = torch.range(-10.0, 10.0, 0.2)
y = torch.sigmoid(x)
plt.plot(x.numpy(), y.numpy())
plt.show()

mark

tanh

$$
f(x)=tanh x=\frac{e^x-e^{-x}}{e^x+e^{-x}}
$$
值域[-1,1], torch.tanh()

1
2
3
4
x = torch.range(-10.0, 10.0, 0.2)
y = torch.tanh(x)
plt.plot(x.numpy(), y.numpy())
plt.show()

tanh

Relu

$$
f(x)=max(0, x)
$$

1
2
3
4
5
x = torch.range(-10.0, 10.0, 0.2)
relu = torch.nn.ReLU()
y =relu(x)
plt.plot(x.numpy(), y.numpy())
plt.show()

relu

relu也容易带来梯度消失问题,即网络中某些输出变为0并永远不会改变。
为解决此问题,提出Leaky ReLU和PReLU之类的变体
$f(x)=max(x,ax)$

$a$是学习的参数,如0.01

1
2
3
4
5
x = torch.range(-10.0, 10.0, 0.2)
prelu = torch.nn.PReLU(num_parameters=1)
y = prelu(x)
plt.plot(x.numpy(), y.detach().numpy())
plt.show()

mark

ELU

类似于ReLU,但它不是将0以下的值归为0,而是对它们求幂。
ELU已经被证明是卷积层之间使用的一种很有前途的非线性激活函数。
$$
f(x)=
\begin{cases}
x& \text{ if x>0}\
\alpha (exp(x)-1)& \text{if x<=0}
\end{cases}
$$
其中α是一个可调整的参数,它控制着ELU负值部分在何时饱和。

softmax

$$
softmax(x_i)= \frac{e^{x_i}}{\sum_{j=1}^k e^{x_j}}
$$

值域(0,1)

1
2
3
4
5
6
7
8
9
10
softmax = torch.nn.Softmax(dim=1)
x=torch.randn(1,3)
y = softmax(x)
print(x)
print(y)
print(torch.sum(y,dim=1))
-----
tensor([[ 0.5431, 2.2414, -0.2871]])
tensor([[0.1449, 0.7919, 0.0632]])
tensor([1.])

损失函数

Mean Squared Error Loss(MSE)

均方误差损失,预测值与目标值差的平方的平均值
$$
L_{MSE}(y,\hat y )=\frac{1}{n}\sum_{i=1}^n(y - \hat y)^2
$$
还有一些其它函数可解决回归问题,如MAE(mean absolute error)平均绝对误差和RMSE(root mean squared error)均方根误差

1
2
3
4
5
6
7
8
9
10
import torch
import torch.nn as nn

mseLoss = nn.MSELoss()
outputs = torch.randn(3 ,5, requires_grad = True)
targets = torch.randn(3,5)
loss = mseLoss(outputs, targets)
print(loss)
-----
tensor(2.6322, grad_fn=<MseLossBackward>)

Cross-Entropy Loss

交叉熵损失函数,通常用于多分类

目标$y$是一个one-hot向量,只有真正的类别为1;预测$\hat y$也是一个向量,表示网络对每类的预测。
$$
L_{cross_entroy}(y,\hat y) = - \frac{1}{N} \sum_{i=1}^N y_i log(\hat y_i)
$$
注意,公式里的$\hat y$是经过softmax的,但我们输入不必进行softmax,CELoss会自己进行softmax。

weight(Tensor)- 为每个类别的loss设置权值,常用于类别不均衡问题。weight必须是float类型的tensor,其长度要于类别C一致,即每一个类别都要设置有weight。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ce_loss = nn.CrossEntropyLoss()
outputs = torch.randn(3, 4, requires_grad=True)
#3是N样本数,4是类别数
targets = torch.empty(3, dtype=torch.long).random_(4)#生成0~4的随机整数
#targets是1维(实际上转化为one-hot表示),样本数3,
loss = ce_loss(outputs, targets)
print(outputs)
print("====")
print(targets)
print("====")
print(loss)
-----
tensor([[ 0.1444, 0.9612, -0.3383, -1.4349],
[-0.3628, -0.4709, 1.1055, -0.2140],
[ 0.8307, -0.1824, -0.2376, -0.4188]], requires_grad=True)
====
tensor([1, 1, 3])
#targets实际上会进行one-hot表示
[[0,1,0,0],
[0,1,0,0],
[0,0,0,3]]
====
tensor(1.5466, grad_fn=<NllLossBackward>)

Re:
https://blog.csdn.net/jasonleesjtu/article/details/89141554

Binary Cross-Entropy loss(BCE)

二进制交叉熵,适用于二分类
$$
L = - \frac{1}{N} \sum _{i=1}^N [ y_i \cdot \log p_i + (1 - y_i) \cdot \log (1 - p_i)]
$$
$N$是样本个数,$p_i$是输出概率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bce_loss = nn.BCELoss()
sigmoid = nn.Sigmoid()
#网络输出的概率,此例样本数为4
probabilities = sigmoid(torch.randn(4, 1, requires_grad=True))
print(probabilities)
#目标用0、1表示
targets = torch.tensor([1,0,1,0], dtype= torch.float32).view(4,1)
print(targets)
loss = bce_loss(probabilities, targets)
print(loss)
-----
tensor([[0.5816],
[0.6175],
[0.5957],
[0.7197]], grad_fn=<SigmoidBackward>)
tensor([[1.],
[0.],
[1.],
[0.]])
tensor(0.8232, grad_fn=<BinaryCrossEntropyBackward>)

BCEWithLogitsLoss

如何计算?例子
https://zhuanlan.zhihu.com/p/34879333

https://morvanzhou.github.io/tutorials/machine-learning/ML-intro/3-08-batch-normalization/

1
2
应用sigmoid再使用BceLoss(torch.nn.BCELoss())可能存在数值稳定性问题。
针对此问题,Pytorch提供BCEWithLogitsLoss(),要使用此函数,输出不能使用sigmoid函数

监督学习的一套流程

比如线性二分类,分别用0和1表示两个类;

设置决策边界$\delta$ ,如果预测的概率$P> \delta$,归为类别1,否则归为类别0.

损失函数选用BCE Loss;

整个训练数据被分成batches

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
n_epochs = 10
n_batches = 10
batch_size = 32
def get_toy_data(batch_size):
x = torch.rand(batch_size, input_dim)
y = torch.zeros(batch_size)
for i in range(batch_size):
if x[i, :].sum() > 1:
y[i] = 1
return x,y
#一个epoch是一个完整的数据集
for epoch_i in range(n_epochs):
# 内部循环是在一个批次数据集上
for batch_i in range(n_batches):
# Step 0: 获取数据
x_data, y_target = get_toy_data(batch_size)

# Step 1: 清除梯度
perceptron.zero_grad()

# Step 2: 计算模型前向参数,这里会自动调用perceptron.forward()
y_pred = perceptron(x_data)

# Step 3: 计算损失
loss = bce_loss(y_pred, y_target)

# Step 4: 后向传递
loss.backward()

# Step 5: 触发优化,更新参数
optimizer.step()

其他

train:val:test 75%:15%:15%

early stopping

观察在val集上的性能,若不再提高,停止训练。在终止训练前等待的epoch数目称为patience。

通过 weight_decay 设置L2正则化强度

Yelp数据集情感分类

将学到:

设置early stop的方法

pytorch构建框架,train和test 的基本框架,关键代码

三个辅助类

Vocabulary : mapping text tokens to intergers and mapping the class labels to integers .

ReviewDataset : 包含DataFrame格式的数据集,和ReviewVectorizer类的实例化vectorizer

ReviewVectorizer: 将word转为向量,包括review_vocab和rating_vocab

DataLoader: 将数据分割成minibatches

具体代码及数据集链接:

https://github.com/drawStar/Machine-Learning/tree/master/pytorch/yelpReview

if help:小手一抖点个广告 or 大手一挥资助一下