深度学习和神经网络的一些概念和符号
target、label、标注都是一个意思
error和loss是一个意思
神经网络的多个输出
看你是做什么任务。
- 二分类最后保留一个输出就可以了。
- 多分类要保留多个输出,结果对应每个类别的概率
举个例子,如果是一个十类的分类问题,而你的输出层是1个神经元,那你如何实现分类呢?
感知机(perceptron)
单层感知机模型
b就是bias
就是来了x,多个输入,然后有w,多个权值,w和x相乘再累加,然后通过激活函数
w是权值
符号含义
首先会对神经网络每一层进行编号,输入层是第0层
上标0是表示它是属于输入层的,下标表示它是这一层的第几个点
上标l是层的编号,i表示上一层的节点编号,j表示这一层的节点编号
是第一层的第1个点,因为是单层感知机,所以第一层就1个点
得到激活函数的输出值是O,就是O是x经过了激活函数之后的值,但是O的层数和x是一致的
E是error,也是loss,是和它的t(target,也就是label)目标值做一个MSE
我们对感知机求的梯度是损失函数E对网络权重w的梯度
优化也是优化它,通过优化它来调整权重W
单层感知机的pytorch实现
import torch from torch.nn import functional as F x = torch.randn(1,10) w = torch.randn(1,10,requires_grad = True) print('x: ',x) print('w: ',w) #w.t()是w的转置 o = torch.sigmoid(x@w.t()) print(o.shape) loss = F.mse_loss(torch.ones(1,1),o) print(loss.shape) loss.backward() w.grad
requires_grad: 设置为True则表示该Tensor需要求导,表示这个地方是需要梯度信息的
指定参数reuqires_grad=True来建立一个反向传播图,从而能够计算梯度
最终我们得到的是一个比较合适的权重w的值
使得x*w的值越来越趋近于它的y的值
多输出感知机
多输出其实已经不能叫感知机了,因为感知机的定义就是单输出的。这里我们还是叫做多输出感知机
import torch from torch.nn import functional as F x = torch.randn(1,10) w = torch.randn(2,10,requires_grad = True) print('x: ',x) print('w: ',w) o = torch.sigmoid(x@w.t()) print('o.shape: ',o.shape) loss = F.mse_loss(torch.ones(1,2),o) print('loss: ',loss) loss.backward() w.grad
链式法则
神经网络的最最重要的公式
通过链式法则,我们就可以把最后一层的误差,一层一层地输出到中间层的权值上面去,从而得到中间层的梯度信息。通过这个梯度信息我们就能很好地更新权指,从而达到一个最优化的效果
通过链式法则
用pytorch写代码验证一下链式法则
import torch from torch.nn import functional as F x = torch.tensor(1.) w1 = torch.tensor(2.,requires_grad=True) b1 = torch.tensor(1.) w2 = torch.tensor(2.,requires_grad=True) b2 = torch.tensor(1.) y1 = x*w1+b1 y2 = y1*w2+b2 dy2_dy1 = torch.autograd.grad(y2,[y1],retain_graph=True)[0] dy1_dw1 = torch.autograd.grad(y1,[w1],retain_graph=True)[0] dy2_dw1 = torch.autograd.grad(y2,[w1],retain_graph=True)[0] print(dy2_dy1 * dy1_dw1) print(dy2_dw1)
autograd自动求微分