当前位置: 首页 > news >正文

PyTorch深度学习快速入门(下)

PyTorch深度学习快速入门(下)

  • 一、现有网络模型的使用及修改
    • (一)背景知识
    • (二)修改网络模型的三种方法
  • 二、网络模型的保存与加载
    • (一)保存网络模型的两种方法
    • (二)加载网络模型的两种方法
  • 三、完整的模型训练套路
    • (一)背景知识
    • (二)代码实战
  • 四、GPU 训练
    • (一)训练方式1 — 调用 .cuda( ) 来改
    • (二)训练方式2 — 调用 .to( device ) 来改
  • 五、完整的模型验证套路(测试 / demo)
  • 六、看看GitHub上的开源项目
    • (一)看一个项目,先看README
    • (二)再看 train.py 文件中的整体架构
    • (三)将函数中 required=True 的地方用 default= ……替换

一、现有网络模型的使用及修改

(一)背景知识

(1)本质迁移学习,即利用现有的网络,去改变它的结构(微调)
(2)所用模型与数据集的解介绍
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(3)pretrained设置为True或False的区别

  • False:只是加载了网络架构,参数都是初始化的默认参数
  • True:从网络中下载每个卷积层在数据集上训练好的参数
    在这里插入图片描述

(二)修改网络模型的三种方法

import torchvision
from torch import nn# traindata = torchvision.datasets.ImageNet("./data_image_net",split='train',download=True,
#                                           transform=torchvision.transforms.ToTensor())
# The dataset is no longer publicly accessible. You need to download the archives externally and place them in the root directory.# False:只是加载了网络架构,参数都是初始化的默认参数
# True:从网络中下载每个卷积层在数据集上训练好的参数
vgg16_false = torchvision.models.vgg16(pretrained=False)
vgg16_true = torchvision.models.vgg16(pretrained=True)train_data = torchvision.datasets.CIFAR10("./dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)print(vgg16_true)
# CIFAR10 只把数据分成了 10 类,而加载的 vgg16 这个模型把数据分成了 1000 个类,需要修改
# vgg16_true.add_module('add_linear',nn.Linear(1000,10)) # 加在 VGG 大类中加
vgg16_true.classifier.add_module('add_linear',nn.Linear(1000,10)) #在 classifier 最后加
print(vgg16_true)print(vgg16_false)
vgg16_false.classifier[6] = nn.Linear(4096,10) # 修改网络模型
print(vgg16_false)

在这里插入图片描述


二、网络模型的保存与加载

(一)保存网络模型的两种方法

  • 保存方式一:保存了 模型结构 + 模型参数
  • 保存方式二:将网络模型中的参数保存成字典,没有了结构,只保存了模型参数(官方推荐,文件小)
    在这里插入图片描述

model_save.py文件

import torch
import torchvision
from torch import nnvgg16 = torchvision.models.vgg16(pretrained=False)# 保存方式一:保存了 模型结构 + 模型参数
# pth文件是 PyTorch 中常用的一种文件格式,主要用于 保存和加载 模型的参数
torch.save(vgg16,"vgg16_method1.pth")# 保存方式二:将网络模型中的参数保存成字典,没有了结构,只保存了模型参数(官方推荐,文件小)
torch.save(vgg16.state_dict(),"vgg16_method2.pth")# 陷阱
class Li(nn.Module):def __init__(self):super().__init__()self.conv = nn.Conv2d(3,64,3)def forward(self,x):x = self.conv(x)return xli = Li()
torch.save(li,"li_method1.pth")

运行完程序后,在终端中输入 dir即可查看到文件相关信息
在这里插入图片描述

mac 里面的 ls(list) == windows 里面的 dir(directory)

(二)加载网络模型的两种方法

  • 加载模型方式一 对应 保存方式一
  • 加载模型方式二 对应 保存方式二:字典形式,无结构

另:如果要恢复网络模型结构
Step1:新建网络模型结构(默认没有参数)
Step2:通过字典形式加载参数(别人训练好的参数)

model_load.py文件

# import torch
# import torchvision
from model_save import * # *代表导入当前目录下的所有函数 (陷阱的解决方法)# 加载模型方式一:--> 保存方式一
model = torch.load("vgg16_method1.pth")
print(model)# 加载模型方式二:--> 保存方式二:字典形式,无结构
# model = torch.load("vgg16_method2.pth")
# 如果要恢复网络模型结构
# Step1:新建网络模型结构,但是没有参数
vgg16 = torchvision.models.vgg16(pretrained=False)
# Step2:通过字典形式加载参数(别人训练好的参数)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
print(vgg16)
# 此方式在自己的数据集上训练达到理想的效果了之后# 陷阱
model = torch.load("li_method1.pth")
print(model)
# Can't get attribute 'Li' on <module '__main__' from 'D:\\Python\\pythonProject3\\model_load.py'>
# 要把 model_save 中的网络架构复制过来才行,或者直接 import 过来

注:
加载模型的时候,要把 model_save 中的网络架构复制过来才行,或者直接 import 过来


三、完整的模型训练套路

(一)背景知识

(1)有 Dropout,BatchNorm 层才需要在 训练/测试前 把网络设置成 训练/测试模式
在这里插入图片描述
在这里插入图片描述
(2)分类问题中,正确率指标的计算方法
在这里插入图片描述

outputs = torch.tensor([0.1,0.2],[0.3,0.4])
# print(outputs.argmax(1)) # 填 1 的时候横向看,填 0 的时候纵向看(填标号的方向)
# 输出 tensor([1,1]) --> 横向来看:第一行预测在 1 位置,第二行也预测在 1 位置
preds = outputs.argmax(1)
targets = torch.tensor([0,1])
# print(preds == targets) # 输出 tensor([False,True])
print((preds == targets).sum()) # 输出 tensor(1) 计算出对应位置相等的个数,这里正确的个数为1

(3)tensor 类型加不加 .item( ) 的区别

a = torch.tensor(5)
print(a) # 打印 tensor(5)
print(a.item()) # 打印 5

(4)验证集 != 测试集

数据集分3部分:
1)训练集:训练神经网络(平时练习)
2)验证集:看网络效果、修改参数,防止模型过拟合(模拟考)
3)测试集:是最后一步,看网络怎么样(高考)

