Pytorch构建vgg16模型

news2024/11/24 4:42:57

VGG-16

1. 导入工具包

import torch.optim as optim
import torch
import torch.nn as nn
import torch.utils.data
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader
import torch.optim.lr_scheduler as lr_scheduler
import os

注:
torch: 这是PyTorch框架的基础库,提供了自动求导机制和丰富的张量运算支持,是构建和训练神经网络的基础。
torch.nn: PyTorch的神经网络库,包含多种构建神经网络所需的层结构(如卷积层、全连接层)和激活函数等
torch.utils.data: 提供了数据加载和处理的工具,是加载数据集并进行批处理的重要模块
torchvision.transforms: PyTorch的视觉库中的一个模块,提供了一系列图像处理的变换操作,用于数据增强和预处理
torchvision.datasets: 提供了常见的数据集和相关的数据加载方法,如MNIST、CIFAR-10、ImageNet等
DataLoader: torch.utils.data中的一个类,用于构建可迭代的数据加载器,可以方便地在训练循环中按批次加载数据
torch.optim.lr_scheduler: 提供了学习率调整策略,如学习率衰减,有助于训练过程中改善模型性能和减少过拟合
os: Python的标准库之一,提供了与操作系统交互的功能,如文件创建、路径操作等

2. 判断环境是CPU运行还是GPU

DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

注:通过这行代码,程序可以根据当前环境自动选择最佳的计算设备,以提高计算效率和性能。在GPU上运行可以显著加速深度学习模型的训练和推理过程。

3. 数据预处理

# 定义数据预处理
transform = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(size=256, scale=(0.8, 1.0)),
        transforms.RandomRotation(degrees=15),
        transforms.RandomHorizontalFlip(),
        transforms.CenterCrop(size=224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(size=256),
        transforms.CenterCrop(size=224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ])
}

注:
训练数据预处理 (transform[‘train’])
transforms.RandomResizedCrop(size=256, scale=(0.8, 1.0)): 随机裁剪图像,裁剪后的图像大小为256x256像素。裁剪区域的大小是原始图像尺寸的0.8到1.0倍之间随机选择
transforms.RandomRotation(degrees=15): 随机旋转图像,旋转角度在-15度到15度之间随机选择
transforms.RandomHorizontalFlip(): 随机水平翻转图像,即有一半的概率会翻转,一半的概率不翻
transforms.CenterCrop(size=224): 从图像中心裁剪出224x224像素的区域
transforms.ToTensor(): 将图像转换为PyTorch张量,并且将像素值从[0, 255]范围缩放到[0, 1]范围
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]): 对图像进行标准化处理。这里使用的是ImageNet数据集的均值和标准差,这些值分别用于每个颜色通道的减均值和除以标准差操作

验证数据预处理 (transform[‘val’])
transforms.Resize(size=256): 将图像大小调整为256x256像素,这里没有使用随机裁剪,而是直接调整大小
transforms.CenterCrop(size=224): 从图像中心裁剪出224x224像素的区域
transforms.ToTensor(): 将图像转换为PyTorch张量,并且将像素值从[0, 255]范围缩放到[0, 1]范围
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]): 对图像进行标准化处理,使用的是ImageNet数据集的均值和标准差

4. 读取数据

dataset = './dataset'
train_directory = os.path.join(dataset, 'train')
valid_directory = os.path.join(dataset, 'val')

注:
valid_directory = os.path.join(dataset, ‘val’):同样地,这行代码将dataset目录和字符串’val’连接起来,创建验证数据集的路径。valid_directory将包含数据集根目录下的验证数据子目录的完整路径。这两行代码通常用于准备深度学习实验的数据集路径,以便在后续的数据加载和模型训练过程中引用这些路径。

5. 设置超参数

batch_size = 32
num_classes = 2  # 修改为您的分类数

注:batch_size = 32:这行代码设置了批量大小(batch size)为32。批量大小是指在一次梯度更新中使用的样本数量。在训练神经网络时,通常会一次性处理一小批数据样本,而不是整个数据集。批量大小的大小会影响模型的训练速度和稳定性。较小的批量大小可能会导致训练过程波动较大,而较大的批量大小可能会提高训练的稳定性但需要更多的内存。
num_classes = 2:这行代码设置了分类数(number of classes)为2,这意味着模型是一个二分类模型,用于区分两个不同的类别。如果您的任务需要识别更多的类别,比如多分类问题,您需要将这个值修改为实际类别的数量。例如,对于一个包含10个类别的数据集,您需要将 num_classes 设置为10。

