深度学习(三):pytorch搭建卷积神经网络

news2024/12/24 9:20:01

1.常用函数介绍

0 设备准备

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

这行代码是用来选择设备的,根据是否有可用的 CUDA 设备来选择使用 GPU 还是 CPU 进行计算。

更详细的解释如下:

  1. torch.cuda.is_available():这个函数用来检查是否有可用的 CUDA 设备。如果返回 True,表示有可用的 CUDA 设备;如果返回 False,表示没有可用的 CUDA 设备。

  2. "cuda:0""cpu":这是设备的标识符。"cuda:0" 表示选择第一个可用的 CUDA 设备,而 "cpu" 表示选择 CPU 设备。

  3. torch.device():这是一个用来表示设备的类。通过传入设备标识符,可以创建一个设备对象。

  4. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu"):这行代码使用了条件语句,如果有可用的 CUDA 设备,则选择 "cuda:0",否则选择 "cpu"。然后将选择的设备赋值给 device 变量。

这行代码的作用是根据是否有可用的 CUDA 设备来选择使用 GPU 还是 CPU 进行计算。在后续的代码中,可以使用 device 变量来指定模型和张量所在的设备,以便进行相应的计算。例如:

model = YourModel().to(device)
input_tensor = input_tensor.to(device)

这样就可以将模型和输入数据都移动到指定的设备上进行计算。如果有可用的 CUDA 设备,计算将在 GPU 上进行;如果没有可用的 CUDA 设备,计算将在 CPU 上进行。

1.1 数据集

1.1.1数据集对象创建

在PyTorch中,数据集对象通常继承自torch.utils.data.Dataset类。创建数据集对象时,需要重写__len__()__getitem__()方法。下面是一个创建自定义数据集对象的示例:

import torch
from torch.utils.data import Dataset

class MyDataset(Dataset):
   def __init__(self, data):
       self.data = data

   def __len__(self):
       return len(self.data)

   def __getitem__(self, index):
       x = self.data[index][0]
       y = self.data[index][1]
       return x, y
#测试用例
data = [(torch.randn(10), torch.randint(0, 2, (1,))) for _ in range(100)]
dataset = MyDataset(data)

在这个例子中,我们创建了一个名为MyDataset的自定义数据集类,它继承自torch.utils.data.Dataset类。

  • __init__()方法中,我们接收一个数据列表data,并将其存储在类属性self.data中。
  • __len__()方法返回数据集的长度,即len(self.data)
  • __getitem__()方法根据索引index返回数据集中的一个样本。

在这个例子中,我们假设每个样本由一个特征向量和一个标签组成,所以我们从数据列表中取出特征向量和标签,并将其作为返回值。我们创建了一个包含100个样本的数据集,每个样本由一个10维的特征向量和一个0到1之间的二进制标签组成。然后,我们将这个数据集传递给MyDataset类,创建一个数据集对象。

1.1.2 数据集划分

在 PyTorch 中,可以使用 torch.utils.data.random_split() 函数来随机划分数据集。

下面是一个示例代码,展示了如何使用 random_split() 函数随机划分数据集:

from torch.utils.data import random_split

# 创建一个数据集对象
dataset = ...

# 计算数据集的大小
dataset_size = len(dataset)

# 计算训练集和验证集的大小
train_size = int(0.8 * dataset_size)
val_size = dataset_size - train_size

# 使用 random_split() 函数随机划分数据集
train_dataset, val_dataset = random_split(dataset, [train_size, val_size])

在这个例子中,我们首先创建了一个数据集对象 dataset。然后,我们计算了数据集的大小 dataset_size。接下来,我们计算了训练集和验证集的大小,并将它们分别设置为 train_sizeval_size。最后,我们使用 random_split() 函数将数据集随机划分为训练集和验证集,并将它们分别存储在 train_datasetval_dataset 变量中。

需要注意的是,random_split() 函数会打乱数据集的顺序。因此,划分的训练集和验证集的顺序是随机的。

1.1.3 数据集加载器

在PyTorch中,可以使用torch.utils.data.DataLoader类加载数据集。下面是一个使用DataLoader加载自定义数据集的示例:

# 创建数据加载器
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)

