kaggle竞赛系列基于图像对水稻分类代码案例

news2024/11/24 4:31:03

目录

依赖环境

代码

导入依赖包

定义数据集路径:

创建训练集、验证集和测试集的文件夹:

代码的作用:

设置新的数据集路径与类别名称

代码的作用:

定义数据预处理和增强变换:

代码的作用:

定义数据集评估划分与batch大小

代码的作用:

可视化

代码的作用:

 评估可视化

代码的作用:

网络结构定义

代码的作用:

定义损失函数和优化器,并训练模型

 模型可视化评估

代码的作用:

下载地址:

python深度学习pytorch水稻图像分类完整案例


依赖环境

!pip install split-folders
!pip install torch-summary
!pip install torch matplotplib

代码

导入依赖包

import os
import pathlib
import numpy as np
import splitfolders
import itertools
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from termcolor import colored 
from datetime import datetime
import warnings
from tqdm.notebook import tqdm
from sklearn.metrics import confusion_matrix, classification_report
from torchsummary import summary
from numpy import asarray
from PIL import Image
  • ospathlib 用于文件和目录操作。
  • numpy 用于数组和数值计算。
  • splitfolders 用于分割数据集。
  • itertools 提供迭代生成器。
  • matplotlib.pyplot 用于绘图和数据可视化。
  • torchtorch.nntorch.nn.functionaltorch.optimtorchvisiontorchvision.transforms 用于构建和训练神经网络模型。
  • termcolor 用于终端中的彩色输出。
  • datetime 用于时间操作。
  • warnings 用于忽略警告信息。
  • tqdm.notebook 用于显示进度条。
  • sklearn.metrics 提供评估指标,包括混淆矩阵和分类报告。
  • torchsummary 用于总结模型结构。
  • numpy.asarrayPIL.Image 用于图像处理。

定义数据集路径

data = './Rice_Image_Dataset'
data = pathlib.Path(data)

创建训练集、验证集和测试集的文件夹

splitfolders.ratio(input=data, output='rice_imgs', seed=42, ratio=(0.7, 0.15, 0.15))
  • 使用 splitfolders.ratio 函数将数据集按照 7:1.5:1.5 的比例划分为训练集、验证集和测试集。
  • input 参数指定输入数据集的路径。
  • output 参数指定输出文件夹的名称 'rice_imgs',划分后的数据集将保存在这个文件夹中。
  • seed 参数设置随机种子,以确保划分结果的可重复性。
  • ratio 参数指定训练集、验证集和测试集的比例,分别为 70%、15% 和 15%。

代码的作用:

这段代码通过 splitfolders 库将原始的水稻图像数据集划分为训练集、验证集和测试集,以便在模型训练、验证和测试过程中使用不同的数据子集,从而提高模型的泛化能力和评估准确性。

设置新的数据集路径与类别名称

root_dir = './rice_imgs'
root_dir = pathlib.Path(root_dir)
Arborio='./Rice_Image_Dataset/Arborio'

Arborio_classes=os.listdir(Arborio)
Rice_classes = os.listdir(root_dir)
batchsize=8

from colorama import Fore, Style

print(Fore.GREEN +str(Rice_classes))
print(Fore.YELLOW +"\nTotal number of classes are: ", len(Rice_classes))
  • root_dir 定义为之前划分后的数据集路径 './rice_imgs',并转换为路径对象。
  • Arborio 定义为原始数据集中某个类别的路径。
  • 使用 os.listdir(Arborio) 获取 Arborio 类别中的所有文件和文件夹名称。
  • 使用 os.listdir(root_dir) 获取新的数据集路径中的所有类别名称。
  • 导入 colorama 库中的 ForeStyle,用于终端输出的颜色设置。

代码的作用:

这段代码的主要作用是设置新的数据集路径,并获取数据集中各个类别的名称,以便在后续的数据加载和处理过程中使用。此外,代码还打印出了类别名称和总数,以便进行检查和验证。

定义数据预处理和增强变换