6. 创建训练(train)和验证(val)数据集的数据加载器

data = {
    'train': datasets.ImageFolder(root=train_directory, transform=transform['train']),
    'val': datasets.ImageFolder(root=valid_directory, transform=transform['val'])
}
train_loader = DataLoader(data['train'], batch_size=batch_size, shuffle=True, num_workers=8)
test_loader = DataLoader(data['val'], batch_size=batch_size, shuffle=False, num_workers=8)

注:train_loader = DataLoader(…):这行代码创建了一个用于训练的数据加载器。DataLoader会遍历data[‘train’]中的数据,每次返回一个包含batch_size个样本的小批量。shuffle=True表示在每个epoch开始时,数据加载器会随机打乱数据顺序。num_workers=8表示使用8个子进程来同时加载数据,这可以在数据读取时提高效率。这些数据加载器在训练深度学习模型时非常重要,因为它们可以高效地加载和批量处理数据,同时还能够提供数据的随机化,这对于模型的泛化能力至关重要。

7. 定义VGG16模型

class VGG16(nn.Module):
    def __init__(self, num_classes=1000):
        super(VGG16, self).__init__()
        self.features = nn.Sequential(
            # Block 1
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            # Block 2
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            # Block 3
            nn.Conv2d(128, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            # Block 4
            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            # Block 5
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, num_classes)  # 修改这里,默认为1000个类别
        )
    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, 1)  # 展开特征图
        x = self.classifier(x)
        return x

注:这段代码定义了一个继承自nn.Module的类VGG16,它是一个用于图像分类的卷积神经网络模型。

class VGG16(nn.Module):定义了一个名为VGG16的类,它继承自nn.Module,这是PyTorch中定义神经网络模型的基础类。

def init(self, num_classes=1000):这是类的构造函数,它接受一个可选参数num_classes,默认值为1000。这个参数决定了模型的输出层有多少个神经元,对应于分类任务中的类别数。

super(VGG16, self).init():调用父类nn.Module的构造函数。

self.features = nn.Sequential(…):创建了一个序列模块self.features,它包含了一系列的卷积层、ReLU激活函数和最大池化层。这些层组成了VGG-16的卷积部分。

self.classifier = nn.Sequential(…):创建了一个序列模块self.classifier,它包含了一系列的全连接层、ReLU激活函数和dropout层。这些层组成了VGG-16的全连接部分。

nn.Linear(512 * 7 * 7, 4096):第一个全连接层有512个输入神经元,对应于卷积部分最后一个池化层后的特征图大小(512个特征图,每个特征图7x7像素),输出4096个神经元。

nn.Linear(4096, 4096):第二个全连接层有4096个输入神经元,对应于第一个全连接层的输出,输出4096个神经元。

nn.Linear(4096, num_classes):输出层有num_classes个输入神经元,对应于分类任务的类别数,输出num_classes个神经元。

def forward(self, x):定义了模型的前向传播函数。这个函数定义了当输入一个张量x时,模型如何计算输出。

x = self.features(x):通过self.features模块处理输入的图像x,得到一系列的卷积特征。

x = torch.flatten(x, 1):将特征图x展平为一个一维张量,以便输入到全连接层。

x = self.classifier(x):通过self.classifier模块处理展平的特征,得到最终的分类结果。

return x:返回模型的输出,通常是一个包含每个类别概率的向量。

8. 初始化VGG-16模型

vgg16 = VGG16(num_classes=2)
vgg16 = vgg16.to(DEVICE)

注:
vgg16 = VGG16(num_classes=2): 这行代码创建了一个VGG-16模型的实例,并将输出类别数设置为2。这意味着模型的最后一层全连接层将有2个输出节点,对应于两个类别
vgg16 = vgg16.to(DEVICE): 这行代码将创建的VGG-16模型移动到指定的设备上。这里的DEVICE应该是一个之前定义的变量,表示您希望模型运行的设备。例如,如果DEVICE是torch.device(‘cuda’),则模型将被移动到GPU上;如果DEVICE是torch.device(‘cpu’),则模型将在CPU上运行

9. 定义损失函数和优化器

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(vgg16.parameters(), lr=0.001, momentum=0.9)

