昇思25天学习打卡营第18天|ResNet50 迁移学习实战:从数据准备到模型构建

news2024/9/9 1:26:58

目录

环境配置

加载数据集

数据集可视化

构建Resnet50网络

固定特征进行训练

训练和评估

可视化模型预测


环境配置


         MindSpore 库的版本管理和数据集的下载操作。首先,它卸载了已安装的 MindSpore 版本,并重新安装指定版本(2.3.0rc1)。然后,通过 pip show mindspore 查看当前安装的 MindSpore 版本。最后,使用自定义的 download 函数从给定的 URL 下载一个名为 Canidae_data.zip 的数据集到指定的本地路径(./datasets-Canidae),并设置了覆盖已存在文件的选项。

        代码如下:

%%capture captured_output
# 实验环境已经预装了mindspore==2.3.0rc1,如需更换mindspore版本,可更改下面mindspore的版本号
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.3.0rc1
# 查看当前 mindspore 版本
!pip show mindspore
from download import download

dataset_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/intermediate/Canidae_data.zip"

download(dataset_url, "./datasets-Canidae", kind="zip", replace=True)

加载数据集


        首先定义了一些训练相关的参数,如批量大小、图像大小、训练周期数、学习率、动量和并行线程个数。

        然后指定了训练集和验证集的目录路径。

        接着定义了一个名为 create_dataset_canidae 的函数,用于根据指定的数据集路径和用途(训练或验证)创建数据集。

        在函数内部,先创建了一个 ImageFolderDataset 对象,并根据用途定义了不同的数据增强操作,包括随机裁剪、水平翻转、归一化等。然后对数据进行映射操作,并执行批量操作。

        最后,使用上述函数创建了训练集 dataset_train 和验证集 dataset_val ,并获取了它们的批量数量。

        代码如下:

batch_size = 18                             # 批量大小
image_size = 224                            # 训练图像空间大小
num_epochs = 5                             # 训练周期数
lr = 0.001                                  # 学习率
momentum = 0.9                              # 动量
workers = 4                                 # 并行线程个数
import mindspore as ms
import mindspore.dataset as ds
import mindspore.dataset.vision as vision

# 数据集目录路径
data_path_train = "./datasets-Canidae/data/Canidae/train/"
data_path_val = "./datasets-Canidae/data/Canidae/val/"

# 创建训练数据集

