第一章-PyTorch基础概念 Pytorch基础学习

课程一览表:
目录
一、.pytorch简介
?二、环境配置
1.pycharm
2.annaconda
3.安装pytorch
三、张量简介与创建
1.张量的概念
2.Tensor——直接创建
3.Tensor——依据数值创建
4.Tensor——依据概率创建
四、张量操作与线性回归
1.张量操作(拼接、切分、索引和变换)
2.张量索引
3.张量变换
4.张量数学运算
5.线性回归
五、计算图与动态度机制
1.计算图
2.pytorch动态图机制
六、autograd与逻辑回归
1.autograd——自动求导系统
2.逻辑回归
一、.pytorch简介 pytorch优点
二、环境配置 1.pycharm 官网下载链接:Download PyCharm: Python IDE for Professional Developers by JetBrains
可以参考这篇博客:PyCharm2021安装教程_学习H的博客-CSDN博客_pycharm2021安装教程
2.annaconda annaconda的下载与安装:annaconda安装_Billie使劲学的博客-CSDN博客
annaconda环境管理:annaconda虚拟环境管理常用指令_Billie使劲学的博客-CSDN博客
3.安装pytorch pytorch的安装(以cuda11.0为例):cuda11.0+pytorch
三、张量简介与创建 1.张量的概念 (1)张量是什么?
(2)Tensor与Variable
Variable是torch.autograd中的数据类型,主要用于封装Tensor,进行求导 。
Variable的五个属性:
data:被包装的Tensor
grad:data的梯度
grad_fn:创建Tensor的Function,是自动求导的关键
requires_grad:指示是否需要梯度
is_leaf:指示是否是叶子结点(张量)
(3)Tensor
PyTorch0.4.0版开始,Variable并入Tensor
张量的主要属性有八个:
其中五个属性在Variable中已经说到 。
dtype:张量的数据类型,如,torch.FloatTensor,torch.cuda.FloatTensor
shape:张量的形状,如(1,3,512,512)->(batch_size,channel,height,width)
device:张量所在设备,GPU/CPU,是加速的关键
张量常用的数据类型:
2.Tensor——直接创建 (1)torch.tensor()
功能:从data创建tensor
data:数据,可以使list,numpy
dtype:数据类型,默认与data的一致
device:所在设备,cuda/cpu 。device=‘cuda’
requires_grad:是否需要梯度
pin_memory:是否存于锁页内存,通常设为false
(2)torch.form_numpy(ndarray)
功能:从numpy创建tensor
注意事项:从torch.from_numpy创建的tensor与原ndarray共享内存,当修改其中一个的数据,另一个也将会被改动 。
3.Tensor——依据数值创建 (1)torch.zeros()
功能:依size创建全0张量
size:张量的形状,如(3,3)、(3,224,224)
out:输出的张量(将输出的张量赋给out,该属性与输出张量的地址是一致的)
layout:内存中布局形式,有strided(默认),sparse_coo(稀疏张量时设置)等
device:所在设备,gpu/cpu
requires_grad:是否需要梯度
out_t = torch.tensor([1])t = torch.zeros((3, 3), out=out_t)print(t, '\n', out_t)print(id(t), id(out_t), id(t) == id(out_t)) (2)torch.zeros_like()
功能:依input形状创建全0张量
input:创建与input同形状的全0张量
dtype:数据类型
layout:内存中布局形式
(3)torch.ones()
功能:创建全1张量
size:张量的形状,如(3,3)、(3,224,224)
(4)torch.ones_like()
功能:依input形状创建全1张量
dtype:数据类型
layout:内存中布局形式
device:所在设备,gpu/cpu
requires_grad:是否需要梯度
(5)torch.full()
功能:依input形状创建全 i 张量
size:张量的形状,如(3,3)
fill_value:张量的值 i
(6)torch.full_like()
(7)torch.arrange()
功能:创建等差的一维张量
注意事项:数值区间为[start,end)
start:数列起始值
end:数列“结束值”
step:数列公差,默认为1
(8)torch.linspace()
功能:创建均分的1维张量
注意事项:数值区间为[start,end)
start:数列起始值
end:数列结束值
steps:数列长度
[步长计算:(end-start)/steps - 1]
(9)torch.logspace()
功能:创建对数均分的1维张量
注意事项:长度为steps,底为base
start:数列起始值
end:数列结束值
steps:数列长度
base:对数函数的底,默认为10
(10)torch.eye()
功能:创建单位对角矩阵(2维张量)
注意事项:默认为方阵
n:矩阵行数(一般只设置行数,列数默认)
m:矩阵列数
4.Tensor——依据概率创建 (1)torch.normal()
功能:生成正态分布(高斯分布)
mean:均值
std:标准差
四种模式:
mean为标量,std为标量
mean为标量,std为张量
mean为张量,std为标量
mean为张量,std为张量
注意事项:当mean和std均为标量时, 应设定size来规定张量的长度
(2)torch.randn()
功能:生成标准正态分布
size:张量的形状
(3)torch.randn_like()
(4)torch.rand()
功能:在区间[0,1)上,生成均匀分布