注:
optimizer = optim.SGD(vgg16.parameters(), lr=0.001, momentum=0.9):这里创建了一个SGD优化器的实例,它是随机梯度下降(Stochastic Gradient Descent)的缩写。SGD优化器用于更新模型的参数,以最小化损失函数。vgg16.parameters()表示要优化的参数集合,包括所有的卷积层、全连接层等。lr=0.001表示学习率,即每次迭代时参数更新的步长。momentum=0.9表示动量,这是一种加速SGD收敛的技术,它利用了之前的梯度信息来调整当前梯度。

10. 定义学习率调整策略

scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)

注:
scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1):这里创建了一个StepLR调度器的实例。StepLR是一种简单的学习率调度策略,它在训练过程中按照预定的步长step_size来调整学习率。每个步长结束后,学习率会按照gamma的比例进行缩减。optimizer是需要调度的优化器,而step_size=7表示每7个epoch学习率会调整一次,gamma=0.1表示每次调整时学习率会减少10%。
学习率调度器在训练过程中是非常有用的,尤其是在使用较大的学习率时,它可以帮助模型在训练的早期阶段快速收敛,然后在后期阶段更加稳定地优化模型。这样可以防止模型在训练早期过拟合,并在后期仍然保持较好的性能。

11. 定义训练过程

def train(model, device, train_loader, optimizer, criterion, epoch):
    model.train()
    running_loss = 0.0
    correct = 0
    total = 0
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)  # 修正缩进
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        _, predicted = torch.max(output.data, 1)
        total += target.size(0)
        correct += (predicted == target).sum().item()

        if batch_idx % 10 == 0:  # 每10个批次打印一次
            print(f'Epoch {epoch}, Batch {batch_idx}, Loss: {loss.item()}')
    print(f'Epoch {epoch}, Loss: {running_loss / len(train_loader)}, Accuracy: {100 * correct / total}%')

注:
model.train():将模型设置为训练模式,这会启用如批标准化(Batch Normalization)和dropout等训练时的特定功能。

running_loss = 0.0:初始化一个变量来记录当前epoch的损失总和。

correct = 0 和 total = 0:初始化两个变量来记录当前epoch的预测正确的数量和总数量。

for batch_idx, (data, target) in enumerate(train_loader):循环遍历训练数据加载器的每个批次。batch_idx是当前批次的索引,(data, target)是当前批次的数据和目标标签。

data, target = data.to(device), target.to(device):将数据和标签移动到指定的设备上。如果device是’cuda’,则数据会被复制到GPU上;如果是’cpu’,则数据会保留在CPU上。

optimizer.zero_grad():清空所有参数的梯度,以便在新的批数据上重新计算。

output = model(data):通过模型计算输出。

loss = criterion(output, target):计算损失,使用output和target。

loss.backward():反向传播计算损失的梯度。

optimizer.step():使用计算出的梯度来更新模型的参数。

running_loss += loss.item():累加损失值。

_, predicted = torch.max(output.data, 1):预测输出中的最大值所在的索引,这代表了模型对每个样本的预测类别。

11.定义验证过程

# 定义验证过程
def val(model, device, test_loader, criterion):
    model.eval()
    running_loss = 0.0
    correct = 0
    total = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            loss = criterion(output, target)
            running_loss += loss.item()
            _, predicted = torch.max(output.data, 1)
            total += target.size(0)
            correct += (predicted == target).sum().item()

    print(f'Validation, Loss: {running_loss / len(test_loader)}, Accuracy: {100 * correct / total}%')

注:
model.eval(): 这行代码将模型设置为评估模式。在某些模型中,训练模式和评估模式(例如BatchNorm和Dropout)的行为是不同的

running_loss = 0.0: 初始化运行损失为0,用于累加每个批次的损失

correct = 0: 初始化正确分类的样本数为0

total = 0: 初始化总样本数为0

with torch.no_grad(): 这个上下文管理器用于告诉PyTorch在接下来的代码块中不要计算梯度。因为在验证过程中我们不需要更新模型参数,所以不需要计算梯度

for data, target in test_loader: 这行代码开始一个循环,遍历验证数据加载器test_loader中的每个批次。data是当前批次的数据,target是当前批次的目标标签

data, target = data.to(device), target.to(device): 这行代码将数据和目标标签移动到之前定义的设备上,如果设备是GPU,这将使数据能够在GPU上进行计算

12.训练模型

EPOCHS = 10
for epoch in range(1, EPOCHS + 1):
    train(vgg16, DEVICE, train_loader, optimizer, criterion, epoch)
    val(vgg16, DEVICE, test_loader, criterion)
    scheduler.step()  # 调整学习率

