pytorch入门笔记01

本文档详细介绍了PyTorch中的张量概念,包括标量、向量、矩阵、三维张量和四维张量等,并展示了张量的切片、加法、乘法、形状变换以及与numpy之间的转换。此外,还讨论了GPU上张量运算的效率优势和模型的保存与加载方法。
摘要由CSDN通过智能技术生成

Pytorch 张量

该笔记从02开始后面是pytorch官网上的60分钟入门篇,我自己翻译的,翻译的不太好,凑活看哈哈哈。。。

标量(0D)

只包含一个元素的张量为标量。类型通常为FloatTensor或LongTensor

import torch
x = torch.rand(10)
x.size()

向量(1D)

import torch
x = torch.FloatTensor([1.0,2.0,3.0,4.0])

out:

torch.Size([4])

矩阵(2D)

x = torch.FloatTensor([[1,2],[3,4]])
print(x.size())

out:

torch.Size([2, 2])

三维向量

多个矩阵累加在一起。比如一张图片,有三个通道,每个通道都有一个矩阵。此处的pic2.jpg是一个28x28x3的图片。

import numpy as np
import torch
import cv2 as cv
src = cv.imread('../pic2.jpg')
matrix = np.array(src)
tensor = torch.from_numpy(matrix)
print(tensor.size())

out:

torch.Size([28, 28, 3])

切片张量

这里和python的用法一样

sales = torch.FloatTensor([1.0,2.0,3.0,4.0,5.0])
print(sales[:2])

out:

tensor([1., 2.])

对于前面的如果需要其中一个通道。一种用切片向量,一种用opencv的split方法。

import numpy as np
import torch
import cv2 as cv
src = cv.imread('../pic2.jpg')
matrix = np.array(src)
tensor = torch.from_numpy(matrix)
#切片
qp_tensor = tensor[:,:,0]
print(qp_tensor.size)

#opencv方法
b,g,r = cv.split(src)

4维张量

对于多张图片,批处理那种

5维张量

视频数据。

GPU上的张量

import torch
import time
a = torch.rand(10000,10000)
b = torch.rand(10000,10000)

cpustart = time.time()
a.matmul(b)
cpuEnd = time.time()
#将张量转移到GPU
a = a.cuda()
b = b.cuda()

gpustart = time.time()
a.matmul(b)
gpuEnd = time.time()

print("CPU cost: " + str(cpuEnd - cpustart))
print("GPU cost: " + str(gpuEnd - gpustart))

out:

CPU cost: 7.888931035995483
GPU cost: 0.1765275001525879

常见的方法

判断GPU是否可用

if torch.cuda.is_available():
    tensor = tensor.to('cuda')
    print(f"device tensor is stored on: {tensor.device}")

生成空矩阵

没有初始化

import torch
# 构造一个5 x 3的矩阵,没有初始化
x = torch.empty(5,3)
print(x)

out:

tensor([[9.3673e-39, 9.5511e-39, 1.0194e-38],
[4.2246e-39, 1.0286e-38, 1.0653e-38],
[1.0194e-38, 8.4490e-39, 1.0469e-38],
[9.3674e-39, 9.9184e-39, 8.7245e-39],
[9.2755e-39, 8.9082e-39, 9.9184e-39]])

随机初始化

# 构造一个随机初始化的矩阵
x1 = torch.rand(5,3)

out:

tensor([[0.4749, 0.0095, 0.4786],
[0.5207, 0.4228, 0.0364],
[0.8313, 0.9352, 0.6975],
[0.2701, 0.5206, 0.8709],
[0.3670, 0.3378, 0.9704]])

创建零矩阵

# 构造一个矩阵全为0,数据类型是long类型的
x2 = torch.zeros(5,3,dtype=torch.long)

out:

tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])

构造一个张量

#构造一个张量,直接使用数据
x3 = torch.tensor([5.5,3])

out:

tensor([5.5000, 3.0000])

基于一个已存在的tensor创建一个

# 创建一个tensor基于已经存在的tensor
x4 = x.new_ones(5,3,dtype=torch.double)
#Tensor.new_ones 返回一个与size大小相同的用1填充的张量,
#默认情况下,返回的Tensor具有次张量相同的torch.dtype和torch.device

