《动手学深度学习》PyTorch版Task01

《动手学:线性回归》

1.生成数据集
随机标签,指定参数,计算标准结果添加噪声
2.定义模型
3.定义损失函数
4.定义优化模型
5.训练模型
1)设置超参,初始化模型参数
2)每次迭代中,小批量读取数据,初始化模型计算预测值,损失函数计算插值,反向传播求梯度,优化算法更新参数,参数梯度清零

本视频用了许多pytorch的函数,由于不是太了解pytorch内的函数,因此查询记录了一下。
torch.ones()/ torch.zeros(),与MATLAB的ones / zeros很接近。初始化生成
均匀分布
torch.rand(* sizes,out = None)→张量
返回一个张量,包含了从区间[0,1)的均匀分布中抽取的单个随机数。张量的形状由参数sizes定义。
标准正态分布
torch.randn(* sizes,out = None)→张量
返回一个张量,包含从标准正态分布(均值0,方差为1,即高斯白噪声)中捕获的一组随机数。张量的形状由参数大小定义。
torch.mul(a,b)是矩阵a和b对应位相乘,a和b的尺寸必须对齐,例如a的尺寸是(1,2),b的尺寸是(1,2),返回的仍是(1,2)的矩阵
torch.mm(a,b)是矩阵a和b矩阵相乘,某种a的维度是(1,2),b的维度是(2,3),返回的就是(1,3)的矩阵
torch.Tensor是一种包含单一数据类型元素的多维矩阵,定义了7种CPU tensor和8种GPU tensor类型。
random.shuffle(a):用于将一个列表中的元素打乱。shuffle()是不能直接访问的,需要引入random模块,然后通过random静态对象调用该方法。
向后()是pytorch中提供的函数,配套有require_grad:
1.所有的tensor都有.requires_grad属性,可以设置这个属性.x = tensor.ones(2,4,requires_grad = True)
2.如果想改变这个属性,就调用tensor.requires_grad_()方法:x.requires_grad_(False)

(1)torch.mm和torch.mul的区别?
torch.mm是矩阵相乘,torch.mul是按元素相乘
(2)torch.manual_seed(1)的作用?
设置随机种子,使实验结果可以复现
(3)optimizer.zero_grad()的作用?
使梯度置零,防止不同batch得到的梯度累加

Softmax与分类模型

关于Pytorch中Dataset和Dataloader的理解

import torch.utils.data as Data

batch_size = 10

# combine featues and labels of dataset
dataset = Data.TensorDataset(features, labels)
print(dataset)
# put dataset into DataLoader
data_iter = Data.DataLoader(
    dataset=dataset,            # torch TensorDataset format
    batch_size=batch_size,      # mini batch size
    shuffle=True,               # whether shuffle the data or not
    num_workers=2,              # read data in multithreading
)

使用Pytorch自定义读取数据时步骤如下:
1)创建Dataset对象
2)将Dataset对象作为参数传递到Dataloader中

详述步骤1)创建Dataset对象:
参见
详述步骤2)创建将Dataset对象作为参数传递到Dataloader中:
需要注意的是,Dataloader中存在一个默认的collate_fn函数,需要根据自己的需求重写collate_fn函数:
(1)该函数的作用是将数据整理成一个batch,即根据batch_size的大小一次性在数据集中取出batch_size个数据。例如数据集中有4条数据,batch_size的值为2,则每次在4条数据中取出2条数据。
(2)collate_fn函数的输入是一个list,list中的每个元素为自己编写的dataset类中__getitem__函数的返回值。
(3)Dataloader中drop_last代表将不足一个batch_size的数据是否保留,即假如有4条数据,batch_size的值为3,将取出一个batch_size之后剩余的1条数据是否仍然作为训练数据。

softmax函数的常数不变性,即softmax(x)= softmax(x + c)
在计算softmax概率的时候,为了保证数值稳定性(数值稳定性),我们可以选择给输入条目一个常数,例如x的每个元素都要用一个x中的最大元素。当输入项很大的时候,如果不减这样一个常数,取指数之后结果会变得非常大,发生溢出的现象,导致结果出现INF。

多层感知机

多层感知机,激活函数(加入非线性结构):常用计算量更小的ReLU函数(保留整数,转负元素为0),而Sigmoid(元素变换为0-1之间)与tanh函数(元素变换为-1〜1之间)可能出现梯度消失的问题。

文本预处理

文本预处理
文本是一类序列数据,一篇文章可以看作是字符或单词的序列,本节将介绍文本数据的常见预处理步骤,预处理通常包括四个步骤:

