昇思25天学习打卡营第23天|CV-ResNet50迁移学习

news2024/9/9 4:53:18

打卡

目录

打卡

迁移学习

实战练习

数据准备

数据处理

数据处理函数

数据处理流程

数据可视化

训练模型

构建Resnet50网络

固定特征进行训练

network 的输出

训练和评估

可视化模型预测 


通过本文,了解迁移学习的重点在于,了解你的模型结构,通过冻结不需要更新的模型参数,根据你的任务需求状况,修改模型的输出结构等部分,只更新所需参数,从而能从预训练的模型中快速训练出一个针对特定任务场景的模型,如N分类模型。

迁移学习

实际应用场景中,因为训练数据集不足,普遍的网络训练策略是,在一个非常大的基础数据集上训练得到一个预训练模型,然后用该模型来初始化网络的权重参数或作为固定特征提取器,从而应用于特定的任务中。

迁移学习详细内容见Stanford University CS231n。

本文使用迁移学习的方法对 ImageNet 数据集中的狼和狗图像进行分类。

实战练习

数据准备

本次的 狗与狼分类数据集 中的图像来自于ImageNet,每个分类有大约 120 张训练图像与 30 张验证图像。数据下载方式如下。

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)

数据处理

用 mindspore.dataset.ImageFolderDataset接口来加载数据集,并进行相关图像增强操作。

数据处理函数

处理后的图像尺寸【channel, height, wight】

import mindspore as ms
import mindspore.dataset as ds
import mindspore.dataset.vision as vision
 

