超详细避坑指南!OrangpiAIPro转换部署模型全流程!

news2024/9/19 17:04:30

目录

OrangepiPro初体验

前述:

一、硬件准备

二、安装CANN工具链(虚拟机)

三、配置模型转换环境(虚拟机)

1.安装miniconda 。

2.创建环境。

3.安装依赖包

四、转换模型

1. 查看设备号(开发板)

2. 使用ATC命令转换onnx模型为om模型(虚拟机)

补:使用ATC命令时遇到问题

五、模型推理(开发板)

1. 在板端安装CANN

2. 安装Mindx,用于推理。

3. 使用conda创建虚拟环境- python=3.9

4. python推理代码。

六、效果展示(开发板)

七、总结


OrangepiPro初体验

   终于!怀着激动的心情拿到了期待已久的开发板,迫不及待赶紧拆箱,映入眼帘的只有一个字:酷!正如下面几个大字所写:为AI而生。该开发板搭载华为昇腾AI处理器。能覆盖生态开发板者的主流应用场景,让用户实践各种创新场景,并为其提供配套的软硬件。丰富的接口更是赋予了Orange Pi AIpro强大的可拓展性。包括两个HDMI输出、GPIO接口、Type-C电源接口、支持SATA/NVMe SSD 2280的M.2插槽、TF插槽、千兆网口、两个USB3.0、一个USB Type-C 3.0、一个Micro USB、两个MIPI摄像头、一个MIPI屏等,预留电池接口。在操作系统方面,Orange Pi AIpro可运行Ubuntu、openEuler操作系统,满足大多数AI算法原型验证、推理应用开发的需求。实物如下:

在这里插入图片描述

在这里插入图片描述

前述:

   本文将不再介绍获取ip、连接wifi、vnc等操作,详情查看OrangpiPro官方手册即可。官方地址。
   作者认为后续的进一步学习或开发都应该建立在有基本了解的前提下,所以本文的宗旨就是带刚入门的初级开发者实现模型部署的完整流程。且本文内容还涉及在部署模型时所遇到的问题及其解决方法。每一步都有详细的步骤,避免踩坑。对刚入门进行学习的开发者来说,简直是不要太友好。相信根据本文部署完成后,会对流程有一些较为清楚的认识,对以后其他模型部署以及学习会有很大的帮助。创造不易,且看且珍惜。

一、硬件准备

Ubuntu22.04_x86系统(虚拟机)
OrangepiPro开发板

二、安装CANN工具链(虚拟机)

  异构计算架构CANN是华为针对AI场景推出的异构计算架构,向上支持多种AI框架,包括MindSpore、PyTorch、TensorFlow等,向下服务AI处理器与编程,发挥承上启下的关键作用,是提升昇腾AI处理器计算效率的关键平台。所以CANN工具链是我们必备工具链。打开ubuntu的浏览器:资源下载地址。
在这里插入图片描述

下载完成后,自动保存在Downloads目录下,如下所示:
在这里插入图片描述

   这里我已经给软件包添加了执行权限,如果初次下载请使用添加可执行权限。后续使用安装命令进行安装。安装命令: ./Ascend-cann-toolkit_7.0.RC1_linux-x86_64.run --install 。安装完成后,配置环境变量。使用命令:vi ~/.bashrc。将下述命令粘贴到文件里,这样就可以永久有效使用了,而不是只对当前命令窗口有效。

source /home/qjl/Ascend/ascend-toolkit/set_env.sh
export LD_LIBRARY_PATH=/home/qjl/Ascend/ascend-toolkit/7.0.RC1/x86_64-linux/devlib/x86_64:$LD_LIBRARY_PATH

   添加成功后,使用source ~/.bashrc命令来刷新使得文件配置生效。此时我们就可以使用atc命令来转换模型咯!如下,出现下面内容说明我们atc命令可以使用。
在这里插入图片描述

三、配置模型转换环境(虚拟机)

1.安装miniconda 。

//linux_x86架构下的conda
wget https://repo.anaconda.com/miniconda/Miniconda3-py37_4.12.0-Linux-x86_64.sh
bash Miniconda3-py37_4.12.0-Linux-x86_64.sh