1.读入文本
2.分词
3.建立字典,将每个词映射到一个唯一的索引(index)
4.将文本从词的序列转换为索引的序列,方便输入模型
对视频中所说的不同的现实场景有不同的预处理方法深有体会,视频的讲解是处理英文文本。
而在中国处理的最多是中文文本,但是中文文本相对英文文本存在了大量的问题。
对于自己所做的短文本的推进系统中,总结了这些中文文本存在的问题(如果大家遇到别中文文本的问题希望补充):

  1. 中文存在词的语义比英文更为复杂
  2. 词汇少
  3. 特征稀释
  4. 分类精确率低
    并且在中文的文本的预处理中,个人觉得还需要做不同停用词表和无关词表。
    其中视频中lines = [re.sub(’[^a-z]+’, ’ ', line.strip().lower()) for line in f]可以看做为停用词的处理。
    而无关词即是对场景无关紧要之词,相当于我们日常所说的废话(但并不是人为觉得的)。
    视频中提及的分词工具可以说目前也是相对英文,对于中文的分词工具目前大多数使用的是jieba
    #建立字典,设置阈值
    #去重筛选词,特殊需求token
    #1、count_corpus统计词频,得到counter
    #2、增删,利用空列表
    #pad:二维矩阵长度不一,短句子补token利用pad
    #bos:开始token
    #eos:结束token
    #unk:未登录词当作unk
    #3、词到索引号
    1.pad的作用是在采用批量样本训练时,对于长度不同的样本(句子),对于短的样本采用pad进行填充,使得每个样本的长度是一致的
    2.bos( begin of sentence)和eos(end of sentence)是用来表示一句话的开始和结尾
    3.unk(unknow)的作用是,处理遇到从未出现在预料库的词时都统一认为是unknow ,在代码中还可以将一些频率特别低的词也归为这一类

语言模型

一段自然语言文本可以看作是一个离散时间序列,给定一个长度为 T 的词的序列 w1,w2,…,wT ,语言模型的目标就是评估该序列是否合理,即计算该序列的概率:
P(w1,w2,…,wT).
本节我们介绍基于统计的语言模型,主要是 n 元语法( n -gram)。在后续内容中,我们将会介绍基于神经网络的语言模型。

n元语法

序列长度增加,计算和存储多个词共同出现的概率的复杂度会呈指数级增加。 n 元语法通过马尔可夫假设简化模型,马尔科夫假设是指一个词的出现只与前面 n 个词相关,即 n 阶马尔可夫链(Markov chain of order n ),如果 n=1 ,那么有 P(w3∣w1,w2)=P(w3∣w2) 。
当 n 分别为1、2和3时,我们将其分别称作一元语法(unigram)、二元语法(bigram)和三元语法(trigram)。例如,长度为4的序列 w1,w2,w3,w4 在一元语法、二元语法和三元语法中的概率分别为

P(w1,w2,w3,w4)=P(w1)P(w2)P(w3)P(w4),
P(w1,w2,w3,w4)=P(w1)P(w2∣w1)P(w3∣w2)P(w4∣w3)
P(w1,w2,w3,w4)=P(w1)P(w2∣w1)P(w3∣w1,w2)P(w4∣w2,w3).
当 n 较小时, n 元语法往往并不准确。例如,在一元语法中,由三个词组成的句子“你走先”和“你先走”的概率是一样的。然而,当 n 较大时, n 元语法需要计算并存储大量的词频和多词相邻频率。

n 元语法可能有哪些缺陷?
1.参数空间过大
2.数据稀疏

时序数据的采样
随机采样
其中批量大小batch_size是每个小批量的样本数,num_steps是每个样本所包含的时间步数。 在随机采样中,每个样本是原始序列上任意截取的一段序列,相邻的两个随机小批量在原始序列上的位置不一定相毗邻。
先按步数进行划分成组,每次去除批量大小个组
相邻采样(后续补充)
在相邻采样中,相邻的两个随机小批量在原始序列上的位置相毗邻。
先按批量大小分,形成一个(batch_size,-1)矩阵

循环神经网络基础

我们的目的是基于当前的输入与过去的输入序列,预测序列的下一个字符。循环神经网络引入一个隐藏变量 H ,用 Ht 表示 H 在时间步 t 的值。 Ht 的计算基于 Xt 和 Ht−1 ,可以认为 Ht 记录了到当前字符为止的序列信息,利用 Ht 对序列的下一个字符进行预测。

one-hot向量
我们需要将字符表示成向量,这里采用one-hot向量。假设词典大小是 N ,每次字符对应一个从 0 到 N−1 的唯一的索引,则该字符的向量是一个长度为 N 的向量,若字符的索引是 i ,则该向量的第 i 个位置为 1 ,其他位置为 0 。下面分别展示了索引为0和2的one-hot向量,向量长度等于词典大小。

裁剪梯度
循环神经网络中较容易出现梯度衰减或梯度爆炸,这会导致网络几乎无法训练。裁剪梯度(clip gradient)是一种应对梯度爆炸的方法。假设我们把所有模型参数的梯度拼接成一个向量 g ,并设裁剪的阈值是 θ 。裁剪后的梯度的 L2 范数不超过 θ 。
困惑度
我们通常使用困惑度(perplexity)来评价语言模型的好坏。回忆一下“softmax回归”一节中交叉熵损失函数的定义。困惑度是对交叉熵损失函数做指数运算后得到的值。特别地,

最佳情况下,模型总是把标签类别的概率预测为1,此时困惑度为1;
最坏情况下,模型总是把标签类别的概率预测为0,此时困惑度为正无穷;
基线情况下,模型总是预测所有类别的概率都相同,此时困惑度为类别个数。
显然,任何一个有效模型的困惑度必须小于类别个数。在本例中,困惑度必须小于词典大vocab_size。

需要再好好研究学习。

参考:https://www.boyuai.com/elites/course/cZu18YmweLv10OeV/video/Rosi4tliobRSKaSVcsRx_#comment-kD989m0SsQuJAZARvz_3s

你可能感兴趣的:(《动手学深度学习》PyTorch版Task01)