首页 > 其他分享 >kaggle竞赛系列基于图像对水稻分类代码案例

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

时间:2024-05-31 18:02:18浏览次数:16  
标签:loss 竞赛 训练 val 模型 kaggle 案例 train model

目录

依赖环境

代码

导入依赖包

定义数据集路径:

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

代码的作用:

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

代码的作用:

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

代码的作用:

定义数据集评估划分与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水稻图像分类完整案例

标签:loss,竞赛,训练,val,模型,kaggle,案例,train,model
From: https://blog.csdn.net/qq_42452134/article/details/139355329

相关文章

  • 用python写一个抖店选品的案例
    今天我使用Python编写抖店选品策略的简单案例。我们将使用pandas库处理数据,并假设你已经安装了pandas库。首先,我们需要准备以下数据:1.销售数据:包含商品、销售日期、销售额等信息。2.用户评价数据:包含商品、评价日期、评价分数等信息。3.库存数据:包含商品、库存信息。4.......
  • python 使用面向对象思想解决案例
    要求:步骤一文件读取:父类子类1子类2测试效果图步骤二数据计算:步骤三可视化开发效果图知识点:魔术方法之字符串方法__str__,构造方法__init__pass关键字,占位语句,用来保证函数或类定义的完整性,表示无内容抽象类:含有抽象方法的类抽象方法:没有具体实现......
  • JAVA【案例4-8】模拟物流快递系统程序设计
    【模拟物流快递系统程序设计】1、案例描述网购已成为人们生活的重要组成部门,当人们在购物网站中下订单后,订单中的货物就会在经过一系列的流程后,送到客户的手中。而在送货期间,物流管理人员可以在系统中查看所有物品的物流信息。编写一个模拟物流快递系统的程序,模拟后台系统处......
  • C#中接口的显式实现与隐式实现及其相关应用案例
    C#中接口的显式实现与隐式实现最近在学习演化一款游戏项目框架时候,框架作者巧妙使用接口中方法的显式实现来变相对接口中方法进行“密封”,增加实现接口的类访问方法的“成本”。接口的显式实现和隐式实现:先定义一个接口,接口中有这两个方法。publicinterfaceICanSingSong{......
  • 一文搞透常见的Python编码陷阱(上)(分析+案例)
    一个认为一切根源都是“自己不够强”的INTJ个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数Python-3.12.0文档解读目录一、别忘了冒号1.if语句2.while语句3.for语句4.函数定义5.类定义6.try/except语句7.with语句......
  • SQL KEEP 窗口函数等价改写案例
    一哥们出条sql题给我玩,将下面sql改成不使用keep分析函数的写法。selectdeptno,ename,sal,hiredate,min(sal)keep(dense_rankfirstorderbyhiredate)over(partitionbydeptno)min_sal,max(sal)keep(dense_ranklastorderby......
  • 编程奇境:C++之旅,从新手村到ACM/OI算法竞赛大门(基础语法)
    踏入C++王国的神秘之门,首要任务是装备上基础语法这把万能钥匙,它不仅是你与代码世界对话的初级咒语,更是构筑编程魔法塔的基石。想象自己是一位即将踏上征途的勇士,先要学会站立、行走,方能奔跑、飞跃。基础语法:勇者的起跑线顺序结构:这就像是一场精心策划的冒险,你的每一个指令—......
  • CATIA二次开发VBA入门(4)——进程外开发环境搭建,vb.net在Visual Studio中开发,创建圆柱曲
    目录引出vb.net和vb6.0进程外开发环境搭建vb.net开发环境搭建《CATIA二次开发技术基础》模板添加宏库引用vs开发环境初步vs中的立即窗口对象浏览器建立模板案例:创建一堆圆柱曲面第一步:录制宏第二步:代码精简第三步:for循环改造第四步:人机交互改造窗口模态设置导出窗口......
  • SSMP整合案例第四步 表现层controller开发及用Result进行统一消息处理
    表现层开发数据层和业务层都做完了我们首先得创建我们表现层对应的包和类Controller层控制层先写的是查询所有信息控制层调用业务层使用的是依赖注入的方法packagecom.bigdata1421.ssmp.controller;importcom.bigdata1421.ssmp.domain.User;importcom.bigdata1......
  • 第二十二届SCU程序设计竞赛(Tencent CUP)
    ProblemA.配对质数此题事先把素数筛出来,由于从前往后可能会导致后面的数字无法配对,我们只需从后往前,把数x/2得到的两个数,即可完成配对操作#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;template<typenameT>inlinevoidread(T&x)......