本文主要参考kaggle上的两篇文章:
Deep Learning Tutorial for Beginners
Pytorch Tutorial for Deep Learning Lovers
不是全文翻译,算是我的学习笔记吧。
先看Deep Learning Tutorial for Beginners。
深度学习,是一种直接从数据中学习特征的机器学习技术。(Deep learning: One of the machine learning technique that learns features directly from data.)随着数据规模上升(如超过1百万个数据),传统机器学习技术不太适合,深度学习在准确率方面有更好的表现。深度学习应用在语音识别,图像分类,自然语言处理(nlp)或者推荐系统等方面。机器学习包括深度学习,在机器学习中,特征是人工标注的,而深度学习中特征是直接从数据中学习出来的。
实验数据是2062个手语数字图像,从0到9,一共10个不同的符号。0的序号从204到408,有205个。1的序号从822到1027,有206个。先只考虑0和1两个数字,因此每个分类有205个样本。尽管205个样本对深度学习来说太少了,但这是教程,就不管了。
先加载数据(从教程页面上下载,放到源代码目录。)
1 | import numpy as np |
把数据连接起来,并创建标签。
1 | # 把数据连接起来,并创建标签 |
X的大小是(410, 64, 64),即410个图片,每个图片的大小是64×64
Y的大小是(410, 1),即有410个标签。
现在将数据划分为训练集和测试集,其中训练集占85%。
1 | # 划分训练集和测试集 |
将三维数据变换到二维(flatten)
1 | #将三维数据变换到二维 |
1 | X_train_flatten (348, 4096) |
将数据倒置
1 | x_train = X_train_flatten.T |
1 | (4096, 348) |
数据准备好了,下面开始干活。
一想到二分类问题我们首先想到的是逻辑回归。实际上逻辑回归是一个非常简单的神经网络。神经网络和深度学习是一回事。
计算图(computation graph)的概念
数学表达式的可视化。这个我这只能看到图片的一部分,折腾半天没弄下来,大家到网站上看吧。
逻辑回归同样有计算图。参数是权重(weight)和偏差值(bias)。权重是每个点的系数,偏差值是截距。
z = (w.t)x+b
另一个说法:z = b+px1w1+px2w2+…+px4096*w4096
yhead = sigmoid(z)
sigmoid使得z在[0,1]区间内。即一个概率值。
sigmoid函数的计算图
为什么我们使用sigmoid函数?它返回一个概率性的结果,它是可微的,因此我们可以使用梯度下降算法。
下面我们初始化参数。
输入的数据是有4096个点的图像,每个点都有其自己的权重值。第一步是将每个点乘以其自己的权重值。初始权重值的设置有不同的方法,这里设置为0.01。偏差值为0。
下面是代码。
1 | # 初始化参数 |
下面看前向传播过程:从输入点数据到成本的所有步骤称为前向传播(Forward Propagation)。
z = (w.T)x + b,w和b都知道了(.T是转置),可以算出z。将z输入sigmoid函数得到返回的概率值yhat。然后计算损失/误差函数(loss/error)。所有损失值之和就是成本。
下面撸代码:
先定义sigmoid函数。
1 | # 定义sigmoid函数 |
然后计算损失函数,使得当模型预测正确时损失值很小,而当预测错误时损失值很大。
下面实现前向传播过程。
1 |
|
采用梯度下降的优化算法
我们需要降低成本。首先初始化权重和偏置值,这决定了初始成本。然后要更新权重和偏置值。这项技术称为梯度下降。
更新的方法,用老的参数值减去在该点的梯度,将该值作为参数的新的值。计算梯度的方法,是求损失函数在该点对该参数的偏导数。梯度同时确定了迭代的大小和方向。在迭代的时候,梯度要乘以一个学习率α。w’ = w - α∂L/∂w 学习率是需要权衡的,太小,学习得太慢,但不容易错过最低值。太大,学习得快,但容易错过最低值。学习率也被称为超参数(hyperparameter),是需要选择和调参的。因此前向过程就是从参数到成本,反向过程就是从成本到参数,更新参数。怎么计算梯度及更新参数,就是数学内容了。直接上结果吧。
1 | # 前后向传播过程 |
下面更新参数。
1 | # 更新参数 |
下面进行预测。
1 | # 进行预测 |
最后用测试数据进行预测。
1 | # 进行预测 |
准确率分别为100%和96.8%。
人工神经网络(Artificial Neural Network, ANN)
又称深度神经网络(deep neural network)或深度学习(deep learning)。最基础的人工神经网络为将逻辑回归进行至少两次。在逻辑回归中,只有输入层和输出层,而在神经网络中,有至少一个隐藏层在输入层和输出层之间。“深度(deep)”是隐藏层的层数很多,有多少是一个相对的概念,随着硬件的发展不断增加。“隐藏”的意思是它们不能直接看到输入的训练数据。
如下图,有一个隐藏层,这样的神经网络有2层,在计算层数的时候输入层被忽略。
隐藏层有3个节点,数量的选择是随意的,没有理由。节点的数量就像学习率一样,是一个超参数。输入和输出层的情况和逻辑回归中一样。其中用到了tanh函数,用作激活函数,比sigmoid产生的输出更加集中。它还能增加非线性,使得模型学习得更好。隐藏层是输入层的输出,是输出层的输入。
下面就来具体研究2层神经网络。
层数和参数的初始化。
将权重初始化为0.01,偏差为0。
1 | # 初始化参数和层数 |
前向传播过程与逻辑回归基本一样,唯一的不同采用tanh函数,进行两次。
1 | # 神经网络前向传播过程 |
损失函数跟逻辑回归一样,用交叉熵函数。
1 | # 神经网络的损失函数 |
后向传播过程,即意味着求导。要了解数学内容,去看其它材料吧。逻辑跟逻辑回归是一样的。
1 | # 神经网络后向传播过程 |
更新参数,跟逻辑回归里一样的。
1 | # 更新神经网络参数 |
进行预测
1 | # 进行预测 |
最后,建立神经网络
1 | # 建立两层神经网络 |
最后,看结果。
1 | parameters = NN(x_train, y_train, x_test, y_test, num_iterations = 2500) |
训练集预测准确率100.000000
测试集预测准确率95.161290
不比逻辑回归好啊?
L层神经网络(L layer neural network)
当隐藏层数量增加是,它能探测到更复杂的特征。
有许多超参数需要我们选择,如学习率,隐藏层层数,迭代次数,激活函数类型等。
用keras实现L层神经网络,老调不对,先摆着,看第二篇文章,讲pytorch的。
https://www.kaggle.com/kanncaa1/pytorch-tutorial-for-deep-learning-lovers
pytorch是numpy的替代品,可以充分利用GPU的运算能力,是一个深度学习研究平台,提供了最大程度的扩展性和速度。
Pytorch基础
在pytorch中,矩阵(数组)被称为张量(tensors)。
先看numpy数组的例子
1 | # numpy数组 |
1 | <class 'numpy.ndarray'> |
下面看张量
1 | import torch |
1 | <built-in method type of Tensor object at 0x7f555a14b690> |
张量与numpy数组的转换
1 | # 张量与数组的转换 |
1 | <class 'numpy.ndarray'> [[0.22831416 0.2857514 ] |
pytorch基础数学
1 | # 基础数学 |
1 | tensor([[1., 1., 1.], |
变量(Variables)
它能积累梯度。在神经网络的反向传播过程中,我们将计算梯度。因此我们需要处理梯度。变量与张量的区别是变量能够自动累积梯度。变量同样的也能进行那些数学运算。为了完成反向传播我们需要变量。
假设我们有方程y = x^2,定义变量x = [2,4],计算后我们发现y = [4,16],Recap o方程(Recap o equation,不知道咋翻)是o = (1/2)sum(y) = (1/2)sum(x^2),o的导数为o = x,因此梯度为[2,4]。下面用程序来实现。
1 | from torch.autograd import Variable |
1 | tensor([1., 1., 1.], requires_grad=True) |
线性回归
y = Ax + B,A为直线斜率,B为偏差值(y截距)。
一个例子:车的价格和销量。
先初始化数据,画图看看。
1 | # 线性回归的例子 |
现在要问当车价为100时的销量。用线性回归来解决。要用直线来拟合这些数据,目标是误差最小。
线性回归的步骤:
①创建线性回归类。
②从线性回归类定义模型。
③计算MSE:平均误差平方(Mean Squared Error)
④优化SGD:随机梯度下降(Stochastic Gradient Descent)
⑤反向传播过程。
⑥预测。
下面用Pytorch实现。
1 | class LinearRegression(nn.Module): |
进行了1001次迭代。在1000次迭代后,损失接近为0。现在进行预测。
1 | # 进行预测 |
逻辑回归
对于分类问题,线性回归表现并不好。
线性回归+逻辑方程(softmax)=逻辑回归。
步骤:
①导入库。
②准备数据,采用MNIST,是一些标记为0-9十个数字的28×28的图片,把其转换为一维的256个数据,划分为训练集和测试集,创建tensor变量。batch_size的意思:例如我们有1000个样本,可以把1000个样本拿到一起训练,也可以把样本划分为10组,每组100个样本,依次进行10次训练。batch_size是每组的样本量,在这个例子中,等于100。确定迭代次数(epoch),即把所有样本训练一次。在本例中,有33600个样本,训练一次要训练33600个样本,分成了336组,进行29次迭代,一共的迭代次数是9744次(接近10000次)。使用TensorDataset()封装数据。DataLoader()将数据和样本结合到一起,也提供了对数据的并行迭代功能。将数据可视化。
③创建逻辑回归模型。
④实例化模型。
输入维度2828, 输出维度10。
⑤计算损失,采用交叉熵(Cross entropy loss)。
⑥定义优化器,采用SGD优化器。
⑦训练模型。
⑧预测。
程序调不对,用另一个
1 | # 逻辑回归的例子 |
模型准确率92%。
人工神经网络(Artificial Neural Network, ANN)
逻辑回归处理分类问题很好,但当复杂性(非线性)增加时,模型准确性下降。为了增加模型的复杂性,需要增加更多的非线性函数的隐藏层。
具体步骤:
①导入库。
②准备数据。
③创建ANN模型:增加三个隐藏层,用ReLU, Tanh和ELU做为激活函数。
④实例化模型。隐藏层维度150,随便选的。这也是超参数之一。
⑤选择损失函数,跟逻辑回归一样。
⑥优化器也一样。
⑦训练模型。
⑧预测。
1 | # 人工神经网络 |
结果,正确率97.8%,花了大概一小时。
还有卷积神经网络,图像处理用得比较多,先pass了。
总结一下,机器学习也好,深度学习也好,其实质都是拟合数据,拟合的方法(模型)不一样而已。用已知数据训练模型(求出一组参数),然后用模型对未知数据做出预测。深度学习的模型是神经网络,由神经节组成。每个神经节接受若干输入,经过激活函数(通常为非线性函数,以拟合非线性关系),产生一个输出。若干个神经节形成一层,前一层的输出作为下一层的输入,一直向前传递直到输出层。用输出结果与真实值对比(用损失函数)计算出损失值(前向传播)。接着,用梯度下降的方法沿着路径反向计算使损失值最小的参数,并更新参数(反向传播)。上述步骤重复若干次,损失值和预测准确率收敛到一定程度,即停止训练,运用模型进行预测。
整个过程,pytorch等框架为我们做了什么呢?数据准备(tensor,便于GPU运算; Variable,自动进行梯度运算并保存结果;dataLoader,便于分组训练)、定义模型(nn.Module,定义神经网络结构,定义前向传播过程,计算出输出值)、进行训练(Optimizer,梯度清零,更新参数;model,前向传播过程,计算输出值;提供损失函数:计算损失值,反向传播过程:backward)。其中核心是自动求导的过程。tensorflow我没了解过,应该也差不多。
这几天听了一个自己实现深度网络框架的课,正在整理笔记,下次奉上。
本文代码
我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地