# 使用数据加载器
for batch_idx, (inputs, targets) in enumerate(dataloader):
   print(f"Batch {batch_idx}:")
   print(f"  Inputs: {inputs.shape}")
   print(f"  Targets: {targets.shape}")

使用torch.utils.data.DataLoader类将其转换为数据加载器dataloaderDataLoader类需要两个参数:数据集对象dataset和批次大小batch_sizeshuffle参数设置为True,表示在训练过程中对数据进行随机打乱。

最后,我们使用for循环遍历数据加载器,并每次从数据加载器中获取一个批次的数据,将其存储在inputstargets变量中。我们可以使用print()函数输出每个批次的数据形状。在这个例子中,我们假设每个批次的大小为10,并且每个样本的特征向量大小为10,新的二进制标签大小为1。

1.2卷积网络结构

1.2.1 参数配置

  1. torch.nn.Linear:

    • 用法:torch.nn.Linear(in_features, out_features, bias=True)
    • 参数:
      • in_features:输入特征的大小。
      • out_features:输出特征的大小。
      • bias:是否使用偏置项,默认为True。
    • 用途:线性层用于进行线性变换,将输入特征映射到输出特征空间。
  2. torch.nn.Conv2d:

    • 用法:torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, bias=True)
    • 参数:
      • in_channels:输入通道数。
      • out_channels:输出通道数。
      • kernel_size:卷积核的大小。
      • stride:卷积步长,默认为1。
      • padding:填充大小,默认为0。
      • bias:是否使用偏置项,默认为True。
    • 用途:二维卷积层用于处理二维输入数据,例如图像。
  3. torch.nn.ConvTranspose2d:

    • 用法:torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, bias=True)
    • 参数:
      • in_channels:输入通道数。
      • out_channels:输出通道数。
      • kernel_size:卷积核的大小。
      • stride:卷积步长,默认为1。
      • padding:填充大小,默认为0。
      • output_padding:输出填充大小,默认为0。
      • bias:是否使用偏置项,默认为True。
    • 用途:二维转置卷积层用于将低维特征图转换为高维特征图,常用于图像生成任务或图像分割任务。
  4. torch.nn.MaxPool2d:

    • 用法:torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
    • 参数:
      • kernel_size:池化窗口的大小。
      • stride:池化步长,默认为None,表示与kernel_size相同。
      • padding:填充大小,默认为0。
      • dilation:扩张率,默认为1。
      • return_indices:是否返回池化操作的索引,默认为False。
      • ceil_mode:是否使用向上取整的方式计算输出大小,默认为False。
    • 用途:二维最大池化层用于减小特征图的空间尺寸,并保留最显著的特征。
  5. torch.nn.AvgPool2d:

    • 用法:torch.nn.AvgPool2d(kernel_size, stride=None, padding=0, ceil_mode=False, count_include_pad=True, divisor_override=None)
    • 参数:
      • kernel_size:池化窗口的大小。
      • stride:池化步长,默认为None,表示与kernel_size相同。
      • padding:填充大小,默认为0。
      • ceil_mode:是否使用向上取整的方式计算输出大小,默认为False。
      • count_include_pad:是否将填充值包含在计算中,默认为True。
      • divisor_override:覆盖除数的值,默认为None。
    • 用途:二维平均池化层用于减小特征图的空间尺寸,并对每个池化窗口内的特征进行平均。
  6. torch.nn.BatchNorm2d:

    • 用法:torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    • 参数:
      • num_features:输入特征的通道数。
      • eps:数值稳定性参数,默认为1e-05。
      • momentum:动量参数,用于计算移动平均和方差,默认为0.1。
      • affine:是否使用可学习的缩放和偏移参数,默认为True。
      • track_running_stats:是否跟踪运行时的统计信息,默认为True。
    • 用途:二维批归一化层用于加速神经网络的训练过程和提高模型的泛化能力,对每个通道的特征进行归一化,并通过学习可调参数来进一步调整特征的均值和方差。
  7. torch.nn.ReLU:

    • 用法:torch.nn.ReLU(inplace=False)
    • 参数:
      • inplace:是否进行原地操作,默认为False。
    • 用途:ReLU激活函数用于引入非线性性,将负值置为零。
  8. torch.nn.Dropout:

    • 用法:torch.nn.Dropout(p=0.5, inplace=False)
    • 参数:
      • p:丢弃概率,默认为0.5。
      • inplace:是否进行原地操作,默认为False。
    • 用途:随机失活层用于在训练过程中随机丢弃一部分神经元,以减少过拟合。