transform = transforms.Compose(
    [
        transforms.Resize((250,250)),
        transforms.ToTensor(),
        transforms.Normalize((0),(1)),
        transforms.RandomHorizontalFlip(),
        transforms.RandomRotation(30),
    ]
)
  • transforms.Compose:将多个变换操作组合在一起。
  • transforms.Resize((250,250)):将图像调整为 250x250 的固定尺寸。
  • transforms.ToTensor():将图像转换为 PyTorch 的张量格式,并将像素值归一化到 [0,1] 的范围。
  • transforms.Normalize((0),(1)):标准化图像,使图像的每个通道均值为 0,标准差为 1。
  • transforms.RandomHorizontalFlip():随机水平翻转图像,用于数据增强,以增加模型的泛化能力。
  • transforms.RandomRotation(30):随机旋转图像最多 30 度,用于数据增强。

代码的作用:

这段代码通过定义一个数据预处理和增强的变换流水线,在加载图像数据时自动对图像进行调整大小、转换为张量、标准化、随机水平翻转和随机旋转等操作。这些预处理和增强操作有助于提高模型的训练效果和泛化能力。

定义数据集评估划分与batch大小

import torch.utils.data
batch_size = 32

# Read train images as a dataset
train_set = torchvision.datasets.ImageFolder(
    os.path.join(root_dir, 'train'), transform=transform
)
# Create a Data Loader
train_loader = torch.utils.data.DataLoader(
    train_set,  batch_size = batch_size, shuffle=True
)
print(colored(f'Train Folder :\n ', 'green', attrs=['bold']))
print(train_set)
print('_'*100)

#############################################################

# Read validation images as a dataset
val_set = torchvision.datasets.ImageFolder(
    os.path.join(root_dir, 'val'), transform=transform
)
# Create a Data Loader
val_loader = torch.utils.data.DataLoader(
    val_set,  batch_size = batch_size, shuffle=True
)
print(colored(f'Validation Folder :\n ', 'red', attrs=['bold']))
print(val_set)
print('_'*100)

#############################################################

# Read test images as a dataset
test_set = torchvision.datasets.ImageFolder(
    os.path.join(root_dir, 'test'), transform=transform
)
# Create a Data Loader
test_loader = torch.utils.data.DataLoader(
    test_set,  batch_size = batch_size, shuffle=True
)
print(colored(f'Test Folder :\n ', 'yellow', attrs=['bold']))
print(test_set)
  1. 设置批量大小

    • 首先导入 torch.utils.data,并设置批量大小为 32,用于后续的数据加载器中。
  2. 加载训练集数据并创建数据加载器

    • 使用 torchvision.datasets.ImageFolder 函数加载训练集图像数据,并应用之前定义的变换 transformos.path.join(root_dir, 'train') 指定了训练集数据的路径。
    • 创建一个数据加载器 train_loader,它从 train_set 中以批量的形式读取数据,batch_size 设置为 32,并启用了随机打乱 shuffle=True
  3. 打印训练集信息

    • 使用 colored 函数将输出文本设置为绿色,并打印训练集文件夹的信息和训练集数据集对象。
  4. 加载验证集数据并创建数据加载器

    • 类似于加载训练集,使用 torchvision.datasets.ImageFolder 函数加载验证集图像数据,并应用相同的变换 transformos.path.join(root_dir, 'val') 指定了验证集数据的路径。
    • 创建一个数据加载器 val_loader,从 val_set 中以批量的形式读取数据,batch_size 设置为 32,并启用了随机打乱 shuffle=True
  5. 打印验证集信息

    • 使用 colored 函数将输出文本设置为红色,并打印验证集文件夹的信息和验证集数据集对象。
  6. 加载测试集数据并创建数据加载器

    • 类似于加载训练集和验证集,使用 torchvision.datasets.ImageFolder 函数加载测试集图像数据,并应用相同的变换 transformos.path.join(root_dir, 'test') 指定了测试集数据的路径。
    • 创建一个数据加载器 test_loader,从 test_set 中以批量的形式读取数据,batch_size 设置为 32,并启用了随机打乱 shuffle=True
  7. 打印测试集信息

    • 使用 colored 函数将输出文本设置为黄色,并打印测试集文件夹的信息和测试集数据集对象。

代码的作用:

这段代码通过加载和处理训练集、验证集和测试集的数据,创建了相应的数据加载器。这些加载器将在模型训练和评估过程中使用,以批量的形式高效地读取和处理图像数据,从而提高模型训练和评估的效率。

可视化

# 可视化数据集以进行检查
# 首先创建一个包含标签名称的字典
labels_map = {
    0: "Arborio",
    1: "Basmati",
    2: "Ipsala",
    3: "Jasmine",
    4: "Karacadag",
}

