首页 > 其他分享 >第二章 Pytorch基础

第二章 Pytorch基础

时间:2024-04-13 09:44:25浏览次数:22  
标签:loss tensor nn 10 self torch 基础 Pytorch 第二章

2.1 Pytorch 张量

学习心得:

标量是0维张量
向量可以表示一维张量(轴0)
形状(4,)
二维矩阵表示二维张量(上到下轴0,左到右轴1)
形状(4,3)
三维维矩阵表示三维张量(上到下轴0,左到右轴1,外到内轴2)
形状(4,3,2)

初始化张量

import torch
x = torch.tensor([[1,2]])
y = torch.tensor([[1],[2]])

print(x.shape)
# torch.Size([1,2]) # one entity of two items
print(y.shape)
# torch.Size([2,1]) # two entities of one item each

torch.zeros(3, 4)
# tensor([[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]])
torch.ones(3, 4)
# tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]])
torch.randint(low=0, high=10, size=(3,4))
# tensor([[8, 2, 5, 9],
        [6, 1, 6, 0],
        [5, 6, 9, 5]])
torch.rand(3, 4) # 0-1之间随机
# tensor([[0.3196, 0.9387, 0.9268, 0.1246],
        [0.6700, 0.7529, 0.8687, 0.3948],
        [0.2279, 0.2309, 0.0151, 0.0339]])
torch.randn(3,4) # 服从正态分布的随机
# tensor([[-0.4039, -1.8015,  0.9784, -1.5263],
        [ 0.9577, -1.2826,  0.2746, -0.2621],
        [-1.4713,  0.6437,  0.3326, -1.0703]])

x = np.array([[10,20,30],[2,3,4]])
# np.ndarrary
y = torch.tensor(x)
# 将numpy转换为张量
print(type(x), type(y))
# <class 'numpy.ndarray'> <class 'torch.Tensor'>

张量运算

x = torch.tensor([[1,2,3,4], [5,6,7,8]]) 
print(x * 10)
# tensor([[10, 20, 30, 40],
#         [50, 60, 70, 80]])

x = torch.tensor([[1,2,3,4], [5,6,7,8]]) 
y = x.add(10)
print(y)
#tensor([[11, 12, 13, 14],
#        [15, 16, 17, 18]])

重塑张量

y = torch.tensor([2, 3, 1, 0]) 
y = y.view(4,1)
y 

# tensor([[2],
    [3],
    [1],
    [0]])

#另一种重塑方法squeeze方法,只适合在某个轴上数值为1才行
x = torch.randn(10,1,10)# 三维张量轴0,轴1 轴2
z1 = torch.squeeze(x, 1) # 1表示轴为1
# z1 = x.squeeze(1)
z1.shape
# torch.Size([10, 10])

x = torch.randn(10,1,10)# 三维张量轴0,轴1 轴2
z1 = torch.unsqueeze(x, 0) # 1表示轴为1
# z1 = x.unsqueeze(0)
# torch.Size([1,10,10])

除了unsqueeze也可以用None见下

z2, z3, z4 = x[None,:,:], x[:,None,:], x[:,:,None]
# torch.Size([1, 10, 10]) 
torch.Size([10, 1, 10]) 
torch.Size([10, 10, 1])

张量的矩阵乘法

y = torch.tensor([2, 3, 1, 0])
x = torch.tensor([[1,2,3,4], [5,6,7,8]])
print(torch.matmul(x, y))
# 或者 print(x@y)

张量的连接

x = torch.randn(10,10,10)
z = torch.cat([x,x], axis=0) # np.concatenate()
print('Cat axis 0:', z.shape)
# torch.Size([20, 10, 10])

提取张量最大值

x = torch.arange(25).reshape(5,5)
print('Max:', x.shape, x.max())    
# Max: torch.Size([5, 5]) tensor(24)

x.max(dim=0)# 轴0上的最大值
# torch.return_types.max(
values=tensor([20, 21, 22, 23, 24]),
indices=tensor([4, 4, 4, 4, 4]))

