第1周学习:深度学习和pytorch基础

该篇博客介绍了机器学习的基础,包括无监督学习、监督学习和深度学习的概念。深度学习中讨论了神经网络结构的发展、存在的局限性,如梯度消失问题。博主通过PyTorch展示了如何构建和训练线性模型及两层神经网络,并探讨了不同优化函数和激活函数的影响。此外,还提供了代码示例来解决梯度消失问题。
摘要由CSDN通过智能技术生成

在这里插入图片描述

视频学习

机器学习概述

机器学习 (Machine Learning) 是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析的一门学科。

机器学习的过程

在这里插入图片描述

模型分类

在这里插入图片描述

无监督学习:样本没有标记。无监督学习从数据中学习模式,适用于描述数据,目的在于发现数据中模式/有意义信息
监督学习:样本具有标记(输出目标)。监督学习从数据中学习标记分界面 (输入-输出的映射函数),适用于预测数据标记
半监督学习:部分数据标记已知,是监督学习和无监督学习的混合
强化学习:数据标记未知,但 知道与输出目标相关的反馈,适用决策类问题

参数模型:对数据分布进行假设,待求解的数据模式/映射可以用一组有限且固定数目的参数进行刻画。比如 线性回归、逻辑回归、感知机、K均值聚类
非参数模型:不对数据分布进行假设,数据的所有统计特性都来源于数据本身。比如K近邻、SVM、决策树、随机森林

生成模型: 对输入𝑋和输出𝑌的联合分布𝑃(𝑋, 𝑌)建模,利用贝叶斯公式求解
判别模型: 对已知输入𝑋条件下输出Y的条件分布𝑃(𝑌|𝑋) 建模,直接预测出最可能的解

深度学习概述

深度学习是学习样本数据的内在规律和表示层次,这些学习过程中获得的信息对诸如文字,图像和声音等数据的解释有很大的帮助。它的最终目标是让机器能够像人一样具有分析学习能力,能够识别文字、图像和声音等数据。

神经网络结构的发展

在这里插入图片描述

深度学习存在的局限性

  1. 算法输出不稳定,容易被“攻击”
  2. 模型复杂度高,难以纠错和调试
  3. 模型层级复合程度高,参数不透明
  4. 端到端训练方式对数据依赖性强,模型增量性差
  5. 专注直观感知类问题,对开放性推理问题无能为力
  6. 人类知识无法有效引入进行监督,机器偏见难以避免

深度学习基础

万有逼近定理

如果一个隐层包含足够多的神经元,三层前馈神经网络(输入-隐层
-输出)能以任意精度逼近任意预定的连续函数。

BP神经网络

BP神经网络是这样一种神经网络模型,它是由一个输入层、一个输出层和一个或多个隐层构成,它的激活函数采用sigmoid函数,采用BP算法训练的多层前馈神经网络。

BP算法基本思想

BP算法全称叫作误差反向传播(error Back Propagation,或者也叫作误差逆传播)算法。其算法基本思想为:在2.1所述的前馈网络中,输入信号经输入层输入,通过隐层计算由输出层输出,输出值与标记值比较,若有误差,将误差反向由输出层向输入层传播,在这个过程中,利用梯度下降算法对神经元权值进行调整。

多层神经网络的问题:梯度消失

目前优化神经网络的方法都是基于BP,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。其中将误差从末层往前传递的过程需要链式法则(Chain Rule)的帮助,因此反向传播算法可以说是梯度下降在链式法则中的应用。而链式法则是一个连乘的形式,所以当层数越深的时候,梯度将以指数形式传播。梯度消失问题和梯度爆炸问题一般随着网络层数的增加会变得越来越明显。在根据损失函数计算的误差通过梯度反向传播的方式对深度网络权值进行更新时,得到的梯度值接近0或特别大,也就是梯度消失或爆炸。

多层神经网络梯度消失解决方法

在这里插入图片描述

代码学习

pytorch 基础练习

**#一些函数的基本参数**

