Pytorch基础

news2024/9/22 17:31:45

文章目录

  • 一、Pytorch简介
  • 二、安装
    • 2.1 安装GPU环境
    • 2.2 安装Pytorch
    • 2.3 测试
  • 三、Tensor
    • 3.1 Tensor创建
      • 3.1.1 torch.tensor() && torch.tensor([])
      • 3.1.2 torch.randn && torch.randperm
      • 3.1.3 torch.range(begin,end,step)
      • 3.1.4 指定numpy
    • 3.2 Tensor运算
      • 3.2.1 A.add() && A.add_()
      • 3.2.2 torch.stack
  • 四、CUDA
  • 五、其他技巧
    • 5.1 自动微分
      • 5.1.1 backward求导
      • 5.1.2 autograd.grad求导
    • 5.2 求最小值
    • 5.3 Pytorch层次结构
  • 六、数据
    • 6.1 Dataset and DataLoader
    • 6.2 数据读取与预处理
    • 6.3 Pytorch数据处理工具
  • 七、torch.nn
  • 八、模型保存
    • 8.1 状态字典state_dict
    • 8.2 加载/保存状态字典(state_dict)
    • 8.3 加载/保存整个模型
  • 参考

一、Pytorch简介

Torch是一个经典的对多维矩阵数据进行操作的张量( tensor ) 库。
Pytorch的计算图是动态的,可以根据计算需要实时改变计算图。

二、安装

2.1 安装GPU环境

conda环境、CUDA环境和 CUDNN环境

2.2 安装Pytorch

https://pytorch.org/
在这里插入图片描述

官网会自动显示符合电脑配置的Pytorch版本

2.3 测试

import torch

print(torch.__version__)           # pytorch版本
print(torch.version.cuda)          # cuda版本
print(torch.cuda.is_available())   # 查看cuda是否可用

在这里插入图片描述
这里使用的是CPU版本

三、Tensor

Tensor张量是Pytorch里最基本的数据结构,是一个多维矩阵。
基本数据类型
在这里插入图片描述

3.1 Tensor创建

  • 全0
    torch.zeros(3,3)
  • 全1
    torch.ones(3,3)
  • 单位矩阵
    torch.eye(3,3)
  • 基础
    torch.Tensor([1,3]) # 将序列[1,3]转换为tensor
  • 指定数据类型
    torch.IntTensor([1,2])
  • 随机数
    torch.randn(3,3)
  • n数字随机排序
    torch.randperm(n)
  • 根据A的尺寸创建
    A.new_ones(size=B.size())

3.1.1 torch.tensor() && torch.tensor([])

主要区别在于创建的对象的size和value不同

torch.Tensor(2,3)    # 2行3列 
torch.Tensor([2,3])  # 将列表[2,3]转换为tensor

3.1.2 torch.randn && torch.randperm

torch.randn生成的数据类型为浮点型,生成的数据取值满足均值为0,方差为1的正态分布。

torch.randn(2,3)

torch.randperm(n)创建一个n个整数,随机排列的Tensor

torch.randperm(10)

3.1.3 torch.range(begin,end,step)

生成一个一维的Tensor,三个参数分别为起始位置,终止位置和步长。

torch.range(1,10,2)
# tensor([1.,3.,5.,7.,9.])

3.1.4 指定numpy

需要创建指定的Tensor,可以使用numpy

torch.tensor(np.arange(15).reshape(3,5))