# randn_like,基于已存在的tensor,创建随机相似的
x5 = torch.randn_like(x4,dtype=torch.float)
print(x4)
print(x5)

out:

tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-0.7830, 0.2870, 0.3721],
[ 0.2931, 0.4255, 0.3800],
[-0.1016, 0.6011, -0.7567],
[ 0.4526, -1.0510, -0.4116],
[ 1.4605, 1.4378, 0.4322]])

获取维度信息

#获取维度信息
print(x5.size())

out:

torch.Size([5, 3])

加法

#######################加法####################
y1 = torch.ones(5,3) #创建一个全是1的矩阵
print(x4 + y1)
x6 = torch.add(x4,y1)
torch.add(x4,y1,out=x) #提供输出tensor作为参数
#还可以in-place
y1.add_(x4)

# 任何使张量发生变化的操作都有一个前缀'_'

out:

tensor([[2., 2., 2.],
[2., 2., 2.],
[2., 2., 2.],
[2., 2., 2.],
[2., 2., 2.]])

numpy一样标准的索引和切片

import torch
tensor = torch.ones(4,4)
tensor[:,1] = 0
print(tensor)

out:

tensor([[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.],
[1., 0., 1., 1.]])

乘法

a = torch.rand(2,2)
b = torch.rand(2,2)
#乘法 对应位置相乘
print(a * b)
print(a.mul(b))
#自身乘法,相当于a = a * b
print(a.mul_(b))
print(a)

矩阵乘法计算,行乘列求和的那种

mul = tensor.matmul(tensor.t())
mul2 = tensor @ tensor.t()
print(mul)
print(mul2)

out:

tensor([[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.]])
tensor([[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.],
[3., 3., 3., 3.]])

连接张量

连接张量可以使用torch.cat。 将给定维数的张量顺序连接起来,也可以用torch.stack,另一种张量连接,略有不同

t1 = torch.cat([tensor,tensor],dim=1)
print(t1)

out:

tensor(

​ [[1., 0., 1., 1., 1., 0., 1., 1.],
​ [1., 0., 1., 1., 1., 0., 1., 1.],
​ [1., 0., 1., 1., 1., 0., 1., 1.],
​ [1., 0., 1., 1., 1., 0., 1., 1.]])

改变tensor的形状

#改变tensor大小或形状 torch.view
x7 = torch.randn(4,4)
y = x7.view(16)
z = x7.view(-1,8) #尺寸设为-1,表示自己算这个大小
print(x7.size(),y.size(),z.size())

out:

torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

获取标量的值

#如果只有一个tensor,使用item()可以获得这个value
x8 = torch.tensor([1])
print(x8)
print(x8.item())

out:

tensor([1])
1

numpy和tensor相互转换

numpy转pytorch

import numpy as np
import torch
import cv2 as cv
src = cv.imread('../pic2.jpg')
cv.imshow("hello",src)
matrix = np.array(src)
panda_tensor = torch.from_numpy(matrix)
print(panda_tensor.size())

cv.waitKey(0)
cv.destroyAllWindows()

主要是torch.from_numpy()

pytorch转numpy

tensor = torch_data.numpy()
# torch_data是一个tensor

模型的保存和读取

# 保存
def save():
    net1 = torch.nn.Sequential(
        torch.nn.Linear(1,10),
        torch.nn.ReLU(),
        torch.nn.Linear(10,1)
    )
    optimizer = torch.optim.SGD(net1.parameters(),lr=0.5)
    for t in range(100):
        prediction = net1(x)
        loss = F.mse_loss(prediction,y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    torch.save(net1,'net.pkl') # 方式1: 直接保存当前网络
    torch.save(net1.state_dict(),'net_params.pkl') # 方式2: 保存网络中的参数parameters
def restore_net():
    net2 = torch.load('net.pkl') # 加载网络
def restore_params():
    net3 = torch.nn.Sequential(
        torch.nn.Linear(1,10),
        torch.nn.ReLU(),
        torch.nn.Linear(10,1)
    )
    # 通过Parameters加载,由于存储的是参数而不是网络,所以这个需要构建一个和保存时候一样的网络,然后加载参数即可。
    # 加载参数比直接加载网络要快。
    net3.load_state_dict(torch.load('net_params.pkl'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值