昇思MindSpore学习笔记6-02计算机视觉--ResNet50迁移学习

news2024/9/23 7:19:59

摘要:

        记录MindSpore AI框架使用ResNet50迁移学习方法对ImageNet狼狗图片分类的过程、步骤。包括环境准备、下载数据集、数据集加载、构建模型、固定特征训练、训练评估和模型预测等。

一、

迁移学习的方法

        在大数据集上训练得到预训练模型

        初始化网络权重参数

        固定特征提取器

        应用于特定任务

ImageNet数据集中的狼和狗图像进行分类。

二、环境准备

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

输出:

Name: mindspore
Version: 2.2.14
Summary: MindSpore is a new open source deep learning training/inference framework that could be used for mobile, edge and cloud scenarios.
Home-page: https://www.mindspore.cn
Author: The MindSpore Authors
Author-email: contact@mindspore.cn
License: Apache 2.0
Location: /home/nginx/miniconda/envs/jupyter/lib/python3.9/site-packages
Requires: asttokens, astunparse, numpy, packaging, pillow, protobuf, psutil, scipy
Required-by: 

三、数据准备

1.下载数据集

ImageNet

        狼与狗每个分类

        120张训练图像

        30张验证图像

download接口

        下载数据集

        自动解压到当前目录下

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)

输出:

Creating data folder...
Downloading data from https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/intermediate/Canidae_data.zip (11.3 MB)

file_sizes: 100%|███████████████████████████| 11.9M/11.9M [00:00<00:00, 140MB/s]
Extracting zip file...
Successfully downloaded / unzipped to ./datasets-Canidae
'./datasets-Canidae'

数据集目录结构:

datasets-Canidae/data/
└── Canidae
    ├── train
    │   ├── dogs
    │   └── wolves
    └── val
        ├── dogs
        └── wolves

2.加载数据集

mindspore.dataset.ImageFolderDataset接口

        加载数据集

        图像增强操作。

定义执行过程的输入参数:

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()

3.数据集可视化

mindspore.dataset.ImageFolderDataset接口

        加载训练数据集

        返回值为字典

create_dict_iterator 接口

        创建数据迭代器

        next 迭代访问数据集

        batch_size 设为18

                next一次获取图像及标签数据的数量

data = next(dataset_train.create_dict_iterator())
images = data["image"]
labels = data["label"]
​
print("Tensor of image", images.shape)
print("Labels:", labels)

输出:

Tensor of image (18, 3, 224, 224)
Labels: [0 0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 1]

显示图像及标签数据

标题为图像对应的label名称

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

        Pretrained=True

        下载ResNet50的预训练模型

        加载权重参数

1.构建Resnet50网络

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)

2.固定特征进行训练

训练固定特征

        冻结除最后一层之外的所有网络层

        设置 requires_grad == False 冻结参数

        不在反向传播中计算梯度

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()})

输出:

Downloading data from https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt (97.7 MB)

file_sizes: 100%|█████████████████████████████| 102M/102M [00:00<00:00, 115MB/s]
Successfully downloaded file to ./LoadPretrainedModel/resnet50_224_new.ckpt

五、训练和评估

保存评估精度最高的ckpt文件于当前路径:

        ./BestCheckpoint/resnet50-best-freezing-param.ckpt

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)

输出:

Start Training Loop ...
--------------------
Epoch: [  1/  5], Average Train Loss: [0.641], Accuracy: [0.850]
epoch time: 125652.211 ms, per step time: 8975.158 ms
--------------------
Epoch: [  2/  5], Average Train Loss: [0.560], Accuracy: [0.983]
epoch time: 1105.189 ms, per step time: 78.942 ms
--------------------
Epoch: [  3/  5], Average Train Loss: [0.507], Accuracy: [0.983]
epoch time: 838.326 ms, per step time: 59.880 ms
--------------------
Epoch: [  4/  5], Average Train Loss: [0.451], Accuracy: [1.000]
epoch time: 927.405 ms, per step time: 66.243 ms
--------------------
Epoch: [  5/  5], Average Train Loss: [0.377], Accuracy: [0.983]
epoch time: 950.847 ms, per step time: 67.918 ms
================================================================================
End of validation the best Accuracy is:  1.000, save the best ckpt file in ./BestCheckpoint/resnet50-best-freezing-param.ckpt