def create_dataset_canidae(dataset_path, usage):
    """数据加载"""
    data_set = ds.ImageFolderDataset(dataset_path,
                                     num_parallel_workers=workers,
                                     shuffle=True,)

    # 数据增强操作
    mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]
    std = [0.229 * 255, 0.224 * 255, 0.225 * 255]
    scale = 32

    if usage == "train":
        # Define map operations for training dataset
        trans = [
            vision.RandomCropDecodeResize(size=image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
            vision.RandomHorizontalFlip(prob=0.5),
            vision.Normalize(mean=mean, std=std),
            vision.HWC2CHW()
        ]
    else:
        # Define map operations for inference dataset
        trans = [
            vision.Decode(),
            vision.Resize(image_size + scale),
            vision.CenterCrop(image_size),
            vision.Normalize(mean=mean, std=std),
            vision.HWC2CHW()
        ]


    # 数据映射操作
    data_set = data_set.map(
        operations=trans,
        input_columns='image',
        num_parallel_workers=workers)


    # 批量操作
    data_set = data_set.batch(batch_size)

    return data_set


dataset_train = create_dataset_canidae(data_path_train, "train")
step_size_train = dataset_train.get_dataset_size()

dataset_val = create_dataset_canidae(data_path_val, "val")
step_size_val = dataset_val.get_dataset_size()

数据集可视化


        首先从训练数据集 dataset_train 中获取了下一个数据批次,并提取出其中的图像数据 images 和标签数据 labels 。然后打印出图像数据的张量形状和标签。接着定义了一个包含类别名称与标签对应关系的字典 class_name 。之后使用 matplotlib.pyplot 绘制图像,从获取的数据中选取了 4 幅图像进行展示。对每幅图像进行了预处理,包括转置维度、反标准化等操作,并为每个子图添加了对应的类别名称标题,同时关闭了坐标轴显示,最后展示了绘制的图像。

        代码如下:

data = next(dataset_train.create_dict_iterator())
images = data["image"]
labels = data["label"]

print("Tensor of image", images.shape)
print("Labels:", labels)
import matplotlib.pyplot as plt
import numpy as np

# class_name对应label,按文件夹字符串从小到大的顺序标记label
class_name = {0: "dogs", 1: "wolves"}

plt.figure(figsize=(5, 5))
for i in range(4):
    # 获取图像及其对应的label
    data_image = images[i].asnumpy()
    data_label = labels[i]
    # 处理图像供展示使用
    data_image = np.transpose(data_image, (1, 2, 0))
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    data_image = std * data_image + mean
    data_image = np.clip(data_image, 0, 1)
    # 显示图像
    plt.subplot(2, 2, i+1)
    plt.imshow(data_image)
    plt.title(class_name[int(labels[i].asnumpy())])
    plt.axis("off")

plt.show()

        运行结果:

构建Resnet50网络


        实现基于残差网络(Residual Network)的 ResNet 模型。

        首先,定义了两种残差块 ResidualBlockBase 和 ResidualBlock ,它们具有不同的卷积层结构和参数。

        然后,定义了 make_layer 函数,用于构建包含多个相同残差块的层。

        接下来是 ResNet 类,它在初始化方法中定义了一系列的卷积层、池化层、残差网络层、平均池化层、全连接层等。construct 方法定义了数据在模型中的前向传播过程。

        之后,定义了 _resnet 函数,用于创建 ResNet 模型,并根据是否预训练来加载预训练模型的参数。

        最后,resnet50 函数具体创建了一个 ResNet50 模型,并指定了预训练模型的 URL 和本地保存路径,以及是否使用预训练模型。

        代码如下:

from typing import Type, Union, List, Optional
from mindspore import nn, train
from mindspore.common.initializer import Normal


weight_init = Normal(mean=0, sigma=0.02)
gamma_init = Normal(mean=1, sigma=0.02)
class ResidualBlockBase(nn.Cell):
    expansion: int = 1  # 最后一个卷积核数量与第一个卷积核数量相等

    def __init__(self, in_channel: int, out_channel: int,
                 stride: int = 1, norm: Optional[nn.Cell] = None,
                 down_sample: Optional[nn.Cell] = None) -> None:
        super(ResidualBlockBase, self).__init__()
        if not norm:
            self.norm = nn.BatchNorm2d(out_channel)
        else:
            self.norm = norm

        self.conv1 = nn.Conv2d(in_channel, out_channel,
                               kernel_size=3, stride=stride,
                               weight_init=weight_init)
        self.conv2 = nn.Conv2d(in_channel, out_channel,
                               kernel_size=3, weight_init=weight_init)
        self.relu = nn.ReLU()
        self.down_sample = down_sample

    def construct(self, x):
        """ResidualBlockBase construct."""
        identity = x  # shortcuts分支

        out = self.conv1(x)  # 主分支第一层:3*3卷积层
        out = self.norm(out)
        out = self.relu(out)
        out = self.conv2(out)  # 主分支第二层:3*3卷积层
        out = self.norm(out)

        if self.down_sample is not None:
            identity = self.down_sample(x)
        out += identity  # 输出为主分支与shortcuts之和
        out = self.relu(out)

        return out
class ResidualBlock(nn.Cell):
    expansion = 4  # 最后一个卷积核的数量是第一个卷积核数量的4倍

    def __init__(self, in_channel: int, out_channel: int,
                 stride: int = 1, down_sample: Optional[nn.Cell] = None) -> None:
        super(ResidualBlock, self).__init__()

        self.conv1 = nn.Conv2d(in_channel, out_channel,
                               kernel_size=1, weight_init=weight_init)
        self.norm1 = nn.BatchNorm2d(out_channel)
        self.conv2 = nn.Conv2d(out_channel, out_channel,
                               kernel_size=3, stride=stride,
                               weight_init=weight_init)
        self.norm2 = nn.BatchNorm2d(out_channel)
        self.conv3 = nn.Conv2d(out_channel, out_channel * self.expansion,
                               kernel_size=1, weight_init=weight_init)
        self.norm3 = nn.BatchNorm2d(out_channel * self.expansion)

        self.relu = nn.ReLU()
        self.down_sample = down_sample

    def construct(self, x):

        identity = x  # shortscuts分支

        out = self.conv1(x)  # 主分支第一层:1*1卷积层
        out = self.norm1(out)
        out = self.relu(out)
        out = self.conv2(out)  # 主分支第二层:3*3卷积层
        out = self.norm2(out)
        out = self.relu(out)
        out = self.conv3(out)  # 主分支第三层:1*1卷积层
        out = self.norm3(out)

        if self.down_sample is not None:
            identity = self.down_sample(x)

        out += identity  # 输出为主分支与shortcuts之和
        out = self.relu(out)

        return out
def make_layer(last_out_channel, block: Type[Union[ResidualBlockBase, ResidualBlock]],
               channel: int, block_nums: int, stride: int = 1):
    down_sample = None  # shortcuts分支


    if stride != 1 or last_out_channel != channel * block.expansion:

        down_sample = nn.SequentialCell([
            nn.Conv2d(last_out_channel, channel * block.expansion,
                      kernel_size=1, stride=stride, weight_init=weight_init),
            nn.BatchNorm2d(channel * block.expansion, gamma_init=gamma_init)
        ])

    layers = []
    layers.append(block(last_out_channel, channel, stride=stride, down_sample=down_sample))

    in_channel = channel * block.expansion
    # 堆叠残差网络
    for _ in range(1, block_nums):

        layers.append(block(in_channel, channel))

    return nn.SequentialCell(layers)
from mindspore import load_checkpoint, load_param_into_net


class ResNet(nn.Cell):
    def __init__(self, block: Type[Union[ResidualBlockBase, ResidualBlock]],
                 layer_nums: List[int], num_classes: int, input_channel: int) -> None:
        super(ResNet, self).__init__()

        self.relu = nn.ReLU()
        # 第一个卷积层,输入channel为3(彩色图像),输出channel为64
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, weight_init=weight_init)
        self.norm = nn.BatchNorm2d(64)
        # 最大池化层,缩小图片的尺寸
        self.max_pool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')
        # 各个残差网络结构块定义,
        self.layer1 = make_layer(64, block, 64, layer_nums[0])
        self.layer2 = make_layer(64 * block.expansion, block, 128, layer_nums[1], stride=2)
        self.layer3 = make_layer(128 * block.expansion, block, 256, layer_nums[2], stride=2)
        self.layer4 = make_layer(256 * block.expansion, block, 512, layer_nums[3], stride=2)
        # 平均池化层
        self.avg_pool = nn.AvgPool2d()
        # flattern层
        self.flatten = nn.Flatten()
        # 全连接层
        self.fc = nn.Dense(in_channels=input_channel, out_channels=num_classes)

    def construct(self, x):

        x = self.conv1(x)
        x = self.norm(x)
        x = self.relu(x)
        x = self.max_pool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avg_pool(x)
        x = self.flatten(x)
        x = self.fc(x)

        return x