3.2 Tensor运算

  1. torch.abs(A)
    绝对值
  2. torch.add(A,B)
    相加,A和B既可以是Tensor也可以是标量
  3. torch.clamp(A,max,min)
    裁剪,A中的数据如果小于min或者大于max,则变成min或者max,保证范围在[min,max]
  4. torch.div(A,B)
    相除,A/B, A和B既可以是Tensor也可以是标量
  5. torch.mul(A,B)
    点乘,A*B, A和B既可以是Tensor也可以是标量
  6. torch.pow(A,n)
    求幂, A的n次方
  7. torch.mm(A,B.T)
    矩阵叉乘
  8. torch.mv(A,B)
    矩阵与向量相乘,A是矩阵,B是向量,这里的B需不需要转置都是可以的
  9. A.item()
    将Tensor转换为基本数据类型,Tensor中只有一个元素的时候才可以使用,一般用于在Tensor中取出数值。
  10. A.numpy()
    将Tensor转换成Numpy类型
  11. A.size()
    查看尺寸
  12. A.shape()
    查看尺寸
  13. A.dtype()
    查看数据类型
  14. A.view()
    重构张量尺寸,类似于Numpy中的reshape
  15. A.transpose(0,1)
    行列交换
  16. A[1:] && A[-1,-1] = 100
    切片,类似Numpy中的操作
  17. A.zero_()
    归零化
  18. torch.stack((A,B),sim=-1)
    拼接升维
  19. torch.diag(A)
    对A对角线元素形成一个一维向量
  20. torch.diag_embed(A)
    将一维向量放到对角线上,其余数值为0的Tensor
  21. torch.unsqueeze()
  22. torch.squeeze()

3.2.1 A.add() && A.add_()

所有带_符号的操作都会对原数据进行修改

b.add(1)
b.add_(1)

3.2.2 torch.stack

stack为拼接函数,函数第一个参数为需要拼接的Tensor, 第二个参数为分到哪个维度

C1 = torch.stack((A,B).dim=0)  # -1 默认是按最后一个维度

四、CUDA

CUDA是一种操作GPU的软件架构,Pytorch配合GPU环境,模型的训练速度会大大加快。

import torch
# 测试GPU环境是否可用
print(torch.__version__)   # pytorch版本
print(torch.version.cuda)  # cuda版本
print(torch.cuda.is_available())   # 查看cuda是否可用

# 使用GPU or CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 判断某个对象是在什么环境中运行的
a.device
# 将对象的环境设置为device环境
A = A.to(device)
# 将对象环境设置为CPU
A.cpu().device
# 若一个没有环境的对象与另一个有环境A的对象进行交互,则环境全变为环境A
a + b.to(device)
# cuda环境下tensor不能直接转换为numpy类型,必须要先转换成CPU环境中
a.cpu().numpy()
# 创建CUDA型的tensor
torch.tensor([1,2],device)

五、其他技巧

5.1 自动微分

神经网络依赖反向传播求梯度来更新网络的参数。
在Pytorch中,提供了两种求梯度的方式

  • backward,将求得的结果保存在自变量的grad属性中
  • torch.autograd.grad

5.1.1 backward求导

使用backward进行求导,针对两种对象:标量Tensor和非标量Tensor求导。
两者的主要区别在于非标量Tensor求导加了一个gradient的Tensor, 其尺寸与自变量X的尺寸一致,在求完导后,需要与gradient进行点积,只是一般的求导的话,设置的gradient的Tensor元素值全部为1。

import numpu as np
import torch

# 标量Tensor求导
# 求f(x) = a*x**2 + b*x + c 的导数
x = torch.tensor(-2.0,requires_grad=True)  # 需要添加requires_grad
a = torch.tensor(1.0)
b = torch.tensor(2.0)
c = torch.tensor(3.0)
y = a * torch.pow(x,2) + b*x +c
y.backward()  # backward求得的梯度会存储在自变量x的grad属性中
dy_dx = x.grad

# 非标量Tensor求导
# 求f(x) = a*x**2 + b*x + c 的导数
x = torch.tensor([[-2.0,-1.0],[0.0,1.0]],requires_grad=True)
a = torch.tensor(1.0)
b = torch.tensor(2.0)
c = torch.tensor(3.0)
gradient = torch.tensor([[1.0,1.0],[1.0,1.0]])
y = a * torch.pow(x,2) + b*x +c
y.backward(gradient = gradient)  # backward求得的梯度会存储在自变量x的grad属性中
dy_dx = x.grad


# 使用标量求导方式解决非标量求导
# 求f(x) = a*x**2 + b*x + c 的导数
x = torch.tensor([[-2.0,-1.0],[0.0,1.0]],requires_grad=True)
a = torch.tensor(1.0)
b = torch.tensor(2.0)
c = torch.tensor(3.0)
gradient = torch.tensor([[1.0,1.0],[1.0,1.0]])
y = a * torch.pow(x,2) + b*x +c
z = torch.sum(y*gradient)
z.backward()
dy_dx = x.grad