figure = plt.figure(figsize=(10, 10))
cols, rows = 5, 5
for i in range(1, cols * rows + 1):
    sample_idx = torch.randint(len(train_set), size=(1,)).item()
    img, label = train_set[sample_idx]
    figure.add_subplot(rows, cols, i)
    plt.title(labels_map[label])
    plt.axis("off")
    img_np = img.numpy().transpose((1, 2, 0))
    # 将像素值剪辑到 [0, 1] 范围内
    img_valid_range = np.clip(img_np, 0, 1)
    plt.imshow(img_valid_range)
    plt.suptitle('Rice Images', y=0.95)
plt.show()
  1. 创建标签字典

    • 创建一个字典 labels_map,将类别索引映射到类别名称,方便后续的可视化和检查。
  2. 创建可视化图形

    • 使用 plt.figure 创建一个图形对象,设置图形大小为 10x10。
    • 设置图形的列数和行数为 5,意味着将显示 25 个图像样本。
  3. 可视化图像样本

    • 使用 torch.randint 随机选择训练集中图像样本的索引。
    • train_set 中获取图像和对应的标签。
    • 将图像添加到图形的子图中,并设置子图的标题为对应的类别名称。
    • 关闭子图的坐标轴显示。
    • 将图像从张量格式转换为 NumPy 数组格式,并进行转置以匹配 plt.imshow 的输入格式。
    • 使用 np.clip 将图像的像素值限制在 [0, 1] 范围内,以确保显示的图像颜色正常。
    • 显示图像样本,并设置图形的整体标题为 "Rice Images"。

代码的作用:

这段代码通过随机选择并显示训练集中的图像样本,以及相应的类别名称,帮助检查数据是否正确加载,并提供对数据分布的直观理解。可视化的图像可以帮助确认图像增强和预处理步骤是否按照预期执行。

 评估可视化

def train(model, train_loader, validation_loader, device,
          loss_fn, optimizer, num_epochs, patience=3):
    """
    训练模型:
        model: 创建的模型
        train_loader: 使用DataLoader加载的训练集
        validation_loader: 使用DataLoader加载的验证集
        device: 训练模型可用的设备(CPU或CUDA)
        loss_fn: 定义的损失函数
        optimizer: 定义的优化器
        num_epochs (int): 训练的轮数
        patience (int): 用于早停的耐心参数
    
    """
    
    history = {
        'train_loss': [],
        'val_loss': [],
        'train_acc': [],
        'val_acc': []
    }

    epoch = 0
    best_val_loss = float('inf')
    best_model_weights = None
    early_stopping_counter = 0

    while epoch < num_epochs and early_stopping_counter < patience:
        model.train()
        train_loss = 0.0
        correct = 0
        total = 0

        pbar = tqdm(enumerate(train_loader), ncols=600, total=len(train_loader))
        for batch_idx, (inputs, labels) in pbar:
            pbar.set_description(f'Epoch {epoch+1}/{num_epochs} ')
            inputs, labels = inputs.to(device), labels.to(device)

            optimizer.zero_grad()
            outputs = model(inputs)
            loss = loss_fn(outputs, labels)
            loss.backward()
            optimizer.step()

            train_loss += loss.item()
            _, predicted = outputs.max(1)
            total += labels.size(0)
            correct += predicted.eq(labels).sum().item()

        train_loss /= len(train_loader)
        train_acc = correct / total
        history['train_loss'].append(train_loss)
        history['train_acc'].append(train_acc)

        val_loss, val_acc = evaluate(model, validation_loader, device, loss_fn)
        history['val_loss'].append(val_loss)
        history['val_acc'].append(val_acc)

        # 打印进度
        print(f'train_loss: {train_loss:.4f} | '
              f'train_acc: {train_acc:.4f} | ' +
              f'val_loss: {val_loss:.4f} | ' +
              f'val_acc: {val_acc:.4f}', '\n')

        if history['val_loss'][-1] < best_val_loss:
            best_model_weights = model.state_dict()
            early_stopping_counter = 0
        else:
            early_stopping_counter += 1
            
        best_val_loss = history['val_loss'][-1]
        epoch += 1

    return history, best_model_weights

# ---------------------------------------------------------------