def _resnet(model_url: str, block: Type[Union[ResidualBlockBase, ResidualBlock]],
            layers: List[int], num_classes: int, pretrained: bool, pretrianed_ckpt: str,
            input_channel: int):
    model = ResNet(block, layers, num_classes, input_channel)

    if pretrained:
        # 加载预训练模型
        download(url=model_url, path=pretrianed_ckpt, replace=True)
        param_dict = load_checkpoint(pretrianed_ckpt)
        load_param_into_net(model, param_dict)

    return model


def resnet50(num_classes: int = 1000, pretrained: bool = False):
    "ResNet50模型"
    resnet50_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt"
    resnet50_ckpt = "./LoadPretrainedModel/resnet50_224_new.ckpt"
    return _resnet(resnet50_url, ResidualBlock, [3, 4, 6, 3], num_classes,
                   pretrained, resnet50_ckpt, 2048)

固定特征进行训练


        首先,使用预训练的 resnet50 模型,并对其进行了一些修改。将全连接层 fc 重置为输出通道数为 2 的新全连接层,将平均池化层 avg_pool 重置为 kernel_size=7 的新平均池化层。然后冻结除最后一层(新的全连接层)外的所有参数,使其在训练中不更新。

        接着,定义了优化器 opt 和损失函数 loss_fn 。

        然后,通过 ms.value_and_grad 计算损失函数关于可训练参数的梯度。

        定义了 train_step 函数,用于执行一步训练,包括计算损失和应用优化器更新参数。

        最后,实例化了一个 train.Model 对象 model1 ,用于模型的训练和评估。

        代码如下:

import mindspore as ms
import matplotlib.pyplot as plt
import os
import time

net_work = resnet50(pretrained=True)

# 全连接层输入层的大小
in_channels = net_work.fc.in_channels
# 输出通道数大小为狼狗分类数2
head = nn.Dense(in_channels, 2)
# 重置全连接层
net_work.fc = head

