D2DL笔记_1
torch.arange(): 生成一个数列/一维数组
Torch.tensor(): 生成给定元素的张量。一般张量有三个及以上的维度。例子是一个一维数组:
可以生成全0或全1的张量:需要给出张量中矩阵的(个数,行,列),意为几个几行几列的矩阵(二维数组):
由输出可见:形如
[x, x, …, x]为一个单行矩阵;
[ [x, x, …, x]
[x, x, …, x] ]为一个两行矩阵。
需要用一个总括的方括号把矩阵所有的行包括进来,才能表示这些数列属于同一个矩阵。所以在生成给定元素的多行矩阵时,需要多一组总括的方括号:
可将该矩阵视作一个除开行和列的第三维是1的张量。
打印shape可发现,这是一个三行三列的矩阵:
它是二维的,长这样:。(数列/单行矩阵则是一维的,类比点/线、面、体,如此类推更高维)
假如多一组方括号,尝试shape:
它真正地变成了一个第三维只有1的张量。
可以尝试复制一个一样的矩阵进这个张量,自然地,需要再多一组方括号来总括这两个矩阵,表示它们属于同一个张量:
Shape一下:
表示这个张量由两个二维矩阵组成,自此,它有了进深,也就是第三个维度(= 2)。
在这个基础上,再添一对方括号呢?
自然而然地,变成了四维张量,第四维为1,所以,shape打印的列数,为该张量的维度。
通过reshape函数,也可以对张量进行reshape(reshape函数输入的参数是元组,所以需要两对圆括号):
当然,对给定元素的矩阵也可以一样reshape:
但是,reshape只会帮你修改矩阵的形式,而不会改动矩阵的元素,所以,reshape前后矩阵的元素个数必须相同,让reshape忽略后面的元素压缩矩阵或者补零扩大矩阵都不可以。
张量的运算:
加法:x + y;减法:x - y;乘法:x * y;除法:x / y;求幂:x**y。
对矩阵作运算:
每种运算都是按位做的,不同矩阵相同位置的元素做对应运算。
指数运算:也是按位做的:
通过torch.cat((·, ·), dim=·),可以将多个张量在dim=·维度上进行合并,而其它维度保持不变,例子是两个三行四列的矩阵进行合并,其中dim=0是第一个维度,为行,dim=1是第二个维度,为列:
如果维度足够,可以做更高维的合并(dim>1):
一个张量的维度之间合并的话,通过reshape就可以了。
X == Y可以判断对应元素是否相等:
X.sum可以对张量X中的所有元素进行求和,生成一个只有一个元素的张量:
形状不同的张量相加时,默认通过广播机制强行相加:
广播机制:从已有的行/列复制元素补足,进行相加:
因为要a和b相加,a的列数不足,所以复制仅有的一列补足缺失的列,b的行数补足,所以复制仅有的一行补足缺失的行,最后得到一个3 x 2的矩阵。
广播机制补行/列时,补行/列的矩阵不止一行/列,就会报错,比如:
此时a要和b相加,最终会得到一个3 x 2的矩阵,a需要补一列,但a不是单列,不能相加。
X[-1]可以取张量X中最后一个“单位”中的元素(更严谨的写法:X[-1, :]),若X是三维张量,取最后一维的矩阵,如果X是二维矩阵,取最后一行,如果X是一个数列/单行矩阵,取末尾的元素:
其他取元素方法:
Tip: eg. [1:3]:python中:两侧的数字在数学区间的含义上其实为:[1,3),即左闭右开。
[1,3]:取第1行第3个元素(从第0个开始计,其实是取第二行的第四个元素,下同);
[1, :]:取第1行,到该行最后;
[, :1]:取第1列,到该列最后;
[1:3]:取第1个和第2个行:
Python中,id()可以得到变量在内存中十进制表示的地址,该id唯一:
从前一个y和后一个y在内存中存储值的地址不同可看出,前一个y在y = x + y的赋值过程中被析构掉了,可见赋值操作为新结果分配了新的内存,此时变量名虽然相同,但值不同,期望通过访问之前的地址得到该变量值已不可能,在对大矩阵进行操作时容易出错。
在对矩阵进行赋值操作时,可以使用对“矩阵[ : ]”赋值,即对矩阵的所有元素赋值,此时不会改变矩阵在内存中的地址。
另,y += x操作也是可以保证原地操作的。
Numpy和Torch之间的转换:
将只有一个元素的张量转换为python标量: