感知机
-
感知机其实就是一个二分类问题
-
给定输入x,权重w,和偏移b,感知机的输出: o = σ ( ⟨ w , x ⟩ + b ) σ = { 1 i f x > 0 − 1 o t h e r w i s e o=\sigma (\left \langle w, x \right \rangle + b) \quad \sigma = \left\{\begin{matrix} 1 & if x > 0 \\ -1 & otherwise \end{matrix}\right. o=σ(⟨w,x⟩+b)σ={1−1ifx>0otherwise
-
二分类:1或-1
vs.回归模型输出实数
vs.Softmax回归输出概率
训练感知机
- 等价于使用批量大小为1的梯度下降并使用损失函数: l ( y , x , w ) = m a x ( 0 , − y ⟨ w , x ⟩ ) l(y,x,w)=max(0,-y\left \langle w,x \right \rangle) l(y,x,w)=max(0,−y⟨w,x⟩)
收敛定理
- 所谓的收敛定理就是算法什么时候能够停
- 这里做几个假设:数据在半径r内,余量
ρ
\rho
ρ分类两类:
y
(
x
T
w
=
b
)
≥
ρ
y(x^Tw=b) \geq \rho
y(xTw=b)≥ρ,对于
∥
w
∥
2
+
b
2
≤
1
\left \|w \right \|^2 + b^2 \leq 1
∥w∥2+b2≤1。余量的意思就是两个类分的很开,也就是两类之间还有一些空间。
感知机保证在 r 2 + 1 ρ \frac{r^2+1}{\rho} ρr2+1步后收敛。这里的意思就是r是数据的大小, ρ \rho ρ就是看我们的数据是不是分的很开
XOR问题(Minsky & Papert, 1969)
- 感知机不能拟合XOR函数,它只能产生线性分割面
总结
- 感知机是一个二分类模型,是最早的AI模型之一
- 它的求解算法等价于使用批量大小为1的梯度下降
- 它不能拟合XOR函数,导致的第一次AI寒冬
多层感知机
-
学习XOR:这里的意思就是如果我们使用一层感知机做不了我们就使用多层,先去学习一个简单的。下图的意思就是把坐标先把坐标分开,然后相乘
-
单隐藏层
隐藏层的大小是一个超参数
-
单隐藏层——单分类
输入 x ∈ R n x\in \mathbb{R}^n x∈Rn
隐藏层 W 1 ∈ R m × n , b 1 ∈ R m W_1 \in \mathbb{R}^{m\times n}, b_1 \in \mathbb{R}^m W1∈Rm×n,b1∈Rm
输出层 w 2 ∈ R m , b 2 ∈ R w_2 \in \mathbb{R}^m, b_2\in \mathbb{R} w2∈Rm,b2∈R
h = σ ( W 1 x + b 1 ) h=\sigma(W_1x+b_1) h=σ(W1x+b1)
o = w 2 T h + b 2 o=w_2^Th+b_2 o=w2Th+b2
σ 是 按 元 素 的 激 活 函 数 \sigma是按元素的激活函数 σ是按元素的激活函数
为什么我们需要一个非线性的激活函数?
如果是一个线性函数,放进去其实没什么变化
Sigmoid激活函数
将输入投影到(0,1), s i g m o i d ( x ) = 1 1 + e x p ( − x ) sigmoid(x)=\frac{1}{1+exp(-x)} sigmoid(x)=1+exp(−x)1
Tanh激活函数
将输入投影到(-1,1), t a n h ( x ) = 1 − e x p ( − 2 x ) 1 + e x p ( − 2 x ) tanh(x)=\frac{1-exp(-2x)}{1+exp(-2x)} tanh(x)=1+exp(−2x)1−exp(−2x)
ReLU函数
ReLU:rectified linear unit, R e L U ( x ) = m a x ( x , 0 ) ReLU(x)=max(x,0) ReLU(x)=max(x,0) -
多类分类
和softmax类似,softmax没有隐藏层
输入 x ∈ R n x\in \mathbb{R}^n x∈Rn
隐藏层 W 1 ∈ R m × n , b 1 ∈ R m W_1 \in \mathbb{R}^{m\times n}, b_1 \in \mathbb{R}^m W1∈Rm×n,b1∈Rm
输出层 w 2 ∈ R m × k , b 2 ∈ R k w_2 \in \mathbb{R}^{m\times k}, b_2\in \mathbb{R}^k w2∈Rm×k,b2∈Rk
h = σ ( W 1 x + b 1 ) h=\sigma(W_1x+b_1) h=σ(W1x+b1)
o = w 2 T h + b 2 o=w_2^Th+b_2 o=w2Th+b2
y = s o f t m a x ( o ) y=softmax(o) y=softmax(o)
σ 是 按 元 素 的 激 活 函 数 \sigma是按元素的激活函数 σ是按元素的激活函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ancBqwv-1627187888558)(attachment:image-3.png)] -
多隐藏层
总结
- 多层感知机使用隐藏层和激活函数来来得到非线形模型
- 常用激活函数是Sigmoid、Tanh、ReLU
- 使用Softmax来处理多类分类
- 超参数为隐藏层数,和各个隐藏层大小
多层感知机从零开始实现
import torch
from torch import nn
from d2l import torch as d2l
# 加载数据
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
实现一个具有单隐藏层的多层感知机,它包含256个隐藏单元
num_inputs, num_outputs, num_hiddens = 784, 10, 256
# 这里的作用初始化一个隐藏层随机的参数,行数为784,列数为256,256的意思就是有256个隐藏单元
W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens, requires_grad=True)) #Parameter函数的作用就是使得某些参数可以在学习过程中不断的优化以达到最好的值
# 这里是隐藏层的bias
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
# 这里是初始化输出层
W2 = nn.Parameter(torch.randn(num_hiddens, num_outputs, requires_grad=True))
# 这里是输出层的bias
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
# 这里是我们的所有的参数
params = [W1, b1, W2, b2]
实现ReLU激活函数
def relu(X):
a = torch.zeros_like(X) # 这里zeros_like函数的作用就是创建一个形状和X相同但是元素值都为0的矩阵
return torch.max(X, a)
实现我们的模型
def net(X):
X = X.reshape((-1, num_inputs))
H = relu(X @ W1 + b1) # @就相当于X.dot(W1)做矩阵乘法
return (H @ W2 + b2)
loss = nn.CrossEntropyLoss()
多层感知机的训练过程与softmax回归的训练过程完全相同
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-12-c05076c9830f> in <module>
1 num_epochs, lr = 10, 0.1
2 updater = torch.optim.SGD(params, lr=lr)
----> 3 d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
~/miniconda3/envs/d2l-zh/lib/python3.8/site-packages/d2l/torch.py in train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
333 animator.add(epoch + 1, train_metrics + (test_acc,))
334 train_loss, train_acc = train_metrics
--> 335 assert train_loss < 0.5, train_loss
336 assert train_acc <= 1 and train_acc > 0.7, train_acc
337 assert test_acc <= 1 and test_acc > 0.7, test_acc
AssertionError: 0.5474652306556702
多层感知机的简洁实现
通过高级API更简洁的实现多层感知机
import torch
from torch import nn
from d2l import torch as d2l
# 这里的nn.Flatten()展平层,就是将输入转成一个二维的东西。nn.Linear()线形层输入是784,输出是256。
# nn.ReLU()表示激活函数是ReLU,nn.Linear()表示输入是256输出是10
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 256), nn.ReLU(), nn.Linear(256, 10)) # Sequential的作用就是拿到一个network
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights)
Sequential(
(0): Flatten(start_dim=1, end_dim=-1)
(1): Linear(in_features=784, out_features=256, bias=True)
(2): ReLU()
(3): Linear(in_features=256, out_features=10, bias=True)
)
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr=lr)
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)