ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Pytorch 代码练习

2021-10-06 22:02:49  阅读:204  来源: 互联网

标签:torch tensor nn pred 代码 练习 Pytorch print model


一、Pytorch:

一般定义数据使用torch.Tensor

1.torch有许多创建函数:如empty,ones, zeros, eye, arange, linspace, rand, randn, normal, uniform, randperm等,可以直接创建所需的张量、数字、矩阵等,具体使用方法可以百度

2.Tensor支持各种各样类型的数据:torch.float32, torch.float64, torch.float16, torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64,并使用dtype改变数据类型。

 

以下是一些运行代码和截图:

import torch
# 可以是一个数
x = torch.tensor(666)
print(x)
# 可以是一维数组(向量)
x = torch.tensor([1,2,3,4,5,6])
print(x)
# 可以是二维数组(矩阵)
x = torch.ones(2,3)
print(x)
# 可以是任意维度的数组(张量)
x = torch.ones(2,3,4)
print(x)
# 创建一个空张量
x = torch.empty(5,3)
print(x)
# 创建一个随机初始化的张量
x = torch.rand(5,3)
print(x)
# 创建一个全0的张量,里面的数据类型为 long
x = torch.zeros(5,3,dtype=torch.long)
print(x)
# 基于现有的tensor,创建一个新tensor,
# 从而可以利用原有的tensor的dtype,device,size之类的属性信息
y = x.new_ones(5,3)   #tensor new_* 方法,利用原来tensor的dtype,device
print(y)
z = torch.randn_like(x, dtype=torch.float)    # 利用原来的tensor的大小,但是重新定义了dtype
print(z)

警告:

torch.tensor() 总是拷贝 data. 如果你有一个 Tensor data 并且仅仅想改变它的 requires_grad 属性, 可用 requires_grad_() or detach() 来避免拷贝. 如果你有一个 numpy 数组并且想避免拷贝, 请使用 torch.as_tensor().

image-20211005230426255

 

image-20211005230641519

支持向量的内积、矩阵转置等,算术运算有广播机制

image-20211005230754344

Tensor可以利用randn()函数生成均值为0,方差为1的随机数,并利用matlabplotlib的库函数来生成图像

image-20211005230854738

tensor的cat()函数可以实现两个矩阵在0轴方向(Y)或1轴方向(X)的拼接,并得到新的矩阵

 

二.螺旋数据分类:

image-20211005232413771

首先是下载plot_lib.py,再import所需的函数和库

运行结果:device: cuda:0

初始化 X 和 Y。 X 可以理解为特征矩阵,Y可以理解为样本标签。 结合代码可以看到,X的为一个 NxC 行, D 列的矩阵。C 类样本,每类样本是 N个,所以是 N*C 行。每个样本的特征维度是2,所以是 2列。

在 python 中,调用 zeros 类似的函数,第一个参数是 y方向的,即矩阵的行;第二个参数是 x方向的,即矩阵的列。

image-20211005232544728

1.构建线性模型分类

learning_rate = 1e-3
lambda_l2 = 1e-5
​
# nn 包用来创建线性模型
# 每一个线性模型都包含 weight 和 bias
model = nn.Sequential(
    nn.Linear(D, H),
    nn.Linear(H, C)
)
model.to(device) # 把模型放到GPU上
​
# nn 包含多种不同的损失函数,这里使用的是交叉熵(cross entropy loss)损失函数
criterion = torch.nn.CrossEntropyLoss()
​
# 这里使用 optim 包进行随机梯度下降(stochastic gradient descent)优化
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, weight_decay=lambda_l2)
​
# 开始训练
for t in range(1000):
    # 把数据输入模型,得到预测结果
    y_pred = model(X)
    # 计算损失和准确率
    loss = criterion(y_pred, Y)
    score, predicted = torch.max(y_pred, 1)
    acc = (Y == predicted).sum().float() / len(Y)
    print('[EPOCH]: %i, [LOSS]: %.6f, [ACCURACY]: %.3f' % (t, loss.item(), acc))
    display.clear_output(wait=True)
​
    # 反向传播前把梯度置 0 
    optimizer.zero_grad()
    # 反向传播优化 
    loss.backward()
    # 更新全部参数
    optimizer.step()

 

运行结果:[EPOCH]: 999, [LOSS]: 0.861541, [ACCURACY]: 0.504

image-20211006211627943

使用 print(y_pred.shape) 可以看到模型的预测结果,为[3000, 3]的矩阵。每个样本的预测结果为3个,保存在 y_pred 的一行里。值最大的一个,即为预测该样本属于的类别

score, predicted = torch.max(y_pred, 1) 是沿着第二个方向(即X方向)提取最大值。最大的那个值存在 score 中,所在的位置(即第几列的最大)保存在 predicted 中。下面代码把第10行的情况输出,供解释说明

此外,大家可以看到,每一次反向传播前,都要把梯度清零

image-20211005234133300

print(y_pred.shape)
print(y_pred[10, :])
print(score[10])
print(predicted[10])
# Plot trained model
print(model)
plot_model(X, Y, model)

 

上面使用 print(model) 把模型输出,可以看到有两层:

  • 第一层输入为 2(因为特征维度为主2),输出为 100;

  • 第二层输入为 100 (上一层的输出),输出为 3(类别数)

从上面图示可以看出,线性模型的准确率最高只能达到 50% 左右,对于这样复杂的一个数据分布,线性模型难以实现准确分类。

2.构建两层神经网络分类

添加一层神经网络,利用 ReLU作为 激活函数

learning_rate = 1e-3
lambda_l2 = 1e-5
​
# 这里可以看到,和上面模型不同的是,在两层之间加入了一个 ReLU 激活函数
model = nn.Sequential(
    nn.Linear(D, H),
    nn.ReLU(),
    nn.Linear(H, C)
)
model.to(device)
​
# 下面的代码和之前是完全一样的,这里不过多叙述
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=lambda_l2) # built-in L2
​
# 训练模型,和之前的代码是完全一样的
for t in range(1000):
    y_pred = model(X)
    loss = criterion(y_pred, Y)
    score, predicted = torch.max(y_pred, 1)
    acc = ((Y == predicted).sum().float() / len(Y))
    print("[EPOCH]: %i, [LOSS]: %.6f, [ACCURACY]: %.3f" % (t, loss.item(), acc))
    display.clear_output(wait=True)
    
    # zero the gradients before running the backward pass.
    optimizer.zero_grad()
    # Backward pass to compute the gradient
    loss.backward()
    # Update params
    optimizer.step()

 

运行结果::[EPOCH]: 999, [LOSS]: 0.213117, [ACCURACY]: 0.926

 

image-20211005235808828

ReLU函数速度快精度高,逐渐取代了Sigmoid函数。在两层神经网络里加入 ReLU 激活函数以后,分类的准确率得到了显著提高,

 

标签:torch,tensor,nn,pred,代码,练习,Pytorch,print,model
来源: https://www.cnblogs.com/Dracula-Zs/p/15374282.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有