x.max(dim=1)# 轴1上的最大值
# torch.return_types.max(
values=tensor([ 4,  9, 14, 19, 24]),
indices=tensor([4, 4, 4, 4, 4]))

置换张量维数(不要通过重塑张量来交换维数)

x = torch.randn(10,20,30)# (0,1,2)
z = x.permute(2,0,1) # np.permute()
print('Permute dimensions:',z.shape)
# torch.Size([30, 10, 20])

dir(torch.Tensor)

查看张量方法

help(torch.Tensor.<method>)

对某个方法查看如何使用

2.2 张量的自动梯度

x = torch.tensor([[2., -1.], [1., 1.]], requires_grad=True)
# requires_grad=True 参数指定为张量对象计算梯度
# tensor([[ 2., -1.],
    [ 1.,  1.]], requires_grad=True)
out = x.pow(2).sum()
out.backward()
# 计算out的梯度
x.grad
# 得到out 关于 x 的梯度
# tensor([[ 4., -2.],
          [ 2.,  2.]])

一般来说,在CPU上使用Torch张量运算仍然比Numpy要快
torch的GPU最快

2.3 Pytorch构建神经网络

import torch
x = [[1,2],[3,4],[5,6],[7,8]]
y = [[3],[7],[11],[15]]

# 转换为浮点对象
X = torch.tensor(x).float()
Y = torch.tensor(y).float()
print(X,Y)

# 将数据注册到GPU
device = 'cuda' if torch.cuda.is_available() else 'cpu'
X = X.to(device)
Y = Y.to(device)

# 定义网络架构
import torch.nn as nn

# 对nn.Module的继承是强制的因为是神经网络的基类
# 必须利用super().__init__()来确保继承nn.Module就可以利用事先编写好的功能
class MyNeuralNet(nn.Module):
def __init__(self):
    super().__init__()
    self.input_to_hidden_layer = nn.Linear(2,8)#等价于 nn.Parameter(torch.rand(2,8))
    # 具体为Linear(in_features = 2 , out_features = 8 , bias = True)
    self.hidden_layer_activation = nn.ReLU()
    self.hidden_to_output_layer = nn.Linear(8,1)# nn.Parameter(torch.rand(8,1))
# 必须使用forward作为方法名,因为Pytorch保留了,用其他的会报错!!!
def forward(self, x):
    x = self.input_to_hidden_layer(x)
    #若 nn.Parameter(torch.rand(2,8)),则x = x @ self.input_to_hidden_layer(x)
    x = self.hidden_layer_activation(x)
    x = self.hidden_to_output_layer(x)
    #若 nn.Parameter(torch.rand(8,1)),则x = x @ self.hidden_to_output_layer(x)
    return x

# 创建实例并注册到GPU上
mynet = MyNeuralNet().to(device)

# 获取参数权重看一下
mynet.input_to_hidden_layer.weight

# 更详细的看下参数
mynet.parameters()
for i in  mynet.parameters():
    print(i)

# 定义MSE损失
loss_func = nn.MSELoss()
# CrossEntropyLoss() # 多分类损失
# BCELoss # 二分类损失

# 计算损失
_Y = mynet(X)
loss_value = loss_func(_Y,Y)
# 在pytorch中约定先传预测,再传真实数据
print(loss_value)

# 优化器随机梯度下降
from torch.optim import SGD
opt = SGD(mynet.parameters(), lr = 0.001)   

loss_history = []
for _ in range(50):
    opt.zero_grad()# 刷新上一步计算的梯度
    loss_value = loss_func(mynet(X),Y)
    loss_value.backward()# 计算梯度
    opt.step()# 根据梯度更新权重
    loss_history.append(loss_value.item())

# 绘图
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(loss_history)
plt.title('Loss variation over increasing epochs')
plt.xlabel('epochs')
plt.ylabel('loss value')

2.4 数据集、数据加载器和批大小

批大小:用于计算损失或更新权重的数据点的数量
在有数百万数据点的情况下很有用,