# 平均池化层kernel size为7
avg_pool = nn.AvgPool2d(kernel_size=7)
# 重置平均池化层
net_work.avg_pool = avg_pool

# 冻结除最后一层外的所有参数
for param in net_work.get_parameters():
    if param.name not in ["fc.weight", "fc.bias"]:
        param.requires_grad = False

# 定义优化器和损失函数
opt = nn.Momentum(params=net_work.trainable_params(), learning_rate=lr, momentum=0.5)
loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')


def forward_fn(inputs, targets):
    logits = net_work(inputs)
    loss = loss_fn(logits, targets)

    return loss

grad_fn = ms.value_and_grad(forward_fn, None, opt.parameters)

def train_step(inputs, targets):
    loss, grads = grad_fn(inputs, targets)
    opt(grads)
    return loss

# 实例化模型
model1 = train.Model(net_work, loss_fn, opt, metrics={"Accuracy": train.Accuracy()})

        运行结果:

训练和评估


        实现模型的训练和验证过程,并在训练过程中保存最优模型的检查点。

        首先,获取了训练集和验证集的数据,并计算了它们的批量数量,创建了迭代器。

        然后,设定了训练的轮数 num_epochs ,定义了保存最优检查点的目录和路径。

在训练循环中,每一轮都进行以下操作:

        将模型设置为训练模式。

        记录训练过程中的损失值。

        在每一轮结束后,在验证集上评估模型的准确率。

        计算并打印每一轮的训练时间和每步的平均时间。

        如果当前轮的准确率高于之前的最优准确率,就保存当前模型的参数为最优检查点。

        最后,打印出验证结束后的最优准确率和保存最优检查点的路径。

        代码如下:

import mindspore as ms
import matplotlib.pyplot as plt
import os
import time
dataset_train = create_dataset_canidae(data_path_train, "train")
step_size_train = dataset_train.get_dataset_size()

dataset_val = create_dataset_canidae(data_path_val, "val")
step_size_val = dataset_val.get_dataset_size()

num_epochs = 5

# 创建迭代器
data_loader_train = dataset_train.create_tuple_iterator(num_epochs=num_epochs)
data_loader_val = dataset_val.create_tuple_iterator(num_epochs=num_epochs)
best_ckpt_dir = "./BestCheckpoint"
best_ckpt_path = "./BestCheckpoint/resnet50-best-freezing-param.ckpt"
import mindspore as ms
import matplotlib.pyplot as plt
import os
import time
# 开始循环训练
print("Start Training Loop ...")

best_acc = 0

for epoch in range(num_epochs):
    losses = []
    net_work.set_train()

    epoch_start = time.time()

    # 为每轮训练读入数据
    for i, (images, labels) in enumerate(data_loader_train):
        labels = labels.astype(ms.int32)
        loss = train_step(images, labels)
        losses.append(loss)

    # 每个epoch结束后,验证准确率

    acc = model1.eval(dataset_val)['Accuracy']

    epoch_end = time.time()
    epoch_seconds = (epoch_end - epoch_start) * 1000
    step_seconds = epoch_seconds/step_size_train

    print("-" * 20)
    print("Epoch: [%3d/%3d], Average Train Loss: [%5.3f], Accuracy: [%5.3f]" % (
        epoch+1, num_epochs, sum(losses)/len(losses), acc
    ))
    print("epoch time: %5.3f ms, per step time: %5.3f ms" % (
        epoch_seconds, step_seconds
    ))

    if acc > best_acc:
        best_acc = acc
        if not os.path.exists(best_ckpt_dir):
            os.mkdir(best_ckpt_dir)
        ms.save_checkpoint(net_work, best_ckpt_path)

print("=" * 80)
print(f"End of validation the best Accuracy is: {best_acc: 5.3f}, "
      f"save the best ckpt file in {best_ckpt_path}", flush=True)

        运行结果:

可视化模型预测


        定义了一个名为 visualize_model 的函数,用于可视化模型在验证集上的预测结果。

        函数内部首先构建了一个 resnet50 模型,并对其全连接层和平均池化层进行了修改。然后加载了最优模型的参数。

        接着,从验证集中获取了一批数据,包括图像和标签。使用训练好的模型对这批图像进行预测,并获取预测结果。

        之后,通过绘制图像来展示预测结果。对于每幅图像,如果预测正确,标题显示为蓝色;如果预测错误,标题显示为红色。同时展示了经过处理后的图像,并关闭了坐标轴。

        最后,调用 visualize_model 函数并传入最优检查点路径和验证集 dataset_val 来执行可视化操作。

        代码如下:

