pytorch官方案例(2)-Tensors基本操作

Tensors

tensors(张量)时一个特殊的数据结构他和矩阵数组相似。在pytorch中使用tensor作为模型的输入,输出,参数。

1. 初始化Tensor

  • 直接来自数据
  • numpy转换
  • 另一个tensor转换
  • 随机值或常数
import torch
import numpy as np
# 直接来自数据
data = [[1,2],[3,4]]
x_data = torch.tensor(data)

# numpy转换
np_array = np.array(data)
x_np = torch.from_numpy(np_array)

# 来自另一个tensor
x_ones =torch.ones_like(x_data)     #保留x_data的属性
x_rand = torch.rand_like(x_data, dtype=torch.float) #覆写x_data的dtype属性
print(f"全一Tensor: \n {x_ones} \n")
print(f"随机Tensor: \n {x_rand} \n")

输出:

# 随机数或者常数

shape = (2,3,)      # shape是tensor的维度元组, 它决定了输出的tensor的维度
rand_tensor  = torch.rand(shape)    #随机tensor
ones_tensor = torch.ones(shape)     #全一的tensor
zeros_tensor = torch.zeros(shape)   #全0的tensor

print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")

输出:

2. Tensor的属性

Tensor的属性描述的他们的形状,数据类型和存储设备(shape, dtype, device)

tensor  = torch.rand(3,4)

print(f"Tensor的形状:{tensor.shape}")
print(f"tensor的数据类型:{tensor.dtype}")
print(f"tensor的存储在:{tensor.device}")

3. Tensor的操作

tensor的操作包括算术运算,线性代数运算,矩阵处理(转置,索引,切片),采样。具体可参考官网。
这些操作可以上GPU上运行(通常会比CPU快点),默认tensor是创建在cpu上,可以使用to(device)的方法把张量转移到gpu上。跨设备复制张量可能会浪费时间和内存。

# 如果需要把tensor转移到GPU上
device = "cuda" if torch.cuda.is_available() else "cpu" #检查是否有cuda
tensor.to(device)


索引和切片

tensor =torch.arange(0,16).view(4,4)    #生成从0到15,4*4矩阵
print("原始数据:",tensor)
print('第一行: ',tensor[0])
print('第一列: ', tensor[:, 0])
print('最后一列:', tensor[..., -1])
tensor[:,1] = 0                 # 第二列置0
print(tensor)


连接操作
使用tensor.cat()将tensor按照指定维度连接

t1 = torch.cat([tensor,tensor,tensor], dim=1)  #列连接
print(t1)

算数操作

# 矩阵乘法,下列计算是等价得
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)

y3 = torch.ones_like(tensor)
torch.matmul(tensor,tensor.T,out=y3)
print(f"y1: {y1}")
print(f"y2: {y2}")
print(f"y3: {y3}")

# 按元素相乘
z1 = tensor * tensor
z2 = tensor.mul(tensor)

z3 = torch.ones_like(tensor)
torch.mul(tensor, tensor, out=z3)
print(f"z1: {z1}")
print(f"z2: {z2}")
print(f"z3: {z3}")


就地操作(in-place operation)
将结果存储到操作数中得操作称为就地操作,他们通常形式如a_后缀,例如:x.copy_(y), x.t_(), 将会改变x

print(tensor,"\n")
tensor.add_(5)
print(tensor)

4. Tensor与numpy的转换

张量在CPU和NumPy数组上可以共享它们的底层内存位置,改变一个就会改变另一个

# Tensor to Numpy
t = torch.ones(5)
print(f"t: {t}")

n = t.numpy()
print(f"n: {n}")

t.add_(1)
print(f"t: {t}")
print(f"n: {n}")

# Numpy  to tensor
n = np.ones(5)
t = torch.from_numpy(n)

np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")

5. 小试牛刀:线性回归

线性回归是机器学习入门知识,应用十分广泛。线性回归利用数理统计中回归分析,
来确定两种或两种以上变量间相互依赖的定量关系的,其表达形式为 y = w x + b y = wx+b y=wx+b
首先让我们来确认线性回归的损失函数:
l o s s = ∑ i N 1 2 ( y i − ( w x i + b ) ) 2 loss = \sum_i^N\frac{1}{2}(y_i-(wx_i+b))^2 loss=iN21(yi(wxi+b))2
然后利用随机梯度下降法更新参数 w \textbf{w} w b \textbf{b} b来最小化损失函数,最终学得 w \textbf{w} w b \textbf{b} b的数值。

import torch as t
%matplotlib inline
from matplotlib import pyplot as plt
from IPython import display

# 设置随机数种子,保证每次输出的结果一致
t.manual_seed(1000)

def get_fake_data(batch_size):
    '''随机产生: y = 2x+3,再加上一些噪声'''
    x = t.rand(batch_size,1,device=device) * 5
    y = x * 2 + 3 + torch.randn(batch_size,1, device=device)
    return x,y

# 看看xy的分布
x, y = get_fake_data(100)
plt.scatter(x.squeeze().cpu().numpy(),y.squeeze().cpu().numpy())

# 随机初始化参数
w = t.rand(1,1).to(device)
b = t.zeros(1,1).to(device)

lr = 0.01 #学习率

for i in range(500):
    x , y = get_fake_data(batch_size=4)
    x, y = x.to(device),y.to(device)
    # 1.前向计算
    y_pred = torch.matmul(x,w) + b

    # 2.计算损失
    loss = 0.5 * (y_pred - y) ** 2  #均方误差
    loss = loss.mean()

    # 3.反向传播
    dloss = 1
    dy_pred = dloss * (y_pred-y)

    dw = torch.matmul(x.t(), dy_pred)   #dw = dl/d
    db = dy_pred.sum()

    # 更新参数
    w = w - lr * dw
    b = b - lr * db
    if i % 50 ==0 :
        # 画图
        plt.cla()
        display.clear_output(wait=True)
        x = t.arange(0,6,dtype=t.float).view(-1,1).to(device)
        y = torch.matmul(x, w) +b
        plt.plot(x.cpu().numpy(), y.cpu().numpy(),'r-',lw=5)  #画出预测结果

        x3, y3 = get_fake_data(batch_size=32)
        plt.scatter(x3.cpu().numpy(), y3.cpu().numpy()) # true data
        plt.xlim(0, 5)
        plt.ylim(0, 13)
        plt.show()
        plt.pause(0.5)

print("w:",w.item(),"b: ",b.item())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值