1.2.2代码实例

  1. torch.nn.Linear:
import torch
import torch.nn as nn

# 创建一个线性层,输入特征大小为10,输出特征大小为5
linear_layer = nn.Linear(10, 5)

# 创建一个随机输入张量
input_tensor = torch.randn(3, 10)

# 将输入张量传递给线性层进行线性变换
output = linear_layer(input_tensor)

print(output.shape)  # 输出: torch.Size([3, 5])
  1. torch.nn.Conv2d:
import torch
import torch.nn as nn

# 创建一个二维卷积层,输入通道数为3,输出通道数为16,卷积核大小为3x3
conv_layer = nn.Conv2d(3, 16, kernel_size=3)

# 创建一个随机输入张量,大小为(batch_size, channels, height, width)
input_tensor = torch.randn(4, 3, 32, 32)

# 将输入张量传递给卷积层进行卷积操作
output = conv_layer(input_tensor)

print(output.shape)  # 输出: torch.Size([4, 16, 30, 30])
  1. torch.nn.ConvTranspose2d:
import torch
import torch.nn as nn

# 创建一个二维转置卷积层,输入通道数为16,输出通道数为8,卷积核大小为4x4
conv_transpose_layer = nn.ConvTranspose2d(16, 8, kernel_size=4)

# 创建一个随机输入张量,大小为(batch_size, channels, height, width)
input_tensor = torch.randn(4, 16, 14, 14)

# 将输入张量传递给转置卷积层进行转置卷积操作
output = conv_transpose_layer(input_tensor)

print(output.shape)  # 输出: torch.Size([4, 8, 17, 17])
  1. torch.nn.MaxPool2d:
import torch
import torch.nn as nn

# 创建一个二维最大池化层,池化窗口大小为2x2
maxpool_layer = nn.MaxPool2d(kernel_size=2)

# 创建一个随机输入张量,大小为(batch_size, channels, height, width)
input_tensor = torch.randn(4, 3, 32, 32)

# 将输入张量传递给最大池化层进行池化操作
output = maxpool_layer(input_tensor)

print(output.shape)  # 输出: torch.Size([4, 3, 16, 16])
  1. torch.nn.AvgPool2d:
import torch
import torch.nn as nn

# 创建一个二维平均池化层,池化窗口大小为2x2
avgpool_layer = nn.AvgPool2d(kernel_size=2)

# 创建一个随机输入张量,大小为(batch_size, channels, height, width)
input_tensor = torch.randn(4, 3, 32, 32)

# 将输入张量传递给平均池化层进行池化操作
output = avgpool_layer(input_tensor)

print(output.shape)  # 输出: torch.Size([4, 3, 16, 16])
  1. torch.nn.BatchNorm2d:
import torch
import torch.nn as nn

# 创建一个二维批归一化层,输入特征通道数为3
batchnorm_layer = nn.BatchNorm2d(3)

# 创建一个随机输入张量,大小为(batch_size, channels, height, width)
input_tensor = torch.randn(4, 3, 32, 32)

# 将输入张量传递给批归一化层进行归一化操作
output = batchnorm_layer(input_tensor)

print(output.shape)  # 输出: torch.Size([4, 3, 32, 32])
  1. torch.nn.ReLU:
import torch
import torch.nn as nn

# 创建一个ReLU激活函数
relu = nn.ReLU()

# 创建一个随机输入张量
input_tensor = torch.randn(3, 5)

# 将输入张量传递给ReLU激活函数进行非线性变换
output = relu(input_tensor)

print(output)
  1. torch.nn.Dropout:
import torch
import torch.nn as nn

# 创建一个随机失活层,丢弃概率为0.5
dropout_layer = nn.Dropout(p=0.5)

# 创建一个随机输入张量
input_tensor = torch.randn(3, 5)

# 将输入张量传递给随机失活层进行随机丢弃
output = dropout_layer(input_tensor)

print(output)

1.2.3 动手实践

