Pytorch
一、pytorch张量数据类型:
1.python数据类型与pytorch数据类型的对应关系:
python pytorch
Int IntTensor of size()
float FloatTensor of size()
Int array IntTensor of size [d1,d2,.....]
Float array FloatTensor of size[d1,d2,.....]
string pytorch没有内建string说明,只能用数字编码来表示
2.查看数据类型的方法:
a=torch.randn(2,3)
a.type() type(a) isinstance(a,torch.FloatTensor)
部署到gpu上则用a.cuda()可以把部署到cpu上的数据转化到gpu上
标量:torch.tensor(1.)
查看变量的维度:
a.shape len(a.shape) a.size,如果是标量那么就会返回0或者空
张量:
torch.tesnor([n,....])如:torch.tensor([1.1])或者torch.tensor([1.1,2.2]),a.shape返回的是[向量的个数],为第0个维度,维度为1
torch.FloatTensor(1)----随机初始化1个1维的float类型的张量
torch.FloatTensor(2)---随机初始化1个2维的float类型的张量
data=np.ones(2)生成一个numpy的2维数据
torch.from_numpy(data)
dim是指维度或者长度rank
size/shape:是指具体的形状
a.size(0)/a.shape[0]是返回0维的参数以此类推
a.dim看数据的维度
a.numel---具体的数据量,元素个数
3.创建tensor对象
a.从numpy导入数据
例如:a=np.array([2,3.3])
torch.from_numpy(a)
b.从list导入数据
torch.tensor([2.,3.2])/torch.FloatTensor([2.,3.2])/torch.tensor([2.,3.2],[1.,2.0])
注意:torch.Tensor()是接受数据的维度,与torch.FloatTensor()接收维度的效果类似,接收数据是用list,接收维度使用(2,3)
4.生成未初始化的数据:
a.torch.empty()----向内存申请空间,例如:torch.empty([2,3])----生成一个2行3列的未初始化的数据,其中并不是没有数据,而是数据以随机的数字给出
b.torch.FloatTensor(d1,d2,d3...)----内存空间没有初始化,只是作为内存的载体而已,后续会跟输入数据的步骤
c.torch.IntTensor(d1,d2,d3)---生成int类型的载体
使用torch.Tensor()来生成数据,产生数据类型是torch默认数据类型,默认类型为float,可以更改默认类型数据,torch.set_default_tensor_type(torch.DoubleTensor),增强学习中double类型的会用得多一些
5.随机初始化:
rand------使用随机的0-1不包括1的初始化,输入的参数为维度的信息,例如:a=torch.rand(3,3),x=10*torch.rand(d1,d2),randint只能采样整数
rand_like,例如:rand_like(a),把a的shape读出来以后再给rand_like函数
randint(1,10,[3,3])---1到10的整数不包括10,生成1个3*3的矩阵,第一个参数是最小值,第二个参数是最大值,第三个参数为一个shape
正太分布初始化:
torch.randn(3,3)------N(0,1)正太的均值分布,均值为0,方差为1
torch.normal(mean=torch,full([10],0),std=torch.arange(1,0,-0.1))
torch.full([2,3],7)-----full的意思就是fullall全部都是的意思,第一个参数是shape,如果给[0]的话,那么就是生成一个标量,如果给[1]的话就是一个向量只有1个元素
生成等差数列的api:
torch.arange(0,10)----生成从0开始不包含10的数列
torch.arange(0,10,2)----生成一个等差为2的数列,第三个参数为阶梯(等差)
生成等分数列api:
torch.linspace(0,10,steps=4)----第三个参数为数量,这里的10是包括进来的
torch.logspace(0,-1,steps=10)------log可以设置base为2、10、e为底数,就是10的0次方到10的-1次方之间的数,然后等差
torch.ones(3,3)----生成全部为1的3*3的矩阵
torch.zeros(3,3)----生成全部为0的3*3的矩阵
torch.eye(3,4)----生成单位矩阵
torch.one_like(变量)----把变量的shape读出来给torch.one来用
torch.randmperm----随机打散,例如:torch.randmperm(10)生成随机打散的0-10不包括10的数列
6.索引及切片:
a[0]---为第一个维度的索引,a[1,1]---为第二个维度的索引,一次类推,与一般的python的取索引的类型
a[:2]---为第一个维度的切片,以此类推,与python切片的类似。
第二种方式,采用a.index_select(0---第0个维度,[1,2]---在给定维度上取哪几个索引的值);a.index_select(1,[1,2])----第一个维度上取索引1和2的值,其中[1,2]不是一个list,必须转换成为一个tensor才能给index_select()函数,例如:a.index_select(0,torch.arange(28)) .shape,相当于取了第0个维度28(0-27)行的数据
第三种方式:a[...]或者a[0,...],三个点号表示任意多的维度,用三个点代表,:的多个组合
第四种方式:select by mask
mask=a.ge[0.5]----取出a中大于0.5的index就是生成一个矩阵,矩阵中大于0.5的地方标识为1(类型为troch.unit8)与matlab类似,然后把标识为1的数从矩阵中取出来,形成一个向量,调用torch.masked_select(a,mask),得出向量(相当于把数据打平来处理)
第五种方式:torch.take(a,torch.tensor([0,2,4]))----把a打平成为向量,然后取索引为0,2,4的元素
7.维度变换
a.view/reshape(view和reshape的操作是一致的):
例如:a=torch.rand(4,1,28,28),a.view(4,28*28),得到一个[4,1*28*28]的矩阵,数据在做此操作的时候,需要有一定的物理意义,不然容易造成数据的污染,也可以是a.view(4*1*28,28),也可以是a.view(4*1,28,28)
b.Squeeze(维度挤压的操作)和unsqueeze(维度分摊的操作):
a.shape=[1,2,3];a.unsqueeze(0),则a.shape=[1,1,2,3],在原来的第一个维度之增加了一个维度,变成4维,其中Squeeze(position/index),这里给的参数是指在shape返回的这个List里面,哪个索引的位置插入一个维度,如果给-1就是在最后一个维度插入,正负数与list的访问形式类似
sqeeze的用法与unsqueeze的用法相反。
c.expand/repaeat:
expand(推荐)----broadcasting,只是数据的理解方式,并没有扩展数据
例如:b.shape=[1,32,1,1];b.expand(4,32,14,14)---这是可以得只有原来的tensor在维度上是1的可以扩展为n,而为32的不能任意扩展,是能保持b;
b.expand(-1,32,-1,-1)------为原来的维度都不变,保持原来的维度信息,扩展以后为[1,32,1,1]
repeat---memory copied,实实在在的在增加了数据
b.shape=[1,32,1,1];b.repeat(4,32,1,1).shape=[4,1024,1,1];参数说明:repeat()中参数为每个维度要拷贝数据的次数,如上为0维度拷贝4次,1维度拷贝32次,以此类推。。。。repeat给的参数是每个维度需要重复的次数,b.repeat(4,1,1,1)=[4,32,1,1]
8.矩阵转置:
第一种:a.t(),只能使用2D的数据,1D、3D、4D均不能使用
第二种:a.transpose(1,3)----参数为需要交换的维度信息,此时为1维度与3维度的数据进行交换,此种方法容易是数据收到污染与原来的数据结构不相同
例如:a.shape=[4,3,32,32]
a1=a.transpose(1,3).contiguous().view(4,3*32*32).view(4,3,32,32)
a2=a.transpose(1,3).contiguous().view(4,3*32*32).view(4,32,32,3).transpose(1,3)
结果a=a2.a!=a1
可以使用torch.all(torch.eq(a.a1))比较两个张量是否相同;contiguous是把数据连接起来。
第三种:
a.permute(),传的参数是维度的顺序
b.broadcasting----自动扩张(语义)
自定扩展维度,不需要拷贝数据,从最小的维度开始匹配;自动扩展维度然后增加数据
9.拼接与分割
a.cat
例如:a=torch.random(4,32,8);b=torch.random(5,32,8);torch.cat([a,b],dim=0);dim是指在哪一个维度上进行合并
注意:cat函数当dim=0时,第一个维度的大小可以不一致但是在其他维度上必须一致,如果dim不0,其他维度上可以不一致,在原来的dim上进行扩展操作
b.stack---creat new dim创建新的维度
例如; a=troch.random(4,3,16,32);b=torch.random(4,3,16,32);c=torch.stack([a,b],dim=2);得到的是c=[4,3,2,16,32]-----dim是指在哪个位置上扩展一个维度
注意:stack是要求所有的维度必须一致,产生一个新的概念
c.split:by len
按照长度拆分:
例如:a=torch.rand(4,32,8);b,c,d,f=a.split(1,dim=0),长度一致的时候只用一个数来分割,分割成4个形状一样的Tensor,如果形状不一样的时候可以传入数组,如分割成3个tensor[2,1,1]
d.chunk;by num 按照数量来分割
例如:a=torch.rand(4,32,8);b,c=a.chunk(2,dim=0);得到4/2=2个相同维度的tensor
10.数学运算
a.基本运算符:sub(-) add(+) div(/) mul(*) + -.....的符号是重载运算符
b.矩阵运算:
matmul:torch.mm(只能对2维数组使用) torch.matmul(可以对任意维度的矩阵使用,推荐)相当于@重载运算符
>2d tensor matmul:
其实就是多个矩阵并行相乘,前面的维度不变,只计算最后两个维度的相乘
c.pow次方运算:
a.pow(n) 或者a**n a.sqrt平方根 a.rsqrt()平方根的倒数
d.approximination----近似值
.floor()向上近似 .ceil()向下近似 .round()---四舍五入
a.trunc()就是裁剪,得出整数部分,a.frac()得出小数部分
e.clamp函数----裁剪,用得比较多的是梯度裁剪功能
a.clamp(10),最少值设为10,把a中最小值小于10的都变为10,a.clamp(0,10)---最小值设置为0,最大值设置为10,就是a中大于10的全部变为10
11.属性统计:
startistics:
norm---范数,第一个参数给的是求多少的范数比如1,2,3,4,第二个参数给的是dim是求哪一维度的范数
mean sum prod(累乘)
max min argmin(最小值的位置) argmax(最大值的位置)----如何不设置维度的话就是把矩阵打平成一个向量,然后返回向量所在的下标,如果固定维度的话就是返回当前维度的最大值的下标,例如a.argmax(dim=1),返回第一个维度的最大值,a.max(dim=1)返回第一个维度的最大值以及最大值的下标
keepdim---保持和原来的维度一致,例如:a.shape=[4,10];a.max(dim=1).shape=[4];a.max(dim=1,keepdim=True)=[4,1]
top-k ---返回最大的前k个数,例如:a.topk(3,dim=1)返回第一个维度最大的前三个数以及下标,如果要返回最小的前k个数以及下标,可以用a.topk(3,dim=1,largest=false)
kthvalue--- 返回第k小的数以及下标,例如:a.kthvalue(8,dim=1),返回第一个维度第k小的数以及下标。
compare:torch.eq(a,b) ---判断两个元素是否相等,为1或者0的tensor torch.equal---- 判断两个元素是否相等,直接返回True torch.gt(a,b)
高级操作:
torch.where(condition,x,y)(三个参数)--->Tensor,此api得到一个新的矩阵,当满足条件的时候,新的矩阵的对应位置会选择x,y矩阵中对应位置的值,有利于并行
torch.gather(input,dim,index,out=None)-------->Tensor,收集数据的操作,第一个参数是输入的矩阵数据,第二个参数是在哪一个维度上进行查表,第三个是所收集数据的下标,如果dim=0(竖着),则index代表的是行号,dim=1(横着)则index代表的是列号。
11.梯度
定义:变量沿着某一个自变量方向的变化趋势,是一个向量,由所有方向的偏微分组成
12.激活函数
a.sigmod/logistical
使用形式:torch.sigmod(a),sigmod的导数sigmod(1-sigmod)
b.tanh激活函数----在rnn中应用比较多
f(x)=2sigmod(2x)-1,取值范围在[-1,1],导数形式为:1-tanh(x)^2
c.ReLU-----Rectified Linear Unit
13.Loss及梯度
a.Mean Squared Error ------MSE
torch.auto.grad-----求导函数方法一,例如:torch.auto.grad(loss,[w1,w2.....])返回[w1 grad,w2 grad......]
求导函数方法二------计算图.backward()函数,从调用的节点往后向前传播,例如:loss.backward(),返回w1.grad,w2.grad
b.Softmax(激活函数)用于分类的
13.感知机