(5)torch.rand_like()
(6)torch.randint()
功能:区间[low,high)生成证书均匀分布
size:张量的形状
(7)torch.randint_like()
(8)torch.randperm()
功能:生成从0到n-1的随机排列
n:张量的长度
(9)torch.bernoulli()
功能:以input为概率,生成伯努利分布(0-1分布,两点分布)
input:概率值
四、张量操作与线性回归 1.张量操作(拼接、切分、索引和变换) (1)torch.cat()
功能:将张量按维度dim进行拼接
tensors:张量序列
dim:要拼接的维度
(2)torch.stack()
功能:在新创建的维度dim上进行拼接
tensors:张量序列
dim:要拼接的维度
(3)torch.chunk()
功能:将张量按维度dim进行平均切分
返回值:张量列表
注意事项:若不能整除,最后一份张量小于其他张量
input:要切分的张量
chunks:要切分的份数
dim:要切分的维度(在哪个维度进行切分)
(4)torch.split()
功能:将张量按维度dim进行切分
返回值:张量列表
tensor:要切分的张量
split_size_or_sections:为int时,表示每一份的长度;为list时,按list元素切分(和为当前维度的长度,否则报错)
dim:要切分的维度
2.张量索引 (1)torch.index_select()
功能:在维度dim上,按index索引数据
返回值:依index索引数据拼接的张量
input:要索引的张量
dim:要索引的维度
index:要索引数据的序号
注意事项:index的数据类型是long类型
[将索引的张量按在dim进行拼接]
t = torch.randint(0, 9, size=(3, 3))idx = torch.tensor([0, 2], dtype=torch.long)# floatt_select = torch.index_select(t, dim=0, index=idx)print("t:\n{}\nt_select:\n{}".format(t, t_select))(2)torch.masked_select()
功能:按mask中的True进行索引,一般用来筛选数据
返回值:一维张量(因为不能确定张量中True的个数)
input:要索引的张量
mask:与input同形状的布尔类型张量
t = torch.randint(0, 9, size=(3, 3))mask = t.le(5)# ge is mean greater than or equal/gt: greater thanleltt_select = torch.masked_select(t, mask)print("t:\n{}\nmask:\n{}\nt_select:\n{} ".format(t, mask, t_select)) 3.张量变换 (1)torch.reshape()
功能: 变换张量形状
注意事项:当张量在内存中是连续时,新张量与input共享数据内存
input:要变换的张量
shape:新张量的形状
[新张量的大小与原张量要匹配,若维度为-1,则表示该维度不需要关心,它会根据其他维度的大小进行计算]
(2)torch.transpose()
功能:交换张量的两个维度
input:要变换的张量
dim0:要交换的维度
dim1:要交换的维度
(3)torch.t()
功能:2维张量转置,对矩阵而言,等价于torch.transpose(input,0,1)
(4)torch.squeeze()
功能:压缩长度为1的维度(轴)
dim:若为None,移除所有长度为1的轴;若指定维度,当且仅当该轴长度为1时,可以被移除;
(5)torch.unsqueeze()
功能:依据dim扩展维度
dim:扩展的维度
4.张量数学运算 (1)加减乘除
torch.add()
功能:逐元素计算input+alpha*other
input:第一个张量
alpha:乘项因子
other:第二个张量