5.1.2 autograd.grad求导

import torch

# 单个自变量求导
# 求f(x) = a*x**4 + b*x + c的导数
x = torch.tensor(1.0,requires_grad=True)
a = torch.tensor(1.0)
b = torch.tensor(2.0)
c = torch.tensor(3.0)
y = a * torch.pow(x,4) + b*x + c
# create_graph设置为True,允许创建更高阶的导数
# 求一阶导
dy_dx = torch.autograd.grad(y,x,create_graph=True)[0]
# 求二阶导
dy2_dx2 = torch.autograd.grad(dy_dx ,x,create_graph=True)[0]
# 求三阶导
dy_dx3 = torch.autograd.grad(dy2_dx2 ,x)[0]  # 不再求更高阶导

# 多个自变量求偏导
x1 = torch.tensor(1.0,requires_grad=True)
x2 = torch.tensor(2.0,requires_grad=True)
y1 = x1 * x2
y2 = x1 + x2
# 只有一个因变量,正常求偏导
dy1_dx1,dy1_dx2 = torch.autograd(outputs=y1,inputs=[x1,x2],retain_graph=True)
# 若有多个因变量,则对于每个因变量,会将求偏导的结果加起来
dy1_dx,dy2_dx = torch.autograd.grad(outputs=[y1,y2],inputs=[x1,x2])

5.2 求最小值

使用自动微分机制配套使用SGD随机梯度下降来求最小值。

# 利用自动微分和优化器求最小值
import numpy as np
import torch

# f(x) = a*x**2 + b*x + c 的最小值
x = torch.tensor(0.0,requires_grad=True)   # x需要被求导
a = torch.tensor(1.0)
b = torch.tensor(-2.0)
c = torch.tensor(1.0)
optimizer = torch.optim.SGD(params=[x],lr=0.01) # SGD为随机梯度下降,lr学习率

def f(x):
    result = a*torch.pow(x,2) + b*x +c
    return result
for i in range(500):
    optimizer.zero_grad() # 将模型的参数初始化为0
    y = f(x)
    y.backward()      # 反向传播计算梯度
    optimizer.step()  # 更新所有的参数
print("y=",y.data,"->","x=",x.data)

5.3 Pytorch层次结构

Pytorch一共有5个不同的层次结构,分别为硬件层、内核层、低阶API、中阶API和高阶API(torchkeras)。
在这里插入图片描述

六、数据

Pytorch 通过Dataset和DataLoader进行构建数据管道。

6.1 Dataset and DataLoader

  • DataSet 一个数据集抽象类,所有自定义的Dataset都需要继承它,并且重写__getitem__()或者__get_sample__()这个类方法
  • DataLoader 一个可迭代的数据装载器。在训练的时候,每个for循环迭代,就从DataLoader中获取一个batch_size大小的数据。

6.2 数据读取与预处理

DataLoader的参数

DataLoader(
    dataset,                  # 数据集,数据从哪里来,以及如何读取    【需要关注】
    batch_size=1,             # 批次大小,默认1                     【需要关注】
    shuffle=False,            # 每个epoch是否乱序                   【需要关注】
    sampler=None,             # 样本采样函数,一般无需设置
    batch_sampler=None,       # 批次采样函数,一般无需设置
    num_workers=0,            # 使用多进程读取数据,设置的进程数      【需要关注】
    collate_fn=None,          # 整理一个批次数据的函数
    pin_memory=False,         # 是否设置为锁业内存。默认为False,锁业内存不会使用虚拟内存,
                              # 从锁业内存拷贝到GPU上速度会更快
    drop_last = False,        # 是否丢弃最后一个样本数量不足的batch_size批次数据 【需要关注】
    timeout=0,                # 加载一个批次数据的最长等待时间,一般无需设置
    worker_init_fn=None,      # 每个worker中的dataset的初始化函数,常用于IterableDataset,
                              # 一般不使用
    multiprocessing_context=None,
);