六、可视化模型预测

使用固定特征得到的best.ckpt文件

预测验证集的狼和狗图像数据

预测字体为蓝色         预测正确

预测字体为红色         预测错误

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/1921321.html

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

相关文章

爬虫-浏览器自动化

什么是selenium selenium是浏览器自动化测试框架&#xff0c;原本用于网页测试。但到了爬虫领域&#xff0c;它又成为了爬虫的好帮手。有了 selenium&#xff0c;我们便不再需要判断网页数据加载的方式&#xff0c;只要让 selenium 自动控制浏览器&#xff0c;就像有双无形的手…

海南云亿商务咨询有限公司抖店开店正规吗?

在当今的数字经济时代&#xff0c;抖音电商已经成为一股不可忽视的力量。无论是品牌商还是个人创业者&#xff0c;都纷纷涌入这个充满活力和潜力的市场。而在这个风起云涌的浪潮中&#xff0c;海南云亿商务咨询有限公司以其专业的服务和敏锐的市场洞察力&#xff0c;成为抖音电…

GitHub 创始人资助的开源浏览器「GitHub 热点速览」

你是否注意到&#xff0c;现在主流的浏览器如 Chrome、Edge、Brave 和 Opera 都采用了谷歌的 Chromium 引擎&#xff1f;同时&#xff0c;谷歌每年不惜花费数十亿美元&#xff0c;确保其搜索引擎在 Safari 中的默认地位&#xff0c;甚至连 Firefox 也难逃商业利益的影响&#x…

一款好用的特殊字符处理工具

跟mybatis代码的时候&#xff0c;偶然发现的一款特殊字符处理工具java.lang.StringTokenizer。平常&#xff0c;我们看到的mybatis mapper.xml里面各种换行各种缩进&#xff0c;但日志文件里面的sql都是整整齐齐的。没有换行符&#xff0c;缩进等。就是利用该工具做的格式化处理…

在Ubuntu下安装samba实现和Windows系统文件共享

一、安装 apt install -y samba samba-clientSamba is not being run as an AD Domain Controller: Masking samba-ad-dc.service Please ignore the following error about deb-systemd-helper not finding those services. (samba-ad-dc.service masked) Created symlink /et…

每天一个数据分析题(四百二十七)- 方差分析

下面是一个方差分析表&#xff1a; 表中A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E五个单元格内的数据分别是&#xff08; &#xff09;。 A. 40&#xff0c;5&#xff0c;35&#xff0c;60&#xff0c;1.71 B. 40&#xff0c;5&#xff0c;35&#xff0c;60&a…

仙侠天花板,圆你土豪梦,上古传说手游详细图文架设教程

前言 这次给大家带来的是一款我的心头好&#xff0c;绝对是我所有架设游戏里排名前三的&#xff0c;一款经典的仙侠手游&#xff0c;安卓苹果双端&#xff0c;画质精美程度真的没有哪几个游戏可以比得上&#xff0c;故事情节加上背景音乐绝对值得沉浸其中慢慢玩&#xff0c;最…

JSONObject和Map<String, Object>的转换

一、前言 Java开发中出参返回和入参传入更灵活的方法是使用Map<String, Object>入参或出参&#xff0c;或者使用JSONObject。 1、好处&#xff0c;参数可变&#xff0c;对接口扩展性很友好。 public ResponseData<WXModelDTO> getUserInfo(RequestBody Map<…

【unity笔记】常见问题收集

一 . Unity Build GI data 卡住问题 问题解决: 参考官方文档&#xff0c;GI(Global Illumination) data 指的是全局照明信息。 在Unity的Edit->Preference中&#xff0c;可以编辑GI缓存路径和分配GI缓存大小。 调出Window->Rendering->Lighting窗口&#xff0c;取消…

OceanMind海睿思成功签约苏州天准,助力数据管理流程闭环!

近日&#xff0c;中新赛克海睿思与苏州天准科技股份有限公司&#xff08;以下简称“苏州天准”&#xff09;达成深度战略合作&#xff0c;为苏州天准提供数据工程平台。 双方将依托OceanMind海睿思提供的业内领先的数据工程建设理念&#xff0c;为苏州天准搭建以数字化平台底座…

