Pytorch - 关于张量

张量简介

张量(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) 创建正态分布1
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()函数获得2

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

使用张量实现简单线性模型

# -*- coding: utf-8 -*-
# @Author  : Yao Gq
# @FileName: Line_regression_mpdel .py
# @Time    : 2020/9/3 18:01
# @Software: PyCharm

# 建立线性回归模型

import torch
import matplotlib.pyplot as plt
import numpy as np

# torch.manual_seed(10)

iterations = 30000   # 训练次数
lr = 0.1             # 学习率

X = torch.rand(100, 1) * 10
y = 2 * X + (5 + torch.randn(100, 1))   # w_std = 2, b_std = 5

# 构建线性回归参数

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()  # 显示变化曲线

过程截图

损失函数变化


  1. mean和std可以是标量或张量,但是当mean和std都是标量的时候,需要添加shape属性,如torch.normal(0, 1, (3, 3)) ↩︎

  2. index与mask均为张量。 ↩︎

猜你喜欢

转载自blog.csdn.net/seek0226/article/details/108340063