ones(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
返回创建size大小的维度,里面元素全部填充为1

full(size, fill_value, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
返回创建size大小的维度,里面元素全部填充为fill_value

torch.zeros(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
返回创建size大小的维度,里面元素全部填充为0

randn_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format) -> Tensor
返回一个和输入大小相同的张量,其由均值为0、方差为1的标准正态分布填充


dtype            所需的数据返回张量的类型。默认值:如果为 None ,则默认为 input 的dtype 
layout           返回的张量的所需布局。默认值:如果为 None ,则默认为 input 的布局
device           返回张量的所需设备。默认值:如果为 None ,则默认为 input 的设备
requires_grad    如果需要在返回张量上保存梯度,默认为False

torch.linspace(start, end, steps=100, out=None) → Tensor
返回一个1维张量,包含在区间start和end上均匀间隔的step个点。输出张量的长度由steps决定。
import torch
x = torch.tensor(666)  #0维向量是一个标量
print(x)
#tensor(666)

list = [1,2,3,4,5]
x = torch.tensor(list) #一维张量(向量)
print(x)
#tensor([1, 2, 3, 4, 5])

Ones  = torch.ones(2,3) #二维张量(矩阵)2*3 1矩阵
Zeros = torch.zeros(2,3) # 2*3 0矩阵
x = torch.empty(5,3)  # 构建5*3的未初始化的矩阵
Random = torch.rand(5,3)  #构建5*3的随机初始化的矩阵
print(Ones)
print(Zeros)
print(x)
print(Random)

tensor([[1., 1., 1.],
        [1., 1., 1.]])
tensor([[0., 0., 0.],
        [0., 0., 0.]])
tensor([[7.9534e-36, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00]])
tensor([[0.3447, 0.1758, 0.5167],
        [0.3494, 0.1158, 0.9085],
        [0.6784, 0.7626, 0.3200],
        [0.8231, 0.3561, 0.2288],
        [0.0197, 0.4146, 0.8990]])

凡是用Tensor进行各种运算的,都是Function

最终,还是需要用Tensor来进行计算的,计算无非是

基本运算,加减乘除,求幂求余
布尔运算,大于小于,最大最小
线性运算,矩阵乘法,求模,求行列式
基本运算包括: abs/sqrt/div/exp/fmod/pow ,及一些三角函数 cos/ sin/ asin/ atan2/ cosh,及 ceil/round/floor/trunc 等具体在使用的时候可以百度一下

布尔运算包括: gt/lt/ge/le/eq/ne,topk, sort, max/min

线性计算包括: trace, diag, mm/bmm,t,dot/cross,inverse,svd 等

# 创建一个 2x4 的tensor
import torch
list = [[1,2,3,4],
       [4,3,2,1]]
x = torch.tensor(list)
print(x.size(0),x.size(1),x.size(),sep='--')
print(x.numel())     # 返回 x 中元素的数量

#2--4--torch.Size([2, 4])
#8

list = [[1,2,3,4],
       [4,3,2,1]]
x = torch.tensor(list)
print(x[0][1])    # 返回 第0行,第1列的数
print(x[:,2])    # 返回 第2列的全部元素
print(x[0,:])    # 返回 第0行的全部元素
#tensor(2)
#tensor([3, 2])
#tensor([1, 2, 3, 4])

# 创建一个 2x4 的tensor
m = torch.tensor([[2, 5, 3, 7],
                 [4, 2, 1, 9]])
x = torch.arange(1,5)  
m @ x                      #矩阵m和x叉乘
m[[0], :] @ x              #m的第一行和x叉乘
m + torch.rand(2, 4)       #m矩阵加上一个随机的2*4的矩阵
print(m.t())               #m的转置矩阵
#print(m.transpose(0, 1))  #m的转置矩阵 
#tensor([49, 47])
#tensor([49])
#tensor([[2, 4],
        [5, 2],
        [3, 1],
        [7, 9]])

# 创建两个 1x4 的tensor
a = torch.Tensor([[1, 2, 3, 4]])
b = torch.Tensor([[5, 6, 7, 8]])

# 在 0 方向拼接 (即在 Y 方各上拼接), 会得到 2x4 的矩阵
print( torch.cat((a,b), 0))
# 在 1 方向拼接 (即在 X 方各上拼接), 会得到 1x8 的矩阵
print( torch.cat((a,b), 1))
#tensor([[1., 2., 3., 4.],
        [5., 6., 7., 8.]])
#tensor([[1., 2., 3., 4., 5., 6., 7., 8.]])

螺旋数据分类

生成相关的数据