注:
EPOCHS = 10:定义了一个变量EPOCHS,其值为10,表示模型将进行10个epoch的训练。

for epoch in range(1, EPOCHS + 1):开始一个循环,循环的起始值为1,结束值为EPOCHS + 1。每个epoch代表模型在训练数据上的一个完整遍历。

train(vgg16, DEVICE, train_loader, optimizer, criterion, epoch):调用train函数,传入模型vgg16、设备DEVICE、训练数据加载器train_loader、优化器optimizer、损失函数criterion和当前的epoch。train函数负责训练模型,即执行前向传播、计算损失、反向传播和更新参数。

val(vgg16, DEVICE, test_loader, criterion):调用val函数,传入模型vgg16、设备DEVICE、测试数据加载器test_loader和损失函数criterion。val函数负责评估模型的性能,即在测试数据上执行前向传播并计算损失。

scheduler.step():在每个epoch结束后,调用学习率调度器scheduler的step方法,根据预定的策略调整学习率。这有助于模型在训练过程中适应不同的学习速率,以达到更好的性能。

通过这个循环,模型将在训练数据上进行10个epoch的训练,并在每个epoch结束后在测试数据上评估其性能,并调整学习率。这样可以逐渐优化模型的性能,使其在测试数据上达到较好的准确率。

13.保存模型的状态字典

torch.save(vgg16.state_dict(), 'vgg16_model_weights.pth')

在这里插入图片描述

注:
torch.save(vgg16.state_dict(), ‘vgg16_model_weights.pth’):这里使用torch.save函数将模型vgg16的权重(state_dict)保存到文件中。vgg16.state_dict()会返回一个包含模型所有参数的字典,每个键值对代表模型的一个参数及其值。
‘vgg16_model_weights.pth’:这是保存文件的名字,.pth是PyTorch保存文件常用的扩展名。这个文件通常包含了模型的权重,可以用于模型的复现或进一步的训练。
通过这行代码,你可以将训练好的模型权重保存到文件中,以便在后续的实验中使用。这有助于避免每次训练都从头开始,也可以方便地将模型分享给其他研究者或团队成员。

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

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

相关文章

优思学院|IT行业学习六西格玛的价值

提到六西格玛(Six Sigma),很多人可能首先想到的是制造业。六西格玛确实在制造业中有着广泛的应用和显著的效果,如提高产品质量、降低缺陷率、减少浪费等。那么,六西格玛在信息技术(IT)行业是否同…

Android11 以Window的视角来看FallbackHome的启动

在WMS中,使用WindowState代表着一个Window并维护着一个Window的"层级树",每个Window需要按照"层级"的规则进行排列。对于FallbackHome,其Window是挂载在home task上,而home task挂载在DefaultTaskDisplayArea…

IconWorkshop中文版安装包下载及安装教程

​IconWorkshop官方版是一款使用起来非常简单便捷的可以让用户朋友根据自己的需求制作LOGO图标的工具,不管您是在生活中还是软件制作中遇到了需要原创LOGO的机会,通过最短的时间对logo图标进行细节制作,添加各类效果,设置等高线&a…

LabVIEW的热门应用

LabVIEW是一种图形化编程语言,因其易用性和强大的功能,在多个行业和领域中广泛应用。介绍LabVIEW在以下五个热门应用领域中的使用情况,:工业自动化、医疗设备与生物医学工程、科学研究与实验室自动化、能源管理与智能电网、航空航…

跟TED演讲学英文:Entertainment is getting an AI upgrade by Kylan Gibbs

Entertainment is getting an AI upgrade Link: https://www.ted.com/talks/kylan_gibbs_entertainment_is_getting_an_ai_upgrade Speaker: Kylan Gibbs Date: April 2024 文章目录 Entertainment is getting an AI upgradeIntroductionVocabularySummaryTranscriptAfterwor…

Linux下的crontab命令

文章目录 目录 文章目录 前言 一、crond和crontab 二、命令文档 三、命令使用 总结 前言 crontab命令是用于在Unix和类Unix操作系统中安排定期执行的任务的命令。crontab命令允许用户创建、编辑、显示和移除他们的crontab文件。通过在crontab文件中定义任务和执行时间&#xf…

【刷题】LeetCode刷题汇总