Epoch、Iteration、Batchsize的关系
在这里插入图片描述
数据读取的主要流程
在这里插入图片描述

  1. 从DataLoader开始
  2. 进入DataLoaderIter,判断单线程还是多线程
  3. 进入Sampler进行采样,获得一批一批的索引,这些索引表示需要读取的数据
  4. 进入DatasetFetcher, 依据索引读取数据
  5. Dataset获知数据的地址
  6. 自定义的Dataset中会重写__getitem__()方法,针对不同的数据来进行定制化的数据读取
  7. 获取到数据的Text和Label
  8. 进入collate_fn将之前获取的个体数据进行组合成为batch
  9. 一个一个batch组成Batch Data
import torch
from torch.utils.data import DataLoader
from torch.utils.data.dataset import TensorDataset

# 自构建数据集
data = torch.arange(1,40)
dataset = TensorDataset(data)
dl = DataLoader(dataset,
                batch_size = 10,
                shuffle= True,
                num_workers = 0,    # 使用多进程加速报错,这里设置为0
                drop_last = True)
# 数据输出
for batch in dl:
    print(batch)

自定义数据集只有39条,最后一个batch的数据量小于10,被舍弃了
在这里插入图片描述
数据预处理主要是重写Dataset和DataLoader中的方法,实现定制化处理。

6.3 Pytorch数据处理工具

基于Pytorch已经产生了很多封装完备的工具。( 但是数据处理不是很灵活 )
在这里插入图片描述

七、torch.nn

torch.nn是神经网络工具箱,该工具箱建立于Autograd( 主要有自动求导和梯度反向传播功能 ),提供了网络搭建的模组、优化器等一系列功能。
搭建神经网络模型的整个流程

  1. 数据读取
  2. 定义模型
  3. 定义损失函数和优化器
  4. 模型训练
  5. 获取训练结果

一个FNN网络的例子(FNN每一层是全连接层)
https://blog.csdn.net/cxy2002cxy/article/details/124771834

import numpy as np
import torch
import matplotlib.pyplot as plt
from torch.utils.data import Dataset,DataLoader

# prepare the dataset
class DiabetesDataset(Dataset):
    # load dataset
    def __init__(self,filepath):
        xy = np.loadtxt(filepath,delimiter="\t",dtype=np.float32,encoding="utf-8")
        # shape[0]: rows
        # shape[1]: cols
        self.len = xy.shape[0]

        # 归一化
        for i in range(xy.shape[1]):
            xy_max = np.max(xy[:,i])
            xy_min = np.min(xy[:,i])
            xy[:,i] = (xy[:,i]-xy_min) / (xy_max - xy_min)
        
        self.y_max = np.max(xy[:,-1])
        self.y_min = np.max(xy[:,-1])
        
        self.x_data = torch.from_numpy(xy[:,:-1])
        self.y_data = torch.from_numpy(xy[:,-1])

    # get data by index
    def __getitem__(self,index):
        return self.x_data[index],self.y_data[index]
    
    # get total of data
    def __len__(self):
        return self.len
        
dataset = DiabetesDataset("./data/diabetes.txt")

# param
epochs = 300
batchsize = 32
iters  = dataset.len / batchsize 

train_loader = DataLoader(dataset = dataset,
                          batch_size = batchsize,
                          shuffle=True,
                          drop_last= True,
                          num_workers = 0) # num_worker为多线程
                          