#下载绘图函数
!wget https://raw.githubusercontent.com/Atcold/pytorch-Deep-Learning/master/res/plot_lib.py
#导入需要的包
import random
import torch
from torch import nn, optim
import math
from IPython import display
from plot_lib import plot_data, plot_model, set_default

# 因为colab是支持GPU的,torch 将在 GPU 上运行
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print('device: ', device)

# 初始化随机数种子。神经网络的参数都是随机初始化的,
# 不同的初始化参数往往会导致不同的结果,当得到比较好的结果时我们通常希望这个结果是可以复现的,
# 因此,在pytorch中,通过设置随机数种子也可以达到这个目的
seed = 12345
random.seed(seed)
torch.manual_seed(seed)

N = 1000  # 每类样本的数量
D = 2  # 每个样本的特征维度
C = 3  # 样本的类别
H = 100  # 神经网络里隐层单元的数量
X = torch.zeros(N * C, D).to(device)
Y = torch.zeros(N * C, dtype=torch.long).to(device)
for c in range(C):  #生成需要的数据
    index = 0
    t = torch.linspace(0, 1, N) # 在[0,1]间均匀的取10000个数,赋给t
    # 下面的代码不用理解太多,总之是根据公式计算出三类样本(可以构成螺旋形)
    # torch.randn(N) 是得到 N 个均值为0,方差为 1 的一组随机数,注意要和 rand 区分开
    inner_var = torch.linspace( (2*math.pi/C)*c, (2*math.pi/C)*(2+c), N) + torch.randn(N) * 0.2
    
    # 每个样本的(x,y)坐标都保存在 X 里
    # Y 里存储的是样本的类别,分别为 [0, 1, 2]
    for ix in range(N * c, N * (c + 1)):
        X[ix] = t[index] * torch.FloatTensor((math.sin(inner_var[index]), math.cos(inner_var[index])))
        Y[ix] = c
        index += 1

构建线性模型

#构建一个只包含两个全连接层的线性模型
learning_rate = 1e-3
lambda_l2 = 1e-5

# nn 包用来创建线性模型
# 每一个线性模型都包含 weight 和 bias
model = nn.Sequential(  #两个全连接层
    nn.Linear(D, H),
    nn.Linear(H, C)
)
model.to(device) # 把模型放到GPU上

# nn 包含多种不同的损失函数,这里使用的是交叉熵(cross entropy loss)损失函数
criterion = torch.nn.CrossEntropyLoss()

# 这里使用 optim 包进行随机梯度下降(stochastic gradient descent)优化
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, weight_decay=lambda_l2)

# 开始训练
for t in range(1000):
    # 把数据输入模型,得到预测结果
    y_pred = model(X)
    # 计算损失和准确率
    loss = criterion(y_pred, Y)
    score, predicted = torch.max(y_pred, 1)
    acc = (Y == predicted).sum().float() / len(Y)
    print('[EPOCH]: %i, [LOSS]: %.6f, [ACCURACY]: %.3f' % (t, loss.item(), acc))
    display.clear_output(wait=True)

    # 反向传播前把梯度置 0 
    optimizer.zero_grad()
    # 反向传播优化 
    loss.backward()
    # 更新全部参数
    optimizer.step()

构建两层神经网络分类

# 这里可以看到,和上面模型不同的是,在两层之间加入了一个 ReLU 激活函数,使得神经网络拥有了非线性分类的能力
model = nn.Sequential(
    nn.Linear(D, H),
    nn.ReLU(),
    nn.Linear(H, C)
)

不同模型下的结果对比图

不同优化函数的结果变化
结果参数变量
在这里插入图片描述两层全连接层和SGD优化
在这里插入图片描述两层全连接层和Adam优化
不同激活函数的结果变化
结果参数变量
在这里插入图片描述两层全连接层之间加入ReLu激活函数
在这里插入图片描述两层全连接层之间加入ELU激活函数
在这里插入图片描述两层全连接层之间加入GELU激活函数
在这里插入图片描述两层全连接层之间加入PRELU激活函数
在这里插入图片描述两层全连接层之间加入Hardshrink激活函数

遇到的问题

  1. Tensor和tensor的区别
    Tensor 是多维矩阵,矩阵的元素都是同一种数据类型。tensor 需要确切的数据对它进行赋值。叉乘过程过会报 类型不匹配的错误

任务总结

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值