Part1:线性回归
线性回归就是通过一个线性函数来拟合数据集中输入与输出之间的关系。线性函数可以表示为:$$y = XW + b$$通过给定一些训练数据(training set,包含数据的输入\(X\)与其对应的输出\(y\))对线性回归模型进行训练,我们可以得到一个能够有效拟合真实数据集的线性函数模型参数\(W\)和\(b\),该函数可以对新的输入数据预测其对应的输出。下面对线性回归的主要步骤进行一个简单总结。
1.准备数据
我们可以通过线性函数生成一个可以用于线性回归的数据集,例如通过python生成一个大小为1000的数据集。
1 2 3 4 5 6 7 8 9 |
num_examples=1000 #num of examples num_inputs=2 #num of inputs ##linear model true_w = torch.tensor([2,-3.4]) true_b = torch.tensor(4.2) ###data features = torch.randn(num_examples,num_inputs,dtype=torch.float32) labels = true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_b labels += torch.tensor(np.random.normal(0,0.01,size=labels.size()),dtype=torch.float32) |
2.定义损失函数
模型训练需要通过损失函数进行参数更新,我们可以采用一些函数来衡量模型预测的输出与真实输出之间的差距,例如平方损失函数:$$l^{(i)}(W,b) = \frac{1}{2}(\hat{y}^{(i)}-y^{(i)})^2$$那么我们可以定义整个数据集的损失函数为:$$L(W,b) = \frac{1}{n}\sum_{i=1}^{n}{l^{(i)}(W,b)}$$
3.随机梯度下降
随机梯度下降在深度学习中应用广泛,一般都采用小批量随机梯度下降,简单总结来说就是选取数据集固定数目的训练数据作为一个batch \(\mathcal{B}\),然后计算该batch的损失函数,反向传播求梯度,最后通过各个参数的梯度沿梯度反方向对参数进行迭代更新:$$(W,b)=(W,b)-\frac{\eta}{|\mathcal{B}|}\sum _ {i \in \mathcal{B}} {\partial _ {(W,b)}l^{(i)}(W,b)}$$
4.模型测试
我们通过梯度下降训练好的模型可以用来对新的数据进行预测来测试其预测效果。
5.代码实现
1.从零开始实现
soon~
2.基于pytorch的实现
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import torch import numpy as np from matplotlib import pyplot as plt import torch.utils.data as Data from torch.nn import init from torch import nn import torch.optim as optim class LinearNet(nn.Module): def __init__(self,n_feature): super(LinearNet,self).__init__() self.linear=nn.Linear(n_feature,1) def forward(self, x): return self.linear(x) torch.set_default_tensor_type("torch.FloatTensor") num_examples=1000 num_inputs=2 true_w = torch.tensor([2,-3.4]) true_b = torch.tensor(4.2) ###data features=torch.randn(num_examples,num_inputs,dtype=torch.float32) labels = true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_b labels +=torch.tensor(np.random.normal(0,0.01,size=labels.size()),dtype=torch.float32) batch_size=10 dataset=Data.TensorDataset(features,labels) data_iter=Data.DataLoader(dataset=dataset,batch_size=batch_size,shuffle=True,num_workers=0) net =LinearNet(num_inputs) print(net) for layer in net.children(): init.normal_(layer.weight,mean=0.0,std=0.01) init.constant_(layer.bias,val=0.0) optimizer=optim.SGD(net.parameters(),lr=0.03) print(optimizer) loss =nn.MSELoss() num_epochs=3 for epoch in range(1,num_epochs+1): for X,y in data_iter: output =net(X) l=loss(output,y.view(-1,1)) optimizer.zero_grad() l.backward() optimizer.step() print("epoch %d, loss: %f" %(epoch,l.item())) |
Part2:Softmax与分类模型
1.分类模型
分类问题就是模型通过对输入特征数据的处理,输出一个该特征对应的标签。我们可以用类似于上述线性回归的模型来对分类问题进行解决,假设输入特征为\(X\),其对应标签为\(y\),我们定义模型:$$O =XW+b $$其中\(O\)表示输入为分类标签的置信度,其是一个序列,表示分别为某个类型的置信度,例如总共有3类,置信度分别为1、10、20,因为第3类置信度最大所以分为第3类。
2.Softmax函数
因为上述置信度作为分类函数的输出,其值范围不确定,与真实标签直接不好定义衡量的误差,所以往往需要用到Softmax对输出进行处理。Softmax可以将输出变化为0~1的值且所以输出总和为1,这就可以看做是该输入模型预判其属于各个标签的概率。具体地,Softmax函数可以定义为:$$Y = softmax(O)$$其中$$y_i = \frac{e^{o_i}}{\sum_{i=1}^{n}{e^{o_i}}}$$这样\(y_i\)就可以表示被分为\(i\)类的概率了,模型预测的类别就是概率最大的类别。
3.交叉熵损失函数
我们需要构造损失函数来衡量分类模型的预测与真实数据间的误差。对于样本i,我们可以构造类似于模型输出的概率向量,其中样本i所属类别的值为1,其余为0,这样我们可以用平方损失进行误差计算:$$Loss = \frac12|\hat y^{(i)}-y^{(i)}|^2$$然而很明显平方损失函数不能很好的衡量预测的结果,因为只要预测的最大概率所属标签不变的情况下,无论概率值为多少都不会影响损失函数的大小。所以我们可以用交叉熵损失函数来衡量误差,交叉熵一般定义为如下:$$H(y^{(i)},\hat y^{(i)})=-\sum_{j=1}^{q}y_j^{(i)}log \hat y_j^{(i)} = -log\hat y_{y_{(i)}}^{(i)}$$所以交叉熵损失函数可以定义为:$$l(\theta) = \frac1n\sum_{i=1}^{n}H(y^{(i)},\hat y^{(i)})=-\frac1n\sum_{i=1}^{n}log\hat y_{y_{(i)}}^{(i)}$$所以最小化该交叉熵损失函数可以等价于最小化所以标签类别的联合预测概率
4、代码实现
soon~
Part3:多层感知机
1.多层感知机概述
多层感知机是一个由输入层、多层隐藏层、输出层构成的神经网络
因为多层感知机的每一层都是一个线性函数映射,所以在不添加激活函数的情况下,多层感知机相当于一个单层的线性函数。
2.激活函数
激活函数是一个非线性变换,将上一层的输出作为输入,通过非线性映射得到输出作用于下一层输入,从而达到多层线性函数的串联的效果。
- ReLU函数$$ReLU(x) = max(x,0)$$
- Sigmoid函数$$sigmoid(x)=\frac1{1+exp(-x)}$$
- tanh函数$$tanh(x)=\frac{1-exp(-2x)}{1+exp(-2x)}$$
3.代码实现
soon~
latex公式显示不出来
现在已经修复了~