目录 一、刷题题号1:两数之和 二、解法总结1. 嵌套循环2. 双指针 一、刷题 记录LeetCode力扣刷题 题号1:两数之和 双循环(暴力解法): class Solution {public int[] twoSum(int[] nums, int target) {int[] listne…

光伏工程开发的详细步骤

光伏工程作为可再生能源领域的重要组成部分,其开发过程涉及多个环节,包括开发、测绘、设计、施工和运维等。下面将详细介绍这些步骤。 一、开发阶段 1、前期调研:对目标地区进行能源政策、市场需求、资源条件等方面的调研,评估项…

spring boot接入nacos 配置中心

再接入nacos配置中心时,需要确认几点: 1. spring boot 版本 (spring boot 2.x ) 2. nacos 配置中心 服务端 版本 (1.1.4) 3. nacos client 客户端版本 (1.1.4) 方式一 1. 启动 nacos 服务端,这里不做解释 在配置中心中加入几个配置 2. 在…

【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt系统相关 | Qt事件 | 事件的介绍及基本概念 文章编号:Qt…

FPGA的基础仿真项目--七段数码管设计显示学号

一、设计实验目的 1. 了解数码管显示模块的工作原理。 2. 熟悉VHDL 硬件描述语言及自顶向下的设计思想。 3. 掌握利用FPGA设计6位数码管扫描显示驱动电路的方法。 二、实验设备 1. PC机 2.Cyclone IV FPGA开发板 三、扫描原理 下图所…

夏季家里粉尘螨虫满天飞?一招搞定!好用家用空气净化器品牌分享

每到夏季,是家中尘螨滋生的高发期。夏季无论是开窗通风还是关窗开空调,都很容易造成空气中的浮尘堆积,不注意卫生清洁,容易滋生细菌、尘螨。 易过敏、体质弱的人群长时间在空气污染环境中,很容易就会过敏或者发生其他…

在矩池云快速使用ChatTTS,文本转语音太酷了

ChatTTS 最新的一款文本转语音模型,目前支持英文和中文两种语言,面向对话场景的转化则更为精准,在汉语的语音韵律方面超越了以往很多同类模型,此外它还支持细粒度控制,允许在文字中加入笑声、停顿、语气词等&#xff0…

一道全等三角形证明题

接着上次那道题 一道初中一年级几何题解析,再来做一道初中一年级下半学期几何题目: 傍晚丢垃圾散步时看到小小的学生学习群里丢了这个题目,想到一个解法。实在构造不出契合题干阅读材料结论的三角形,索性先根据这结论做一个推论…

openh264 帧间预测编码过程源码分析

openh264 OpenH264 是一个开源的 H.264 编码和解码器,由思科系统开发并维护。它专为实时应用程序如 WebRTC 设计,提供了从基础到高级特性的广泛支持。OpenH264 的编码器支持从 Constrained Baseline Profile 到 5.2 级别,允许任意分辨率的编…

硕士毕业论文《基于磁纹理的磁化动力学研究》

前言 本文是博主的硕士毕业论文,应该也是“自旋电子学(微磁学)”博客专栏的最后一篇博客,该毕业论文预设排版的PDF版本见下载链接:https://download.csdn.net/download/qq_43572058/89447526。若该博客专栏对读者您的…

一分钱不花!本地部署Google最强开源AI大模型Gemma教程

谷歌发布了轻量级开源系列模型Gemma,其性能强大,可与主流开源模型竞争。通过Ollama可轻松部署Gemma模型,并使用JANAI美化UI界面。显卡在AIGC应用中至关重要,推荐选择性能强、显存大的NVIDIA系列显卡。 半个月前,谷歌搞…

验证药品综合稳定性试验箱的挑战与解决方案

在药品研发和生产过程中,药品的稳定性是一个至关重要的因素。为了确保药品在储存和运输过程中保持其质量和疗效,药品综合稳定性试验箱被广泛用于模拟各种环境条件下的药品稳定性。然而,在实际应用中,药品综合稳定性试验箱的验证面…

判断一组数据哪些是素数,并统计一个数组中元素的出现频率

import java.util.HashMap; import java.util.Map; public class Test_A26 {//判断一个数是不是素数public static boolean isPrime(int num){if(num<1){return false;}for(int i2;i<Math.sqrt(num);i){if(num%i0){return false;}}return true;}//统计数组中出现的频率 p…

LVS(Linux Virtual Server)集群

Cluster&#xff1a;集群&#xff0c;为了解决某个特定问题将多台计算机组合起来形成的单个系统。 集群分为三种类型&#xff1a; LB(Load Balancing)&#xff0c;负载均衡&#xff0c;多个主机组成&#xff0c;每个主机只承担一部分访问请求 HA(High Availiablity)&#xf…