2.创建环境。

   这里使用conda来创建环境,这里我创建的为python 3.9版本。创建环境流程这里就不多赘述,具体详情查看创建环境教程。

3.安装依赖包

pip install attrs numpy decorator sympy cffi pyyaml pathlib2 psutil protobuf scipy requests absl-py wheel typing_extensions -i https://mirrors.huaweicloud.com/repository/pypi/simple

这里安装完成后,如果哪些包出现依赖问题,则单独装一下该包即可。

四、转换模型

1. 查看设备号(开发板)

   使用命令:npu-smi info,查看设备号这个操作是在开发板上进行的,上面的操作都是在ubuntu上进行的(当然也可以在开发板上进行,只不过本文演示是在ubuntu_x86)。
在这里插入图片描述

2. 使用ATC命令转换onnx模型为om模型(虚拟机)

atc --model=/home/qjl/cup.onnx --framework=5 --output=/home/qjl/cup --soc_version=Ascend310B4 

该命令的具体参数这里不多介绍,详情请查看官方手册即可。
我们使用完命令后,等待几分钟转换好om模型。此时大功告成!废话不多说,立马部署到开发板上!

补:使用ATC命令时遇到问题

问题一:
在这里插入图片描述
   这个情况说明内存崩溃。这个问题原以为是因为训练模型的时候num_worker数量太大导致的问题,于是修改num_worker=0重新训练模型,将模型导入linux中转换时还是出现该错误,一时不知如何是好。但最终还是找到解决办法,将下面命令导入环境变量。设置最大核心数即可。编译过程仅使用一个核心,为了避免由于使用过多核心导致的资源竞争或内存不足问题。

export TE_PARALLEL_COMPILER=1
export MAX_COMPILE_CORE_NUMBER=1

这里和上面设置环境变量一样,可以设置到~/.bashrc中,使其永久生效。

问题二:
在这里插入图片描述
   找不到<type_traits>(C++库),这是因为缺失C++库导致的。于是我搜索本地gcc及g++库,结果发现还没有安装编译器,如下所示。
在这里插入图片描述
   既然这样,我们使用命令:sudo apt install build-essential,来安装编译工具包。这个工具包里包含了编译时所需要的各种工具以及相应的库文件。安装完成以后,我们就可以使用之前的命令进行模型转换咯~

五、模型推理(开发板)

1. 在板端安装CANN

在这里插入图片描述
   使用命令 ./Ascend-cann-toolkit_7.0.RC1_linux-aarch64.run --install进行安装。安装完成后,和在linux_x86端一样设置环境变量等操作,这里不再赘述。

2. 安装Mindx,用于推理。

注意:这里只有当安装好CANN后再进行安装Mindx!
在这里插入图片描述

   下载好以后,执行 ./Ascend-mindxsdk-mxvision_6.0.RC1_linux-aarch64.run --install进行安装。
   安装完成后vi ~/.bashrc,添加source /home/HwHiAiUser/Mindx/mxVision/set_env.sh。添加完成后使用source ~/.bashrc使得文件生效。

3. 使用conda创建虚拟环境- python=3.9

//arm架构下的conda
wget https://repo.anaconda.com/miniconda/Miniconda3-py37_4.9.2-Linux-aarch64.sh
bash Miniconda3-py37_4.9.2-Linux-aarch64.sh

(1)安装opencv:pip install opencv-python
(2)安装numpy:pip install numpy
(3)安装torch以及torchvision。下载好whl文件安装即可。点击:下载地址。如果缺少哪个包就再pip安装一下即可。
在这里插入图片描述

(4)安装mindx包。
进入Mindx安装目录,路径如下。找到whl文件使用pip进行安装即可。
在这里插入图片描述

4. python推理代码。

(1)后处理代码(公用)

