目录
11 Pytorch 数据加载器: Dataset 和 DataLoader
1 函数x.view(),改变tensor形状
将torch.Size([batch_size = 16, channel = 16, h = 12, w = 5])
改变成torch.Size([batch_size = 16, channel = 16, 60])
input = input.view(batch_size, self.channel, 5*12)
# 或者,下面的写法,会更加自动化,也更方便简洁
input = input.view(batch_size, self.channel, -1)
2 神经网络的momentum
我们通常使用梯度下降来求解神经网络的参数,我们在梯度下降时,为了加快收敛速度,通常使用一些优化方法,比如:momentum、RMSprop、Adam等。
使用SGD(stochastic mini-batch gradient descent,深度学习中一般称之为SGD)训练参数时,有时候会下降的非常慢,并且可能会陷入到局部最小值中,动量的引入就是为了加快学习过程,特别是对于高曲率、小但一致的梯度,或者噪声比较大的梯度能够很好的加快学习过程。动量的主要思想是积累了之前梯度指数级衰减的移动平均(前面的指数加权平均)
一般,神经网络在更新权值时,采用如下公式:
w = w - learning_rate * dw
引入momentum后,采用如下公式:
v = mu * v - learning_rate * dw
w = w + v
3 CNN与GCN
CNN无法直接平移到GCN,因为非欧几里德结构数据无法保持平移不变性。
具体来说,由于在拓扑图中每个顶点的相邻顶点数目都可能不同,因此无法用一个同样尺寸的卷积核来进行卷积运算。需要在图上重新设计卷积的方法,而目前图卷积方法主要分为两大类:谱方法(Spectral Methods)和 空间方法(Spatial Methods)。
谱方法 :大概思路是通过傅里叶变换等将图数据从空间域映射到谱域,然后在谱域实现卷积,最后再将处理后的信号映射回空间域。
空间方法 :在空间域直接定义卷积, 这里的卷积被定义为所有邻居结点的加权平均函数。但主要问题是由于每个结点的邻居大小不一样,很难实现参数共享。
4 einsum爱因斯坦求和
在数学中,爱因斯坦求和约定是一种标记法,也称为Einstein Summation Convention,在处理关于坐标的方程式时十分有效。简单来说,爱因斯坦求和就是简化掉求和式中的求和符号
具体参考:【深度学习中的神仙操作】einsum爱因斯坦求和 - 知乎
5 什么是卷积
什么是卷积,对于两个函数f , h f,hf,h,卷积就是指对这两个函数进行加权平移叠加。
5.1 连续域下卷积如下所示:
公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
根据上面的式子,我们可以看出y(t)由无数个h(t)平移加权后叠加得到,平移的距离是t' , 权重是f(t′), 由于卷积运算具有交换律,所以这两个函数反过来也可以得到同样的结论。包含两个函数,f(t)和h(t)
5.2 离散域下卷积如下所示:
公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
这个形式我们也可以得出与连续域中一样的结论。
5.3 特别的,卷积特殊性质
两个函数卷积的结果的频域信号等于两个函数频域信号的乘积。
公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
(两个函数卷积的结果)的频域信号 = [ (函数A)的频域信号 ] * [(函数B)的频域信号 ]
其中,F = 频域信号 = 傅里叶变换
6 图卷积
6.1 图傅里叶变换
一个图有边和节点构成,为了表示图的节点与节点之间的连接情况,一个比较好的选择是正则化拉普拉斯矩阵
公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
其中A为邻接矩阵,如果节点 i 和节点 j 相连,则Aij = 1
D为度矩阵,D是一个对角矩阵,公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
由于正则化拉普拉斯矩阵是一个对称半正定矩阵,所以该矩阵的特征向量两两正交,且特征值两两互异,并且都非负,这样就可以得到:
公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
其中U是特征向量组成的矩阵,Λ是特征值组成的矩阵。
在一般的数据里面的傅里叶变换是将原始数据投影到以三角波为基底的空间中,这里类比傅里叶变换,得到了图傅里叶变换,也就是把原始数据映射到以特征向量为基底的空间中,即:
公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
图分割那篇博客里,我们提到了U是图分割时梯度为0的分割向量,用于把图一分为二。其中第二小的特征值对应的特征向量就是最优的分割向量。UTX相当于是把节点中被分割成两部分的节点的特征向量分别求和,求和后的结果加权后做差。
6.2 图卷积
这里用 * 表示图卷积,类比普通卷积的性质可以得到下面的结果:
公式参考:基于谱方法的图卷积(卷积,图卷积,切比雪夫图卷积)_基于谱域的图卷积_小人国的蜗牛的博客-CSDN博客
其中⊙为哈德曼乘积(对应位置元素相乘)
g ∈ R N (这里我一直在想一个问题,为什么这里是⊙和R N 而不是外积和R N × N ,这里个人认为是如果这里采用外积的形式,那这里就不是对整个graph做特征提取,而是对于单独某一个节点做特征提取,而且外积不满足交换律)
7 one-hot编码
两个对象
男 => 10
女 => 01
三个对象
中国 => 100
美国 => 010
法国 => 001
四个对象
足球 => 1000
篮球 => 0100
羽毛球 => 0010
乒乓球 => 0001
六个对象
'CLR' = 100000 'FEW' = 010000 'VV ' = 001000 'SCT' = 000100 'BKN' = 000010 'OVC' = 000001
8 标准差
标准差,Standard Deviation,简称std
std = 方差的算术平方根 = 均值与所有样本的差值,差值平方,平方的均值,均值的算术平方根
均值:means
标准差:std
9 切比雪夫多项式
Chebyshev多项式:
T0(x) = 1
T1(x) = x
Tk(x) = 2xTk-1(x) - Tk-2(x)
T2(x) = 2xT1(x) - T0(x)=2x2-1
对矩阵的Chebyshev多项式:
T0(L) = I
T1(L) = L
Tk(L) = 2LTk-1(L) - Tk-2(L)
T2(L) = 2LT1(L) - T0(L)=2L2-1
10 torch.transpose() 函数
转换坐标轴
transpose((0, 2, 3, 1))更换坐标轴,原本为(0,1,2,3)现在改为(0,2,3,1)
本来shape(0,1,2,3) = (1, 72412, 顶点个数, 特征个数)
transpose((0, 2, 3, 1)) = (1, 顶点个数, 特征个数, 72412)
transpose主要用于矩阵转置,注意:transpose()一次只能在两个维度间进行转置(也可以理解为维度转换)
torch.transpose() 是pytorch中的ndarray矩阵进行转置的操作
Tensor_A = torch.transpose(Tensor_A, dim0, dim1)
Lap = Lap.transpose(-1, -2)
11 Pytorch 数据加载器: Dataset 和 DataLoader
Dataset是一个包装类,可对数据进行张量(tensor)的封装,其可作为DataLoader的参数传入,进一步实现基于tensor的数据预处理。
dataset = MyDataset()
dataloader = DataLoader(dataset)
num_epoches = 100
for epoch in range(num_epoches):
for img,label in dataloader :
...........
Dataloader是一个类,设置各种参数,以及数据集
torch.utils.data.DataLoader() dataset: Dataset类, 决定数据从哪读取以及如何读取 bathsize: 批大小 num_works: 是否多进程读取机制 shuffle: 每个epoch是否乱序 drop_last: 当样本数不能被batchsize整除时, 是否舍弃最后一批数据,要理解这个drop_last Epoch: 所有训练样本都已输入到模型中,称为一个Epoch Iteration: 一批样本输入到模型中,称为一个Iteration Batchsize: 一批样本的大小, 决定一个Epoch有多少个Iteration
Dataset抽象类, 所有自定义的Dataset都需要继承它,并且必须复写__getitem__()
这个类方法。
torch.utils.data.Dataset()
shuffle=True,将数据集的顺序随机打乱再取batch
12 nn.Module
torch.nn是Pytorch专门为神经网络设计的模块化接口,基于AutoGrad实现。nn.Module是其中最重要的一个类,可以看作是网络的封装,包含网络各层的定义和forward方法。调用 forward 方法,可以返回前向传播的结果。
定义网络时,就需要继承nn.Module,并实现它的forward方法。
class net(nn.Module):
def __init__(self,):#定义网络
def forward(self,):#前向传播
13 Conv2d
就是用来实现2d卷积操作的
torch.nn.Conv2d(in_channels: int,
out_channels: int,
kernel_size: Union[T, Tuple[T, T]],
stride: Union[T, Tuple[T, T]] = 1,
padding: Union[T, Tuple[T, T]] = 0,
dilation: Union[T, Tuple[T, T]] = 1,
groups: int = 1,
bias: bool = True,
padding_mode: str = 'zeros')
in_channels —— 输入的channels数
out_channels —— 输出的channels数
kernel_size ——卷积核的尺寸,可以是方形卷积核、也可以不是,下边example可以看到
stride —— 步长,用来控制卷积核移动间隔
padding ——输入边沿扩边操作
padding_mode ——扩边的方式
bias ——是否使用偏置(即out = wx+b中的b)
https://blog.csdn.net/qq_34243930/article/details/107231539?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165461991816781483712362%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165461991816781483712362&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-107231539-null-null.142^v11^control,157^v13^control&utm_term=Conv2d&spm=1018.2226.3001.4187
14 Pytorch之contiguous函数
contiguous一般与transpose,permute,view搭配使用:使用transpose或permute进行维度变换后,调用contiguous,然后方可使用view对维度进行变形(如:tensor_var.contiguous().view() ),示例如下:
x = torch.Tensor(2,3)
y = x.permute(1,0) # permute:二维tensor的维度变换,此处功能相当于转置transpose
y.view(-1) # 报错,view使用前需调用contiguous()函数
y = x.permute(1,0).contiguous()
y.view(-1) # OK
具体原因有两种说法: 1 transpose、permute等维度变换操作后,tensor在内存中不再是连续存储的,而view操作要求tensor的内存连续存储,所以需要contiguous来返回一个contiguous copy 2 维度变换后的变量是之前变量的浅拷贝,指向同一区域,即view操作会连带原来的变量一同变形,这是不合法的,所以也会报错;---- 这个解释有部分道理,也即contiguous返回了tensor的深拷贝contiguous copy数据;
15 Pytorch中的view()函数
view()的作用相当于numpy中的reshape,重新定义矩阵的形状。
普通用法:
import torch
v1 = torch.range(1, 16)
v2 = v1.view(4, 4)
# 其中v1为1*16大小的张量,包含16个元素。
# v2为4*4大小的张量,同样包含16个元素。注意view前后的元素个数要相同,不然会报错。
参数使用-1
import torch
v1 = torch.range(1, 16)
v2 = v1.view(-1, 4)
view中一个参数定为-1,代表动态调整这个维度上的元素个数,以保证元素的总数不变。因此两个例子的结果是相同的。
16 list,tensor,array之间的转换
torch.Tensor 转 numpy
ndarray = tensor.numpy()
# 若是在gpu环境下
ndarray = tensor.cpu().numpy()
numpy 转 torch.Tensor
tensor = torch.from_numpy(ndarray)
torch.Tensor 转 list
list = tensor.numpy().tolist()
list 转 numpy
ndarray = np.array(list)
numpy 转 list
list = ndarray.tolist()
17 torch.stack()函数
在pytorch
中,常见的拼接函数主要是两个,分别是:
1、stack()
2、cat()
实际使用中,这两个函数互相辅助,使用场景不同。
stack()
官方解释:沿着一个新维度对输入张量序列进行连接。 序列中所有的张量都应该为相同形状。
浅显说法:把多个2维的张量凑成一个3维的张量;多个3维的凑成一个4维的张量…以此类推,也就是在增加新的维度进行堆叠。
outputs = torch.stack(inputs, dim=?) → Tensor
参数
inputs : 待连接的张量序列。 注:python的序列数据只有list和tuple。
dim : 新的维度, 必须在0到len(outputs)之间。 注:len(outputs)是生成数据的维度大小,也就是outputs的维度值
stack()参考:torch.stack()的官方解释,详解以及例子_模糊包的博客-CSDN博客
cat()torch.cat()函数的官方解释,详解以及例子_模糊包的博客-CSDN博客
18 Pytorch中的矩阵运算
Pytorch学习笔记(11)Pytorch中的矩阵运算 - 百度文库
19 pytorch与tensorflow
在pytorch中许多功能都比tensorflow更加简便,比如网络定义中,pytorch出现了大量的简洁。
如果想继续形如tensorflow定义网络,可以使用nn.funtion模块,一般pytorch的神经网络全部都在nn.module模块中定义就可以