(5)训练网络的大体流程
准备数据集、dataloader加载数据集,搭建网络模型,创建网络模型实例,定义损失函数,定义优化器,设置网络训练的参数,开始训练,验证模型,最后保存模型。可以将训练结果展示

(二)代码实战

model.py

import torch
from torch import nnclass Li(nn.Module):def __init__(self):super().__init__()self.model = nn.Sequential(nn.Conv2d(3,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,64,5,1,2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self,x):x = self.model(x)return x# 可测试网络的正确性
if __name__ == '__main__': # 相当于 mainli = Li()input = torch.ones((64,3,32,32)) # batch_size = 64,代表有 64 张图片output = li(input)print(output.shape)# 输出 torch.Size([64, 10]) # 含义:返回 64 行数据,每一行数据上面有 10 个数据(代表每一张图片在 10 个类别当中的概率)
# 另:__name__ == '__main__':下的代码只有在文件作为脚本直接执行时,才会被执行
#                            而该.py脚本被 import 到其他脚本中去时,其下的代码就不会被执行

train.py

import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from model import * # 1、被引用的 python 文件首字母不能为数字符号  2、两个文件必须在一个文件夹底下# 准备数据集 (下载数据集,并加载到内存中)
train_data = torchvision.datasets.CIFAR10(root="../dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
# 数据集的长度 (批量处理数据,提供一个迭代访问的接口)
train_data_size = len(train_data) # ctr + D 复制此行内容到下一行
test_data_size = len(test_data)
print(f"训练数据集的长度为:{train_data_size}")
print(f"测试数据集的长度为:{test_data_size}")
# 利用DataLoader加载数据集
train_dataloader = DataLoader(train_data,batch_size=64) # DataLoader 是类,Dataloader 是库
test_dataloader = DataLoader(test_data,batch_size=64)# 搭建神经网络
# 创建网络模型
li = Li()# 创建损失函数 mse用于回归,crossentropy 用于分类
loss_fn = nn.CrossEntropyLoss() # 参数为 optional 即为可选的
# 优化器 SGD(随机梯度下降)  parameter:参数
# learning_rate = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(li.parameters(),lr=learning_rate)
# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10# 添加 tensorboard,画图出来
writer = SummaryWriter("../logs_train")for i in range(epoch):print(f"-----------第{i+1}轮训练开始-----------")# Step1:训练步骤开始li.train() # 有 Dropout, BatchNorm 层才需要调用for data in train_dataloader:imgs,targets = dataoutputs = li(imgs)  # 是 10 个类别中的某一个,也就是训练的标准loss = loss_fn(outputs,targets)# 优化器优化模型 --> 梯度清零、反向传播、参数优化、变量加一optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:print(f"训练次数:{total_train_step},Loss:{loss.item()}")writer.add_scalar("train_loss",loss.item(),total_train_step)# Step2:测试步骤开始(不需要调优,在现有的模型上测试),看看模型有没有训练好,是否达到需求li.eval() # 有 Dropout,BatchNorm 层才需要调用total_test_loss = 0  # 想求整个数据集上的 losstotal_accuracy = 0  # 想知道整体正确的个数,正确率:分类问题中特有的衡量指标with torch.no_grad():  # 不调优了for data in test_dataloader:imgs,targets = dataoutputs = li(imgs)loss = loss_fn(outputs,targets)total_test_loss = total_test_loss + loss.item()accuracy = (outputs.argmax(1) == targets).sum()  # outputs.argmax(1) 横向比较单张图片的各种类别概率,求最大total_accuracy = total_accuracy + accuracy  # 整个测试集上正确的个数total_test_step = total_test_step + 1print(f"整体测试集上的Loss:{total_test_loss}")print(f"整体测试集上的正确率:{total_accuracy/test_data_size}")writer.add_scalar("test_loss",total_test_loss,total_test_step) # 深色线:平滑处理,浅色线:真实曲线writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)# Step3:保存每一轮训练的模型结果torch.save(li,f"li_{i}.pth")# torch.save(li.state_dict(),f"li_{}.pth")print("模型已保存")writer.close()

在这里插入图片描述
在这里插入图片描述


四、GPU 训练

用GPU训练,只需要改动代码中网络模型、数据(输入图片&标注)、损失函数这三个部分即可

(一)训练方式1 — 调用 .cuda( ) 来改

import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import time # 用来计时# 准备数据集
train_data = torchvision.datasets.CIFAR10(root="../dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
# 数据集的长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print(f"训练数据集的长度为:{train_data_size}") 
print(f"测试数据集的长度为:{test_data_size}") 
# 加载数据集
train_dataloader = DataLoader(train_data,batch_size=64) # DataLoader是类,Dataloader是库
test_dataloader = DataLoader(test_data,batch_size=64)# 搭建神经网络
class Li(nn.Module):def __init__(self):super().__init__()self.model = nn.Sequential(nn.Conv2d(3,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,64,5,1,2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self,x):x = self.model(x)return x# <<<<<<<<<<<网络模型>>>>>>>>>>>>>
li = Li()
#################################################################
if torch.cuda.is_available():li = li.cuda() # Moves all model parameters and buffers to the GPU
################################################################## <<<<<<<<<<<损失函数>>>>>>>>>>>>>
loss_fn = nn.CrossEntropyLoss()
#################################################################
if torch.cuda.is_available():loss_fn = loss_fn.cuda()
################################################################## 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(li.parameters(),lr=learning_rate)total_train_step = 0
total_test_step = 0
epoch = 10writer = SummaryWriter("../logs_train")
start_time = time.time() # 用 time 库中的 .time() 记录当前时间for i in range(epoch):print(f"-----------第{i+1}轮训练开始-----------")# 训练步骤开始li.train() for data in train_dataloader:# <<<<<<<<<<<数据>>>>>>>>>>>>>imgs,targets = data########################################if torch.cuda.is_available():imgs = imgs.cuda()targets = targets.cuda()########################################outputs = li(imgs)  loss = loss_fn(outputs,targets)optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:end_time = time.time() # 用 time 库中的 .time() 记录当前时间print(end_time - start_time)print(f"训练次数:{total_train_step},Loss:{loss.item()}")writer.add_scalar("train_loss",loss.item(),total_train_step)# 测试步骤开始li.eval()total_test_loss = 0total_accuracy = 0 with torch.no_grad():  for data in test_dataloader:# <<<<<<<<<<<数据>>>>>>>>>>>>>imgs,targets = data########################################if torch.cuda.is_available():imgs = imgs.cuda()targets = targets.cuda()########################################outputs = li(imgs)loss = loss_fn(outputs,targets)total_test_loss = total_test_loss + loss.item()accuracy = (outputs.argmax(1) == targets).sum()  total_accuracy = total_accuracy + accuracyprint(f"整体测试集上的Loss:{total_test_loss}")print(f"整体测试集上的正确率:{total_accuracy/test_data_size}")writer.add_scalar("test_loss",total_test_loss,total_test_step)writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)total_test_step = total_test_step + 1# 保存每一轮训练的结果torch.save(li,f"li_{i}.pth")# torch.save(li.state_dict(),f"li_{}.pth")print("模型已保存")writer.close()

查看云端GPU的配置
在这里插入图片描述
运行程序
在这里插入图片描述

(二)训练方式2 — 调用 .to( device ) 来改

可以用 device = torch.device(“cuda:序号”) 来指定用电脑中那一张显卡
device = torch.device(“cuda”)device = torch.device(“cuda:0”) 两者无差别

import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import time ##########################################################
# <<<<<<<<<<<<<定义训练的设备>>>>>>>>>>>>>>>
# device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 语法糖
device = torch.device("cuda") # 更常用
########################################################### 准备数据集 
train_data = torchvision.datasets.CIFAR10(root="../dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10(root="../dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
# 数据集的长度
train_data_size = len(train_data) 
test_data_size = len(test_data)
print(f"训练数据集的长度为:{train_data_size}") 
print(f"测试数据集的长度为:{test_data_size}") 
# 加载数据集
train_dataloader = DataLoader(train_data,batch_size=64) 
test_dataloader = DataLoader(test_data,batch_size=64)# 搭建神经网络
class Li(nn.Module):def __init__(self):super().__init__()self.model = nn.Sequential(nn.Conv2d(3,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,64,5,1,2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self,x):x = self.model(x)return x# <<<<<<<<<<<<<网络模型>>>>>>>>>>>>>>>
li = Li()
##########################################################
# li = li.to(device) # 将网络转移到设备上去
li.to(device)
########################################################### <<<<<<<<<<<<<损失函数>>>>>>>>>>>>>>>
loss_fn = nn.CrossEntropyLoss() 
##########################################################
# loss_fn = loss_fn.to(device)
loss_fn.to(device)
########################################################### 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(li.parameters(),lr=learning_rate)total_train_step = 0
total_test_step = 0
epoch = 10writer = SummaryWriter("../logs_train")
start_time = time.time()for i in range(epoch):print(f"-----------第{i+1}轮训练开始-----------")# 训练步骤开始li.train()for data in train_dataloader:imgs,targets = data#################################################imgs = imgs.to(device)targets = targets.to(device)#################################################outputs = li(imgs) loss = loss_fn(outputs,targets)optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:end_time = time.time()print(end_time - start_time)print(f"训练次数:{total_train_step},Loss:{loss.item()}")writer.add_scalar("train_loss",loss.item(),total_train_step)# 测试步骤开始li.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs,targets = data##########################################imgs = imgs.to(device)targets = targets.to(device)##########################################outputs = li(imgs)loss = loss_fn(outputs,targets)total_test_loss = total_test_loss + loss.item()accuracy = (outputs.argmax(1) == targets).sum()  total_accuracy = total_accuracy + accuracyprint(f"整体测试集上的Loss:{total_test_loss}")print(f"整体测试集上的正确率:{total_accuracy/test_data_size}")writer.add_scalar("test_loss",total_test_loss,total_test_step) writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)total_test_step = total_test_step + 1# 保存每一轮训练的结果torch.save(li,f"li_{i}.pth")# torch.save(li.state_dict(),f"li_{}.pth")print("模型已保存")writer.close()

五、完整的模型验证套路(测试 / demo)

利用已经训练好的模型,给它提供输入(应用到实际的环境当中,下面随便找到物体图片就是应用)
在这里插入图片描述

import torch
import torchvision
from PIL import Image
from torch import nnimage_path = "../imgs/dog.png" # ../ 到上一层级文件夹里找
image = Image.open(image_path)
print(image)
# <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=348x238 at 0x135148BC6A0>
# png格式是 4 通道(RGBA):除 RGB 三通道外,还有一个透明度通道。但我们只想保留其颜色通道
image = image.convert('RGB')# 要将图片调整成符合要调用的网络模型的大小,才可正常输入
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),torchvision.transforms.ToTensor()])image = transform(image)
print(image.shape)class Li(nn.Module):def __init__(self):super().__init__()self.model = nn.Sequential(nn.Conv2d(3,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,32,5,1,2),nn.MaxPool2d(2),nn.Conv2d(32,64,5,1,2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64*4*4,64),nn.Linear(64,10))def forward(self,x):x = self.model(x)return x# 加载网络模型
# 注:在CPU上加载GPU上训练的模型,要加映射 map_location
model = torch.load("../complete_model_training/li_29_gpu.pth",map_location=torch.device('cpu'))
print(model)
image = torch.reshape(image,(1,3,32,32)) # 网络训练往往需要bach_sizes
model.eval() # 将模型转化为测试类型
with torch.no_grad(): # with 自动处理对文件的关闭操作output = model(image)
print(output)print(output.argmax(1))

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


六、看看GitHub上的开源项目

(一)看一个项目,先看README

里面有安装、训练、测试模型的方法,需要环境配置的版本,还需要注意什么
在这里插入图片描述

在这里插入图片描述

(二)再看 train.py 文件中的整体架构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(三)将函数中 required=True 的地方用 default= ……替换

在这里插入图片描述
在这里插入图片描述


相关文章:

PyTorch深度学习快速入门(下)

PyTorch深度学习快速入门&#xff08;下&#xff09; 一、现有网络模型的使用及修改&#xff08;一&#xff09;背景知识&#xff08;二&#xff09;修改网络模型的三种方法 二、网络模型的保存与加载&#xff08;一&#xff09;保存网络模型的两种方法&#xff08;二&#xff…...

轻松入门Linux—CentOS,直接拿捏 —/— <1>

一、什么是Linux Linux是一个开源的操作系统&#xff0c;目前是市面上占有率极高的服务器操作系统&#xff0c;目前其分支有很多。是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统 Linux能运行主要的UNIX工具软件、应用程序和网络协议 Linux支持 32…...

pandas安装以及导入CSV

安装pandas pip install pandas速度慢可以切换国内镜像源 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas执行导入csv操作 import pandas as pd# 读取csv文件 data pd.read_csv(yourPath)输入data查看数据 导入成功&#xff01;...

新能源车浪潮来袭,同时存在高压低压系统,如何准确进行高低压布线间距EMC分析?

摘要 随着车辆电气化水平的逐步提升&#xff0c;电气零部件布局和布线面临着前所未有的挑战&#xff0c;在不断的压缩电气零部件间间距后&#xff0c;EMC性能成为非常关键的性能指标。特别是对于新能源车型&#xff0c;同时存在高压和低压系统&#xff0c;高低压耦合若处理的不…...

QUIC 协议

详解 QUIC 协议&#xff1a;它为何比 TCP 更优越&#xff1f;...

【软件测试】--接口测试

1. 接口用例设计 接口测试的测试点 功能测试 单接口功能&#xff1a; 手工测试中的单个业务模块&#xff0c;一般对应一个接口 登陆业务 --> 登陆接口加入购物车业务 --> 加入购物车接口订单业务 --> 订单接口支付业务 --> 支付接口 借助工具、代码。绕开前端界面…...

【前端】上传视频,截取第一帧图片

使用input上传视频&#xff0c;获得视频的第一帧 参考&#xff1a;JavaScript获取视频的尺寸信息和第一帧图片 - 掘金 (juejin.cn) html&#xff1a; <inputbind:this{uploadRef}on:change{handleUpload}accept"video/*"type"file"/>视频类型校验&a…...

Redis-GEO数据结构的基本用法

GEO就是Geolocation的简写形式&#xff0c;代表地理坐标。Redis在3.2版本中加入了对GEO的支持&#xff0c;允许存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。常见的命令有&#xff1a; GEOADD&#xff1a;添加一个地理空间信息&#xff0c;包含&#xff1a;经度…...

【Linux C | 网络编程】进程池大文件传输的实现详解(三)

上一篇实现了进程池的小文件传输&#xff0c;使用自定义的协议&#xff0c;数据长度数据本身&#xff0c;类似小火车的形式&#xff0c;可以很好的解决TCP“粘包”的问题。 【Linux C | 网络编程】进程池小文件传输的实现详解&#xff08;二&#xff09; 当文件的内容大小少于…...

Mac如何通过SSH连接Github

目录 前言 一、实现步骤 1.生成 SSH 密钥对 2.添加 SSH 密钥到 GitHub&#xff1a; 3.配置 SSH 连接 1.更新远程仓库 URL 2.测试 SSH 连接 前言 GitHub 在 2021 年 8 月 13 日停止了对使用密码进行身份验证的支持。因此&#xff0c;你需要使用其他认证方式&#xff0c;如…...

成就巴西休闲游戏如何借助Google谷歌广告投放优势

在探讨巴西休闲游戏如何借助谷歌广告投放优势实现市场扩张的过程中&#xff0c;我们不得不深入分析巴西市场的独特属性、休闲游戏的兴起背景&#xff0c;以及谷歌广告平台在全球范围内的强大影响力。近年来&#xff0c;随着移动游戏市场的快速发展&#xff0c;特别是中轻度休闲…...

利用python检查磁盘空间使用情况

目录 一.前言 二.使用的库介绍 三.代码实现以及解析 3.1导入模块 3.2邮件发送函数 send_email 3.3检查磁盘空间函数 check_and_clean_disk 3.4主程序逻辑 四.致谢 一.前言 在信息技术飞速发展的今天&#xff0c;数据量的激增使得磁盘空间管理成为系统运维中的一项基…...

卷积神经网络(五)---图像增强的方法

前面的部分专注于卷积神经网络的层结构介绍&#xff0c;同时还介绍了到目前为止比较出名的卷积神经网络&#xff0c;接着使用比较复杂的卷积神经网络提高了 MNIST 数据集的准确率。下面将从另外的角度——图像增强的方面入手&#xff0c;提高模型的准确率和泛化能力。 一直以来…...

矩阵常见分解算法及其在SLAM中的应用

文章目录 常见特殊矩阵定义Cholesky分解&#xff08;正定Hermittian矩阵&#xff0c;分解结果唯一&#xff09;Cholesky分解应用 SVD分解&#xff08;将singularvalues排序后分解唯一&#xff09;SVD 分解的应用&#xff08;任意矩阵&#xff09; QR分解&#xff08;任意矩阵&a…...

【排序】快速排序详解

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;排序 个人主页&#xff1a;Celias blog~ 一、快速排序的思想 快速排序的核心思想是&#xff1a; 选定一个…...

贪心算法总结(2)

一、买卖股票的最佳时机 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int maxProfit(vector<int>& prices) {int miniINT_MAX;int ret0;for(int&price:prices){//遍历的时候&#xff0c;我们随时去更新最小的值&#xff0c;然后让每一位…...

弘景光电:技术实力与创新驱动并进

在光学镜头及摄像模组产品领域&#xff0c;广东弘景光电科技股份有限公司&#xff08;以下简称“弘景光电”&#xff09;无疑是一颗耀眼的明星。自成立以来&#xff0c;弘景光电凭借其强大的研发实力、卓越的产品性能、精密的制造工艺以及严格的质量管理体系&#xff0c;在光学…...

2024年7月23日~2024年7月29日周报

目录 一、前言 二、完成情况 2.1 一种具有边缘增强特点的医学图像分割网络 2.2 融合边缘增强注意力机制和 U-Net 网络的医学图像分割 2.3 遇到的困难 三、下周计划 一、前言 上周参加了一些师兄师姐的论文讨论会议&#xff0c;并完成了初稿。 本周继续修改论文&#xff0…...

M3U8流视频数据爬虫

M3U8流视频数据爬虫 HLS技术介绍 现在大部分视频客户端都采用HTTP Live Streaming&#xff08;HLS&#xff0c;Apple为了提高流播效率开发的技术&#xff09;&#xff0c;而不是直接播放MP4等视频文件。HLS技术的特点是将流媒体切分为若干【TS片段】&#xff08;比如几秒一段…...

保护您的数字财富:模块化沙箱在源代码防泄露中的突破

在数字化浪潮中&#xff0c;企业面临着前所未有的数据安全挑战。源代码、商业机密、客户数据……这些宝贵的数字资产一旦泄露&#xff0c;后果不堪设想。SDC沙盒防泄密系统&#xff0c;以其卓越的技术实力和创新的解决方案&#xff0c;为企业提供了一个坚不可摧的安全屏障。 核…...

FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析

一、引言 AVIOContext是FFmpeg&#xff08;本文演示用的FFmpeg源码版本为5.0.3&#xff09;中的字节流上下文结构体&#xff0c;用来管理输入输出数据。打开一个媒体文件的时候&#xff0c;需要先把数据从硬盘读到缓冲区&#xff0c;然后会用到AVIOContext中的如下成员&#x…...

如何使用 API 查看极狐GitLab 镜像仓库中的镜像?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…...

软件-vscode-plantUML-IDEA

文章目录 vscode基础命令 实操1. vscode实现springboot项目搭建 &#xff08;包括spring data jpa和sqlLite连接&#xff09; PlantUMLIDEA下载及安装Eval Reset插件配置修改IDEA创建项目的默认目录IDEA配置gitIDEA翻译插件translationIDEA断点调试IDEA全局搜索快捷键不能使用代…...

ES6语法详解,面试必会,通俗易懂版

目录 Set的基本使用WeakSet 使用Set 和 WeakSet 区别内存泄漏示例&#xff1a;使用普通 Set 保存 DOM 节点如何避免这个内存泄漏MapWeakMap 的使用 Set的基本使用 在ES6之前&#xff0c;我们存储数据的结构主要有两种&#xff1a;数组、对象。 在ES6中新增了另外两种数据结构&a…...

CTFshow--Web--代码审计

目录 web301 web302 web303 web304 web305 web306 web307 web308 web309 web310 web301 开始一个登录框, 下意识sql尝试一下 发现 1 的时候会到一个 checklogin.php 的路径下, 但啥也没有 好吧, 这是要审计代码的 ,下载好源码, 开始审计 看了一下源码 , 应该就是sql…...

Java语言程序设计——篇十(1)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 接口介绍 接口概述接口定义接口的实现实战演练 &#x1f445;接口的继承实战演练实战演练 接口的类型常量实战演练 静态方法默认方法解决默认方…...

Qt对比MFC优势

从Qt小白到现在使用了有四年的时间&#xff0c;之前也搞过MFC,WinForm,基本上都是桌面的框架&#xff0c; 从难易程度看MFC>QT>WinForm; 运行的效率上来看MFC>QT>WinForm; 开发效率上WinForm>QT>MFC; 跨平台Qt首选&#xff1b; 界面的美观难易程度Qt>…...

RuntimeError: No CUDA GPUs are available

RuntimeError: No CUDA GPUs are available 目录 RuntimeError: No CUDA GPUs are available 【常见模块错误】 【解决方案】 解决步骤如下&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科…...

URL参数中携带中文?分享 1 段优质 JS 代码片段!

本内容首发于工粽号&#xff1a;程序员大澈&#xff0c;每日分享一段优质代码片段&#xff0c;欢迎关注和投稿&#xff01; 大家好&#xff0c;我是大澈&#xff01; 本文约 800 字&#xff0c;整篇阅读约需 1 分钟。 今天分享一段优质 JS 代码片段&#xff0c;在发送 ajax 请…...

sass的使用

一、变量 //声明一个变量 $highlight-color: #F90; .selected {border: 1px solid $highlight-color; }//编译后 .selected {border: 1px solid #F90; }二、导入 import "xxx.scss"三、混合器简单定义 通过mixin定义&#xff0c;通过include调用 // mixin.scss /…...

【足球走地软件】走地数据分析预测【大模型篇】走地预测软件实战分享

了解什么是走地数据&#xff1f; 走地数据分析&#xff0c;在足球赛事的上下文中&#xff0c;是一种针对正在进行中的比赛进行实时数据分析的方法。这种方法主要用于预测比赛中的某些结果或趋势&#xff0c;如总进球数、比分变化、球队表现等。 在足球走地数据分析中&#xf…...

现在有什么赛道可以干到退休?

最近&#xff0c;一则“90后无论男女都得65岁以后退休”的消息在多个网络平台流传&#xff0c;也不知道是真是假&#xff0c;好巧不巧今天刷热点的时候又看到一条这样的热点&#xff1a;现在有什么赛道可以干到退休&#xff1f; 点进去看了几条热评&#xff0c;第一条热评说的…...

c程序杂谈系列(职责链模式与if_else)

从处理器的角度来说&#xff0c;条件分支会导致指令流水线的中断&#xff0c;所以控制语句需要严格保存状态&#xff0c;因为处理器是很难直接进行逻辑判断的&#xff0c;有可能它会执行一段时间&#xff0c;发现出错后再返回&#xff0c;也有可能通过延时等手段完成控制流的正…...

前端开发技术之CSS(层叠样式表)

盒模型&#xff08;Box Model&#xff09; CSS盒模型描述了如何计算一个元素的总宽度和高度。 它包括以下几个部分&#xff1a; 1. 内容&#xff08;Content&#xff09;&#xff1a;元素的实际内容&#xff0c;比如文本或图片。 2. 内边距&#xff08;Padding&#xff09;&…...

go语言day20 使用gin框架获取参数 使用自定义的logger记录日志

Golang 操作 Logger、Zap Logger 日志_golang zap-CSDN博客 目录 一、 从控制器中获取参数的几种形式 1&#xff09; 页面请求url直接拼接参数。 2&#xff09; 页面请求提交form表单 3&#xff09; 页面请求发送json数据&#xff0c;使用上下文对象c的BindJSON()方法接…...

DHCP笔记

DHCP---动态主机配置协议 作用&#xff1a;为终端动态提供IP地址&#xff0c;子网掩码&#xff0c;网关&#xff0c;DNS网址等信息 具体流程 报文抓包 在DHCP服务器分配iP地址之间会进行广播发送arp报文&#xff0c;接收IP地址的设备也会发送&#xff0c;防止其他设备已经使用…...

TCP为什么需要四次挥手?

tcp为什么需要四次挥手&#xff1f; 答案有两个&#xff1a; 1.将发送fin包的权限交给被动断开发的应用层去处理&#xff0c;也就是让程序员处理 2.接第一个答案&#xff0c;应用层有了发送fin的权限&#xff0c;可以在发送fin前继续向对端发送消息 为了搞清楚这个问题&…...

MySQL 索引相关基本概念

文章目录 前言一. B Tree 索引1. 概念2. 聚集索引/聚簇索引3. 辅助索引/二级索引4. 回表5. 联合索引/复合索引6. 覆盖索引 二. 哈希索引三. 全文索引 前言 InnoDB存储引擎支持以下几种常见索引&#xff1a;BTree索引&#xff0c;哈希索引&#xff0c;全文索引 一. B Tree 索引…...

Neutralinojs教程项目实战初体验(踩坑指南),干翻 electron

Neutralinojs 项目实战初体验&#xff08;踩坑指南&#xff09;&#xff0c;干翻 electron Neutralinojs 官方文档 卧槽卧槽&#xff0c;&#xff01;这个年轻人居然用浏览器把电脑关机了_哔哩哔哩_bilibili正是在下 本教程搭建的是纯原生项目&#xff0c;没有和其它前端框架…...

【轻松拿捏】Java-List、Set、Map 之间的区别是什么?

List、Set、Map 之间的区别是什么&#xff1f; 一、List 二、Set 三、Map &#x1f388;边走、边悟&#x1f388;迟早会好 一、List 有序性&#xff1a;List 保持元素的插入顺序&#xff0c;即元素按添加的顺序存储和访问。允许重复&#xff1a;List 可以包含重复的元素。…...

用户史订单查询业务

文章目录 概要整体架构流程技术细节小结 概要 在电商、金融、物流等行业中&#xff0c;用户历史订单查询是一项常见的业务需求。这项功能允许用户查看他们过去的交易记录&#xff0c;包括但不限于购买的商品、服务详情、交易金额、支付状态、配送信息等。对于企业而言&#xf…...

第8节课:CSS布局与样式——掌握盒模型与定位的艺术

目录 盒模型&#xff1a;网页布局的基础盒模型的属性盒模型的示例 定位&#xff1a;控制元素位置定位的类型定位的示例 实践&#xff1a;使用CSS布局创建响应式网页结语 CSS布局是网页设计中的基石&#xff0c;它决定了网页元素的排列和分布。盒模型和定位是CSS布局中的两个核心…...

electron 主进程和渲染进程

最近在整理electron 相关的项目问题&#xff0c;对自己来说也是温故知新&#xff0c;也希望能对小伙伴们有所帮助&#xff0c;大家共同努力共同进步。加油&#xff01;&#xff01;&#xff01;&#xff01; 虽然最近一年前端大环境不好&#xff0c;但是大家还是要加油鸭&#…...

redis的高可用及性能管理和雪崩

redis的高可用 redis当中&#xff0c;高可用概念更宽泛一些。 除了正常服务以外&#xff0c;数据量的扩容&#xff0c;数据安全。 实现高可用的方式&#xff1a; 1、持久化 最简单的高可用方法&#xff0c;主要功能就是备份数据。 把内存当中的数据保存到硬盘当中。 2、主…...

php基础语法

文章目录 1. PHP(1) 安装php 2. 基础语法(1) 格式(2) 输出语法(3) 注释(4) 变量(无变量类型自动识别)(5) 输入获取(6) 定界符(7) 换行 3. 基本数据类型(1) 字符串(2) 整数(3). 浮点数(4). boolean类型(5). 数组(6). null值 4. 运算符(1) 算术运算符(2) 比较运算符(3) 逻辑运算符…...

js抓取短信验证码发送

油猴(Tampermonkey)是一个流行的浏览器扩展,它允许用户在浏览器中运行自定义的JavaScript脚本。下面是一个简单的示例脚本,用于收集网站上发送短信验证码的API请求,并以JSON格式存储这些信息。请注意,这个脚本需要根据实际网站的API请求进行调整,因为不同的网站可能有不…...

视频怎么加密?常见的四种视频加密方法和软件

视频加密是一种重要的技术手段&#xff0c;用于保护视频内容不被未经授权的用户获取、复制、修改或传播。在加密过程中&#xff0c;安企神软件作为一种专业的加密工具&#xff0c;可以发挥重要作用。 以下将详细介绍如何使用安企神软件对视频进行加密&#xff0c;并探讨视频加密…...

聚焦全局应用可用性的提升策略,详解GLSB是什么

伴随互联网的快速发展和全球化趋势的深入&#xff0c;企业对网络应用的需求日渐增长。为满足全球范围内用户大量的访问需求&#xff0c;同时解决容灾、用户就近访问以及全球应用交付等问题&#xff0c;GLSB&#xff08;全局负载均衡&#xff09;也因此应运而生。那么GLSB是什么…...

无水印下载视频2——基于tkinter完成头条视频的下载

在数字化时代的浪潮中&#xff0c;视频内容以其丰富性和便捷性&#xff0c;逐渐成为了我们获取信息和娱乐的重要途径。尤其是在短视频平台上&#xff0c;各种创意十足、内容精彩的视频层出不穷&#xff0c;更是吸引了数以亿计的用户。然而&#xff0c;随着视频内容的增加&#…...

Java学习Day17:基础篇7

继承 Java中的继承是面向对象编程中的一个核心概念&#xff0c;它允许我们定义一个类&#xff08;称为子类或派生类&#xff09;来继承另一个类&#xff08;称为父类或基类&#xff09;的属性和方法。继承提高了代码的复用性&#xff0c;使得我们不必从头开始编写所有的代码&a…...