def create_dataset_canidae(dataset_path, workers, usage, batch_size, image_size):
    """数据加载"""
    ## 从树状结构的文件目录中读取图片构建源数据集。同一个文件夹中的所有图片将被分配相同的label。
    ### 生成的数据集有两列:[image, label]。数据类型分别为 uint8、uint32。
    data_set = ds.ImageFolderDataset(dataset_path,
                                     num_parallel_workers=workers,   ## 指定读取数据的工作线程数。默认None用全局默认线程数(8)。
                                     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 = [
            ## “裁剪”、”解码”和”调整尺寸大小”的组合处理。该操作将在随机位置裁剪输入图像,以 RGB 模式对裁剪后的图像进行解码,并调整解码图像的尺寸大小。针对 JPEG 图像进行了优化, 可以获得更好的性能。
            vision.RandomCropDecodeResize(size=image_size, ## 调整后图像的输出尺寸大小。大小值必须为正。
                                          scale=(0.08, 1.0),  ## 要裁剪的原始尺寸大小的各个尺寸的范围[min, max),必须为非负数。
                                          ratio=(0.75, 1.333)  ## 宽高比的范围 [min, max) 裁剪,必须为非负数。默认值: (3./4., 4./3.)。
                                          ),
            ## 对输入图像按给定的概率进行水平随机翻转。默认值: 0.5 。
            vision.RandomHorizontalFlip(prob=0.5),
            ## 根据均值和标准差对输入图像进行归一化。默认图像为HWC格式,否则设is_hwc 
            vision.Normalize(mean=mean, std=std),
            ## 将输入图像的shape从 <H, W, C> 转换为 <C, H, W>。 如果输入图像的shape为 <H, W> ,图像将保持不变。
            vision.HWC2CHW()
        ]
    else:
        # Define map operations for inference dataset
        trans = [
            ## 将输入的压缩图像解码为RGB格式。当前支持的图片类型:JPEG、BMP、PNG、TIFF、GIF(需要指定 to_pil=True)、WEBP(需要指定 to_pil=True)。
            vision.Decode(),
            ## 用给定的插值方式(默认mindspore.dataset.vision.Inter.LINEAR)去调整为给定图像的尺寸大小。第一个参数是图像的输出尺寸大小。若输入整型,将调整图像的较短边长度为 size ,且保持图像的宽高比不变;若输入是2元素组成的序列,其输入格式需要是 (高度, 宽度) 。
            vision.Resize(image_size + scale),
            ## 对输入图像应用中心区域裁剪。如果输入图像尺寸小于输出尺寸,则在裁剪前对输入图像边界填充0像素。
            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  ## 指定map操作的多进程/多线程并发数,加快处理速度。
    )

    # 批量操作:将数据集中连续 batch_size 条数据组合为一个批数据
    data_set = data_set.batch(batch_size)

    return data_set

数据处理流程

import mindspore as ms
import mindspore.dataset as ds
import mindspore.dataset.vision as vision

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


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


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

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

如下图,训练集一共14个batch,验证集一共4个batch。

数据可视化

用 next 迭代访问数据迭代器。因为 batch_size 设为18,所以使用 next 一次可获取18个图像及标签数据。下面显示4个图像数据如下。

import matplotlib.pyplot as plt
import numpy as np

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

print("Tensor of image", images.shape)  ##  (18, 3, 224, 224)
print("Labels:", labels)  ## 元素为 1 和 0 的长度为 18 的 list


# 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]
    # 处理图像供展示使用
    ### 通过转置,其维度变为(高度, 宽度, 通道数),即(224, 224, 3),这样更符合图像处理的习惯。
    data_image = np.transpose(data_image, (1, 2, 0))
    ### 三个值对应于RGB三个通道的均值或标准差。这些均值或标准差通常是通过对大量图像数据集进行统计分析得到的,用于后续的标准化处理。 
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    ### 将图像数据从原始的像素值范围转换到均值为0,标准差为1的分布范围,这有助于模型的训练过程。
    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()

可视化一个batch_size 的 18 个图像输出如下。

训练模型

搭建好模型框架后,  下载ResNet50的预训练模型并将权重参数加载到网络中。

构建Resnet50网络

  • 代码调用逻辑为(从浅到深,其中代码调用顺序用>>表示,模型结构输入输出-->表示 ):
  1. func resnet50 >> func _resnet >> class ResNet >>  mindspore.load_checkpoint >>  mindspore.load_param_into_net
  2. class ResNet 结构
    1. conv1 --> norm  --> relu --> max_pool --> layer1 --> layer2 --> layer3 --> layer4 --> avg_pool --> flatten --> fc
    2. layerX 定义 >> func make_layer >> block=Union[ResidualBlockBase, ResidualBlock]
  3. class ResidualBlockBase 残差结构 [Building Block 结构]:conv1[3X3] --> norm  --> relu --> conv2[3X3] --> norm ( --> down_sample) --> +identity  --> relu.
  4. class ResidualBlock 残差块结构 [Bottleneck 结构]:conv1[1X1] --> norm1  --> relu --> conv2[3X3] --> norm2 --> relu --> conv3 [1X1]--> norm3 ( --> down_sample) --> +identity  --> relu.

关于ResNet50的文章介绍见本文。

代码逻辑陈述:下载并加载模型预训练模型到 ResNet50 网络结构,其中 ResNet50 自定义实现,函数 make_layer 创建一个由残差块(Residual Block)组成的层。Block 表示残差块的类型,它可以是ResidualBlockBaseResidualBlock的子类。

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


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:
        ## 如果stride不等于1或者上一个层的输出通道数与当前层的通道数乘以残差块的扩展因子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变量,表示下一个残差块的输入通道数是block.expansion倍的channel数量。
    in_channel = channel * block.expansion
    # 堆叠残差网络
    for _ in range(1, block_nums):
        layers.append(block(in_channel, channel))

    return nn.SequentialCell(layers)

 

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)
        # 在四维输入(具有额外通道维度的小批量二维输入)上应用批归一化处理(Batch Normalization Layer),以避免内部协变量偏移。
        self.norm = nn.BatchNorm2d(64)
        # 最大池化层,缩小图片的尺寸
        self.max_pool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')
        # 各个残差网络结构块定义,参数=上一个层的输出通道数+残差块+当前层的通道数+当前层中残差块的数量+第一个残差块的步长,默认1。
        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)