class MyDataset(Dataset):
    def __init__(self,x,y):
        self.x = torch.tensor(x).float()
        self.y = torch.tensor(y).float()
    def __len__(self):
        return len(self.x)
    def __getitem__(self, ix):
        return self.x[ix], self.y[ix]
ds = MyDataset(X, Y)

# 从ds中获取两个数据点
dl = DataLoader(ds, batch_size=2, shuffle=True)

# 其余没变可套用上方代码
# 变化见下
import time
loss_history = []
start = time.time()
for _ in range(50):
    for data in dl:
        x, y = data
        opt.zero_grad()
        loss_value = loss_func(mynet(x),y)
        loss_value.backward()
        opt.step()
        loss_history.append(loss_value)
end = time.time()
print(end - start)

预测数据点

val_x = [[10,11]]
val_xf = torch.tensor(val_x).float().to('device')
mynet(val_x)

自定义损失函数

def my_mean_squared_error(_y, y):
    loss = (_y-y)**2
    loss = loss.mean()
    return loss

my_mean_squared_error(mynet(X),Y)
# 和这个效果一样 
loss_func = nn.MSELoss()
loss_value = loss_func(mynet(X),Y)
print(loss_value)

获取中间层的值(获取参数上面讲了)

# 种子
torch.random.manual_seed(10)

# 法1
input_to_hidden = mynet.input_to_hidden_layer(X)
hidden_activation = mynet.hidden_layer_activation(input_to_hidden)
x = mynet.hidden_to_output_layer(hidden_activation)
x

# 法2 改下类的forward函数
class MyNeuralNet(nn.Module):
def __init__(self):
    super().__init__()
    self.input_to_hidden_layer = nn.Linear(2,8)
    self.hidden_layer_activation = nn.ReLU()
    self.hidden_to_output_layer = nn.Linear(8,1)
def forward(self, x):
    hidden1 = self.input_to_hidden_layer(x)
    hidden2 = self.hidden_layer_activation(hidden1)
    x = self.hidden_to_output_layer(hidden2)
    return x, hidden1

# 调用
_Y, _Y_hidden = mynet(X)

2.5 使用Sequential类构建神经网络

之前是通过定义一个类来构建神经网络,

model = nn.Sequential(
nn.Linear(2, 8),
nn.ReLU(),
nn.Linear(8, 1)
).to(device)

# 这个包可以输出一个模型的摘要(总体架构)
!pip install torch_summary
from torchsummary import summary

# 输入模型和模型大小
summary(model, torch.zeros(2,2))

# 其余没变化除了模型名称
loss_func = nn.MSELoss()
from torch.optim import SGD
opt = SGD(model.parameters(), lr = 0.001)
import time
loss_history = []
start = time.time()
for _ in range(50):
    for ix, iy in dl:
        opt.zero_grad()
        loss_value = loss_func(model(ix),iy)
        loss_value.backward()
        opt.step()
        loss_history.append(loss_value)
end = time.time()
print(end - start)

# 预测新数据
val = [[8,9],[10,11],[1.5,2.5]]
val = torch.tensor(val).float().to(device)
model(val)

2.6 保存并加载Pytorch模型

保存模型

save_path = 'mymodel.pth'
torch.save(model.state_dict(), save_path)
# torch.save(model.state_dict(), 'mymodel.pth')
# state指的是模型的当前快照
# model.state_dict()返回一个字典

# 注:一个良好的保存做法是在调用torch.save()
之前将模型注册到CPU中,有助于模型加载到任何机器上(助人为乐)
# 所以可以torch.save(model.to('cpu').state_dict(), save_path)

加载模型

# 加载模型前需要事先对模型进行权重初始化
model = nn.Sequential(
        nn.Linear(2, 8),
        nn.ReLU(),
        nn.Linear(8, 1)
).to(device)

# 然后再加载参数
state_dict = torch.load('mymodel.pth')
model.load_state_dict(state_dict)

# 预测数据
val = [[8,9],[10,11],[1.5,2.5]]
val = torch.tensor(val).float().to(device)
model(val)