def letterbox(img, new_shape=(640, 640), color=(114, 114, 114), auto=False, scaleFill=False, scaleup=True):
    # Resize image to a 32-pixel-multiple rectangle https://github.com/ultralytics/yolov3/issues/232
    shape = img.shape[:2]  # current shape [height, width]
    if isinstance(new_shape, int):
        new_shape = (new_shape, new_shape)

    # Scale ratio (new / old)
    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
    if not scaleup:  # only scale down, do not scale up (for better test mAP)
        r = min(r, 1.0)

    # Compute padding
    ratio = r, r  # width, height ratios
    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
    if auto:  # minimum rectangle
        dw, dh = np.mod(dw, 64), np.mod(dh, 64)  # wh padding
    elif scaleFill:  # stretch
        dw, dh = 0.0, 0.0
        new_unpad = (new_shape[1], new_shape[0])
        ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios

    dw /= 2  # divide padding into 2 sides
    dh /= 2

    if shape[::-1] != new_unpad:  # resize
        img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
    return img, ratio, (dw, dh)


def non_max_suppression(
        prediction,
        conf_thres=0.25,
        iou_thres=0.45,
        classes=None,
        agnostic=False,
        multi_label=False,
        labels=(),
        max_det=300,
        nm=0,  # number of masks
):
    """Non-Maximum Suppression (NMS) on inference results to reject overlapping detections

    Returns:
         list of detections, on (n,6) tensor per image [xyxy, conf, cls]
    """

    if isinstance(prediction, (list, tuple)):  # YOLOv5 model in validation model, output = (inference_out, loss_out)
        prediction = prediction[0]  # select only inference output

    device = prediction.device
    mps = 'mps' in device.type  # Apple MPS
    if mps:  # MPS not fully supported yet, convert tensors to CPU before NMS
        prediction = prediction.cpu()
    bs = prediction.shape[0]  # batch size
    nc = prediction.shape[2] - nm - 5  # number of classes
    xc = prediction[..., 4] > conf_thres  # candidates

    # Checks
    assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0'
    assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0'

    # Settings
    # min_wh = 2  # (pixels) minimum box width and height
    max_wh = 7680  # (pixels) maximum box width and height
    max_nms = 30000  # maximum number of boxes into torchvision.ops.nms()
    time_limit = 0.5 + 0.05 * bs  # seconds to quit after
    multi_label &= nc > 1  # multiple labels per box (adds 0.5ms/img)

    t = time.time()
    mi = 5 + nc  # mask start index
    output = [torch.zeros((0, 6 + nm), device=prediction.device)] * bs
    for xi, x in enumerate(prediction):  # image index, image inference
        # Apply constraints
        # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0  # width-height
        x = x[xc[xi]]  # confidence

        # Cat apriori labels if autolabelling
        if labels and len(labels[xi]):
            lb = labels[xi]
            v = torch.zeros((len(lb), nc + nm + 5), device=x.device)
            v[:, :4] = lb[:, 1:5]  # box
            v[:, 4] = 1.0  # conf
            v[range(len(lb)), lb[:, 0].long() + 5] = 1.0  # cls
            x = torch.cat((x, v), 0)

        # If none remain process next image
        if not x.shape[0]:
            continue

        # Compute conf
        x[:, 5:] *= x[:, 4:5]  # conf = obj_conf * cls_conf

        # Box/Mask
        box = xywh2xyxy(x[:, :4])  # center_x, center_y, width, height) to (x1, y1, x2, y2)
        mask = x[:, mi:]  # zero columns if no masks

        # Detections matrix nx6 (xyxy, conf, cls)
        if multi_label:
            i, j = (x[:, 5:mi] > conf_thres).nonzero(as_tuple=False).T
            x = torch.cat((box[i], x[i, 5 + j, None], j[:, None].float(), mask[i]), 1)
        else:  # best class only
            conf, j = x[:, 5:mi].max(1, keepdim=True)
            x = torch.cat((box, conf, j.float(), mask), 1)[conf.view(-1) > conf_thres]

        # Filter by class
        if classes is not None:
            x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)]

        # Check shape
        n = x.shape[0]  # number of boxes
        if not n:  # no boxes
            continue
        elif n > max_nms:  # excess boxes
            x = x[x[:, 4].argsort(descending=True)[:max_nms]]  # sort by confidence
        else:
            x = x[x[:, 4].argsort(descending=True)]  # sort by confidence

        # Batched NMS
        c = x[:, 5:6] * (0 if agnostic else max_wh)  # classes
        boxes, scores = x[:, :4] + c, x[:, 4]  # boxes (offset by class), scores
        i = torchvision.ops.nms(boxes, scores, iou_thres)  # NMS
        if i.shape[0] > max_det:  # limit detections
            i = i[:max_det]

        output[xi] = x[i]
        if mps:
            output[xi] = output[xi].to(device)
        if (time.time() - t) > time_limit:
            print(f'WARNING ⚠️ NMS time limit {time_limit:.3f}s exceeded')
            break  # time limit exceeded

    return output