import matplotlib.pyplot as plt
import mindspore as ms

def visualize_model(best_ckpt_path, val_ds):
    net = resnet50()
    # 全连接层输入层的大小
    in_channels = net.fc.in_channels
    # 输出通道数大小为狼狗分类数2
    head = nn.Dense(in_channels, 2)
    # 重置全连接层
    net.fc = head
    # 平均池化层kernel size为7
    avg_pool = nn.AvgPool2d(kernel_size=7)
    # 重置平均池化层
    net.avg_pool = avg_pool
    # 加载模型参数
    param_dict = ms.load_checkpoint(best_ckpt_path)
    ms.load_param_into_net(net, param_dict)
    model = train.Model(net)
    # 加载验证集的数据进行验证
    data = next(val_ds.create_dict_iterator())
    images = data["image"].asnumpy()
    labels = data["label"].asnumpy()
    class_name = {0: "dogs", 1: "wolves"}
    # 预测图像类别
    output = model.predict(ms.Tensor(data['image']))
    pred = np.argmax(output.asnumpy(), axis=1)

    # 显示图像及图像的预测值
    plt.figure(figsize=(5, 5))
    for i in range(4):
        plt.subplot(2, 2, i + 1)
        # 若预测正确,显示为蓝色;若预测错误,显示为红色
        color = 'blue' if pred[i] == labels[i] else 'red'
        plt.title('predict:{}'.format(class_name[pred[i]]), color=color)
        picture_show = np.transpose(images[i], (1, 2, 0))
        mean = np.array([0.485, 0.456, 0.406])
        std = np.array([0.229, 0.224, 0.225])
        picture_show = std * picture_show + mean
        picture_show = np.clip(picture_show, 0, 1)
        plt.imshow(picture_show)
        plt.axis('off')

    plt.show()
visualize_model(best_ckpt_path, dataset_val)

        运行结果:

        打印时间:

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

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

相关文章

帆软BI 模仿一个可视化护理软件大屏 (三百六十行 行行fine BI)

帆软BI 模仿一个可视化护理软件大屏 (三百六十行 行行fine BI) 文章目录 帆软BI 模仿一个可视化护理软件大屏 (三百六十行 行行fine BI)前言一、怎么做?二、导入数据三、编辑数据制作联合饼图四、编辑数据风险管理五、…

微短剧出海CPS分销推广影视平台系统搭建思维逻辑介绍

随着国内短剧市场的蓬勃发展,其独特的魅力与影响力已跨越国界,成为海外观众的新宠。这一趋势不仅推动了短剧内容的全球化传播,也为海外市场的CPS(按销售分润)分销模式提供了广阔舞台。连接内容创作者、平台运营者、系统…

数据结构与算法-关于堆的基本排序介绍

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、堆排序…

职场中的六条建议

在职场的征途中,我们每个人都是独一无二的行者,面对挑战与机遇并存的每一天。我们在职场中工作要弄清楚工作的本质,一定要牢记几点: 工作的本质与态度 我们工作的目的就是为了挣钱,我们不是来义务劳动也不是来参加快乐…

【Redis 初阶】Redis 常见数据类型(预备知识、String、哈希、List)

Redis 提供了 5 种数据结构,理解每种数据结构的特点对于 Redis 开发运维非常重要,同时掌握每种数据结构的常见命令,会在使用 Redis 的时候做到游刃有余。 一、预备知识 官方文档:Commands | Docs (redis.io) 1、最核心的两个命令…

npm提示 certificate has expired 证书已过期 已解决

在用npm新建项目时,突然发现报错提示 : certificate has expired 证书已过期 了解一下,在网络通信中,HTTPS 是一种通过 SSL/TLS 加密的安全 HTTP 通信协议。证书在 HTTPS 中扮演着至关重要的角色,用于验证服务器身份并加密数据传输…

python——joblib进行缓存记忆化-对计算结果缓存

问题场景 在前端多选框需要选取多个数据进行后端计算。 传入后端是多个数据包的对应路径。 这些数据包需要按一定顺序运行,通过一个Bag(path).get_start_time() 可以获得一个float时间值进行排序,但由于数据包的特性,这一操作很占用性能和时…