标签:loss,tensor,nn,10,self,torch,基础,Pytorch,第二章
From: https://www.cnblogs.com/dxlindex/p/18132024

相关文章

  • HarmonyOS-基础之联系人案例
    使用前面学习的相关组件和api实现联系人的CRUD;效果如下父组件import{Contacts}from'../domain/Model'importContactsItemfrom'../components/ContactsItem'@Entry@ComponentstructContactsExample{//联系人数组@StatecontactsArr:Contacts[]=[......
  • C++ 解引用与函数基础:内存地址、调用方法及声明
    C++解引用获取内存地址和值在上一页的示例中,我们使用了指针变量来获取变量的内存地址(与引用运算符&一起使用)。但是,你也可以使用指针来获取变量的值,这可以通过使用*运算符(解引用运算符)来实现:stringfood="Pizza";//变量声明string*ptr=&food;//指针声明//引用......
  • 基础组合数学
    byTheBigYellowDuck联赛前恶补知识点...排列数&组合数从\(n\)元集合中选出\(m\)个元素的有序排列数记为\(A_n^m\)。计算公式为\[\displaystyleA_n^m=n(n-1)(n-2)\cdots(n-m+1)=\dfrac{n!}{(n-m)!}\]从\(n\)元集合中选出\(m\)个元素的无序排列数记为\(C_n^m\),......
  • 基础数论
    byTheBigYellowDuck联赛前恶补知识点...欧拉函数欧拉函数\(\varphi(n)\)表示\(1\simn\)中与\(n\)互质的数的个数。欧拉函数是积性函数。特殊地,\(\varphi(1)=1\)。对于质数\(p\)显然有\(\varphi(p)=p-1\)。一些常用的结论:设\(p\)是质数,则\(\varphi(p^k)=p^k......
  • 第一章 人工神经网络基础
    1.1人工智能与传统机器学习学习心得:传统机器学习(ML):需要专业的主题专家人工提取特征,并通过一个编写良好的算法来破译给定的特征,从而判断这幅图像中的内容。输入-->人工提取特征-->特征-->具有浅层结构的分类器-->输出当存在欺骗性的图片出现时可能会失效,我们需要创建能够精细......
  • Java基础知识篇02——封装
    大家好,我是白夜,今天给大家聊聊面向对象的三大特征——封装一、包(package)1.1、包的引入先来看看我们之前写的代码结构以上代码存在的问题所有类写在一个目录下面,非常难管理,因为以后项目不可能只有这么几个类,当类数量很大的时候,就不容易管理了。不能写同名但是不同需求的类......
  • 实验2 C语言分支与循环基础应用编程 王刚202383310053
    1#include<stdio.h>2#include<stdlib.h>3#include<time.h>4#defineN55intmain()6{7intnumber,i;8srand(time(0));9for(i=0;i<N;i++)10{number=rand()%65+1;11printf("20238331%04d\n",number);12}13sy......
  • 软件工程基础——第一次实验
    一.原型工具优缺点对比1.墨刀适用领域:墨刀适用于快速原型设计和团队协作。它的界面简洁易用,支持多种交互和动画效果,适合用于移动应用和网页的设计。墨刀是一款在线原型设计与协同工具,借助墨刀,产品经理、设计师、开发、销售、运营及创业者等用户群体,能够搭建为产品原型,演示项目......
  • MySQL基础
    1,初识SQL语句SQL语句:操作文件夹(库) 增 createdatabasedb1charsetutf8; 查 showcreatedatabasedb1; showdatabases; 改 alterdatabasedb1charsetgbk; 删 dropdatabasedb1;操作文件(表) 切换文件夹:usedb1; 查看当前所在文件夹:selectdatabase(); ......
  • redis基础
    redis数据类型redis可以理解成一个全局的大字典,key就是数据的唯一标识符。根据key对应的值不同,可以划分成5个基本数据类型。redis={"name":"yuan","scors":["100","89","78"],"info":{"name":"rain"......