张量简介
张量(tensor)是一个多维数组,是标量,向量和矩阵的高维拓展。
张量属性
属性 |
意义 |
data |
数据 |
dtype |
数据类型 |
shape |
形状 |
device |
张量所在的设备,CPU/GPU |
grad |
梯度 |
grad_fn |
创建张量的function,是自动求导的关键 |
requires_grad |
是否需要梯度 |
is_leaf |
是否叶子节点 |
创建张量
通过numpy数组创建
函数 |
作用 |
torch.tensor(arr) |
通过numpy数组创建张量 |
torch.from_numpy(arr) |
创建张量并与numpy数组共享内存空间,一改俱改 |
通过数值创建
函数 |
作用 |
torch.zeros((3, 3)) |
创建全0张量 |
torch.zeros_like(input) |
根据input形状创建全0张量 |
torch.ones((3, 3)) |
创建全1张量 |
torch.ones_like(input) |
根据input形状创建全1张量 |
torch.full((3, 3), n) |
创建全n张量 |
torch.full_like(input, n) |
根据input形状创建全n张量 |
torch.arange(start, end, strides) |
创建等差一维张量,strides为步幅 |
torch.linspace(start, end, length) |
创建等差一维张量,length为长度 |
torch.logspace(start, end, length, n = 10) |
创建对数均分的一维张量,n为底数 |
torch.eye(5) |
创建 5*5 的对角单位矩阵 |
通过概率创建
函数 |
作用 |
torch.normal(mean, std) |
创建正态分布 |
torch.randn((3, 3)) |
创建标准正太分布 |
torch.randn_like(input) |
根据input形状创建标准正态分布张量 |
torch.rand((3, 3)) |
创建0-1均匀分布 |
torch.rand_like(inpuit) |
根据input形状创建0-1均匀分布张量 |
torch.randint(0, 10, (3,3)) |
创建整数分布 |
torch.randint_like(0, 10, input) |
根据input形状创建0-10整数分布张量 |
torch.randperm(n) |
创建0到n-1的随机排列,长度为n |
torch.bernoulli(input) |
以input为概率,生成伯努利分布 |
张量运算
拼接与切分
函数(t为tensor对象) |
作用 |
torch.cat([t, t], dim=1) |
dim表示维度,(第一维度为行,第二维度为列),根据维度拼接 |
torch.stack([t, t], dim=0) |
拓展张量的维度,将[2,3]拓展为[2,2,3] |
torch.chunk(t, dim=1, chunks=2) |
根据所给的维度dim=1进行平均切割为2份,如果不整除,最后一份小于其他 |
torch.split(t, 2, dim=1) |
dim=1,按长度2进行切分 |
torch.split(t, [2,1,2], dim=1) |
dim=1, 按长度2,1,2进行划分,t的列数要等于5 |
索引
函数(t为tensor对象) |
作用 |
torch.index_select(t, dim, index) |
根据索引提取内容 |
torch.masked_select(t, mask) |
根据mask掩码提取内容 |
mask可以根据ge()或gt()函数获得
t_mask = t.ge(5)
# t中大于或等于5的为True, 否则为False
# gt函数则表示大于
变化形状
函数(t为tensor对象) |
作用 |
torch.reshape(t, (2,4)) |
重塑形状,但是与原张量共享内存 |
torch.transpose(t, 0, 2) |
交换张量的两个维度,常用于图像的预处理 |
torch.t() |
针对二维张量的转置 ,等于torch.transpose(t, 0, 1) |
torch.squeeze(t, dim) |
参数dim = None时,移除所有长度为1的轴, 指定dim且其长度为1的轴可以移除 |
torch.unsqueeze(t_2, dim=3) |
unsqueeze用于拓展维度,拓展后维度为1 |
加减乘除
函数(t为tensor对象) |
作用 |
torch.add(t1, alpha=1, t2) |
逐元素计算,out = t1 + alpha * t2 |
torch.sub(t1, alpha=1, t2) |
逐元素计算,out = t1 - alpha * t2 |
torch.div(t1, alpha=1, t2) |
逐元素计算,out = t1 / alpha * t2 |
torch.mul(t1, alpha=1, t2) |
逐元素计算,out = t1 * alpha * t2 |
torch.addcdiv(t1, alpha=1, t2, t3) |
逐元素计算,out = t1 + alpha * t2/t3 |
torch.addcmul(t1, alpha=1, t2, t3) |
逐元素计算,out = t1 + alpha * t2 *t3 |
使用张量实现简单线性模型
import torch
import matplotlib.pyplot as plt
import numpy as np
iterations = 30000
lr = 0.1
X = torch.rand(100, 1) * 10
y = 2 * X + (5 + torch.randn(100, 1))
w = torch.randn(1, requires_grad=True)
b = torch.full_like(w, 4, requires_grad=True)
losses = []
for time in range(iterations):
wx = torch.mul(w, X)
y_pre = torch.add(wx, b)
loss = (0.5 * (y - y_pre).mean()) ** 2
loss.backward()
b.data -= lr * b.grad.data
w.data -= lr * w.grad.data
if time % 10 == 0:
lr = lr * 299/300
if time % 200 == 0:
losses.append(loss)
print([time, loss.data, w.data, b.data, lr])
if time % 2000 == 0:
plt.scatter(X.data.numpy(), y.data.numpy())
plt.plot(X.data.numpy(), y_pre.data.numpy(), 'r-', lw=3)
plt.text(4, 10, 'Loss = %.4f' % loss.data.numpy(), fontdict={
'size': 20, 'color': 'red'})
plt.xlim(0, 11)
plt.ylim(0, 27.5)
plt.title("Iterations: {}\n w:{} b:{}".format(time, w.data.numpy(), b.data.numpy()))
plt.show()
plt.close()
x_index = np.arange(0, 30000, 200)
plt.plot(x_index, np.array(losses), 'r--', lw=2)
plt.xlim(0, 30000)
plt.ylim(0, 15)
plt.title('Loss')
plt.show()