def evaluate(model, data_loader, device, loss_fn):
    """
    评估模型并返回损失和准确率:
        model: 创建的模型
        data_loader: 测试或验证集加载器
        device: 训练模型可用的设备(CPU或CUDA)
        loss_fn: 定义的损失函数
    """

    model.eval()
    total_loss = 0.0
    correct = 0
    total = 0

    with torch.no_grad():
        for inputs, labels in data_loader:
            inputs, labels = inputs.to(device), labels.to(device)

            outputs = model(inputs)
            loss = loss_fn(outputs, labels)
            total_loss += loss.item()

            _, predicted = outputs.max(1)
            total += labels.size(0)
            correct += predicted.eq(labels).sum().item()

    val_loss = total_loss / len(data_loader)
    val_acc = correct / total

    return val_loss, val_acc

# -------------------------------------------------------------------

def plot_comparision_result(model):
    """
    绘制训练和验证集准确率和损失的对比图:
        model: 创建的模型
    """
    
    fig, axs = plt.subplots(2, 1, figsize=(10, 12))
    
    # 绘制训练和验证集的准确率
    axs[0].plot(model['history']['train_acc'], color="red", marker="o")
    axs[0].plot(model['history']['val_acc'], color="blue", marker="h")
    axs[0].set_title('训练集和验证集准确率对比')
    axs[0].set_ylabel('准确率')
    axs[0].set_xlabel('轮次')
    axs[0].legend(['训练集', '验证集'], loc="lower right")
    
    # 绘制训练和验证集的损失
    axs[1].plot(model['history']['train_loss'], color="red", marker="o")
    axs[1].plot(model['history']['val_loss'], color="blue", marker="h")
    axs[1].set_title('训练集和验证集损失对比')
    axs[1].set_ylabel('损失')
    axs[1].set_xlabel('轮次')
    axs[1].legend(['训练集', '验证集'], loc="upper right")

    plt.tight_layout()
    plt.show()

# -------------------------------------------------------------------

# 定义函数以创建包含实际标签和预测标签的两个列表
def get_ture_and_pred_labels(dataloader, model):
    """
    获取包含实际标签和预测标签的两个列表,用于混淆矩阵:
        dataloader: 数据加载器
        model: 创建的模型
    """
    i = 0
    y_true = []
    y_pred = []
    for images, labels in dataloader:
        images = images.to(device)
        labels = labels.numpy()
        outputs = model(images)
        _, pred = torch.max(outputs.data, 1)
        pred = pred.detach().cpu().numpy()
        
        y_true = np.append(y_true, labels)
        y_pred = np.append(y_pred, pred)
    
    return y_true, y_pred

# ------------------------------------------------------------------

