第1周学习:深度学习和pytorch基础(2022.7.11-7.17)

一、当前任务

(一)视频学习专知课程 01-绪论、02-深度学习概述
(二)pytorch基础练习、螺旋数据分类

二、本周工作

(一)视频学习内容

人工智能:使一部机器像人一样进行感知、认知、决策、执行的人工程序或系统

人工智能三大层面:计算智能(深蓝)、感知智能(无人驾驶)、认知智能(理解思考决策)

概念范围:人工智能>机器学习>深度学习
知识工程:基于手工设计规则建立专家系统判断类别,容易解释结果但系统构建过程费时费力,依赖专家主观经验,难以保证一致性和准确性

机器学习:基于数据机器自动学习进而判断类别,减少人工提高信息处理效率,减少人工规则主观性可信度高,但结果可能不易解释

机器学习三大领域:计算机视觉(人脸识别、图像分类、目标检测、图像搜索、图像分割、视频监控)、语音技术(语音识别、语音合成、声纹识别)、自然语言处理(文本分类、机器翻译、知识图谱、自动问答、信息检索、文本生成)

机器学习:从数据中自动提取知识

机器学习过程:模型(问题建模、确定假设空间)、策略(确定目标函数)、算法(求解模型参数)

模型:数据标记(监督-预测数据标记 VS 无监督学习-描述数据 VS 半监督学习-部分数据标记 VS 强化学习-未标记但奖励反馈)、数据分布(参数模型-线性回归、逻辑回归、感知机、K均值聚类 VS 非参数模型-K近邻)、建模对象(判别模型-SVM、逻辑回归、条件随机场、决策树 VS 生成模型-朴素贝叶斯、隐马尔可夫、马尔科夫随机场)

传统机器学习:预处理、特征提取、特征转换

深度学习:标注代表图像、机器选择和优化模型
第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第1张图片

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

浅层神经网络:
生物神经元、M-P神经元、激活函数的作用
单层与多层感知器

万有逼近定理:如果一个隐层包含足够多的神经元,三层前馈神经网络(输入-隐层
输出)能以任意精度逼近任意预定的连续函数。
第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第2张图片

(二)pytorch基础与螺旋数据分类练习

pytorch:python库,主要提供GPU加速的张量计算、构建在反向自动求导系统上的深度神经网络两个高级功能。
1.定义数据:torch.tensor,tensor的意思是张量,是数字各种形式的总称

import torch
#tensor可以是一个数
x = torch.tensor(666) 
print(x)

#tensor可以是一维数组(向量)
y = torch.tensor([1,2,3,4,5,6])
print(y)

# 可以是二维数组(矩阵)
z = torch.ones(2,3)
print(z)

# 可以是任意维度的数组(张量)
a = torch.ones(2,3,4)
print(a)

# 创建一个空张量
b = torch.empty(5,3)
print(b)

# 创建一个全0的张量,里面的数据类型为 long
c = torch.zeros(5,3,dtype=torch.long)
print(c)

# 基于现有的tensor,创建一个新tensor,
# 从而可以利用原有的tensor的dtype,device,size之类的属性信息
d = x.new_ones(5,3)   #tensor new_* 方法,利用原来tensor的dtype,device
print(d)

e = torch.randn_like(x, dtype=torch.float)    # 利用原来的tensor的大小,但是重新定义了dtype
print(e)

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第3张图片
2.定义操作
基本运算(加减乘除、求幂求余)
例: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
m = torch.Tensor([[2, 5, 3, 7],
                  [4, 2, 1, 9]])

print(m.size(0), m.size(1), m.size(), sep=' -- ')

# 返回 m 中元素的数量
print(m.numel())

# 返回 第0行,第2列的数
print(m[0][2])

# 返回 第1列的全部元素
print(m[:, 1])

# 返回 第0行的全部元素
print(m[0, :])

# Create tensor of numbers from 1 to 5
# 注意这里结果是1到4,没有5
v = torch.arange(1, 5)
print(v)