(2)对数、指数、幂函数
(3)三角函数
5.线性回归 线性回归是分析一个变量与另外一(多)个变量之间关系的方法
因变量:y自变量:x关系:线性
y=wx+b
分析:求解w,b
求解步骤:
(1)确定模型model:y=wx+b
(2)选择损失函数MSE(均方差):
(3)求解梯度并更新w,b
w=w-LR*w.grad
b=b-LR*w.grad
import torchimport matplotlib.pyplot as plttorch.manual_seed(10)lr = 0.05# 学习率# 创建训练数据x = torch.rand(20, 1) * 10# x data (tensor), shape=(20, 1)y = 2*x + (5 + torch.randn(20, 1))# y data (tensor), shape=(20, 1)# 构建线性回归参数w = torch.randn((1), requires_grad=True)b = torch.zeros((1), requires_grad=True)for iteration in range(1000):# 前向传播wx = torch.mul(w, x)y_pred = torch.add(wx, b)# 计算 MSE lossloss = (0.5 * (y - y_pred) ** 2).mean()# 反向传播loss.backward()# 更新参数b.data.sub_(lr * b.grad)w.data.sub_(lr * w.grad)# 清零张量的梯度w.grad.zero_()b.grad.zero_()# 绘图if iteration % 20 == 0:plt.cla()# 防止社区版可视化时模型重叠plt.scatter(x.data.numpy(), y.data.numpy())plt.plot(x.data.numpy(), y_pred.data.numpy(), 'r-', lw=5)plt.text(2, 20, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color':'red'})plt.xlim(1.5, 10)plt.ylim(8, 28)plt.title("Iteration: {}\nw: {} b: {}".format(iteration, w.data.numpy(), b.data.numpy()))plt.pause(0.5)if loss.data.numpy() < 1:breakplt.show() 五、计算图与动态度机制 1.计算图 优点:运算简洁,梯度求导方便
计算图是用来描述运算的有向无环图
计算图有两个元素:结点(Node)和边(Edge)
结点表示数据,如向量,矩阵,张量
边表示运算,如加减乘除卷积等
例如:
用计算图表示:y=(x+w)*(w+1)
a=x+wb=w+1y=a*b

叶子结点:用户创建的结点称为叶子结点,如X与W
is_leaf:指示张量是否为叶子结点
W和X就是叶子结点
叶子结点的作用:节省内存,梯度反向传播结束之后,非叶子结点的梯度会被释放掉 。
若使用非叶子结点的梯度:a.retain_grad(),则会保留a的梯度
grad_fn:记录创建该张量时所用的方法(函数)(梯度反向传播的时候用到)
y是用乘法得到的,a和b是用加法得到的
import torchw = torch.tensor([1.], requires_grad=True)x = torch.tensor([2.], requires_grad=True)a = torch.add(w, x)# retain_grad()b = torch.add(w, 1)y = torch.mul(a, b)y.backward()print(w.grad)# 查看叶子结点# print("is_leaf:\n", w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)# 查看梯度# print("gradient:\n", w.grad, x.grad, a.grad, b.grad, y.grad)# 查看 grad_fnprint("grad_fn:\n", w.grad_fn, x.grad_fn, a.grad_fn, b.grad_fn, y.grad_fn) 2.pytorch动态图机制 根据计算图搭建方式,可将计算图分为动态图和静态图
pytorch采用动态图机制,TensorFlow采用静态图机制
六、autograd与逻辑回归 1.autograd——自动求导系统 (1)torch.autograd.backward
功能:自动求取梯度
tensors:用于求导的张量,如loss
retain_graph:保存计算图
create_graph:创建导数计算图,用于高阶求导
grad_tensors:多梯度权重
w = torch.tensor([1.], requires_grad=True)x = torch.tensor([2.], requires_grad=True)a = torch.add(w, x)b = torch.add(w, 1)y = torch.mul(a, b)#backward中自动调torch.autograd.backwardy.backward(retain_graph=True)# print(w.grad)#若要运行两次backward,需要设置retain_graph=Truey.backward()tensors的作用是对y0和y1设置不同的权重
w = torch.tensor([1.], requires_grad=True)x = torch.tensor([2.], requires_grad=True)a = torch.add(w, x)# retain_grad()b = torch.add(w, 1)y0 = torch.mul(a, b)# y0 = (x+w) * (w+1)y1 = torch.add(a, b)# y1 = (x+w) + (w+1)dy1/dw = 2loss = torch.cat([y0, y1], dim=0)# [y0, y1]grad_tensors = torch.tensor([1., 2.])loss.backward(gradient=grad_tensors)# gradient 传入 torch.autograd.backward()中的grad_tensorsprint(w.grad) (2)torch.autograd.grad
功能:求取梯度
outputs:用于求导的张量,如loss
inputs:需要梯度的张量
create_graph:创建导数计算图,用于高阶求导
retain_graph:保存计算图
grad_outputs:多梯度权重
x = torch.tensor([3.], requires_grad=True)y = torch.pow(x, 2)# y = x**2#一阶求导grad_1 = torch.autograd.grad(y, x, create_graph=True) # grad_1 = dy/dx = 2x = 2 * 3 = 6print(grad_1)#二阶求导grad_2 = torch.autograd.grad(grad_1[0], x)# grad_2 = d(dy/dx)/dx = d(2x)/dx = 2print(grad_2) 【第一章-PyTorch基础概念 Pytorch基础学习】 注意事项:

  • 梯度不自动清零(梯度叠加,需手动清零,w.grad.zero_())
  • 依赖于叶子结点的结点,requires_grad默认为True
  • 叶子结点不可执行in-place,因为反向传播时还需要用到叶子结点的数据,故叶子结点不能改变(zero_的下划线表示原位操作)
