PyTorch学习笔记:基础语法及应用

import torch

v = torch.__version__
cu = torch.cuda.is_available()

k = torch.tensor([1.2, 3.4]).dtype

x = torch.tensor((1, 2, 3), dtype=torch.float32, requires_grad=True)
y = x.pow(2)
z = y.sum()
z.backward()  # 参数必须是个标量
print(x.grad)

print(x, y, z)
# %%
import torch

b = torch.Tensor(2, 3)
a = torch.rand_like(b)

print(a)
print(b)
# %%
# 利用Numpy数组生成张量
import torch
import numpy as np

k = np.ones((3, 3))
s = torch.as_tensor(k)  # 使用torch.as_tensor()函数
t = torch.from_numpy(k)

print(k)
print(s)
print(t)
# %%
import torch

# 指定生成随机数的种子,用于保证生成的随机数是可重复出现的
torch.manual_seed(11)
# torch.normal()用来生成服从正态分布的随机数;mean:均值  std:标准差
A = torch.normal(mean=0.0, std=torch.tensor(1.0))  # 生成服从正态(0,1)分布的随机数
B = torch.normal(mean=0.0, std=torch.arange(1.0, 5.0))  # 生成多个随机数,每个随机数的均值为0,标准差分别为1、2、3、4
C = torch.normal(mean=torch.arange(1, 5.0), std=torch.arange(1.0, 5.0))  # 生成多个随机数,每个随机数的均值分别为1、2、3、4,标准差分别为1、2、3、4

print(A)
print(B)
print(C)
# %%
import torch

torch.manual_seed(11)
# torch.rand():在区间[0,1]上生成服从均匀分布的张量
A = torch.rand(3, 4)
B = torch.rand_like(A)  # 根据其他张量维度,生成与其维度相同的随机数张量
# 生成服从标准正态分布的随机数张量
C = torch.randn(3, 5)
D = torch.randn_like(C)

print(A)
print(B)
print(C)
print(D)
# %%
import torch

torch.manual_seed(11)
# 将0~n(包含0不包含n)之间的整数进行随机排序后输出
A = torch.randperm(5)

print(A)
# %%
import torch

A = torch.arange(start=0, end=10, step=2)  # 用来生成张量,和np.arange()用法相似;step是步长
B = torch.linspace(start=1, end=10, steps=5)  # steps 是生成的张量元素的个数;在范围内生成固定数量的等间隔张量
C = torch.logspace(start=0, end=1, steps=5)  # 生成以对数为间隔的张量

print(A)
print(B)
print(C)
# %%
# 改变张量的形状 torch.reshape()
import torch

A = torch.arange(12.0)  # torch.float32
# A = torch.arange(12)  #torch.int64
B = A.reshape(3, 4)

print(A.dtype)
print(A)
print(B)
# %%
import torch

A = torch.arange(12.0).reshape(3, 4)
B = torch.triu(A, diagonal=0)
C = torch.triu(A, diagonal=1)
D = torch.triu(A, diagonal=2)

print(A)
print(B)
print(C)
print(D)
# %%
import torch

A = torch.arange(6.0).reshape(2, 3)
B = torch.linspace(0., 10.0, 6).reshape(2, 3)

C = torch.cat((A[:, 0:2], A, B), dim=1)

print(A)
print(B)
print(C)
# %%
import torch

k = torch.tensor([1, 2, float("nan"), 0])
r = torch.isnan(k)

print(r)
# %%
import torch

a = torch.arange(1, 13, 1).reshape(3, 4)  # 3行4列
b = torch.tensor([1, 1, 1, 1])  # 4行1列
# b = torch.tensor([[1, 1, 1, 1], [2, 2, 2, 2]])  # 2行4列

c = a.matmul(b)  # 矩阵相乘,a的列数要等于b的行数
d = torch.matmul(a, b)  # 矩阵相乘,c和d的结果相同

print(a, b, c, d)
# %%
import torch

a = torch.rand(3, 3)
b = torch.inverse(a)  # 计算矩阵的逆

c = torch.mm(a, b)  # 等价于 torch.matmul()
d = torch.matmul(a, b)

e = torch.trace(c)  # 计算矩阵的迹:对角线元素的和

print(c)
print(d)
print(e)
# %%
import torch