# Scalar product
v = v.float() #需要转换数据类型
m @ v

# Calculated by 1*2 + 2*5 + 3*3 + 4*7
m[[0], :] @ v

# Add a random tensor of size 2x4 to m
m + torch.rand(2, 4)

# 转置,由 2x4 变为 4x2
print(m.t())

# 使用 transpose 也可以达到相同的效果
print(m.transpose(0, 1))

# returns a 1D tensor of steps equally spaced points between start=3, end=8 and steps=20
torch.linspace(3, 8, 20)

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第4张图片

from matplotlib import pyplot as plt
# matlabplotlib 只能显示numpy类型的数据,下面展示转换数据类型,然后显示
# 注意 randn 是生成均值为 0, 方差为 1 的随机数
# 下面是生成 1000 个随机数,并按照 100 个 bin 统计直方图
plt.hist(torch.randn(1000).numpy(), 100);

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第5张图片

# 当数据非常非常多的时候,正态分布会体现的非常明显
plt.hist(torch.randn(10**6).numpy(), 100);

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第6张图片

# 创建两个 1x4 的tensor
a = torch.Tensor([[1, 2, 3, 4]])
b = torch.Tensor([[5, 6, 7, 8]])
#tensor([[1., 2., 3., 4.],
#		[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.]])

3.螺旋数据分类

!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  # 神经网络里隐层单元的数量

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第7张图片

#初始化X、Y,X可理解为特征矩阵,Y可理解为样本标签
#X为一个 NxC 行,D 列的矩阵,C 类样本,每类样本是 N个,所以是 N*C 行。每个样本的特征维度是2,所以是 2列。
#在python 中,调用 zeros 类似的函数,第一个参数是 y方向的,即矩阵的行;第二个参数是 x方向的,即矩阵的列
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

print("Shapes:")
print("X:", X.size())
print("Y:", Y.size())

# visualise the data
plot_data(X, Y)

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第8张图片
构建线性模型分类

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()
    #[EPOCH]: 999, [LOSS]: 0.857664, [ACCURACY]: 0.504
    
#由print(y_pred.shape)可知模型的预测结果,为[3000, 3]的矩阵。每个样本的预测结果为3个,保存在 y_pred 的一行里。值最大的一个,即为预测该样本属于的类别score, predicted = torch.max(y_pred, 1) 是沿着第二个方向(即X方向)提取最大值。最大的那个值存在 score 中,所在的位置(即第几列的最大)保存在 predicted 中。
print(y_pred.shape)
print(y_pred[10, :])#输出第十行结果用于观察
print(score[10])
print(predicted[10])

# Plot trained model
print(model)
plot_model(X, Y, model)
#由结果可以看到模型共有两层,第一层输入为 2(因为特征维度为主2),输出为 100;第二层输入为 100 (上一层的输出),输出为 3(类别数),线性模型准确率50%左右难以实现准确分类

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第9张图片
构建两层神经网络分类

learning_rate = 1e-3
lambda_l2 = 1e-5

# 这里可以看到,和上面模型不同的是,在两层之间加入了一个 ReLU 激活函数
model = nn.Sequential(
    nn.Linear(D, H),
    nn.ReLU(),
    nn.Linear(H, C)
)
model.to(device)

# 下面的代码和之前是完全一样的
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=lambda_l2) # built-in 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)
    
    # zero the gradients before running the backward pass.
    optimizer.zero_grad()
    # Backward pass to compute the gradient
    loss.backward()
    # Update params
    optimizer.step()
#[EPOCH]: 999, [LOSS]: 0.183666, [ACCURACY]: 0.940
# Plot trained model
print(model)
plot_model(X, Y, model)
#从结果可以看出,在两层神经网络里加入 ReLU 激活函数以后,分类的准确率得到了显著提高

第1周学习:深度学习和pytorch基础(2022.7.11-7.17)_第10张图片

你可能感兴趣的:(深度学习,学习,pytorch)