#搭建神经网络
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        
        self.conv1 = nn.Conv2d(1,6,5)
        self.conv2 = nn.Conv2d(6,16,5)
        
        self.fc1 = nn.Linear(16*8*8,120)
        self.fc2 = nn.Linear(120,84)
    def forward(self,x):
        input_size=x.size(0)
        x=self.conv1(x)
        #print(x.size())
        x=F.relu(x)
        x=F.max_pool2d(x,2)
        
        x=self.conv2(x)
        #print(x.size())
        x=F.relu(x)
        
        x=x.view(input_size,-1)
        
        x=self.fc1(x)
        #print(x.size())
  
        x=F.relu(x)
        
        x=self.fc2(x)
        return F.log_softmax(x,dim=1)

1.3训练迭代

使用优化器进行模型训练时,可以根据需要选择不同的优化器算法和设置不同的参数。

  1. 创建优化器对象:

    optimizer = torch.optim.Optimizer(model.parameters(), lr=learning_rate)
    

    这里的 model.parameters() 是指模型的可学习参数,lr 是学习率(learning rate)。除了学习率,还可以设置其他参数,如权重衰减(weight decay)、动量(momentum)等。

  2. 在每个训练迭代中进行以下步骤:

    • 清零梯度:optimizer.zero_grad()
    • 前向传播:计算模型的输出
    • 计算损失:根据模型输出和目标值计算损失函数的值
    • 反向传播:计算梯度,使用 loss.backward() 方法
    • 更新参数:调用 optimizer.step() 方法来更新模型的参数
  3. 设置不同的优化器参数:

    • 学习率调整:可以使用 optimizer.param_groups 获取优化器的参数组,并对每个参数组设置不同的学习率。
    • 权重衰减:可以通过设置 weight_decay 参数来应用 L2 正则化,以减小模型参数的大小。
    • 动量:对于带有动量的优化器(如 SGD、Adam),可以设置 momentum 参数来控制动量的大小。

下面是一个更详细的示例代码片段,展示了优化器的用法:

import torch
import torch.nn as nn
import torch.optim as optim

# 创建模型实例(这里是你创建的模型)
model = YourModel()

# 定义损失函数
criterion = nn.CrossEntropyLoss()

# 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=0.001, momentum=0.9)

# 在每个训练迭代中进行以下步骤:
for inputs, labels in dataloader:
    # 清零梯度
    optimizer.zero_grad()

    # 前向传播
    outputs = model(inputs)

    # 计算损失
    loss = criterion(outputs, labels)

    # 反向传播
    loss.backward()

    # 更新参数
    optimizer.step()

1.4模型评估

model.eval() 是一个模型方法,用于将模型设置为评估模式。在评估模式下,模型会禁用一些特定的操作,如 Dropout 层和批归一化层的随机性,以确保输出的一致性和可重复性。

更详细的用法如下:

  1. 设置模型为评估模式:

    model.eval()
    

    这将把模型设置为评估模式,禁用一些随机性操作。

  2. 在评估模式下进行推断或评估:

    with torch.no_grad():
        # 进行推断或评估操作
        output = model(input_tensor)
    

    在评估模式下,通常会使用 torch.no_grad() 上下文管理器来禁用梯度计算,以提高推断或评估的效率。

下面是一个更详细的示例代码片段,展示了 model.eval() 的用法:

import torch
import torch.nn as nn
model.eval()

correct=0

with torch.no_grad():
   for data,target in dataloader:
       output = model(data)
       pred = output.argmax(dim=1,keepdim=True)
       correct+=pred.eq(target.view_as(pred)).sum().item()
return correct/len(dataloader.dataset)

在上述示例中,首先创建了模型实例,然后使用 model.eval() 将模型设置为评估模式。接下来,加载了预训练模型参数,并在评估模式下进行推断或评估操作。使用 torch.no_grad() 上下文管理器来禁用梯度计算,以提高推断或评估的效率。

请注意,model.eval() 方法只是将模型设置为评估模式,并不会自动执行推断或评估操作。你需要根据具体的需求编写相应的代码来进行推断或评估。

1.5 保存模型