w = torch.tensor([1.], requires_grad=True)x = torch.tensor([2.], requires_grad=True)for i in range(4):a = torch.add(w, x)b = torch.add(w, 1)y = torch.mul(a, b)y.backward()print(w.grad)#梯度手动清零w.grad.zero_()#依赖于叶子结点的结点,requires_grad默认为Trueprint(a.requires_grad, b.requires_grad, y.requires_grad) 什么是原位操作?
a = torch.ones((1, ))print(id(a), a)#新建地址# a = a + torch.ones((1, ))# print(id(a), a)#原位操作,在原地址上进行改变a += torch.ones((1, ))print(id(a), a) 2.逻辑回归 逻辑回归是线性的二分类模型
模型表达式:
sigmoid函数可以吧y映射到0-1区间,故输出的y可用于做二分类
逻辑回归与线性回归的区别:
线性回归是分析自变量x与因变量y(标量)之间关系的方法
逻辑回归是分析自变量x与因变量y(概率)之间关系的方法
逻辑回归又称为对数几率回归,表示样本x为正样本的可能性
线性回归是wx+b拟合y
对数回归是wx+b拟合对数几率
机器学习模型训练步骤
逻辑回归:
import torchimport torch.nn as nnimport matplotlib.pyplot as pltimport numpy as nptorch.manual_seed(10)# ============================ step 1/5 生成数据 ============================sample_nums = 100mean_value = https://tazarkount.com/read/1.7bias = 1n_data = torch.ones(sample_nums, 2)x0 = torch.normal(mean_value * n_data, 1) + bias# 类别0 数据 shape=(100, 2)y0 = torch.zeros(sample_nums)# 类别0 标签 shape=(100)x1 = torch.normal(-mean_value * n_data, 1) + bias# 类别1 数据 shape=(100, 2)y1 = torch.ones(sample_nums)# 类别1 标签 shape=(100)train_x = torch.cat((x0, x1), 0)train_y = torch.cat((y0, y1), 0)# ============================ step 2/5 选择模型 ============================class LR(nn.Module):def __init__(self):super(LR, self).__init__()self.features = nn.Linear(2, 1)self.sigmoid = nn.Sigmoid()def forward(self, x):x = self.features(x)x = self.sigmoid(x)return xlr_net = LR()# 实例化逻辑回归模型# ============================ step 3/5 选择损失函数 ============================loss_fn = nn.BCELoss()# ============================ step 4/5 选择优化器============================lr = 0.01# 学习率optimizer = torch.optim.SGD(lr_net.parameters(), lr=lr, momentum=0.9)# ============================ step 5/5 模型训练 ============================for iteration in range(1000):# 前向传播y_pred = lr_net(train_x)# 计算 lossloss = loss_fn(y_pred.squeeze(), train_y)# 反向传播loss.backward()# 更新参数optimizer.step()# 清空梯度optimizer.zero_grad()# 绘图if iteration % 20 == 0:mask = y_pred.ge(0.5).float().squeeze()# 以0.5为阈值进行分类correct = (mask == train_y).sum()# 计算正确预测的样本个数acc = correct.item() / train_y.size(0)# 计算分类准确率plt.scatter(x0.data.numpy()[:, 0], x0.data.numpy()[:, 1], c='r', label='class 0')plt.scatter(x1.data.numpy()[:, 0], x1.data.numpy()[:, 1], c='b', label='class 1')w0, w1 = lr_net.features.weight[0]w0, w1 = float(w0.item()), float(w1.item())plot_b = float(lr_net.features.bias[0].item())plot_x = np.arange(-6, 6, 0.1)plot_y = (-w0 * plot_x - plot_b) / w1plt.xlim(-5, 7)plt.ylim(-7, 7)plt.plot(plot_x, plot_y)plt.text(-5, 5, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})plt.title("Iteration: {}\nw0:{:.2f} w1:{:.2f} b: {:.2f} accuracy:{:.2%}".format(iteration, w0, w1, plot_b, acc))plt.legend()plt.show()plt.pause(0.5)if acc > 0.99:break
=========================================================================
转载请注明出处
代码、数据联系作者QQ:1727177407