x = torch.tensor([[1., 2.], [3., 4.]], requires_grad=True)
y = torch.sum(x ** 2 + 2 * x + 1)  # 把矩阵的所有元素求和

print(x)
print(y)

y.backward()  # 计算y在x的每个元素上的导数;只有标量可以求导
print(x.grad)  # 获取此时x的梯度信息,计算得到的梯度值等于2x+2
# %%
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

x = torch.linspace(-6, 6, 100)
sigmoid = nn.Sigmoid()
ysigmoid = sigmoid(x)

tanh = nn.Tanh()
ytanh = tanh(x)

relu = nn.ReLU()
yrelu = relu(x)

softplus = nn.Softplus()
ysoftplus = softplus(x)

plt.figure(figsize=(14, 3))

plt.subplot(2, 2, 1)
plt.plot(x.data.numpy(), ysigmoid.data.numpy(), "r-")
plt.title("sigmoid")
plt.grid()

plt.subplot(2, 2, 2)
plt.plot(x.data.numpy(), ytanh.data.numpy(), "r-")
plt.title("tanh")
plt.grid()

plt.subplot(2, 2, 3)
plt.plot(x.data.numpy(), yrelu.data.numpy(), "r-")
plt.title("relu")
plt.grid()

plt.subplot(2, 2, 4)
plt.plot(x.data.numpy(), ysoftplus.data.numpy(), "r-")
plt.title("softplus")
plt.grid()

plt.show()
# %%
import torch
import torch.utils.data as Data
import numpy as np
from sklearn.datasets import load_boston, load_iris

if __name__ == '__main__':
    #
    # 回归数据准备:使用pytorch时需要的数据应该为torch的32位浮点型的张量;被预测变量为连续的数值
    #
    boston_X, boston_y = load_boston(return_X_y=True)  # float64

    train_xt = torch.from_numpy(boston_X.astype(np.float32))  # 先将Numpy数据转化为32位浮点型
    train_yt = torch.from_numpy(boston_y.astype(np.float32))  # 再将数组转化为张量

    # 训练全连接神经网络时,通常使用一个batch的数据进行更新(batch_size即批处理样本大小,一个batch包括batch_size个样本)
    train_data = Data.TensorDataset(train_xt, train_yt)  # 将x和y整理到一起作为训练数据
    # 定义一个数据加载器,将训练数据集进行批量处理
    train_loader = Data.DataLoader(
        dataset=train_data,  # 使用的数据集
        batch_size=64,  # 批处理样本大小
        shuffle=True,  # 每次迭代前打乱数据
        num_workers=1,  # 使用两个进程
        # #####多进程需要在main函数中运行#####
        # 可以放到main函数中 或者改为单进程,值改为0
    )

    # 检查训练数据集的一个batch的样本的维度是否正确
    for step, (b_x, b_y) in enumerate(train_loader):
        # print(step)  # step的值为0,1,2,3,4,5,6,7 因为506个样本,一个batch是64,故有8个batch,最后一个batch58个样本
        if step > 0:
            break

    # 输出训练图像的尺寸和标签的尺寸及数据类型
    print(b_x.shape)
    print(b_y.shape)
    print(b_x.dtype)
    print(b_y.dtype)
    #
    # 分类数据准备:被预测变量为离散类型变量
    # 在使用pytorch定义的网络模型时,默认的预测标签是64位有符号整型数据,X默认的数据格式是torch.float32
    #
    iris_x, iris_y = load_iris(return_X_y=True)
    train_xt_iris = torch.from_numpy(iris_x.astype(np.float32))
    train_yt_iris = torch.from_numpy(iris_y.astype(np.int64))

    train_data_iris = Data.TensorDataset(train_xt_iris, train_yt_iris)

    train_loader_iris = Data.DataLoader(
        dataset=train_data_iris,
        batch_size=10,
        shuffle=True,
        num_workers=1,
    )

    for step, (b_x_iris, b_y_iris) in enumerate(train_loader_iris):
        if step > 0:
            break

    print(b_x_iris.shape)
    print(b_y_iris.shape)
    print(b_x_iris.dtype)
    print(b_y_iris.dtype)
# %%
# 定义优化器并使用:这段代码不可运行
import torch
from torch.optim import Adam

optimizer = Adam(netname.parameters(), lr=0.1)  # lr默认值为0.001;netname为网络名称