保存模型是在训练完成后将模型的参数保存到磁盘上,以便后续加载和使用。以下是保存模型的一般步骤:

  1. 定义模型:

    model = YourModel()
    
  2. 训练模型:

    # 训练过程...
    
  3. 保存模型参数:

    torch.save(model.state_dict(), 'model.pth')
    

    上述代码将模型的参数保存到名为 'model.pth' 的文件中。model.state_dict() 返回一个包含模型参数的字典,torch.save() 函数将该字典保存到文件中。

完整的示例代码如下:

import torch
import torch.nn as nn

# 定义模型
model = YourModel()

# 训练模型
# ...

# 保存模型参数
torch.save(model.state_dict(), 'model.pth')

保存模型参数后,你可以使用 torch.load() 函数加载模型参数,并将其应用于新的模型实例中:

import torch
import torch.nn as nn

# 定义模型
model = YourModel()

# 加载模型参数
model.load_state_dict(torch.load('CNN.pth'))

通过加载模型参数,你可以恢复之前训练好的模型,并在后续的推断或评估中使用它。

2.在MNIST数据集实验

2.1 结果

数据如图所示
在这里插入图片描述
训练得到,保存模型:
在这里插入图片描述
调用预测:
在这里插入图片描述
调用保存的模型:

在这里插入图片描述

2.2总代码

import torch
from torch.utils.data import Dataset, DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt
import torchvision.transforms as transforms
import torchvision
import torch.nn.functional as F
from torch import nn, optim
import torch
from torch.utils.data import Dataset
import numpy as np

""" class MyDataset(Dataset):
   def __init__(self, data):
       self.data = data

   def __len__(self):
       return len(self.data)

   def __getitem__(self, index):
       x = self.data[index][0]
       y = self.data[index][1]
       return x, y
data = [(torch.randn(10), torch.randint(0, 2, (1,))) for _ in range(100)]
print(data)
dataset = MyDataset(data)
print(dataset)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=10, shuffle=True)"""
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device) 

# 指定数据集的根目录
root = './data'

# 定义数据预处理
transform = transforms.Compose([
   transforms.ToTensor(),
   transforms.Normalize((0.5,), (0.5,))
])

# 加载MNIST数据集
mnist_dataset = torchvision.datasets.MNIST(
   root=root,
   train=True,
   transform=transform,
   download=True
)
print(len(mnist_dataset))
#划分数据集
train_dataset, val_dataset = torch.utils.data.random_split(mnist_dataset, [55000, 5000])

# 创建数据加载器
mnist_train_dataloader = DataLoader(
   dataset=train_dataset,
   batch_size=100,
   shuffle=False,
)
mnist_val_dataloader = DataLoader(
   dataset=val_dataset,
   batch_size=100,
   shuffle=False,
)

#搭建神经网络
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        
        self.conv1 = nn.Conv2d(1,6,5)
        self.conv2 = nn.Conv2d(6,16,5)
        
        self.fc1 = nn.Linear(16*8*8,120)
        self.fc2 = nn.Linear(120,84)
    def forward(self,x):
        input_size=x.size(0)
        x=self.conv1(x)
        #print(x.size())
        x=F.relu(x)
        x=F.max_pool2d(x,2)
        
        x=self.conv2(x)
        #print(x.size())
        x=F.relu(x)
        
        x=x.view(input_size,-1)
        
        x=self.fc1(x)
        #print(x.size())
  
        x=F.relu(x)
        
        x=self.fc2(x)
        return F.log_softmax(x,dim=1)

#训练
def train(epoch_idx,model,dataloader,optimizer):
    model.train()
    
    for batch_idx, (data,target) in enumerate(dataloader):
        optimizer.zero_grad()
        
        output = model(data)
        loss = F.nll_loss(output,target)
        loss.backward()
        optimizer.step()
    
#预测结果
def test(model,dataloader):
    model.eval()
    correct=0
    with torch.no_grad():
        for data,target in dataloader:
            output = model(data)
            pred = output.argmax(dim=1,keepdim=True)
            correct+=pred.eq(target.view_as(pred)).sum().item()
    return correct/len(dataloader.dataset),pred