动手学深度学习V2每日笔记(模型初始化和激活函数)

本文主要参考沐神的视频教程 https://www.bilibili.com/video/BV1u64y1i75ap2&vd_sourcec7bfc6ce0ea0cbe43aa288ba2713e56d 文档教程 https://zh-v2.d2l.ai/ 本文的主要内容对沐神提供的代码中个人不太理解的内容进行笔记记录,内容不会特别严谨仅供参考。 1. 模…

Linux安装与配置

下载VMware 首先我们需要下载一个叫VMware的软件: 进入官方下载,地址:https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html选择与自己电脑版本适配的VMware版本【 输入许可证密钥 MC60H-DWHD5-H80U9-6V85…

硬盘分区读不出来的解决之道:从自救到专业恢复

在日常的计算机使用过程中,硬盘分区读不出来的问题常常令人头疼不已。这一问题不仅阻碍了用户对数据的正常访问,还可能预示着数据安全的潜在威胁。硬盘分区读不出来,通常是由于分区表损坏、文件系统错误、物理扇区损坏、驱动程序冲突或硬件连…

流量卡对比?看看哪个运营商的流量卡更适合你?

你用过流量卡吗?在这个一机双卡的时代,大部分的朋友都是人手两张电话卡,甚至更多,其中还包括一张大流量卡,那么,你会选择流量卡吗? ​ 为了冲量和拉新用户,三大运营商都在线上推出一…

优化极限学习机,实现回归预测,三种算法对比,MATLAB代码免费获取

本期将原始蜣螂算法、减法优化器算法、鲸鱼优化算法进行应用。对极限学习机进行优化实现股票回归预测,三种算法相互对比。 股票预测案例 股票数据特征有:开盘价,盘中最高价,盘中最低价,收盘价等。预测值为股票价格。股…

大白话讲清楚GPT嵌入(Embedding)的基本原理

嵌入(Embedding)是机器学习中的一个基本概念,尤其是在自然语言处理 (NLP) 领域,但它们也广泛应用于其他领域。通常,嵌入是一种将离散的分类数据转换为连续向量的方法,通常在高维空间中,将复杂、…

Jmeter之逻辑控制器(事务控制器+仅一次控制器+吞吐量控制器)-第八天

一.逻辑控制器 1.1事务控制器 事务,其实可以理解为完成一个业务所调用所有接口的集合,当然可以是单个接口,也可以是多个相互关联的串联接口。 所以在进行性能测试时,在用于多接口串联的场景时,需要汇总统计该多个接…

强烈建议产品经理学习AI大模型!

随着GPT大热 “AI大模型”无疑是最火爆的话题! Google、百度、腾讯等等巨头互联网公司, 无不在布局人工智能技术和市场, 甚至还有60k*16的高薪,挖掘AI大模型人才! 非技术岗的AIGC产品经理, **薪资水平…

html+css+js前端作业和平精英官网1个页面(带js)

htmlcssjs前端作业和平精英官网1个页面(带js)有轮播图tab切换等功能 下载地址 https://download.csdn.net/download/qq_42431718/89597007 目录1 目录2 项目视频 htmlcssjs前端作业和平精英官网1个页面(带js) 页面1

leetcode 2236.判断根节点是否等于字节点

1.题目要求: 给你一个 二叉树 的根结点 root,该二叉树由恰好 3 个结点组成:根结点、左子结点和右子结点。如果根结点值等于两个子结点值之和,返回 true ,否则返回 false 。2.思路: 直接数组前序遍历,然后判断后面两个…

前端开发的十字路口,薪的出口会是AI吗?

前言 在数字化转型的浪潮中,前端开发一直扮演着至关重要的角色,它连接着用户与产品之间的桥梁。然而,随着技术的不断进步和社会经济环境的变化,前端开发领域也面临着前所未有的挑战和机遇。 前端开发的困境 前端开发领域的竞争…

大模型LLM- 微调P-Tuning v1

P-tuning v1 一文小结 这篇文章介绍了一种名为P-Tuning的新方法,用于改善预训练语言模型(PLMs)在自然语言理解(NLU)任务中的性能和稳定性。P-Tuning通过将可训练的连续提示嵌入(continuous prompt embeddi…

Javascript前端面试基础(八)

window.onload和$(document).ready区别 window.onload()方法是必须等到页面内包括图片的所有元素加载完毕后才能执行$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕 window.onload 触发时机:window.onload 事件会在整个页面&#xf…