前言:因为自己之前pytorch有大概的走一遍过,这次重新走一遍,记录的都是自己时常记不住的又或者是时常用到的,再者是很重要的,一切以自己记录为主,别人看不看的懂是次要的。当然有问题可以一起探讨。
本章摘要: pytorch的学习与使用需要一些预备知识,具体包括:高等数学中的求导和积分,线性代数中的矩阵计算相关知识,统计计算中的概率问题,python中numpy和pandas的基本使用。
主要是数据类型介绍,在数学中,数据分为:标量(0维),向量(1维),矩阵(2维),在pytorch中,这些都叫张量(Tensor),张量代表n维数据。
在这里需要了解简单的numpy切片,索引的知识,用以对数据操作,同时numpy的广播机制,以及python中的内存占用方式也可以简单了解一下。
作业: 第2题作业,当涉及三维数据加减时,numpy广播机制要求两组数据中的第1维度相同,第二三维度中最少也要有一个相同。例如(2,2,1)和(2,1,3)加法过后形状会变为(2,2,3)。
主要是利用pandas中缺失值的处理,分别是填充法和删除法,示例代码中为填充法,使用均值填充,作业为删除法,要求删除最多的一列。
作业: 感觉自己的代码还是太长,但不知道有没有什么pandas自带的函数可以更简便一些
函数记录:
df.dropna(how='any')
#删除缺失值列
df.fillna(df.mean())
#用均值填充缺失值,没有参数情况下,默认按列均值填充
df.columns.values
#获取列名
df.isna().sum()
#计算每列缺失值数量
pd.get_dummies(inputs, dummy_na=True)
#字符换成数字
主要是torch中矩阵的相关计算,列求和,求均值,L1,L2范数的计算等等
作业:
前面几题是简单的矩阵推算。
第6题会报错,因为它是一行一行去除,每一行向量长度为4,但是当axis=1时,为行求和,结果长度为5,长度不匹配,除不了
第7题,数据原来形状(2,3,4),轴(0,1,2)对应形状分别为(3,4),(2,4),(2,3),分别为按照所给的轴相加从而消除该轴实现降维。
第8题,linalg.norm为numpy里的一个函数,用来求范数的,默认情况下计算的是L2范数。
函数记录:
A.sum(axis=0,keepdims=True)
#A数组中的数据按列相加,keepdims用以保持数组维度不变。
A.numel()
#计算元素个数,等价于A.shape[0]*A.shape[1]
B = A.clone()
#分配新的内存复制A
torch.dot()
#点积
torch.mv(A,x)
#矩阵乘向量,矩阵在前,向量在后
torch.mm(A,B)
#矩阵乘矩阵
torch.norm(u)
#L2范数,各元素平方和再开根号
torch.abs(u).sum()
#L1范数,各元素绝对值和
主要为导数的求解和梯度的介绍,最重要的为链式法则,这是深度学习的基础。
作业:
都是一些数学导数计算。
函数记录:
print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')
#记录一下输出的格式。大括号里面是变量,冒号后面是控制小数位数
然后主要是画图工具matplotlib的使用了,这个虽然之前学过,但是忘了好多,抽个时间复习一下。
主要介绍pytorch中的反向传播机制,利用记录偏导的方式,减少计算量用以换取更多的时间,但同时的代价为需要很大的内存同时记录这些偏导,当参数越大时,所需要的内存要更多,同时为了减少内存,每次计算完最终梯度后都要使偏导清0,从而可以反复使用内存,减少内存损耗。
与正向传播相比,两者的复杂度是一样的,但是前者所花费的时间少,内存大,后者花费时间多,内存小。也基于计算机的快速发展,让反向传播机制的实现得以可能。
作业:
第2题会报错,这是因为第一次反向传播之后,这个计算图的内存就会被释放掉,
这样的话再次进行反向传播就不行了,解决方法就是添加retain_graph=True
这个参数。(翻译过去差不多这个意思,但我不理解是怎么样的计算图)
第3题也会报错,因为这时候f(a)输出也为一个向量或者矩阵,这时候需要d.sum().backward()
才能运行
第5题
#第5题
import matplotlib.pylab as plt
from matplotlib.ticker import FuncFormatter, MultipleLocator
import numpy as np
import torch
f,ax=plt.subplots(1)
x = np.linspace(-3*np.pi, 3*np.pi, 100)
x1= torch.tensor(x, requires_grad=True)
y1= torch.sin(x1)
y1.sum().backward()
ax.plot(x,np.sin(x),label='sin(x)')
ax.plot(x,x1.grad,label='gradient of sin(x)')
ax.legend(loc='upper center', shadow=True)
ax.xaxis.set_major_formatter(FuncFormatter(
lambda val,pos: '{:.0g}\pi'.format(val/np.pi) if val !=0 else '0'
))
ax.xaxis.set_major_locator(MultipleLocator(base=np.pi))
plt.show()
函数记录:
y.backward(torch.arange(len(x)))
#当y也为向量时,需要给backward传递一个参数,该参数为self函数的梯度。
y.detach()
#分离计算,某些计算移动到记录的计算图之外
主要介绍概率论的一些基本知识,方差,标准差,期望。还有贝叶斯公式
作业:
(先留着,等复习机器学习了再回头看看)
函数记录:
from torch.distributions import multinomial
#导包
multinomial.Multinomial(1, fair_probs).sample(10)
#简单抽样,从fair_probs里抽取1次,结果表示各个元素被抽到次数,sample后面的参数表示这样的抽样重复十次