固定特征进行训练

  • 使用固定特征进行训练的时候,需要冻结除最后一层之外的所有网络层。通过net_work.get_parameters() 获取模型的全部参数,并在所需层设置 requires_grad == False 冻结参数,以便不在反向传播中计算梯度。
  • 根据本次的2分类任务需求,将模型的最后一层全连接层重新设置为 nn.Dense(in_channels, 2),
  • mindspore 的模型训练或推理的高阶接口如下,它会根据用户传入的参数封装可训练或推理的实例: mindspore.train.Model(network, loss_fn=None, optimizer=None, metrics=None, eval_network=None, eval_indexes=None, amp_level='O0', boost_level='O0', **kwargs),
    • 参数含义:
      • network (Cell) - 用于训练或推理的神经网络。

      • loss_fn (Cell) - 损失函数。如果 loss_fn 为None,network 中需要进行损失函数计算。默认值: None 。

      • optimizer (Cell) - 用于更新网络权重的优化器。如果 optimizer 为None, 那么 network 的网络结构里需要包括反向传播和权重更新逻辑。默认值: None 。

      • metrics (Union[dict, set]) - 用于模型评估的一组评价函数。例如:{‘accuracy’, ‘recall’}。默认值: None 。

      • eval_network (Cell) - 用于评估的神经网络。未定义情况下,Model 会使用 network 和 loss_fn 封装一个 eval_network 。默认值: None 。

      • eval_indexes (list) - 在定义 eval_network 的情况下使用。如果 eval_indexes 为默认值None,Model 会将 eval_network 的所有输出传给 metrics 。如果配置 eval_indexes ,必须包含三个元素,分别为损失值、预测值和标签在 eval_network 输出中的位置,此时,损失值将传给损失评价函数,预测值和标签将传给其他评价函数。推荐使用评价函数的 mindspore.train.Metric.set_indexes() 代替 eval_indexes 。默认值: None 。

      • boost_level (str) - mindspore.boost 的可选参数,为boost模式训练等级。支持[“O0”, “O1”, “O2”]。默认值: "O0" 。

        • “O1”: 启用boost模式,性能将提升约20%,准确率保持不变。

        • “O2”: 启用boost模式,性能将提升约30%,准确率下降小于3%。

        • O0”: 不变化。

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()})
network 的输出
ResNet<
  (relu): ReLU<>
  (conv1): Conv2d<input_channels=3, output_channels=64, kernel_size=(7, 7), stride=(2, 2), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
  (norm): BatchNorm2d<num_features=64, eps=1e-05, momentum=0.9, gamma=Parameter (name=norm.gamma, shape=(64,), dtype=Float32, requires_grad=False), beta=Parameter (name=norm.beta, shape=(64,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=norm.moving_mean, shape=(64,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=norm.moving_variance, shape=(64,), dtype=Float32, requires_grad=False)>
  (max_pool): MaxPool2d<kernel_size=3, stride=2, pad_mode=SAME>
  (layer1): SequentialCell<
    (0): ResidualBlock<
      (conv1): Conv2d<input_channels=64, output_channels=64, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=64, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.0.norm1.gamma, shape=(64,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.0.norm1.beta, shape=(64,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.0.norm1.moving_mean, shape=(64,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.0.norm1.moving_variance, shape=(64,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=64, output_channels=64, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=64, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.0.norm2.gamma, shape=(64,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.0.norm2.beta, shape=(64,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.0.norm2.moving_mean, shape=(64,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.0.norm2.moving_variance, shape=(64,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=64, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.0.norm3.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.0.norm3.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.0.norm3.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.0.norm3.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      (down_sample): SequentialCell<
        (0): Conv2d<input_channels=64, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
        (1): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.0.down_sample.1.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.0.down_sample.1.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.0.down_sample.1.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.0.down_sample.1.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
        >
      >
    (1): ResidualBlock<
      (conv1): Conv2d<input_channels=256, output_channels=64, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=64, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.1.norm1.gamma, shape=(64,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.1.norm1.beta, shape=(64,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.1.norm1.moving_mean, shape=(64,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.1.norm1.moving_variance, shape=(64,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=64, output_channels=64, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=64, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.1.norm2.gamma, shape=(64,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.1.norm2.beta, shape=(64,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.1.norm2.moving_mean, shape=(64,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.1.norm2.moving_variance, shape=(64,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=64, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.1.norm3.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.1.norm3.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.1.norm3.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.1.norm3.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (2): ResidualBlock<
      (conv1): Conv2d<input_channels=256, output_channels=64, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=64, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.2.norm1.gamma, shape=(64,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.2.norm1.beta, shape=(64,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.2.norm1.moving_mean, shape=(64,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.2.norm1.moving_variance, shape=(64,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=64, output_channels=64, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=64, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.2.norm2.gamma, shape=(64,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.2.norm2.beta, shape=(64,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.2.norm2.moving_mean, shape=(64,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.2.norm2.moving_variance, shape=(64,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=64, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer1.2.norm3.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer1.2.norm3.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer1.2.norm3.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer1.2.norm3.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    >
  (layer2): SequentialCell<
    (0): ResidualBlock<
      (conv1): Conv2d<input_channels=256, output_channels=128, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.0.norm1.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.0.norm1.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.0.norm1.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.0.norm1.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=128, output_channels=128, kernel_size=(3, 3), stride=(2, 2), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.0.norm2.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.0.norm2.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.0.norm2.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.0.norm2.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=128, output_channels=512, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.0.norm3.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.0.norm3.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.0.norm3.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.0.norm3.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      (down_sample): SequentialCell<
        (0): Conv2d<input_channels=256, output_channels=512, kernel_size=(1, 1), stride=(2, 2), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
        (1): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.0.down_sample.1.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.0.down_sample.1.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.0.down_sample.1.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.0.down_sample.1.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
        >
      >
    (1): ResidualBlock<
      (conv1): Conv2d<input_channels=512, output_channels=128, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.1.norm1.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.1.norm1.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.1.norm1.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.1.norm1.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=128, output_channels=128, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.1.norm2.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.1.norm2.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.1.norm2.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.1.norm2.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=128, output_channels=512, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.1.norm3.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.1.norm3.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.1.norm3.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.1.norm3.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (2): ResidualBlock<
      (conv1): Conv2d<input_channels=512, output_channels=128, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.2.norm1.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.2.norm1.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.2.norm1.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.2.norm1.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=128, output_channels=128, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.2.norm2.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.2.norm2.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.2.norm2.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.2.norm2.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=128, output_channels=512, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.2.norm3.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.2.norm3.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.2.norm3.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.2.norm3.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (3): ResidualBlock<
      (conv1): Conv2d<input_channels=512, output_channels=128, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.3.norm1.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.3.norm1.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.3.norm1.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.3.norm1.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=128, output_channels=128, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=128, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.3.norm2.gamma, shape=(128,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.3.norm2.beta, shape=(128,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.3.norm2.moving_mean, shape=(128,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.3.norm2.moving_variance, shape=(128,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=128, output_channels=512, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer2.3.norm3.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer2.3.norm3.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer2.3.norm3.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer2.3.norm3.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    >
  (layer3): SequentialCell<
    (0): ResidualBlock<
      (conv1): Conv2d<input_channels=512, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.0.norm1.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.0.norm1.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.0.norm1.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.0.norm1.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=256, output_channels=256, kernel_size=(3, 3), stride=(2, 2), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.0.norm2.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.0.norm2.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.0.norm2.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.0.norm2.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=256, output_channels=1024, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=1024, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.0.norm3.gamma, shape=(1024,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.0.norm3.beta, shape=(1024,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.0.norm3.moving_mean, shape=(1024,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.0.norm3.moving_variance, shape=(1024,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      (down_sample): SequentialCell<
        (0): Conv2d<input_channels=512, output_channels=1024, kernel_size=(1, 1), stride=(2, 2), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
        (1): BatchNorm2d<num_features=1024, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.0.down_sample.1.gamma, shape=(1024,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.0.down_sample.1.beta, shape=(1024,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.0.down_sample.1.moving_mean, shape=(1024,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.0.down_sample.1.moving_variance, shape=(1024,), dtype=Float32, requires_grad=False)>
        >
      >
    (1): ResidualBlock<
      (conv1): Conv2d<input_channels=1024, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.1.norm1.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.1.norm1.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.1.norm1.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.1.norm1.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=256, output_channels=256, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.1.norm2.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.1.norm2.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.1.norm2.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.1.norm2.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=256, output_channels=1024, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=1024, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.1.norm3.gamma, shape=(1024,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.1.norm3.beta, shape=(1024,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.1.norm3.moving_mean, shape=(1024,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.1.norm3.moving_variance, shape=(1024,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (2): ResidualBlock<
      (conv1): Conv2d<input_channels=1024, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.2.norm1.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.2.norm1.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.2.norm1.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.2.norm1.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=256, output_channels=256, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.2.norm2.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.2.norm2.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.2.norm2.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.2.norm2.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=256, output_channels=1024, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=1024, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.2.norm3.gamma, shape=(1024,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.2.norm3.beta, shape=(1024,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.2.norm3.moving_mean, shape=(1024,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.2.norm3.moving_variance, shape=(1024,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (3): ResidualBlock<
      (conv1): Conv2d<input_channels=1024, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.3.norm1.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.3.norm1.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.3.norm1.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.3.norm1.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=256, output_channels=256, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.3.norm2.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.3.norm2.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.3.norm2.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.3.norm2.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=256, output_channels=1024, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=1024, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.3.norm3.gamma, shape=(1024,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.3.norm3.beta, shape=(1024,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.3.norm3.moving_mean, shape=(1024,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.3.norm3.moving_variance, shape=(1024,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (4): ResidualBlock<
      (conv1): Conv2d<input_channels=1024, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.4.norm1.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.4.norm1.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.4.norm1.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.4.norm1.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=256, output_channels=256, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.4.norm2.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.4.norm2.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.4.norm2.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.4.norm2.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=256, output_channels=1024, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=1024, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.4.norm3.gamma, shape=(1024,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.4.norm3.beta, shape=(1024,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.4.norm3.moving_mean, shape=(1024,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.4.norm3.moving_variance, shape=(1024,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (5): ResidualBlock<
      (conv1): Conv2d<input_channels=1024, output_channels=256, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.5.norm1.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.5.norm1.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.5.norm1.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.5.norm1.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=256, output_channels=256, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=256, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.5.norm2.gamma, shape=(256,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.5.norm2.beta, shape=(256,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.5.norm2.moving_mean, shape=(256,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.5.norm2.moving_variance, shape=(256,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=256, output_channels=1024, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=1024, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer3.5.norm3.gamma, shape=(1024,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer3.5.norm3.beta, shape=(1024,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer3.5.norm3.moving_mean, shape=(1024,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer3.5.norm3.moving_variance, shape=(1024,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    >
  (layer4): SequentialCell<
    (0): ResidualBlock<
      (conv1): Conv2d<input_channels=1024, output_channels=512, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.0.norm1.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.0.norm1.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.0.norm1.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.0.norm1.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=512, output_channels=512, kernel_size=(3, 3), stride=(2, 2), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.0.norm2.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.0.norm2.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.0.norm2.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.0.norm2.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=512, output_channels=2048, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=2048, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.0.norm3.gamma, shape=(2048,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.0.norm3.beta, shape=(2048,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.0.norm3.moving_mean, shape=(2048,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.0.norm3.moving_variance, shape=(2048,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      (down_sample): SequentialCell<
        (0): Conv2d<input_channels=1024, output_channels=2048, kernel_size=(1, 1), stride=(2, 2), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
        (1): BatchNorm2d<num_features=2048, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.0.down_sample.1.gamma, shape=(2048,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.0.down_sample.1.beta, shape=(2048,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.0.down_sample.1.moving_mean, shape=(2048,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.0.down_sample.1.moving_variance, shape=(2048,), dtype=Float32, requires_grad=False)>
        >
      >
    (1): ResidualBlock<
      (conv1): Conv2d<input_channels=2048, output_channels=512, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.1.norm1.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.1.norm1.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.1.norm1.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.1.norm1.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=512, output_channels=512, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.1.norm2.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.1.norm2.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.1.norm2.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.1.norm2.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=512, output_channels=2048, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=2048, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.1.norm3.gamma, shape=(2048,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.1.norm3.beta, shape=(2048,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.1.norm3.moving_mean, shape=(2048,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.1.norm3.moving_variance, shape=(2048,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    (2): ResidualBlock<
      (conv1): Conv2d<input_channels=2048, output_channels=512, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm1): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.2.norm1.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.2.norm1.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.2.norm1.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.2.norm1.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (conv2): Conv2d<input_channels=512, output_channels=512, kernel_size=(3, 3), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm2): BatchNorm2d<num_features=512, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.2.norm2.gamma, shape=(512,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.2.norm2.beta, shape=(512,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.2.norm2.moving_mean, shape=(512,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.2.norm2.moving_variance, shape=(512,), dtype=Float32, requires_grad=False)>
      (conv3): Conv2d<input_channels=512, output_channels=2048, kernel_size=(1, 1), stride=(1, 1), pad_mode=same, padding=0, dilation=(1, 1), group=1, has_bias=False, weight_init=<mindspore.common.initializer.Normal object at 0xffff901e02e0>, bias_init=None, format=NCHW>
      (norm3): BatchNorm2d<num_features=2048, eps=1e-05, momentum=0.9, gamma=Parameter (name=layer4.2.norm3.gamma, shape=(2048,), dtype=Float32, requires_grad=False), beta=Parameter (name=layer4.2.norm3.beta, shape=(2048,), dtype=Float32, requires_grad=False), moving_mean=Parameter (name=layer4.2.norm3.moving_mean, shape=(2048,), dtype=Float32, requires_grad=False), moving_variance=Parameter (name=layer4.2.norm3.moving_variance, shape=(2048,), dtype=Float32, requires_grad=False)>
      (relu): ReLU<>
      >
    >
  (avg_pool): AvgPool2d<kernel_size=7, stride=1, pad_mode=VALID>
  (flatten): Flatten<>
  (fc): Dense<input_channels=2048, output_channels=2, has_bias=True>
  >

训练和评估

开始训练模型,因为不用计算部分梯度,时间较快。保存评估精度最高的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"



# 开始循环训练
print("Start Training Loop ...")

best_acc = 0  ## 保存最好的精度
for epoch in range(num_epochs):
    losses = []  ## 保存当前epoch中每个batch_size下的损失
    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) 
    ### 输出当前epoch中所有batch的平均损失和最好的验证集的精度。
    print("Epoch: [%3d/%3d], Average Train Loss: [%5.3f], Accuracy: [%5.3f]" % (
        epoch+1, num_epochs, sum(losses)/len(losses), acc
    ))
    ## 输出当前 epoch 训练耗时,以及每个batch的平均耗时。
    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)

训练过程截图:

如上图,第一轮用时最多,这里面可能是因为初次模型加载到显存比较费时吧,后面就非常快了。每一个batch 18个图片,总共14个batch 243张图片,差不多1秒左右就完成一轮训练了。

可视化模型预测 

使用固定特征得到的最好的模型权重文件 "./BestCheckpoint/resnet50-best-freezing-param.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/1961426.html

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

相关文章

LGA-4500激光气体分析仪说明手册

目 录 阅 读 说 明 I 用户须知 I 概况 I 注意和警示信息 I 供货和运输 III 质保和维修 III 联系方式 III 一、简介 1 1.1概要 1 1.2测量原理 1 1.2.1单线光谱技术 1 1.2.2激光频率扫描技术 2 1.2.3谱线展宽自动修正技术 2 1.3系统组成 2 1.4系统特点 3 1.5系统指标 4 1.6激光产…

决策树可解释性分析

决策树可解释性分析 决策树是一种广泛使用的机器学习算法&#xff0c;以其直观的结构和可解释性而闻名。在许多应用场景中&#xff0c;尤其是金融、医疗等领域&#xff0c;模型的可解释性至关重要。本文将从决策路径、节点信息、特征重要性等多个方面分析决策树的可解释性&…

Thymeleaf(看这一篇就够了)

目录&#xff1a; Thymeleaf变量输出操作字符串&时间条件判断迭代遍历使用状态变量获取域中的数据URL写法相关配置 Thymeleaf Thymeleaf是一款用于渲染XML/HTML5内容的模板引擎&#xff0c;类似JSP。它可以轻易的与SpringMVC等Web框架进行集成作为Web应用的模板引擎。Spri…

暄桐林曦老师推荐书单——《菜根谭》

暄桐是一间传统美学教育教室&#xff0c;创办于2011年&#xff0c;林曦是创办人和授课老师&#xff0c;教授以书法为主的传统文化和技艺&#xff0c;皆在以书法为起点&#xff0c;亲近中国传统之美&#xff0c;以实践和所得&#xff0c;滋养当下生活。      在暄桐教室的课…

机械运动、工控机概念整理

Signal &#xff1a; 信号 pul 【pulse】是驱动脉冲信号&#xff0c;发一个脉冲&#xff0c;电机走一步。 dir是方向控制信号&#xff0c;控制电机正转或反转。 ena是使能信号&#xff0c;这个信号必须开启&#xff0c;才能驱动电机。 voltage&#xff1a; 电压 VCC&#…

Python软件开发:AI毕业设计生成器引领未来

&#x1f31f; 革新软件开发&#xff1a;Python毕业设计生成器引领未来 &#x1f680; 目录 &#x1f31f; 革新软件开发&#xff1a;Python毕业设计生成器引领未来 &#x1f680;&#x1f393; 课题简介&#x1f31f; 开发目的&#x1f4c8; 开发意义 &#x1f4da; 研究方法&…

[ BLE4.0 ] 伦茨ST17H66开发-串口UART0的接收与发送

目录 一、前言 二、实现步骤 1.设置回调函数 2.关闭睡眠模式 三、效果展示 四、工程源代码 一、前言 串口通信在任何一款单片机开发中都是尤为重要的。本文涉及的开发所使用的例程依然是基于[ BLE4.0 ] 伦茨ST17H66开发-OSAL系统中添加自己的Task任务文章的工程源码&#x…

进程间通信--套接字socket

前面提到的管道、消息队列、共享内存、信号和信号量都是在同一台主机上进行进程间通信&#xff0c;那要想跨网络与不同主机上的进程之间通信&#xff0c;就需要Socket通信了。 实际上&#xff0c;Socket通信不仅可以跨网络与不同主机的进程间通信&#xff0c;还可以在同主机上…

一键升级GIS场景视觉效果,告别繁琐操作

在当今的数字化时代&#xff0c;GIS&#xff08;地理信息系统&#xff09;不再仅仅只能通过一些二维示意图或简陋的三维地形图表示&#xff0c;它可以通过专业的软件简单升级视效。想象一下&#xff0c;在你的GIS场景中&#xff0c;阳光明媚的天气、突如其来的暴风雨、缭绕的晨…

工时管理平台核心功能解析:你需要了解的

国内外主流的10款工时管理平台对比&#xff1a;PingCode、Worktile、Todoist、ClickUp、滴答清单、专注清单、一木清单、NarTick、Tweek、朝暮计划。 在选择合适的工时管理平台时&#xff0c;你是否感到挑战重重&#xff1f;市场上的各种选项似乎都声称能够提升效率和减轻管理负…

【SQL Server点滴积累】SQL Server 2016数据库邮件(Database Mail)功能故障的解决方法

今天和大家分享SQL Server 2016数据库邮件(Database Mail)功能故障的解决方法 故障现象&#xff1a; 在SQL Server 2016中配置完成数据库邮件(Database Mail)功能后&#xff0c;当你尝试发送测试邮件后&#xff0c;既收不到测试邮件&#xff0c;也不显示错误消息 KB3186435 -…

Python数值计算(11)——拉格朗日插值

本篇介绍一下多项式插值中&#xff0c;拉格朗日法的原理及其实现。 1. 一点数学知识 先引用数学背景。如果给定N个点&#xff0c;然后要求一个多项式通过这N个点&#xff0c;最简单直接的方式是列出线性方程求解&#xff0c;N个点可以确定N个未知量&#xff0c;则所求的拟合多…

下面关于枚举的描述正确的一项是?

A. 枚举中定义的每一个枚举项其类型都是String&#xff1b; B. 在Java中可以直接继承java.util.Enum类实现枚举类的定义&#xff1b; C. 利用枚举类中的values()方法可以取得全部的枚举项&#xff1b; D. 枚举中定义的构造方法只能够使用private权限声明&#xff1b; 答案选择…

springboot山东外事职业大学校园食堂点餐系统-计算机毕业设计源码10417

摘 要 近年来&#xff0c;随着国民收入的提高&#xff0c;各行业取得长足进步&#xff0c;也带动了互联网行业的快速发展&#xff0c;许多传统行业开始与互联网相结合&#xff0c;通过数字化转型打造新的发展生态。 本文针对山东外事大学校园食堂点餐系统的需求&#xff0c;基于…

Java内存区域与内存溢出异常详解

在Java编程中&#xff0c;理解Java虚拟机的内存布局及其管理机制对于开发高效、稳定的应用程序至关重要。Java虚拟机的内存主要分为几个运行时区域&#xff0c;这些区域各司其职&#xff0c;共同支撑起Java程序的运行。本文将详细探讨Java虚拟机的内存区域以及这些区域如何与内…

Yolov模型的使用及数据集准备(1)LabelImg的下载和使用

1、LabelImg下载&#xff1a; labelimg简单来说就是打标签用的软件&#xff0c;当需要使用自定义数据集进行模型训练时&#xff0c;往往需要使用该软件来打标签。 下载地址&#xff1a;GitHub - HumanSignal/labelImg 1.1下载之后对压缩包进行解压 2、打开电脑的anaconda pro…

MyBatis XML配置文件

目录 一、引入依赖 二、配置数据库的连接信息 三、实现持久层代码 3.1 添加mapper接口 3.2 添加UserInfoXMLMapper.xml 3.3 增删改查操作 3.3.1 增(insert) 3.3.2 删(delete) 3.3.3 改(update) 3.3.4 查(select) 本篇内容仍然衔接上篇内容&#xff0c;使用的代码及案…

8G 显存玩转书生大模型 Demo

创建可用环境 # 创建环境 conda create -n demo python3.10 -y # 激活环境 conda activate demo # 安装 torch conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.2 pytorch-cuda12.1 -c pytorch -c nvidia -y # 安装其他依赖 pip install transformers4.38 pip in…

Moving Object Segmentation: All You Need Is SAM(and Flow) 论文详解

系列文章目录 文章目录 系列文章目录前言摘要1 引言2 相关工作3 SAM Preliminaries4 帧级分割Ⅰ&#xff1a;以流作为输入5 帧级分割Ⅱ&#xff1a;以流为提示6 序列级掩膜关联7 实验7.1 数据集7.2 评价指标7 .3 实施细节7.4 消融实验7.5 定量结果7 .定性可视化 8 结论致谢附录…

01 - 计算机组成原理与体系结构

文章目录 一&#xff0c;计算机系统硬件基本组成硬件软件 二&#xff0c;CPU的功能与组成功能组成运算器控制器 三&#xff0c;数据表示计算机的基本单位进制转换原码&#xff0c;反码&#xff0c;补码&#xff0c;移码数值表示范围浮点数表示 四&#xff0c;寻址五&#xff0c…