def xywh2xyxy(x):
    # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
    y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
    y[:, 0] = x[:, 0] - x[:, 2] / 2  # top left x
    y[:, 1] = x[:, 1] - x[:, 3] / 2  # top left y
    y[:, 2] = x[:, 0] + x[:, 2] / 2  # bottom right x
    y[:, 3] = x[:, 1] + x[:, 3] / 2  # bottom right y
    return y


def get_labels_from_txt(path):
    labels_dict = dict()
    with open(path) as f:
        for cat_id, label in enumerate(f.readlines()):
            labels_dict[cat_id] = label.strip()
    return labels_dict


def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):
    # Rescale coords (xyxy) from img1_shape to img0_shape
    if ratio_pad is None:  # calculate from img0_shape
        gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / new
        pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh padding
    else:
        gain = ratio_pad[0][0]
        pad = ratio_pad[1]

    coords[:, [0, 2]] -= pad[0]  # x padding
    coords[:, [1, 3]] -= pad[1]  # y padding
    coords[:, :4] /= gain
    clip_coords(coords, img0_shape)
    return coords


def clip_coords(boxes, shape):
    # Clip bounding xyxy bounding boxes to image shape (height, width)
    if isinstance(boxes, torch.Tensor):  # faster individually
        boxes[:, 0].clamp_(0, shape[1])  # x1
        boxes[:, 1].clamp_(0, shape[0])  # y1
        boxes[:, 2].clamp_(0, shape[1])  # x2
        boxes[:, 3].clamp_(0, shape[0])  # y2
    else:  # np.array (faster grouped)
        boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1])  # x1, x2
        boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0])  # y1, y2


def nms(box_out, conf_thres=0.4, iou_thres=0.5):
    try:
        boxout = non_max_suppression(box_out, conf_thres=conf_thres, iou_thres=iou_thres, multi_label=True)
    except:
        boxout = non_max_suppression(box_out, conf_thres=conf_thres, iou_thres=iou_thres)
    return boxout

(2)图片推理:将模型文件和图片、以及推理代码放在一个目录下。运行该文件即可。

# coding=utf-8
import cv2  # 图片处理三方库,用于对图片进行前后处理
import numpy as np  # 用于对多维数组进行计算
import torch  # 深度学习运算框架,此处主要用来处理数据
import time
import torchvision
from mindx.sdk import Tensor  # mxVision 中的 Tensor 数据结构
from mindx.sdk import base  # mxVision 推理接口

def draw_bbox(bbox, img0, color, wt, names):
    det_result_str = ''
    for idx, class_id in enumerate(bbox[:, 5]):
        if float(bbox[idx][4] < float(0.05)):
            continue
        img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])), color, wt)
        img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
        img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
        det_result_str += '{} {} {} {} {} {}\n'.format(names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3])
    return img0
    