# 对目标函数进行优化
for input, target in dataset:
    optimizer.zero_grad()  # 梯度清零
    output = netname(input)  # 计算预测值
    loss = lossfunctionname(output, target)  # 计算损失(预测值与目标值之间)
    loss.backward()  # 损失 后向传播
    optimizer.step()  # 更新网络参数
# %%
# 网络学习率的调整:LambdaLR,StepLR,MultiStepLR,ExponentialLR,CosineAnnealingLR
# 这段代码不可运行
import torch.optim.lr_scheduler as lr_scheduler

# 设置学习率调整方法的类,一般是在网络的训练之前;
# 学习率的调整是在网络的训练过程中,并通过scheduler.step()来更新
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=, last_epoch=)  # 设置学习率调整方式

for epoch in range(100):
    train()  # 训练
    validate()  # 验证
    scheduler.step()  # 更新学习率
# %%
# 损失函数
# 一个最优化问题的目标是将损失函数最小化
# 针对分类问题,直观的表现就是分类正确的样本越多越好
# 在回归问题中,直观的表现就是预测值与实际值误差越小越好
import torch

torch.nn.BCELoss(weight=, reduction=, )  # 二分类交叉熵损失,适用于二分类问题类型
# weight是一维的张量,包含n个元素,分别代表n类的权重,在训练样本不平衡时,非常有用,默认值为为None
# reduction的值为none、mean、sum
# mean即计算的损失为每个batch的均值
# sum则计算的损失为每个batch的和
# none则表示不使用该参数
# %%
# 防止过拟合
# 增加数据量:数据增强技术
# 合理的数据切分:数据集切分为训练集(训练深度学习网络)、验证集(监督网络的学习过程)、测试集(模型训练结束后来测试训练结果的泛化能力)的比例,比如6:2:2,98:1:1(大数据量时)
# 正则化方法:在损失函数上添加对训练参数的惩罚范数,通过添加的范数惩罚对需要训练的参数进行约束,防止模型过拟合
####常用的正则化参数有l1和l2范数
####l1范数惩罚项的目的是将参数的绝对值最小化:趋向于使用更少的参数,而其他的参数都是0,从而增加网络稀疏性
####l2范数惩罚项的目的是将参数的平方和最小化:会选择更多的参数,但是这些参数都会接近于0
####一般利用l2范数进行正则化约束较多
####在经典的线性回归模型中,使用l1范数正则化的模型叫做Lasso回归,使用l2范数正则化的模型叫做Ridge回归
#
# dropout:在深度学习网络中最常用的正则化技术是通过引入dropout层,随机丢掉一些神经元,,即在每个训练批次中,通过忽略一定百分比的神经元数量(通常是一半神经元),减轻网络的过拟合现象
####网络在前向传播时,让某个神经元的激活值以一定的概率p停止工作,可使模型泛化性更强,这样训练得到的网络的鲁棒性会更强,不会过度依赖某些局部的特征
#
# 提前结束训练:当网络在验证集上的损失不再减小,或者精度不再增加时,即认为网络已经训练充分,应终止网络的继续训练,但是该操作可能会获得训练不充分的最终参数
# %%
# 网络参数初始化
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

# 针对一个层的权重初始化方法
conv1 = nn.Conv2d(3, 16, 3)
# 使用标准正态分布初始化权重
torch.manual_seed(12)  # 随机数初始化种子
# nn.init.constant(tensor,val)  # 用val的值填充输入的张量或变量
# nn.init.uniform(tensor,a=0,b=1)  # 从均匀分布U(a,b)中生成值,填充输入的张量或变量
# nn.init.normal(tensor,mean=0,std=1)
# ...
nn.init.normal(conv1.weight, mean=0, std=1)  # 从给定均值mean和标准差std的正态分布中生成值,填充输入的张量或变量(此处是conv1.weight)
# 使用直方图可视化conv1.weight的分布情况
plt.figure(figsize=(8, 6))
plt.hist(conv1.weight.data.numpy().reshape((-1, 1)), bins=30)
plt.show()

# 设置该层的偏置参数bias
torch.nn.init.constant(conv1.bias, val=0.1)
print(conv1.weight)
print(conv1.bias)

参考书籍:

《PyTorch深度学习入门与实战》, 孙玉林、余本国 著

你可能感兴趣的:(深度学习,pytorch,深度学习,python)