network = Net().to(device)
""" n_epochs = 10
learning_rate=0.01
optimizer = optim.SGD(network.parameters(), lr=learning_rate)
for i in range(1,n_epochs+1):
  print(f"Epoch {i}\n-------------------------------")
  train(epoch_idx = i, model = network,dataloader = mnist_train_dataloader, optimizer = optimizer)
  accuray,result=test(model = network,dataloader = mnist_val_dataloader)
  print(accuray)
  print(result.shape)
  print("-------------------------------")
torch.save(network.state_dict(), 'CNN.pth') """
network.load_state_dict(torch.load('CNN.pth'))
accuray,result=test(model = network,dataloader = mnist_val_dataloader)
data_loader_iter = iter(mnist_val_dataloader)
while True:
   try:
       item = next(data_loader_iter)
       # 对 item 进行处理
       image, label = item
   except StopIteration:
       break
images=image.numpy()
labels=label.numpy()

fig = plt.figure(figsize=(25,4))
for idx in np.arange(20):
    ax = fig.add_subplot(2,10, idx+1, xticks=[], yticks=[])
    ax.imshow(images[idx][0], cmap='gray')
    ax.set_title('real:'+str(labels[idx].item())+'ped:'+str(result[idx].item()))
plt.show()

    

  



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

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

相关文章

Rust UI开发(5):iced中如何进行页面布局(pick_list的使用)?(串口调试助手)

注:此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库,用于为rust语言程序构建UI界面。 这是一个系列博文,本文是第五篇,前四篇链接: 1、Rust UI开发(一):使用iced构建UI时…

【深度学习】KMeans中自动K值的确认方法

1 前言 聚类常用于数据探索或挖掘前期,在没有做先验经验的背景下做的探索性分析,也适用于样本量较大情况下的数据预处理等方面工作。例如针对企业整体用户特征,在未得到相关知识或经验之前先根据数据本身特点进行用户分群,然后再…

Apache DolphinScheduler 开源之夏采访:苏国伟的开源之旅

个人介绍 大家好,我是苏国伟,来自西安电子科技大学软件工程专业。我在实验室中主要从事数据集成等方面的工作。除了编程,我还热衷于踢足球、观看球赛和健身,这些爱好让我的生活更加丰富多彩。 开源之路 我最初是在本科的分布式…

鸿蒙系统开发手册 - HarmonyOS内核驱动层源码分析

众所周知系统定义HarmonyOS是一款“面向未来”、面向全场景(移动办公、运动健康、社交通信、媒体娱乐等)的分布式操作系统。在传统的单设备系统能力的基础上,HarmonyOS提出了基于同一套系统能力、适配多种终端形态的分布式理念,能…

博文小调研

感谢信 很高兴认识各位盆友,天南地北一家人! 无论身在行业差异,所处职位高低,工作年限长短,这个平台都为爱好学习的人们提供了很好的机会和进步的源动力。 博主今年自11月份开启了新的系列文章,每周发表6…

【Linux】第二十二站:文件(二)深入理解重定向

文章目录 一、重定向1.文件描述符对应的分配规则2.重定向的接口 二、再次实现myshell1.实现细节2.盘点文件与进程替换的一个细节3.代码 三、1号文件和2号文件的区别四、如何理解“一切皆文件?” 一、重定向 1.文件描述符对应的分配规则 我们先看如下代码 #includ…

【Qt开发流程】之打印文档

描述 Qt为打印提供了广泛的跨平台支持。使用每个平台上的打印系统,Qt应用程序可以打印到连接的打印机上,也可以通过网络打印到远程打印机上。Qt的打印系统还支持PDF文件生成,为基本报表生成工具提供了基础。 支持打印的类 下面的类支持选择…

【c++|SDL】三、画图类抽象

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 1. 画图类抽象 之前将画图(显示图像)放在Game.cpp中,现在将其单独放在一个类中, 编译运行为: g m14main.cpp Game.…

Course1-Week3-分类问题

Course1-Week3-分类问题 文章目录 Course1-Week3-分类问题1. 逻辑回归1.1 线性回归不适用于分类问题1.2 逻辑回归模型1.3 决策边界 2. 逻辑回归的代价函数3. 实现梯度下降4. 过拟合与正则化4.1 线性回归和逻辑回归中的过拟合4.2 解决过拟合的三种方法4.3 正则化4.4 用于线性回归…