# define the model
class FNNModel(torch.nn.Module):
    def __init__(self):
        super(FNNModel,self).__init__()
        # 输入特征有10个,也就是10个维度,将其降为6个维度
        self.linear1 = torch.nn.Linear(10,6)
        # 6维 -> 4 维
        self.linear2 = torch.nn.Linear(6,4)
        # 4维 -> 2 维
        self.linear3 = torch.nn.Linear(4,2)
        # 2维 -> 1 维
        self.linear4 = torch.nn.Linear(2,1)
        # sigmoid层,作为输出层
        self.sigmoid = torch.nn.Sigmoid()
        
    # forward
    def forward(self,x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        x = self.sigmoid(self.linear4(x))
        return x
        
model = FNNModel()

# define the criterion(标准) and optimizer
criterion = torch.nn.BCELoss(reduction="mean")  # 返回损失的平均值
optimizer = torch.optim.SGD(model.parameters(),lr = 0.01)

epoch_list = []
loss_list = []

# training
if __name__ == "__main__":
    for epoch in range(epochs):
        # data 获取的数据为 (x,y)
        loss_one_epoch = 0
        for i ,data in enumerate(train_loader,0):
            inputs,labels = data
            y_pred = model(inputs)
            loss = criterion(y_pred,labels.unsqueeze(dim=1))
            loss_one_epoch += loss.item()  # 累加
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
        loss_list.append(loss_one_epoch/iters) # 求个平均值
        epoch_list.append(epoch)
        print("Epoch[{}/{}], loss:{:.6f}".format(epoch+1,epochs,loss_one_epoch/iters))
        
    # drawing
    plt.plot(epoch_list,loss_list)
    plt.xlabel("epoch")
    plt.show()

在这里插入图片描述

八、模型保存

在保存和加载模型方面主要有三个核心 的方法:

  • torch.save
    将对象序列化保存到磁盘中,底层通过python中的pickle来序列化,各种Models,tensors,dictionaries都可以使用该方法保存。保存的模型文件名可以是.pth,.pt,.pkl
  • torch.load
    采用pickle将反序列化的对象从存储中加载进内存。
  • torch.nn.Module.load_state_dic
    采用一个反序列的state_dict()方法将模型的参数加载到模型结构上
      load_state_dict(state_dict,strict=True)
      # state_dict, 保存parameters和persistent buffers的字典
      # stric 可选,bool, state_dict中的key是否和model.state_dict()返回的key一致
    

序列化和反序列化:

  • 序列化( Serialization ) 是将对象的状态信息转换为可以存储在或者传输的形成的过程。
  • 在序列化器件,对象将其当前状态写入到临时或者持久性存储区,以后可以从存储区中读取或者反序列化对象的状态,重建该对象。

8.1 状态字典state_dict

state_dict()在神经网络中可以认为是模型上训练出来的模型参数,权重和偏置值。
Pytorch中,定义的网络模型是通过继承torch.nn.Module来实现的,网络模型中包含可以学习的参数( weights、bias和一些登记的缓存 )。模型内部的可学习参数可以通过两种方式进行调用。

  • model.parameters() 访问所有参数
  • model.state_dict() 来为每一层和它的参数建立一个映射关系并存储在字典中,键值由每个网络层和其对应的参数张量构成。

除了模型,优化器对象( torch.optim ) 也有一个状态字典,包含优化器状态信息以及使用的超参数。
使用ResNet18,并使用与训练权重。

import torch.optim as optim
from torchvision.models import resnet18,ResNet18_Weights

# 定义模型,并使用预训练权重
model = resnet18(weights=ResNet18_Weights.DEFAULT)
# 定义优化器,随机梯度优化器
optimizer = optim.SGD(model.parameters(),lr=0.001,momentum=0.9)
# 模型的 state_dict
print(type(model.state_dict()))
for key,value in model.state_dict().items():
    print(key,"\t",value,size())
# 模型的model.parameters()
print(model.parameters())
# 1. 使用for循环
for para in model.parameters():
    print(para.size())
# 2. 使用list() 转换为list

# 优化器的state_dict
for key,value in optimizer.state_dict().items():
    print(key,value)
  1. 通过.state_dict()打印模型每个网络层的名字和参数
  2. 通过.parameters()打印模型的每个网络层的参数
  3. 通过.state_dict()打印优化器每个网络层名字和参数

8.2 加载/保存状态字典(state_dict)

保存一个模型的时候,只需要保存训练模型的可学习参数即可,通过torch.save()来保存模型的状态字典。
加载模型时,通过torch.load()来加载模型的状态字典,且通过.load_state_dict()将状态字典加载到模型上。

import torch
from torchvision.models import resnet18,ResNet18_Weights

# 定义模型,并使用预训练权重
model = resnet18(weights=ResNet18_Weights.DEFAULT)

# 保存模型的state_dict
# 可以是pth,pt,pkl后缀的文件名
path = "./model.pth"
torch.save(model.state_dict(),path)

# =========加载模型 ===========
# 1. 定义模型
model = resnet18()
# 2. 加载状态字典进内存
state_dict = torch.load(path)
# 3. 将状态字典中的可学习参数加载到模型上使用
model.load_state_dict(state_dict)

8.3 加载/保存整个模型

保存整个模型对象(包括模型结构和状态字典等)
这种保存模型的做法是采用python的pickle模块来保存整个模型,方法的缺点是pickle不保存模型类别,而是保存一个包含该类的文件的路径。
在加载的时候,需要先定义一下这个模型类,否则可能会报错。
保存模型

import torch
from torchvision.models import resnet18,ResNet18_Weights
# 定义模型,并使用预训练权重
model = resnet18(weights=ResNet18_Weights.DEFAULT)
# 保存模型的全部
path = './model.pth'
torch.save(model,path)

加载模型

import torch
# 需要注意:定义一下这个类,否则会报错
from torchvision.models import resnet18

# 加载模型
path = "./model.pth"
model = torch.load(path)

参考

  • Pytorch官网
    https://pytorch.org/
  • 清华pypi镜像:
    https://mirrors.tuna.tsinghua.edu.cn/help/pypi/
  • 2022 Pytorch基础入门教程
    https://blog.csdn.net/ccaoshangfei/article/details/126074300
  • Pytorch教程
    https://blog.csdn.net/weixin_45526117/article/details/123997738
  • Pytorch中文文档
    https://www.pytorchtutorial.com/docs/
  • 数据集
    https://zhuanlan.zhihu.com/p/618818240
  • pytorch保存和加载模型
    https://blog.csdn.net/weixin_41012765/article/details/128008960

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/818852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql 非definer用户如何查看存储过程定义

当我们创建存储过程时,如果没有显示指定definer,则会默认当前用户为该sp的definer,如果没有相关授权,则其他用户是看不了这个sp的。 比如用户zhenxi1拥有如下权限: 它拥有对dev_nacos库的查询权限,这个时候…

流程节点图形变化

一、背景 (1)流程节点为矩形,只有上下左右四个连接点。 (2)支持移动,放大缩小,连接线。 二、需求 (1)流程节点支持图形变化。 (2)支持节点边框…

第7期ThreadX视频教程:如何实现RTOS高效的任务管理,抢占式调度,时间片调度和零中断延迟(2023-07-31)

视频教程汇总帖:https://www.armbbs.cn/forum.php?modviewthread&tid110519 本期视频为大家分享高效的RTOS任务管理设计,通过这个点来引出抢占式调度,时间片调度,任务优先级设置和零中断延迟。 RTOS任务高效管理是我们使用R…

吃透《西瓜书》第四章 决策树定义与构造、ID3决策树、C4.5决策树、CART决策树

目录 一、基本概念 1.1 什么是信息熵? 1.2 决策树的定义与构造 二、决策树算法 2.1 ID3 决策树 2.2 C4.5 决策树 2.3 CART 决策树 一、基本概念 1.1 什么是信息熵? 信息熵: 熵是度量样本集合纯度最常用的一种指标,代表一个系统中蕴…

Python小红书旋转验证码识别

本周免费接了一个用户的需求,研究了一下小红书旋转验证码。刚开始小瞧了它,觉得它应该没有百度旋转验证码那么难,毕竟图像没有干扰,需要的训练样本就可以很少。然而事情并没有这么简单,所以记录一下。 首先看一下最终…

代码随想录算法训练营第二天| 977. 有序数组的平方y,螺旋矩阵 II,209. 长度最小的子数组

977. 有序数组的平方y 思路,原数组是有序的,但是因为负数平方后可能变无序了,因此利用双指针遍历原数组,比较 nums[left]*nums[left]和nums[right]*nums[right]谁更大,然后对新数组赋值 class Solution {public int…

uni-table行点击事件

uni-app 如何点击表格的行跳转到对应的页面 找到uni-ui的源码,在源码里面绑定事件 用$emit发射事件 在你使用了uni-table的组件中接受改事件 然后绑定调用成功

在中国区部署日志通2.0

前提条件 一个域名:使用此域名来访问日志通控制台提供aws iam 的ssl证书 ,而且必须跟域名相关联具有四个子网(两个公有子网和两个私有子网)和NAT网关的VPC 步骤 1.创建ACM证书 1.1 请求公有证书 1.2 配置域名 1.3 新申请的证书记…

Python自动化测试之函数知识讲解

一、前言 本文章主要讲解Python中的函数定义调用、参数分类、函数使用、作用域以及内置函数等内容,是函数专题讲解,这些都是python自动化学习中的基础哟,只有学好了基础才会有利于后面自动化的学习哟。这里我不多说废话了,直接进入…

GO学习之 多线程(goroutine)

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 文章目录 GO系列前言一、并发介绍1.1 进程和线程和协程1.2 并发和并行 二、goroutine介绍三…

Android 中 app freezer 原理详解(二):S 版本

基于版本:Android S 0. 前言 在之前的两篇博文《Android 中app内存回收优化(一)》和 《Android 中app内存回收优化(二)》中详细剖析了 Android 中 app 内存优化的流程。这个机制的管理通过 CachedAppOptimizer 类管理,为什么叫这个名字,而不…

HTTP协议 和 HTTPS协议的区别(4点) HTTPS如何使用SSL/TLS协议加密过程 CA证书干啥的

(一)HTTP协议 和 HTTPS协议的区别(4点): 1. HTTP协议的端口号是80, HTTPS协议的端口号是443 2. HTTP协议使用的URL是以 http:// 开头,HTTPS协议使用的URL是以https://开头 3. HTTP协议和HTTP…

Qt 中操作xml文件和JSON字符串

文章目录 1、概述1.1、xml介绍1.2、json介绍 2、xml文件增删改查2.1、写xml文件内容2.2、读xml文件内容2.3、删除xml文件内容2.4、修改xml文件内容 3、构建JSON字符串3.1、JSON字符串排版4、剪切板操作 1、概述 1.1、xml介绍 XML 指可扩展标记语言(EXtensible Mark…

“效能指标”,该由谁来定义?| 谈效风生

第5期:效能指标,该由谁来定义? 回顾上期《「自动化」聊起来简单,做起来难》我们聊了聊如何打造「自动化」的事,这也是真正实现研发效能提升的必要条件。从单点自动化提升效率,到全工具链自动化,…

常微分方程建模R包ecode(二)——绘制相速矢量场

本节中我们考虑一个更为复杂的常微分方程模型, d X C d t ν ( X A Y A ) − β ⋅ X C ⋅ ( Y C Y A ) − ( μ g ) ⋅ X C , ( 1 ) d Y C d t β ⋅ X C ⋅ ( Y C Y A ) − ( μ g ρ ) ⋅ Y C , ( 2 ) d X A d t g ⋅ X C − β ⋅ X A ⋅ ( Y C Y A …

2023最新版本~十分钟零基础搭建EMQX服务器

购买服务器 已知服务器大厂商 1 阿里云 点击直接访问 2 华为云点击直接访问 3 腾讯云 点击直接访问 还是比较推荐大公司 不会跑路 这里我购买的是一年的华为云服务器(新用户 64一年) 镜像推荐乌班图18 登陆服务器(需要重置密码!!&…

Ansible自动化运维工具 —— Playbook 剧本

playbooks 本身由以下各部分组成 (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 (2)Variables:变量 (3)Templates:模…

ubuntu16.04忘记密码了怎么办,亲测有效

由于装载Ubuntu系统的电脑(非虚拟机)好久没有用,忘记了密码,只能进行密码重置,亲测有效: 1.首先ubuntu系统开机,期间按着shift键不放,选择高级选项。 2.enter键进入如下界面&#x…

python-occ入门指北

0、系统环境: Win10 在Windows环境中玩PythonOCC比较简单的方式是使用anaconda的cmd prompt或者powershell的prompt,这里我用的是cmd。PowerShell也有很多粉丝,但是个人真的觉得这个东西挺鸡肋的。 另外在Win10或Win11上另一个玩法是使用WSL2&#xff…

【漏洞挖掘】Xray+rad自动化批量漏洞挖掘

文章目录 前言一、挖掘方法二、使用步骤工具安装使用方法开始挖掘 总结 前言 自动化漏洞挖掘是指利用计算机程序和工具来扫描、分析和检测应用程序、网络和系统中的安全漏洞的过程。这种方法可以帮助安全专家和研究人员更高效地发现和修复潜在的安全威胁,从而提高整…