大模型中 KV Cache 原理及显存占用分析

本文记录大模型推理阶段 KV Cache 的原理及显存占用情况。 Self-Attention 与 KV Cache 如图&#xff0c;当新生成的 token x 进到模型计算 Attention 时&#xff0c;先分别乘上参数矩阵 W q W_q Wq​、 W k W_k Wk​、 W v W_v Wv​ 得到向量 q&#xff0c;以及矩阵 K、V。…

汽车零配件行业看板管理系统应用

生产制造已经走向了精益生产&#xff0c;计算时效产出、物料周转时间等问题&#xff0c;成为每一个制造企业要面临的问题&#xff0c;工厂更需要加快自动化&#xff0c;信息化&#xff0c;数字化的布局和应用。 之前的文章多次讲解了企业MES管理系统&#xff0c;本篇文章就为大…

华为机试题-从(0,0)开始,计算绘图面积-Java

代码在最后面 1 题目描述 绘图机器的绘图笔初始位置在原点(0,0)&#xff0c;机器启动后按照以下规则来进行绘制直线。 尝试沿着横线坐标正向绘制直线直到给定的终点E。期间可以通过指令在纵坐标轴方向进行偏移&#xff0c;offset Y为正数表示正向偏移&#xff0c;为负数表示负…

linux源码安装mysql8.0的小白教程

1.下载8.x版本的mysql MySQL :: Download MySQL Community Server (Archived Versions) 2.安装linux 我安装的是Rocky Linux8.6 3.设置ip地址,方便远程连接 使用nmcli或者nmtui设置或修改ip地址 4.使用远程连接工具MobaXterm操作: (1)将mysql8版本的压缩包上传到mybaxterm…

【电商选品干货】差异化卖点要这样打造,80%商家却做不到

今天就给大家说说&#xff0c;如何去挖掘产品的差异化卖点&#xff1f;我们要找差异化卖点&#xff0c;就是因为我们的产品转化率不足&#xff0c;通常有下面几点原因&#xff1a; 1、产品差异化卖点不足&#xff0c;商家占比30% 2、流量和产品卖点不匹配&#xff0c;商家占比…

U-2 Net原理+代码实战教程

目录 一、显著性目标检测1.1 核心目标1.2 技术方法 二、U2-Net2.1 双层嵌套U结构2.2 残差U块&#xff08;RSU&#xff09;2.3 网络训练和监督 三、代码实战3.1 克隆仓库3.2 下载预训练模型3.3 安装依赖3.4 运行模型显著性目标检测&#xff1a;训练模型&#xff1a; 一、显著性目…

美团到家平台业务探索

背景 到家业务发展已经近10年&#xff0c;目前最为火热的应该有美团到家、抖音到家等&#xff0c;这种极具挑战性的业务&#xff0c;值得学习和思考。 既然是服务平台化&#xff0c;那一定是兼容了多种业务以及多种模式。 挑战 订单、骑手规模大&#xff0c;供需匹配过程的…

UDS协议——Authentication(29服务)

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍诊断和通讯管理功能单元下的29服务Authentication (29 16) service。此服务是在ISO 14229-2020版本中首次增加的为应对网联汽车日益增加的安全风险的新服务。为Client和Server之间的身份认证提供一种方法,以便对意图…

常用3D建模软件有哪些?如何实现3D模型在线预览?

3D建模是指使用计算机软件或其他工具创建三维物体模型的过程。3D建模大概可分为NURBS和多边形网格两类。NURBS对要求精细、弹性与复杂的模型有较好的应用&#xff0c;适合量化生产用途&#xff1b;多边形网格建模则靠拉面方式&#xff0c;适合做效果图与复杂场景动画。建模方法…

论文AIGC率超标,专业去痕工具是快速整改的钥匙,降低学术风险。

在学术领域&#xff0c;独创性是每位研究者梦寐以求的桂冠。随着AI技术的突飞猛进&#xff0c;AI辅助写作软件已成为学术工作者的得力伙伴。尽管如此&#xff0c;这些工具在提供帮助的同时&#xff0c;也引发了一个问题——如何有效减少论文的AI率。AI率&#xff0c;也就是由人…