C语言之结构体详解

C语言之结构体详解 文章目录 C语言之结构体详解1. 结构体类型的声明2. 结构体变量的创建和初始化3. 结构体的特殊声明4. 结构体的自引用结构体的自引用匿名结构体的自引用 5. 结构体内存对齐5.1 练习一5.2 练习三 6. 为什么存在内存对⻬? 1. 结构体类型的声明 struct tag {me…

【Web】UUCTF 2022 新生赛 个人复现

目录 ①websign ②ez_rce ③ez_upload ④ez_unser ⑤ezsql ⑥ezpop ⑦funmd5 ⑧phonecode ⑨ezrce ①websign 右键打不开,直接抓包发包看源码 ②ez_rce “反引号” 在PHP中会被当作SHELL命令执行 ?codeprintf(l\s /); ?codeprintf(ta\c /ffffffffffl…

leetCode 131.分割回文串 + 动态规划 + 回溯算法 + 优化 + 图解 + 笔记

我的往期文章: leetCode 647.回文子串 动态规划 优化空间 / 中心扩展法 双指针-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/133883091?spm1001.2014.3001.5501leetCode 131.分割回文串 回溯算法 图解 笔记-CSDN博客https://blog.csdn.n…

有什么值得推荐的node. js练手项目吗?

前言 可以参考一下下面的nodejs相关的项目,希望对你的学习有所帮助,废话少说,让我们直接进入正题 1、 NodeBB Star: 13.3k 一个基于Node.js的现代化社区论坛软件,具有快速、可扩展、易于使用和灵活的特点。它支持多种数据库&…

在Windows中加密文件或文件夹不需要太大的努力就可以实现,主要有两种加密方法

如果你正在寻找一种在Windows计算机上保持文件和文件夹隐私的简单方法,你有几个选择。 得益于Microsoft Office Suite,你可以使用内置的加密功能对Office文件(如Word文档或PowerPoint演示文稿)进行密码保护。 一些Windows操作系统还配备了加密文件系统(EFS),可以对任何…

Set集合的特点

Set系列集合特点: 无序:添加数据的顺序和获取出的数据顺序不一致;不重复;无索引; HashSet:无序,不重复,无索引 LinkedHashSet:有序,不重复,无索引…

python进阶技巧

1.闭包 通过函数嵌套,可以让内部函数依赖外部变量,可以避免全局变量的污染问题 闭包注意事项: 总结: 2.装饰器 2.1装饰器的一般写法 2.2 装饰器的语法糖写法 def outer(func):def inner():print(睡了)func()print(起床)retur…

Zookeeper从零入门笔记

Zookeeper从零入门笔记 一、入门1. 概述2. 特点3. 数据结构4. 应用场景 二、本地1.安装2. 参数解读 三、集群操作3.1.1 集群安装3.2 选举机制1. 第一次启动2. 非第一次启动 3.3 ZK集群启动停止脚本3.4 客户端命令行操作3.2.1 命令行语法3.2.2 节点类型(持久/短暂/有…

飞致云开源社区月度动态报告(2023年11月)

自2023年6月起,中国领先的开源软件公司FIT2CLOUD飞致云以月度为单位发布《飞致云开源社区月度动态报告》,旨在向广大社区用户同步飞致云旗下系列开源软件的发展情况,以及当月主要的产品新版本发布、社区运营成果等相关信息。 飞致云开源大屏…

传统算法:使用 Pygame 实现选择排序

使用 Pygame 模块实现了选择排序的动画演示。首先,它生成一个包含随机整数的数组,并通过 Pygame 在屏幕上绘制这个数组的条形图。接着,通过选择排序算法对数组进行排序,动画效果可视化每一步的排序过程。在排序的过程中,程序找到未排序部分的最小元素,并将其与未排序部分…

如何获取阿里巴巴中国站按图搜索1688商品(拍立淘) API接口(item_search_img-按图搜索1688商品(拍立淘))

一、背景介绍 阿里巴巴中国站作为中国领先的B2B电子商务平台,提供了大量的商品信息和交易服务。其中,按图搜索1688商品(拍立淘)是阿里巴巴中国站特有的功能之一,它可以通过上传图片来搜索与图片相似的商品&#xff0c…