#本文章用于本人学习李哥考研深度学习。#
学习注意事项
1、代码和课程学习共同理解,相互结合
2、深层次的原理是最重要的,代码不是最重要的,要理解选择这个东西的方法、原理、原因。
3、深度学习一直在变化
零——机器学习与深度学习介绍。深度学习基本知识
人工智能:能够感知、推理、行动和适应的程序。
机器学习:能够随着数据量的不断增加不断改进性能的算法。
深度学习:机器学习的一个子集;利用多层神经网络从大量数据中进行学习。
零-1、机器学习算法简介
- 一般是基于数学,或者统计学的方法,具有很强的可解释性。
- 这里简述几个经典的传统机器学习算法。
- KNN, 决策树,朴素贝叶斯
零-1-①、KNN:k最近邻居(K-Nearesst Neighbors,简称KNN)
一种监督(#监督:是指你的数据有没有标签)学习算法,用于分类和回归问题。它的基本思想是通过测量不同数据点
之间的距离来进行预测。KNN的工作原理可以概括为以下几个步骤:
- 距离度量: KNN使用距离度量(通常是欧氏距离)来衡量数据点之间的相似性。
- 确定邻居数量K
- 投票机制
零-1-②、决策树
决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。在机器学习中,决策树是一个预测模型,他代表的是对象属性与对象值之间的一种映射关系。Entropy = 系统的凌乱程度,使用算法ID3, C4.5和C5.0生成树算法使用熵。这一度量是基于信息学理论中熵的概念。
决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。
分类树(决策树)是一种十分常用的分类方法。它是一种监督学习,所谓监督学习就是给定一堆样本,每个样本都有一组属性和一个类别,这些类别是事先确定的,那么通过学习得到一个分类器,这个分类器能够对新出现的对象给出正确的分类。这样的机器学习就被称之为监督学习。
思考1:因为认识的人更重要
思考2:没有决策的作用,所以引入基尼系数(观察贫富差距)。
决策树不善于处理未见过的特征。
零-1-③、朴素贝叶斯
朴素贝叶斯法(Naive Bayes model)是基于贝叶斯定理与特征条件独立假设的分类方法 [1]。
最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBM)。和决策树模型相比,朴素贝叶斯分类器(Naive Bayes Classifier 或 NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。理论上,NBC模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为NBC模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,这给NBC模型的正确分类带来了一定影响。
优点
朴素贝叶斯算法假设了数据集属性之间是相互独立的,因此算法的逻辑性十分简单,并且算法较为稳定,当数据呈现不同的特点时,朴素贝叶斯的分类性能不会有太大的差异。换句话说就是朴素贝叶斯算法的健壮性比较好,对于不同类型的数据集不会呈现出太大的差异性。当数据集属性之间的关系相对比较独立时,朴素贝叶斯分类算法会有较好的效果。
缺点
属性独立性的条件同时也是朴素贝叶斯分类器的不足之处。数据集属性的独立性在很多情况下是很难满足的,因为数据集的属性之间往往都存在着相互关联,如果在分类过程中出现这种问题,会导致分类的效果大大降低。
应用:
一、文本分类
分类是数据分析和机器学习领域的一个基本问题。文本分类已广泛应用于网络信息过滤、信息检索和信息推荐等多个方面。数据驱动分类器学习一直是近年来的热点,方法很多,比如神经网络、决策树、支持向量机、朴素贝叶斯等。相对于其他精心设计的更复杂的分类算法,朴素贝叶斯分类算法是学习效率和分类效果较好的分类器之一。直观的文本分类算法,也是最简单的贝叶斯分类器,具有很好的可解释性,朴素贝叶斯算法特点是假设所有特征的出现相互独立互不影响,每一特征同等重要。但事实上这个假设在现实世界中并不成立:首先,相邻的两个词之间的必然联系,不能独立;其次,对一篇文章来说,其中的某一些代表词就确定它的主题,不需要通读整篇文章、查看所有词。所以需要采用合适的方法进行特征选择,这样朴素贝叶斯分类器才能达到更高的分类效率。
二、其他
朴素贝叶斯算法在文字识别, 图像识别方向有着较为重要的作用。 可以将未知的一种文字或图像,根据其已有的分类规则来进行分类,最终达到分类的目的。
现实生活中朴素贝叶斯算法应用广泛,如文本分类,垃圾邮件的分类,信用评估,钓鱼网站检测等等。
零-2、深度学习
设计一个很深的网络让机器自己学习。
深度学习就是找一个函数f
零-3、初识神经网络任务
认识很多输入和输出,然后得到你的结果。
常见的神经网络的输入,一般有三种数据形式:
- 向量
- 矩阵/张量
- 序列
输出形式:
- 回归任务(填空题):根据以前的推测以后的
- 分类任务(选择题):1、图片:猫/狗 2、句子:积极/消极
- 生成任务(结构化、简答题):
深度学习需要数据,为什么?
因为要从数据中找到函数
如何从数据中找到函数?
一些英文对应名词(需要掌握)
loss:损失函数,就是这些未知参数的函数,判断我们选择的这组参数怎么样。
Linaer model:线性模型
weight:权重 bias:偏差
feature:数据
label:标签
optimization:优化
用于规定移动的参数
一、多层神经网络
圆圈y:表示神经元
一个这个组合:表示一个线性关系和神经元
多层:通过加深层数使得函数更加完整
这样带来的问题是,输入和输出都是线性组合,对结果的影响不大。
所以引入了激活函数,给神经元引入了非线性元素,使得神经网络逼近任何非线性函数,这样使得神经网络应用到更多非线性模型。
偏置,权重都是要学习的
就有了三种表达形式:
- 神经元
- 输入输出和函数
- 矩阵、公式
一-1、深度学习的训练过程
前向过程:输入到输出的过程
梯度下降算法进行更新的
一些名词
Fully Connected Network(FC Network):全连接网络
Neural Network:神经网络 == Deep Learning:深度学习
多层感知机:超过两层的全连接网络
一-2、过拟合和欠拟合
过拟合(overfitting)和欠拟合(underfitting)
过拟合:骄傲了
欠拟合:谦虚了
二、深度学习代码解析
import torch
import matplotlib.pyplot as plt #用来画图的
import random # 生成随机数
先载入资源包,torch包包括了对于多维张量的数据结构和对其进行数学计算。
def create_data(w, b, data_num):
x = torch.normal(0, 1, (data_num, len(w)))
#0为方差,1为均值,data_num表示多少个向量,len(w)表示多少个输入
y = torch.matmul(x, w) + b #y= wx + b
noise = torch.normal(0, 0.01, y.shape) #噪声0到0.01 ,加到y身上,与y同型
y += noise
return x, y
定义函数:create_data(w,b,data_num)用来创建数据。 y = wx + b 中的w, b都被函数引入,data_num表示矩阵中的行数,len(w)表示列数。
pytorch中两个张量的乘法可以分为两种:
- 两个张量对应元素相乘,在PyTorch中可以通过torch.mul函数(或*运算符)实现;
- 两个张量矩阵相乘,在PyTorch中可以通过torch.matmul函数实现;
torch.normal用于生成服从正态分布的随机数。
noise引入噪声,注意这里使用+=而不是 = +,因为前者不会创建一个新的数据。
num = 500
true_w =torch.tensor([0.1, 2, 2, 4]) #转为张量
true_b =torch.tensor(1.1)
X, Y = create_data(true_w, true_b, num) #x是500*4 , y是500*1
创建张量w与b,规定数量为500个。
X是500*4的矩阵, Y是500*1的矩阵(Y有噪声)。
def data_provider(data, label, batchsize): #每次访问,就提供一笔数据。
length = len(label) #label表示x,batchsize表示步长
indices = list(range(length)) #下标变成列表
random.shuffle(indices) #打乱
for each in range(0, length, batchsize): #按顺序去取
get_indices = indices[each: each+batchsize]
get_data = data[get_indices]#要取的下标
get_label = label[get_indices]
yield get_data, get_label #有存档点的return,不看前三句了从for继续
定义一个提供数据的函数:每次访问该函数就提供数据。
label表示x的数据个数,batchsize表示步长,
indices 代表把数据的下标变成列表便于访问,
random.shuffle将(indices下标)打乱。
get_indices = indices[each: each+batchsize] 取到当前each到each步长的下标。
get_data = data[get_indices] 要取的下标,get_indices已经是下标所以取data中的下标即可。
get_label = label[get_indices] 取label的下标。
batchsize = 16
for batch_x,batch_y in data_provider(X, Y, batchsize):
print(batch_x, batch_y)
break
定义步长为16,batch_x 与 batch_y 用来表示所创建的数据。循环利用data_provider创建数据
此时X是500*4的矩阵, Y是500*1的矩阵(Y有噪声)。根据步长为16,每隔16步取一个张量。
获得对应数据。
到这里就获得了实际的数据
def fun(x, w, b):
pred_y = torch.matmul(x,w) + b
return pred_y
定义函数模型