if __name__ == '__main__':
 
    # 初始化资源和变量
    base.mx_init()  # 初始化 mxVision 资源
    DEVICE_ID = 0  # 设备id
    model_path = 'best.om'  # 模型路径
    image_path = 'image.jpg'  # 测试图片路径

    # 数据前处理
    img_bgr = cv2.imread(image_path, cv2.IMREAD_COLOR)  # 读入图片
    img, scale_ratio, pad_size = letterbox(img_bgr, new_shape=[640, 640])  # 对图像进行缩放与填充,保持长宽比
    img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, HWC to CHW
    img = np.expand_dims(img, 0).astype(np.float32)  # 将形状转换为 channel first (1, 3, 640, 640),即扩展第一维为 batchsize
    img = np.ascontiguousarray(img) / 255.0  # 转换为内存连续存储的数组
    img = Tensor(img) # 将numpy转为转为Tensor类

    # 模型推理, 得到模型输出
    model = base.model(modelPath=model_path, deviceId=DEVICE_ID)  # 初始化 base.model 类
    output = model.infer([img])[0]  # 执行推理。输入数据类型:List[base.Tensor], 返回模型推理输出的 List[base.Tensor]

    # 后处理
    output.to_host()  # 将 Tensor 数据转移到内存
    output = np.array(output)  # 将数据转为 numpy array 类型
    boxout = nms(torch.tensor(output), conf_thres=0.4, iou_thres=0.5)  # 利用非极大值抑制处理模型输出,conf_thres 为置信度阈值,iou_thres 为iou阈值
    pred_all = boxout[0].numpy()  # 转换为numpy数组
    scale_coords([640, 640], pred_all[:, :4], img_bgr.shape, ratio_pad=(scale_ratio, pad_size))  # 将推理结果缩放到原始图片大小
    labels_dict = get_labels_from_txt('./coco_names.txt')  # 得到类别信息,返回序号与类别对应的字典
    img_dw = draw_bbox(pred_all, img_bgr, (0, 255, 0), 2, labels_dict)  # 画出检测框、类别、概率

    # 保存图片到文件
    cv2.imwrite('result.png', img_dw)
    print('save infer result success'
import cv2
import numpy as np
import torch
import time
import torchvision
from mindx.sdk import Tensor
from mindx.sdk import base

# 这里包括你已经提供的所有函数
# letterbox, non_max_suppression, xywh2xyxy, get_labels_from_txt, scale_coords, clip_coords, nms

def draw_bbox(bbox, img0, color, wt, names):
    det_result_str = ''
    for idx, class_id in enumerate(bbox[:, 5]):
        if float(bbox[idx][4] < float(0.05)):
            continue
        img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])), color, wt)
        img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        img0 = cv2.putText(img0, '{:.2f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] - 30)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        det_result_str += '{} {} {} {} {} {}\n'.format(names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3])
    return img0

def process_frame(frame, model, labels_dict, scale_ratio, pad_size, input_shape=(640, 640)):
    img, _, _ = letterbox(frame, new_shape=input_shape)
    img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, HWC to CHW
    img = np.expand_dims(img, 0).astype(np.float32)  # batch size 1
    img = np.ascontiguousarray(img) / 255.0
    img = Tensor(img)

    output = model.infer([img])[0]
    output.to_host()
    output = np.array(output)

    boxout = nms(torch.tensor(output), conf_thres=0.4, iou_thres=0.5)
    pred_all = boxout[0].numpy()
    scale_coords(input_shape, pred_all[:, :4], frame.shape, ratio_pad=(scale_ratio, pad_size))
    img_with_boxes = draw_bbox(pred_all, frame, (0, 255, 0), 2, labels_dict)

    return img_with_boxes

if __name__ == '__main__':
    # 初始化资源和变量
    base.mx_init()
    DEVICE_ID = 0
    model_path = 'best.om'
    video_path = 'video.mp4'
    output_video_path = 'result_video.mp4'

    # 初始化视频读取与写入
    cap = cv2.VideoCapture(video_path)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    fps = int(cap.get(cv2.CAP_PROP_FPS))
    frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    out = cv2.VideoWriter(output_video_path, fourcc, fps, (frame_width, frame_height))

    # 读取类别标签
    labels_dict = get_labels_from_txt('./coco_names.txt')

    # 加载模型
    model = base.model(modelPath=model_path, deviceId=DEVICE_ID)

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        # 数据前处理
        img_bgr = frame
        img, scale_ratio, pad_size = letterbox(img_bgr, new_shape=[640, 640])

        # 处理帧
        processed_frame = process_frame(frame, model, labels_dict, scale_ratio, pad_size)
        
        # 写入处理后的帧
        out.write(processed_frame)

    # 释放资源
    cap.release()
    out.release()
    print('Video processing complete. Saved to', output_video_path)

遇到问题
在这里插入图片描述
   我们在运行推理代码时出现上述问题,原因是因为我们torch和torchvision的版本有点高,只需要降低版本即可。如使用torch==1.10.0 torchvision==0.11.0即可。当然这里不影响我们最后的结果,所以觉得烦的小伙伴可以降低版本,该问题就解决了。

六、效果展示(开发板)

在这里插入图片描述

图片推理结果:
在这里插入图片描述

视频推理结果:
在这里插入图片描述

七、总结

  这里我们使用自训练的车辆数据集模型,部署到开发板上可见效果很好,这里我们就完成了从0到1的全部流程,中间也遇到很多问题,也是通过查阅大量资料来解决的问题,这也是必备的学习方法之一。本人也是处于学习阶段,所以有错误的地方,希望各位积极指正,我们一起加油。

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

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

相关文章

Linux服务器安装anaconda、配置pytorch环境

Linux服务器安装anaconda并配置pytorch环境 Linux服务器安装anaconda下载anaconda安装anaconda验证是否安装成功注意默认python版本 配置pytorch环境新建虚拟环境安装pytorch Linux服务器安装anaconda 下载anaconda 首先进入anaconda网站&#xff0c;根据自己的需要选择一个版…

LLM中的RoPE位置编码代码解析与RoPE的性质分析(一)

本博客需要对位置编码有一定了解&#xff0c;但不熟悉代码实现的老哥看。 正弦位置编码&#xff08;sinusoidal&#xff09; 在介绍RoPE之前&#xff0c;先回顾一下正弦位置编码。 数学表达 P E ( p o s , 2 i ) s i n ( p o s 1000 0 2 i / d m o d e l ) PE(pos, 2i) sin…

5.27作业

定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置。 #include <iostream>using namespace std; namespace my_space {string s1;string reverse1(string s1);} using namespace my_space; int m…

Web(数字媒体)期末作业

一.前言 1.本资源为类似于打飞机的网页游戏 2.链接如下&#xff1a;【免费】前端web或者数字媒体的期末作业&#xff08;类似于打飞机的2D网页小游戏&#xff09;资源-CSDN文库 二.介绍文档

HR人才测评,哪些岗位需要测评想象力?

什么是想象力&#xff1f; 想象力是指&#xff0c;人们通过在已有物质的基础上&#xff0c;通过大脑想象、加工、创造出新事物的能力&#xff0c;举一个非常简单的例子&#xff0c;在提到鸟这种生活的时候&#xff0c;大家会联想到各种各样不同鸟的品种。 哪些岗位需要测评…

喜讯 | 聚铭网络入选2024安在新榜网络安全产品“大众点评”百强榜及全景图

近日&#xff0c;安在新榜发布了备受期待的《2024中国网络安全产品用户调查报告》。在这份权威报告中&#xff0c;聚铭网络凭借先进的技术、优秀的产品和专业的配套服务&#xff0c;成功入选《2024安在新榜网络安全产品“大众点评”百强榜》。 报告通过对全国企业用户进行专项调…

海外仓erp系统是什么?和海外仓管理系统一样吗?

为了满足海外仓全球化发展的大趋势&#xff0c;同时提升海外仓运转的效率&#xff0c;一套好用&#xff0c;性价比高的海外仓管理系统还是非常重要的。 不过很多海外仓企业其实不太分得清erp系统和海外仓管理系统的差异&#xff0c;今天我们就来系统的聊一下&#xff0c;方便大…

React useState修改对象

在 React 中&#xff0c;useState 是一个 Hook&#xff0c;它可以让函数组件拥有状态。当想要改变一个对象类型的状态时&#xff0c;我们需要使用展开运算符&#xff08;...&#xff09;或者 Object.assign 来确保状态是正确地更新。 以下是一个使用 useState 来更新对象的例子…

windows下nvm的安装及使用

目录 一、下载二、安装三、使用 一、下载 下载链接&#xff1a;https://github.com/coreybutler/nvm-windows/releases 二、安装 双击 nvm-setup.exe&#xff0c;按提示一步步安装。 三、使用 # 查看已安装的版本信息 nvm list&#xff08;可简写为&#xff1a;nvm ls&am…

计算机视觉中-语义分割

语义分割 语义分割是计算机视觉中的一个关键技术&#xff0c;它涉及对图像中的每个像素进行类别划分&#xff0c;从而识别出图像中的不同物体或区域。具体来说&#xff0c;语义分割就是按照“语义”给图像上目标类别中的每一点打上一个标签&#xff0c;使得不同种类的东西在图像…

【RSGIS数据资源】中国多时期土地利用遥感监测数据集(CNLUCC)

文章目录 数据基本信息摘要数据说明数据引用方式 数据基本信息 数据时间&#xff1a; 多时期(1970年代末期以来11期) 空间位置&#xff1a; 中国 数据格式&#xff1a; 矢量与栅格 空间分辨率&#xff1a; 30m 主题分类&#xff1a; 中国土地利用遥感监测数据 DOI标识&#xf…

Android Gradle plugin 版本和Gradle 版本

1.当看到这两个版本时&#xff0c;确实有点迷糊。但是他们是独立的&#xff0c;没有太大关联。 就是说在Android studio中看到的两个版本信息&#xff0c;并无太大关联&#xff0c;是相互独立的。Gradle插件版本决定了你的项目是如何构建的&#xff0c;而Gradle版本是执行构建…

UML-系统架构师(二)

1、UML&#xff08;Unified Modeling Language&#xff09;是面向对象设计的建设工具&#xff0c;独立于任何具体程序设计语言&#xff0c;以下&#xff08;&#xff09;不属于UML中的模型。 A用例图 B协作图 C活动图 DPAD图 解析&#xff1a; UML一共14种图 结构图&…

电商场景的视频动效

AtomoVideo:AIGC赋能下的电商视频动效生成本文分享阿里妈妈视频 AIGC(AtomoVideo等) 赋能视频广告创意的探索和实践。通过基于扩散模型的视频生成技术,结合可控生成技术,使静态电商图片能够栩栩如生地“动”起来,实现了在电商领域的视频 AIGC 应用落地。https://mp.weixi…

LDRA Testbed(TBrun)软件单元测试_操作指南

系列文章目录 LDRA Testbed软件静态分析_操作指南 LDRA Testbed软件静态分析_自动提取静态分析数据生成文档 LDRA Testbed软件静态分析_Jenkins持续集成_(1)自动进行静态分析的环境搭建 LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果 LDRA Testb…

星融元获2024网络开源优秀创新成果奖!

5月25日&#xff0c;星融元受邀参加2024年第四届网络开源技术生态大会&#xff0c;分享主题为“开放的网络 开放的AI生态”主题演讲&#xff0c;深受现场用户的认可&#xff1b;《Easy RoCE&#xff1a;基于SONiC、Klish和Prometheus的极简无损网络解决方案》获得2024网络开源优…

网络其他重要协议(DNS、ICMP、NAT)

1.DNS DNS是一整套从域名映射到IP的系统 1.1 DNS背景 TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序&#xff0c;但是IP地址不方便记忆&#xff0c;例如我们想访问百度就会在浏览器中输入baidu.com而不是百度的IP地址。于是人们发明了一种叫主机名的东西, 是…

程序员日志之我的创作纪念日

目录 传送门正文日志1、概要2、ChatGPT的成为创作者初心的回答3、最受欢迎的博文4、未来创作 传送门 SpringMVC的源码解析&#xff08;精品&#xff09; Spring6的源码解析&#xff08;精品&#xff09; SpringBoot3框架&#xff08;精品&#xff09; MyBatis框架&#xff08;…

HTML+CSS+JavaScript网页制作案例教程第2版-黑马程序员-第8章动手实践

HTMLCSSJavaScript网页制作案例教程第2版-黑马程序员-第8章动手实践 文章目录 HTMLCSSJavaScript网页制作案例教程第2版-黑马程序员-第8章动手实践效果图代码素材 效果图 代码 <!doctype html> <html><head><meta charset"utf-8"><title…

nginx+nginx-http-flv-module在Linux服务器搭建

需求 在服务器搭建点播/视频平台的话需要在服务器搭建nginx和rtmp模块 rtmp模块 rtmp 模块有 nginx-rtmp-module &#xff0c;但是我们这里使用 nginx-http-flv-module 来替代。因为后者是基于前者开发的&#xff0c;前者拥有的功能后者都有&#xff0c;后者是国内的开发开…