目录
- 感知机
- 训练感知机
- 感知机模型
- 感知机学习算法
- 收敛定理
- XOR问题
- 总结
- 多层感知机
- 学习XOR
- 隐藏层
- 单隐藏层---单分类
- 激活函数
- Sigmoid激活函数
- Tanh 激活函数
- ReLU 激活函数
- 多类分类---单隐藏层
- 多类分类---多隐藏层
- 总结
- 多层感知机从零开始
- 多层感知机的简洁实现
- 总结
感知机
给定输入x,权重w,和偏移b,感知机输出:
x:是一个向量
w:向量
b:是一个标量
其中公式中的1和0随便这是,其实一个二分类。例如:改为1和-1
训练感知机
1、首先设置w为0个b为0
2、对一个样本i从0开始一直到最后,假设当前是第i个样本,那么原来的标号
y
i
y_i
yi (此时设置的是1和-1两个标号)乘以(w和
x
i
x_i
xi做内积加上b)
相当于
y
i
y_i
yi是标签值,<w,
x
i
x_i
xi>+b是预测值 即:σ(x)。
if相乘≤0那么说明预测错了,则对w进行一次更新和b的更新。
3、等价于使用批量大小为1的梯度下降,并使用如下的损失函数。
max(0)代表的是if后面的语句,
如果分类正确的话,那么-y<w,x>是小于0的,那么max输出为0,那么梯度就是一个常数,就不会进行更新,则对应着if
y
i
y_i
yi[<w,
x
i
x_i
xi>+b]≤0不成立。
如果分类错误的话,那么这个时候就有梯度了,则进入到if
y
i
y_i
yi[<w,
x
i
x_i
xi>+b]≤0语句里进行更新。
所以说是为什么加入max函数了。
举个例子:1、(分为狗和猫)
2、假设来了一只新的狗,发现对狗分类分错了,然后对样本进行一次更新,然后发现线往下移动了一点
3、又来了一只新的狗然后线又往下移动了一点,然后来了一只猫,线又往上移动了一点点
一直做,做到最后发现所有的样本看完,所有的分类没问题就可以停止了。停止的条件:对所有的分类正确。
4、再来一只狗,发现往下移动一点点。
感知机模型
sign是符号函数:
w,b为感知机模型参数,w叫做权值或权值向量,b叫做偏置,w·x表示w和x的内积。感知机对应的超平面w·x + b = 0 称为分离超平面;其几何解释如下:
对应于特征空间中的一个超平面S,其中w是超平面的法向量,b是超平面的截距。该超平面将特征空间划分为两个部分,即正、负两类,其效果如图:
两个图均可表示。通过超平面将两类点分开,黑色点和红色点是两类标签取值不同的点,
x
(
1
)
x^{(1)}
x(1),
x
(
2
)
x^{(2)}
x(2)是数据的特征。
点到直线的距离公式:
故公式为:
∴原点到超平面的距离为 b ∣ ∣ w ∣ ∣ {b\over ||w ||} ∣∣w∣∣b
故公式为:
∴某点到超平面的距离为:
对于误分类的数据来说:
或
那么当
当
所以,误分类点到超平面距离可以写为:
误分类点到超平面总距离可以写为:
不考虑||w||,就能够得到感知机学习的损失函数。
M为误分类点的集合,L(w,b)为感知机学习的经验风险函数。
显然,这个经验损失函数是非负的,当误分类点个数为0时,损失值也为0,且误分类点越少,误分类点总距离离超平面就越近。
感知机学习算法
感知机模型的求解是一个无约束优化问题,可以采用随机梯度下降法。梯度下降的基本思想是:负梯度方向是函数值下降最快的方向。
对获得的经验风险函数进行最优化处理,由于考虑到风险函数对w和b连续可导,所以求风险函数最小值可以采用梯度下降的方法。
若误分类的点集M 固定, L(w,b)的梯度由如下给出:
随机梯度下降法(SGD)的核心是随机选取一个误分类点(
x
i
x_i
xi,
y
i
y_i
yi),对参数w,b进行更新:
其中η(0<η≤1)是步长 (或学习率)。通过迭代,使L(w ,b)不断减小,直至为0。
总结:此算法就是不断减少误分类集合中的点,并一 一将其归类于正确分类中,直至全部正确分类。
收敛定理
收敛是指是什么时候停。
假设数据在半径r的区域内
假设一个余量ρ使得存在一个分截面 ∣ ∣ w ∣ ∣ 2 ||w||^2 ∣∣w∣∣2+ b 2 b^2 b2≤1。
使得这个分截面对所有的分类都是正确的,而且它是有一定余量的。即:
公式左边等价于
感知机确信找到最优解,而且保证在之后收敛。即停止。
r是数据的大小,当r很大的时候,收敛会很慢,ρ看数据是不是很好,很好的话两个点分的特别开,收敛就会很快。
XOR问题
感知机不能拟合XOR函数,它只能生产线性分割面。
也可用这个图表示
XOR就类似异或,输入相同则输出-1,输入不同则输出为+1。
总结
①感知机是一个二分类模型,是最早的AI模型之一。
②它的求解算法等价于使用批量大小为1的梯度下降。
③它不能拟合XOR函数,导致的第一次AI寒冬
多层感知机
学习XOR
① 先用蓝色的线分,再用黄色的线分。
② 再对蓝色的线和黄色的线分出来的结果做乘法。
首先学习蓝色的线,使1点和3点为正,2点和4点为负。
然后再学习黄色的线,使1点和2点为正,3点和4点为负。
有了蓝色的分类器和黄色的分类器结果的话,再看两个结果是否一样,一样则为正,反之为负。
然后就可以做一个分类了。
首先先进入蓝色的分类器。
然后在进入黄色的分类器。
最后它的结果进入灰色分类器,就可以得到正确的结果。
最上面用坐标轴的简单,用相同为负,相异为正,更容易理解。
隐藏层
首先,输入有
x
1
x_1
x1,
x
2
x_2
x2,
x
3
x_3
x3,
x
4
x_4
x4。
然后,加入了一个隐藏层,有
h
1
h_1
h1,
h
2
h_2
h2,
h
3
h_3
h3,
h
4
h_4
h4,
h
5
h_5
h5,所有的
x
1
x_1
x1,
x
2
x_2
x2,
x
3
x_3
x3,
x
4
x_4
x4先算
h
1
h_1
h1,然后依次算到
h
5
h_5
h5。然后在作为一个输入,放到下一个层。
输入的大小是不能更改的,因为数据维度有多大就有多大。
输出则看有多少类了,由数据决定。
唯一能干的事情,设置隐藏层有多大。
单隐藏层—单分类
x表示一个n维的向量,即n个输入特征。
输入为n,隐藏层大小为m,每个x到隐藏层的神经元都有一个w,所以
隐藏层的权重是的形状为:隐藏层的大小*n个输入特征的矩阵,
b
1
b_1
b1为有多少个隐藏层就有多少个偏移(是一个长为m的的向量)
隐藏层的输出为m * 1,因为
W
1
W_1
W1是m * n,x是n * 1,所以输出为m * 1
输出层:一个长为m的向量。
h是一个长为m的向量,经过激活函数得到,然后作为输入进入到输出层。输出层的权重转置乘以h做内积加上偏移,输出是一个标量。
为什么需要非线性激活函数?
假设:激活函数是本身的话,那就是σ(x)=x
h相当于你的输入了,如果把h带入到第二个式子可得:
化简可得:
可以化为这样,因为
w
2
⊺
w_2^⊺
w2⊺是一个向量,
b
1
b_1
b1也是一个向量,两者内积为一个标量,然后再加上
b
2
b_2
b2这个标量可得
b
′
b'
b′。其中
w
2
⊺
W
1
w_2^⊺W_1
w2⊺W1可以看作
W
′
W'
W′,那么公式就可以写为:
o=
W
′
W'
W′x+
b
′
b'
b′
发现仍然是线性函数,就是说σ(激活函数)不能是一个线性函数,如果是的话,就等价于一个单层的感知机。相当于没加激活函数。
激活函数
Sigmoid激活函数
Tanh 激活函数
ReLU 激活函数
多类分类—单隐藏层
做k类分类的话,输出k个元素,要得到置信度的话要把它放在softmax的操作子里面得到
y
1
y_1
y1,
y
2
y_2
y2,
y
3
y_3
y3,…,
y
k
y_k
yk。
softmax就是把所有的输入拉到0~1之间的区域,使得
y
1
y_1
y1+
y
2
y_2
y2+
y
3
y_3
y3+…+
y
k
y_k
yk=1。
所以说多类分类和softmax没有本质区别是说,唯一加的是隐藏层
如果没有加的话,就是最简单的softmax回归,加了隐藏层就会变为多层感知机。
x表示一个n维的向量,即n个输入特征。
输入为n,隐藏层大小为m,每个x到隐藏层的神经元都有一个w,所以
隐藏层的权重(
W
1
W_1
W1)形状为:隐藏层的大小* n个输入特征的矩阵,
b
1
b_1
b1为有多少个隐藏层就有多少个偏移(是一个长为m的的向量)
输出层的权重(
W
2
W_2
W2)形状为:输出层的大小 * 输出层的输入(隐藏层的输出),所以输出层的形状为m * k
其中h的形状为m * 1,
W
2
W_2
W2的形状是m * k,
b
2
b_2
b2的形状是k * 1,将
W
2
W_2
W2转置的形状是k * m ,又因为h的形状为m * 1,所以
W
2
⊺
W_2^⊺
W2⊺为k * 1的形状,所以会得到k * 1的向量o,
多类分类—多隐藏层
h
1
h_1
h1是第一个隐藏层的输出,第二个隐藏层的输入。然后依次类推最后到输出,而最后的输出不需要激活函数。因为激活函数主要是用来避免层数的塌陷。最后一层则不需要。
超参数:每个隐藏层的的大小。
配置每个层的大小,一般来说,第一个隐藏层设置的稍微大一点
eg:越大模型越复杂,根据输入的复杂度(感觉数据比较难的话)来选择.
一:使用单隐藏层:把隐藏层设的大一点,假设输入维度为128,那么隐藏层可以设置为64,128,256都可。
二:把模型做的深一点:使用三个隐藏层,且一般来说隐藏层从下往上 大小 依次减少。
为什么隐藏层从下往上 大小 依次减少?
假设数据比较复杂,通常来说,维度是比较高的,比如128,那么相对来说输出是比较少的,比如5类。就是把一个128维的输入压缩到5维的空间。最好先压缩到64,再到32,再到16,再到8,最后压缩到5.
总结
①多层感知机使用隐藏层和激活函数来得到非线性模型。
②常用激活函数是Sigmoid,Tanh,ReLU。
③使用Softmax来处理多类分类。
④超参数为隐藏层数,和各个隐藏层大小。
多层感知机从零开始
import torch
from torch import nn
from d2l import torch as d2l
def relu(X):
a = torch.zeros_like(X)
return torch.max(X, a)
def net(X):
X = X.reshape((-1, num_inputs))
# -1为自动获取,这里是batch_size,num_inputs=784
H = relu(X @ W1 + b1) # 这里“@”代表矩阵乘法
return (H @ W2 + b2)
d2l.use_svg_display()
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
num_inputs, num_outputs, num_hiddens = 784, 10, 256
# 1个隐藏层,包含256个隐藏单元,均为超参数
# nn.Parameter()不加也没关系
W1 = nn.Parameter(torch.randn(
num_inputs, num_hiddens, requires_grad=True) * 0.01)
"""* 0.01,可以将生成的随机张量缩小为原来的1/100倍,即进行了一个缩放操作,
这样可以使得随机初始化的参数具有较小的初始值,并且更接近于0。
有助于提高训练的稳定性和效果。"""
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(
num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
# 权重W必须设置为随机,如果初始化为0或1,则隐藏层接收到的输入H相同,并产生相同的输出
# 并且权重的梯度为0,导致反向传播过程权重没有更新,不能进行有效学习
params = [W1, b1, W2, b2]
loss = nn.CrossEntropyLoss(reduction='none')
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)
d2l.predict_ch3(net, test_iter)
d2l.plt.tight_layout() # 调整子图参数,使之填充整个图像区域
d2l.plt.show()#在PyCharm等IDE中可能需要显式调用show()来显示图形
多层感知机的简洁实现
import torch
from torch import nn
from d2l import torch as d2l
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01)
net = nn.Sequential(nn.Flatten(),
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10))
net.apply(init_weights)
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss(reduction='none')
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)
d2l.plt.show()
总结
①x>0,输出为什么是1,通过设计w和b吗?还是通过训练?
这里的x并不是前面的输入特征x,而是x=<w,x>+b
②神经网络中的一层网络是指什么?是一层神经元经过线性变换后称为一层网络,还是一层神经元经过线性变化加非线性变换后称为一层?
通常的一层是指带权重的一层,所以这里有两层。
(输入层不算层)
③感知机只能产生XOR函数,所以当时人们才会使用SVM(向量机)吗?
SVM替代了感知机,多层感知机解决了感知机的XOR问题,之后没有流行的原因是得选择超参数(多少个隐藏层,隐藏层多大)而且收敛也不好收敛,SVM对超参数不敏感。SVM优化相对容易,不需要SGD。
④为什么神经网络要增加隐藏层的层数,而不是神经元的个数?不是有神经网络万有近似性质吗?
第一个模型:设置一个隐藏层且隐藏单元很大。
第二个模型:比输入稍微大一点,然后使用多个隐藏层依次减少。
两个模型的复杂度基本上是等价的。
第一个模型不好训练,第一个模型叫浅度学习,第二个模型叫深度学习。
⑤不同任务下的激活函数是不是不一样?也是通过实验来确认吗?
其实都差不多