def plot_confusion_matrix(cm, classes,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    绘制混淆矩阵:
        cm(array): 混淆矩阵
        classes(dictionary): 目标类别(key=分类类型,value=数值类型)
    """
    plt.figure(figsize=(10,7))
    plt.grid(False)
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))

    plt.xticks(tick_marks, [f"{value}={key}" for key , value in classes.items()], rotation=45)
    plt.yticks(tick_marks, [f"{value}={key}" for key , value in classes.items()])

    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, f"{cm[i,j]}\n{cm[i,j]/np.sum(cm)*100:.2f}%",
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    
    plt.ylabel('实际值')
    plt.xlabel('预测值')
    plt.tight_layout()
    plt.show()

代码的作用:

  1. train 函数

    • 训练模型并记录训练和验证集的损失和准确率。
    • 实现早停机制以防止过拟合。
  2. evaluate 函数

    • 评估模型在给定数据集上的表现,返回损失和准确率。
  3. plot_comparision_result 函数

    • 绘制训练和验证集的准确率和损失随训练轮次变化的对比图。
  4. get_ture_and_pred_labels 函数

    • 获取实际标签和预测标签的列表,用于计算混淆矩阵。
  5. plot_confusion_matrix 函数

    • 绘制混淆矩阵以评估分类模型的性能,显示分类结果的准确性。

网络结构定义

# 定义第二个卷积神经网络模型:包含两个卷积层和两个池化层
class Model(nn.Module):
    def __init__(self, dim_output):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)  # 第一个卷积层,输入通道数为3(RGB图像),输出通道数为6,卷积核大小为5x5
        self.pool = nn.MaxPool2d(2, 2)  # 最大池化层,窗口大小为2x2
        self.conv2 = nn.Conv2d(6, 16, 5)  # 第二个卷积层,输入通道数为6,输出通道数为16,卷积核大小为5x5
        self.fc1 = nn.Linear(16 * 59 * 59, 120)  # 第一个全连接层,输入维度为16*59*59,输出维度为120
        self.fc2 = nn.Linear(120, 84)  # 第二个全连接层,输入维度为120,输出维度为84
        self.fc3 = nn.Linear(84, dim_output)  # 第三个全连接层,输入维度为84,输出维度为类别数

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))  # 第一个卷积层后接ReLU激活函数和池化层
        x = self.pool(F.relu(self.conv2(x)))  # 第二个卷积层后接ReLU激活函数和池化层
        x = torch.flatten(x, 1)  # 展平操作,展平所有维度除了批量维度
        x = F.relu(self.fc1(x))  # 第一个全连接层后接ReLU激活函数
        x = F.relu(self.fc2(x))  # 第二个全连接层后接ReLU激活函数
        x = self.fc3(x)  # 第三个全连接层
        return x

model_ = Model(5)  # 实例化模型,类别数为5

summary(model_, (3, 250, 250))  # 打印模型结构和参数信息,输入图像尺寸为3x250x250
  1. 定义卷积神经网络模型

    • __init__ 方法中定义了两个卷积层、两个池化层和三个全连接层。
    • conv1:第一个卷积层,输入通道数为3,输出通道数为6,卷积核大小为5x5。
    • pool:最大池化层,窗口大小为2x2。
    • conv2:第二个卷积层,输入通道数为6,输出通道数为16,卷积核大小为5x5。
    • fc1:第一个全连接层,输入维度为165959,输出维度为120。
    • fc2:第二个全连接层,输入维度为120,输出维度为84。
    • fc3:第三个全连接层,输入维度为84,输出维度为类别数(即输出维度)。
  2. 定义前向传播

    • forward 方法定义了前向传播过程。
    • 输入图像依次通过卷积层、激活函数、池化层、展平操作和全连接层。
    • 最后输出的结果用于分类任务。
  3. 实例化模型

    • model_ = Model(5):实例化模型,类别数为5。
  4. 显示模型结构和参数信息

    • summary(model_, (3, 250, 250)):使用 torchsummary 显示模型的结构和参数信息,输入图像尺寸为3x250x250。

代码的作用:

这段代码定义了一个用于图像分类的卷积神经网络模型,并显示了模型的结构和参数信息。这有助于了解模型的层次结构和参数量,为后续的模型训练和评估做准备。

定义损失函数和优化器,并训练模型

# define a Loss function and optimizer for model_2
loss_fn = nn.CrossEntropyLoss()
optimizer = optim.Adam(model_.parameters(), lr=0.001)

# train model_
history_2, best_model_weights_2 = train(model_, train_loader, val_loader,
                                        device, loss_fn, optimizer, num_epochs=5, patience=5)

 模型可视化评估

size_histories = {}

# 存储训练结果
size_histories['Model_'] = {'history': history_2, 'weights': best_model_weights_2}

# 绘制模型在每个训练轮次的准确率和损失图
plot_comparision_result(size_histories['Model_'])

# 检查混淆矩阵进行错误分析
y_true, y_pred = get_ture_and_pred_labels(val_loader, model_)

print(classification_report(y_true, y_pred), '\n\n')
cm = confusion_matrix(y_true, y_pred)

classes = {
    "Arborio": 0,
    "Basmati": 1,
    "Ipsala": 2,
    "Jasmine": 3,
    "Karacadag": 4,
}

plot_confusion_matrix(cm, classes, title='Confusion matrix', cmap=plt.cm.Blues)
  • 存储训练结果

    • 初始化一个字典 size_histories 用于存储不同模型的训练结果。
    • Model_ 模型的训练历史记录和最佳模型权重存储在 size_histories['Model_'] 中。
  • 绘制模型的准确率和损失图

    • 调用 plot_comparision_result 函数,绘制模型在每个训练轮次的准确率和损失图。该函数将绘制训练集和验证集的准确率和损失随训练轮次变化的对比图,以便直观地评估模型的性能。
  • 检查混淆矩阵进行错误分析

    • 使用 get_ture_and_pred_labels 函数获取验证集中真实标签和预测标签的列表 y_truey_pred
    • 打印分类报告 classification_report(y_true, y_pred),显示每个类别的精度、召回率和F1分数。
    • 计算混淆矩阵 cm,显示模型在验证集上的分类错误情况。
    • 定义类别名称和对应的数值标签字典 classes
    • 调用 plot_confusion_matrix 函数,绘制混淆矩阵图,显示各类别的分类结果。

代码的作用:

这段代码将模型的训练结果进行存储,并通过绘制准确率和损失图帮助评估模型在训练过程中的表现。通过分类报告和混淆矩阵,可以详细分析模型在验证集上的分类效果,识别模型在不同类别上的分类准确性以及存在的错误,从而为模型的优化提供依据。这种详细的错误分析对于提高模型的性能和泛化能力具有重要意义。

 

 

下载地址:

python深度学习pytorch水稻图像分类完整案例

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

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

相关文章

C语言 | Leetcode C语言题解之第122题买卖股票的最佳时机II

题目&#xff1a; 题解&#xff1a; int maxProfit(int* prices, int pricesSize) {int ans 0;for (int i 1; i < pricesSize; i) {ans fmax(0, prices[i] - prices[i - 1]);}return ans; }

FPGA DMA IP核使用指南

摘要 本文旨在介绍FPGA中DMA(Direct Memory Access)IP核的使用,包括其基本框架、测试代码编写以及仿真波形的分析。DMA是一种允许外围设备直接与内存进行数据交换的技术,无需CPU的介入,从而提高了数据传输的效率。 1. 引言 在现代FPGA设计中,DMA IP核因其…

一站式链路追踪:阿里云的端到端解决方案

作者&#xff1a;涯海 炎炎夏日&#xff0c;当你打开外卖 APP 购买奶茶却发现下单失败&#xff1b;五一佳节&#xff0c;当你自驾游途中发现导航响应缓慢&#xff0c;频繁错过路口&#xff1b;深更半夜&#xff0c;当你辅导孩子功课&#xff0c;却发现 GPT 应用迟迟无法应答。…

【VTKExamples::Utilities】第十七期 ZBuffer

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例ZBuffer,并解析接口vtkWindowToImageFilter,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ…

一个案例告诉你,MySQL如何查询今天、昨天、近7天、近30天、本月、上个月、本季度、上季度、本年、上一年数据

参考博客 mysql查询当天/昨天/近7天/近30天/本月/上个月/本季度/上季度/本年/上一年 数据 正文内容 创建测试案例&#xff08;也可直接使用附录MySQL脚本生成数据&#xff09; 1、新建测试表 CREATE TABLE example (id INT AUTO_INCREMENT PRIMARY KEY,date_column DATE,d…

无信号、弱信号地区的“关键先生”,北三区域短报文应急通信——户外应急救援的安全保障

随着中国经济高速发展和民众生活水平、文化素养的不断提高&#xff0c;户外探险活动已经成为越来越多民众自主选择的一种休闲生活方式。 然而&#xff0c;产业发展和参与人数激增的同时户外探险事故也不断增多。根据中国探险协会发布《2022年度中国户外探险事故报告》显示2022…

跨境电商站外推广全攻略:揭秘有效推广方法!

随着全球贸易的蓬勃兴起&#xff0c;越来越多的企业开始涉足跨境电商领域。然而&#xff0c;要在国际市场上取得成功&#xff0c;仅仅依赖平台内的推广策略是远远不够的。站外推广成为了跨境电商拓展业务、吸引潜在客户的关键策略。那么&#xff0c;跨境电商的站外推广具体包括…

计算机组成原理·海明编码及其实验

前言&#xff1a;海明编码这一块在刚开始的时候没有弄懂&#xff0c;后面通过做实验、复习慢慢摸清了门道。在学习计算机组成原理的过程中&#xff0c;实验实践是很重要的&#xff0c;它会让你去搞清楚事情背后的原理&#xff0c;逼着你学会你没听懂的东西。这篇文章会从海明码…

Vue3实战笔记(53)—奇怪+1,VUE3实战模拟股票大盘工作台

文章目录 前言一、实战模拟股票大盘工作台二、使用步骤总结 前言 实战模拟股票大盘工作台 一、实战模拟股票大盘工作台 接上文&#xff0c;这两天封装好的组件直接应用,上源码&#xff1a; <template><div class"smart_house pb-5"><v-row ><…

做外贸,怎么选国外服务器?

不管是新手还是外贸老司机&#xff0c;大家都知道要用海外服务器来做外贸网站&#xff0c;无论外贸独立站的客户是欧美、东南亚、还是非洲&#xff0c;都不能选择国内机房的服务器&#xff0c;必须选择海外服务器&#xff0c;这是共识。 但是今天&#xff0c;我要告诉大家一个…

关联规则(Apriori算法)

文章目录 1 关联规则1.1 关联规则简介1.2 典型例子1.3 频繁项集的评估标准1.3.1 支持度&#xff08;support&#xff09;1.3.2 置信度&#xff08;confidence&#xff09;1.3.3 提升度&#xff08;lift&#xff09; 1.4 最小支持度、最小置信度 2 Python实战2.1 Python实战关联…

基于网关的ip频繁访问web限制

一、前言 外部ip对某一个web进行频繁访问&#xff0c;有可能是对web进行攻击&#xff0c;现在提供一种基于网关的ip频繁访问web限制策略&#xff0c;犹如带刀侍卫&#xff0c;审查异常身份人员。如发现异常或者暴力闯关者&#xff0c;即可进行识别管制。 二、基于网关的ip频繁访…

面向Java程序员的Go工程开发入门流程

对于一个像我这样没有go背景的java程序员来说&#xff0c;使用go开发一个可用的程序的速度是肉眼可见的缓慢。 其难点不在于go语言本身&#xff0c;而是搭建整个工程链路的过程&#xff0c;即所谓的“配环境”。 本文主要讲述如何配出一个适合go开发的环境&#xff0c;以免有同…

STL:vector

文章目录 标准库中的vectorvector的构造vector的迭代器vector的容量vector的元素访问data vector的修改 vector和string的迭代器失效问题resize、reserve、insert、push_back、assigneraseg 和 vs 的区别string解决迭代器失效的方法 标准库中的vector vector是表示可变大小数组…

【学习Day3】计算机基础

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 1.5.4 Cache替换算法 Cache的页面淘汰算法 常用替换算法有&#xff1a; • 随机替换算法RA…

浏览器【详解】Cookie(含Cookie的起源,属性,个数和大小限制,作用,优点,缺点,JS 的操作方法等)

什么是 Cookie &#xff1f; Cookie 是一段不超过 4KB 的小型文本数据&#xff0c;由一个名称&#xff08;Name&#xff09;、一个值&#xff08;Value&#xff09;和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成。 浏览器为什么需要 Cookie &#xff1f; …

atk-esp8266-01刷新固件-链接-配置

1.刷新固件 加载固件&#xff1a; 编写地址&#xff1a; 2.链接IO-->GND 关闭其他所有占用此串口的软件&#xff1b; 重新上电 开始刷新固件&#xff1a; 刷新完成&#xff1b; 拆掉IO与GND链接。 3.配置 ATCWMODE_DEF3 //配置模式 ATRST //重启 …

Linux学习笔记(清晰且清爽)

本文首次发布于个人博客 想要获得最佳的阅读体验&#xff08;无广告且清爽&#xff09;&#xff0c;请访问本篇笔记 Linux安装 关于安装这里就不过多介绍了&#xff0c;安装版本是CentOS 7&#xff0c;详情安装步骤见下述博客在VMware中安装CentOS7&#xff08;超详细的图文教…

3d模型移动中心点偏移太远怎么解决?---模大狮模型网

在3D建模和动画制作中&#xff0c;移动模型时确保中心点的准确性至关重要。然而&#xff0c;有时候在移动模型时&#xff0c;中心点可能会偏移得太远&#xff0c;导致操作不便甚至影响到后续的工作流程。本文将介绍在3D模型移动中心点偏移太远时的常见原因&#xff0c;并提供解…

基于Linux的文件操作(socket操作)

基于Linux的文件操作&#xff08;socket操作&#xff09; 1. 文件描述符基本概念文件描述符的定义&#xff1a;标准文件描述符&#xff1a;文件描述符的分配&#xff1a; 2. 文件描述符操作打开文件读取文件中的数据 在linux中&#xff0c;socket也被认为是文件的一种&#xff…