YOLOv5配置訓練以及華為昇騰910B推理

參考文章:

保姆式yolov5教程,訓練你自己的數據集 - 知乎

Windows 10|11下安裝mmyolo-0.5.0版本 - 知乎

Ubuntu22.04安裝教程&基于華為Ascend AI處理器的om模型atc轉換環境安裝_ubuntu安裝atc工具-CSDN博客嵌入式AI---在華為昇騰推理自己的yolov5目標檢測模型_昇騰 yolo-CSDN博客?

YOLOv5配置

使用conda創建新的虛擬環境并激活

conda create -n openmmlab python=3.8 -y
conda activate openmmlab

?pytorch安裝

CPU:

conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 cpuonly -c pytorch

Nvidia顯卡且CUDA>=11.6:

conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.6 -c pytorch -c nvidia

其他的pytorch版本沒測試

下載mmyolo-0.5.0,進入mmyolo-0.5.0目錄下

cd path  # 這里的path就是上面復制的路徑,用你自己的路徑替換path
# --------------進入到目錄中后直接復制下面的命令并執行-------------------------
pip install chardet
pip install -U openmim
mim install -r requirements/mminstall.txt
# Install albumentations
pip install -r requirements/albu.txt
# Install MMYOLO,使用可編輯模式安裝,以后編輯這個文件夾下的代碼會對整個環境生效
mim install -v -e .

安裝可視化工具?

WandB 可視化需要在官網注冊,并在?Weights & Biases?獲取到 WandB 的 API Keys。?

pip install wandb
# 運行了 wandb login 后輸入上文中獲取到的 API Keys ,便登錄成功。
wandb login

?

YOLOv5訓練

進入yolov5文件夾目錄

cd [path_to_yolov5] 

數據集格式

在yolov5目錄下新建文件夾dataset?

road #(數據集名字) 
├── images      ├── train          ├── xx.jpg     ├── val         ├── xx.jpg 
├── labels      ├── train          ├── xx.txt     ├── val         ├── xx.txt 

在yolov5/data文件夾下新建road.yaml

內容如下所示:

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: /opt/data/private/zyx/yolov5/dataset/road8802  # dataset root dir
train: images/train  # train images (relative to 'path')
val: images/val  # val images (relative to 'path')
test:  # test images (optional)# Classes
nc: 5  # number of classes
names: ['VT', 'VC', 'RS', 'VR','LN']  # class names

其中:

  • path:數據集的根目錄

  • train:訓練集與path的相對路徑

  • val:驗證集與path的相對路徑

  • nc:類別數量,因為這個數據集只有一個類別(fire),nc即為1。

  • names:類別名字。

訓練

python train.py --weights yolov5s.pt --data data/road.yaml --epochs 200 --workers 1 --batch-size 64

推理

模型訓練完成后,將runs/exp/weights下的模型(best.pt)復制在yolov5文件夾下

python detect.py --weights best.onnx --source ../yolov5/dataset/road7190/images/val --data data/road.yaml 

pt->onnx

python export.py --weights best.pt --data data/road.yaml --include onnx

完成后會在目錄下看到best.onnx文件?

ATC轉OM文件

創建python3.7.5的虛擬環境和安裝python依賴

conda create -n v3onnx python=3.7.5
pip3 install attrs numpy decorator sympy cffi pyyaml pathlib2 psutil protobuf scipy requests absl-py

下載CANN的兩個包

在昇騰社區官網上下載CANN的兩個包:toolkit和nnrt包

一定要根據推理時使用的cann版本下載對應版本的包

這是我的鏡像:model_convert_cann7.0_aarch64_910b_py310:v6.0

可以看到cann時7.0版本?

社區版資源下載-資源下載中心-昇騰社區

Ascend-cann-nnrt_7.0.1_linux-x86_64.run

Ascend-cann-toolkit_7.0.1_linux-x86_64.run

安裝包?

?將包下載好放入虛擬環境中,開始安裝:

chmod +x Ascend-cann-nnrt_7.0.1_linux-x86_64.run
chmod +x Ascend-cann-toolkit_7.0.1_linux-x86_64.run
#賦予權限./Ascend-cann-nnrt_7.0.1_linux-x86_64.run --check
./Ascend-cann-toolkit_7.0.1_linux-x86_64.run --check
#檢查安裝包完整性./Ascend-cann-nnrt_7.0.1_linux-x86_64.run --install
./Ascend-cann-toolkit_7.0.1_linux-x86_64.run --install

配置ATC運行環境?

由于環境未配置,哪怕我們安裝了CANN包也無法使用atc命令,因此我們需要配置環境?

vi ~/.bashrcexport ASCEND_TOOLKIT_HOME=/usr/local/Ascend/ascend-toolkit/latest
export LD_LIBRARY_PATH=${ASCEND_TOOLKIT_HOME}/lib64:${ASCEND_TOOLKIT_HOME}/lib64/plugin/opskernel:${ASCEND_TOOLKIT_HOME}/lib64/plugin/nnengine:/usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/devlib/:$LD_LIBRARY_PATH
export PYTHONPATH=${ASCEND_TOOLKIT_HOME}/python/site-packages:${ASCEND_TOOLKIT_HOME}/opp/op_impl/built-in/ai_core/tbe:$PYTHONPATH
export PATH=${ASCEND_TOOLKIT_HOME}/bin:${ASCEND_TOOLKIT_HOME}/compiler/ccec_compiler/bin:$PATH
export ASCEND_AICPU_PATH=${ASCEND_TOOLKIT_HOME}
export ASCEND_OPP_PATH=${ASCEND_TOOLKIT_HOME}/opp
export TOOLCHAIN_HOME=${ASCEND_TOOLKIT_HOME}/toolkit
export ASCEND_HOME_PATH=${ASCEND_TOOLKIT_HOME}source ~/.bashrc

export后點擊Esc,然后輸入:wq來保存退出

然后即可使用atc命令?

使用ATC命令

atc --model=best.onnx --framework=5 --output=best --input_format=NCHW --soc_version=Ascend910B2

?--soc_version這個參數一定要通過查看npu-smi info來看,一定要一模一樣,不能忽略后面的數字

?然后即可生成best.om文件,之后就可以在昇騰910B上推理

910B推理?

代碼編寫

新建一個文件夾om_infer:

新建detect.py、det_utils.py、labels.txt;將轉換好的om模型復制到文件夾中;try保存原始的推理圖片

?填充labels.txt

一個類別一行

編寫detect.py(檢測)和det_util.py(后處理)?

det_utils.py

import cv2
import numpy as npdef 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/232shape = 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 paddingratio = r, r  # width, height ratiosnew_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 paddingif auto:  # minimum rectangledw, dh = np.mod(dw, 64), np.mod(dh, 64)  # wh paddingelif scaleFill:  # stretchdw, dh = 0.0, 0.0new_unpad = (new_shape[1], new_shape[0])ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratiosdw /= 2  # divide padding into 2 sidesdh /= 2if shape[::-1] != new_unpad:  # resizeimg = 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 borderreturn img, ratio, (dw, dh)def xyxy2xywh(x):# Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] where xy1=top-left, xy2=bottom-righty = np.copy(x)#y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)y[:, 0] = (x[:, 0] + x[:, 2]) / 2  # x centery[:, 1] = (x[:, 1] + x[:, 3]) / 2  # y centery[:, 2] = x[:, 2] - x[:, 0]  # widthy[:, 3] = x[:, 3] - x[:, 1]  # heightreturn ydef xywh2xyxy(x):# Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-righty = np.copy(x)#y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)y[:, 0] = x[:, 0] - x[:, 2] / 2  # top left xy[:, 1] = x[:, 1] - x[:, 3] / 2  # top left yy[:, 2] = x[:, 0] + x[:, 2] / 2  # bottom right xy[:, 3] = x[:, 1] + x[:, 3] / 2  # bottom right yreturn ydef numpy_nms(predictions, conf_thres=0.25, iou_thres=0.45):"""修正后的NMS函數"""# 處理輸入維度if predictions.ndim == 3:predictions = predictions.squeeze(0)# 過濾低置信度預測mask = predictions[:, 4] >= conf_threspredictions = predictions[mask]if predictions.shape[0] == 0:return np.empty((0, 6))# 轉換坐標格式boxes = xywh2xyxy(predictions[:, :4])# 獲取類別ID(關鍵修正)class_scores = predictions[:, 5:]class_ids = np.argmax(class_scores, axis=1).astype(int)  # 強制轉換為整數# 組合最終結果 [x1, y1, x2, y2, conf, class_id]detections = np.concatenate([boxes,predictions[:, 4:5],  # 置信度class_ids[:, None].astype(int)  # 確保整數類型], axis=1)return _nms_boxes(detections, iou_thres)def _nms_boxes(detections, iou_threshold):"""修正后的NMS核心函數"""if detections.size == 0:return np.empty((0, 6))x1 = detections[:, 0]y1 = detections[:, 1]x2 = detections[:, 2]y2 = detections[:, 3]scores = detections[:, 4]areas = (x2 - x1 + 1) * (y2 - y1 + 1)order = scores.argsort()[::-1]keep = []while order.size > 0:i = order[0]keep.append(i)xx1 = np.maximum(x1[i], x1[order[1:]])yy1 = np.maximum(y1[i], y1[order[1:]])xx2 = np.minimum(x2[i], x2[order[1:]])yy2 = np.minimum(y2[i], y2[order[1:]])w = np.maximum(0.0, xx2 - xx1 + 1)h = np.maximum(0.0, yy2 - yy1 + 1)inter = w * hovr = inter / (areas[i] + areas[order[1:]] - inter)inds = np.where(ovr <= iou_threshold)[0]order = order[inds + 1]return detections[keep]def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):# Rescale coords (xyxy) from img1_shape to img0_shapeif ratio_pad is None:  # calculate from img0_shapegain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / newpad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh paddingelse:gain = ratio_pad[0][0]pad = ratio_pad[1]coords[:, [0, 2]] -= pad[0]  # x paddingcoords[:, [1, 3]] -= pad[1]  # y paddingcoords[:, :4] /= gainclip_coords(coords, img0_shape)return coordsdef clip_coords(boxes, shape):# Clip bounding xyxy bounding boxes to image shape (height, width)boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1])boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0])return boxesdef nms(box_out, conf_thres=0.4, iou_thres=0.5):return numpy_nms(box_out, conf_thres=conf_thres, iou_thres=iou_thres)#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

detect.py?


#python detect.py --input ./test --img_output ./res_images --json_output ./res_json
import json
import cv2
import numpy as np
import glob
import os
from det_utils import letterbox, nms, scale_coords
from ais_bench.infer.interface import InferSession
from time import time
import argparsemodel_path = "./best.om"  # om格式模型文件
label_path = './labels.txt'  # 標簽def calculate_iou(box1, boxes):"""計算單個框與多個框的IoU"""# 計算交集區域x1 = np.maximum(box1[0, 0], boxes[:, 0])y1 = np.maximum(box1[0, 1], boxes[:, 1])x2 = np.minimum(box1[0, 2], boxes[:, 2])y2 = np.minimum(box1[0, 3], boxes[:, 3])intersection = np.maximum(0, x2 - x1) * np.maximum(0, y2 - y1)# 計算面積area_box1 = (box1[0, 2] - box1[0, 0]) * (box1[0, 3] - box1[0, 1])area_boxes = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])union = area_box1 + area_boxes - intersectionreturn intersection / uniondef preprocess_image(image, cfg, bgr2rgb=True):  # 圖片預處理img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape'])  # image尺度不定,故需調整尺寸適配模型輸入if bgr2rgb:img = img[:, :, ::-1]img = img.transpose(2, 0, 1)  # HWC2CHWimg = np.ascontiguousarray(img, dtype=np.float32)  # 將輸入數組轉換為連續存儲數組,加速運算效率return img, scale_ratio, pad_sizedef draw_bbox(bbox, img0, wt, names):"""繪制不同顏色的預測框"""# 定義5種類別對應的BGR顏色(可根據需要修改)color_palette = [(0, 255, 0),  # 綠色 - 類別0(255, 0, 0),  # 藍色 - 類別1(0, 0, 255),  # 紅色 - 類別2(0, 255, 255),  # 黃色 - 類別3(255, 0, 255)  # 粉色 - 類別4]det_result_str = ''for idx, class_id in enumerate(bbox[:, 5]):# 確保類別ID是整數class_id = int(round(float(class_id)))if class_id >= len(color_palette) or class_id < 0:print(f"Warning: 無效的類別ID {class_id},使用默認顏色")color = (255, 255, 255)  # 白色作為默認else:color = color_palette[class_id]  # 根據類別選擇顏色if float(bbox[idx][4]) < 0.05:continue# 繪制邊界框x1, y1 = int(bbox[idx][0]), int(bbox[idx][1])x2, y2 = int(bbox[idx][2]), int(bbox[idx][3])img0 = cv2.rectangle(img0, (x1, y1), (x2, y2), color, wt)# 繪制類別標簽(黑色背景白字)label = f"{names.get(class_id, 'unknown')} {bbox[idx][4]:.2f}"(tw, th), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)# 標簽背景img0 = cv2.rectangle(img0, (x1, y1 - 20), (x1 + tw, y1), color, -1)# 標簽文字img0 = cv2.putText(img0, label, (x1, y1 - 5),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)return img0def get_labels_from_txt(path):"""從txt文件獲取圖片標簽"""labels_dict = dict()with open(path) as f:for cat_id, label in enumerate(f.readlines()):labels_dict[cat_id] = label.strip()return labels_dictdef detect_img(model, detect_path, img_output_dir, json_output_dir, conf_thres=0.4, iou_thres=0.5):raw_img = cv2.imread(detect_path)  # 載入原始圖片img_height, img_width = raw_img.shape[:2]# 獲取圖片原始尺寸labels = get_labels_from_txt(label_path)# 預處理cfg = {'conf_thres': conf_thres,  # 模型置信度閾值,閾值越低,得到的預測框越多'iou_thres': iou_thres,  # IOU閾值,重疊率過低的框會被過濾'input_shape': [640, 640],  # 輸入尺寸}img, scale_ratio, pad_size = preprocess_image(raw_img, cfg)img = img / 255.0  # 訓練模型時將0~255值域轉化為了0~1,故推理階段也需同樣處理# 檢測t1 = time()output = model.infer([img])[0]#output = torch.tensor(output)# 使用numpy實現的nmsboxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])if len(boxout) > 0:pred_all = boxout[0] if isinstance(boxout, list) else boxoutscale_coords(cfg['input_shape'], pred_all[:, :4], raw_img.shape, ratio_pad=(scale_ratio, pad_size))else:pred_all = np.empty((0, 6))# 非極大值抑制后處理#boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])#pred_all = boxout[0].numpy()# 預測坐標轉換#scale_coords(cfg['input_shape'], pred_all[:, :4], raw_img.shape, ratio_pad=(scale_ratio, pad_size))t2 = time()print("detect time: %fs" % (t2 - t1))# 準備JSON數據結構json_data = {"file_name": os.path.basename(detect_path),"detections": [],"image_size": {"width": img_width,"height": img_height}}# 結果繪制if pred_all.size > 0:draw_bbox(pred_all, raw_img,2, labels)for det in pred_all:x_min, y_min, x_max, y_max = map(int, det[:4])confidence = float(det[4])class_id = int(det[5])json_data["detections"].append({"disease_class": labels.get(class_id, "unknown"),"confidence": round(confidence, 4),"bbox": {"x_min": x_min,"y_min": y_min,"x_max": x_max,"y_max": y_max}})# 保存JSON到獨立目錄os.makedirs(json_output_dir, exist_ok=True)json_filename = os.path.basename(detect_path).rsplit('.', 1)[0] + ".json"json_path = os.path.join(json_output_dir, json_filename)with open(json_path, 'w') as f:json.dump(json_data, f, indent=2)# 保存圖片到圖片目錄os.makedirs(img_output_dir, exist_ok=True)img_filename = "res_" + os.path.basename(detect_path)img_output_path = os.path.join(img_output_dir, img_filename)cv2.imwrite(img_output_path, raw_img, [int(cv2.IMWRITE_JPEG_QUALITY), 95])def batch_detect(model, input_dir, img_output_dir, json_output_dir, conf_thres=0.4, iou_thres=0.5):"""帶參數傳遞的批量推理函數"""os.makedirs(json_output_dir, exist_ok=True)  # 自動創建JSON目錄os.makedirs(img_output_dir, exist_ok=True)  # 自動創建圖片目錄# 擴展支持更多圖像格式image_extensions = ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.tiff']image_paths = []for ext in image_extensions:image_paths.extend(sorted(glob.glob(os.path.join(input_dir, ext))))print(f"Found {len(image_paths)} pictures")for img_path in image_paths:detect_img(model=model,detect_path=img_path,img_output_dir=img_output_dir,json_output_dir=json_output_dir,conf_thres=conf_thres,iou_thres=iou_thres)if __name__ == "__main__":# 創建參數解析器parser = argparse.ArgumentParser(description='目標檢測批量推理腳本')parser.add_argument('--input', type=str, required=True, help='輸入圖片目錄路徑,支持jpg/png/bmp格式')parser.add_argument('--img_output', type=str, required=True, help='圖片輸出目錄')parser.add_argument('--json_output', type=str, required=True, help='JSON輸出目錄')parser.add_argument('--conf', type=float, default=0.4, help='置信度閾值 (默認: 0.4)')parser.add_argument('--iou', type=float, default=0.5, help='IOU閾值 (默認: 0.5)')# 解析參數args = parser.parse_args()# 初始化模型model = InferSession(0, model_path)# 執行批量推理batch_detect(model=model,input_dir=args.input,img_output_dir=args.img_output,json_output_dir=args.json_output,conf_thres=args.conf,iou_thres=args.iou)print('檢測完成!\n圖片結果保存在: {}\nJSON結果保存在: {}'.format(os.path.abspath(args.img_output),os.path.abspath(args.json_output)))

示例命令:

python detect.py \--input ./try \--img_output ./res_images \--json_output ./res_json

完成推理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75270.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75270.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75270.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于yolov11的汽車損傷檢測系統python源碼+onnx模型+評估指標曲線+精美GUI界面

【算法介紹】 基于YOLOv11的汽車損傷檢測系統是一種先進的計算機視覺技術&#xff0c;旨在快速準確地識別汽車的各種損傷類型。該系統利用YOLOv11模型的強大性能&#xff0c;實現了對車輛損傷的精確檢測與分類。 該系統能夠識別的損傷類型包括裂紋&#xff08;crack&#xff…

[ 3分鐘算法 ] | 遞歸搜索題目 : 合并兩個有序鏈表(遞歸版)

目錄 1. 題目鏈接&#xff1a; 2. 思路分析&#xff1a; 1. 重復子問題&#xff1f; 2. 具體子問題&#xff1f; 3. 遞歸出口&#xff1f; 3. 代碼實現&#xff1a; 4. 小結&#xff1a; 1. 循環(迭代) vs 遞歸 2. 遞歸 vs 深搜 1. 題目鏈接&#xff1a; 21. 合并…

單元測試原則之——不要模擬值對象 (1)

1. 什么是值對象(Value Objects)? 值對象是指那些不可變且僅通過其屬性(數據)來定義的對象。它們通常沒有復雜的邏輯或行為,主要用于存儲和傳遞數據。例如: ● 字符串(String) ● 數字(Integer, Double) ● 日期(LocalDate, Instant) ● 自定義的簡單數據類(如…

【軟件】在Windows和Ubuntu上使用TFTP和NFS

在Windows和Ubuntu上使用TFTP和NFS 零、介紹 最近在玩Linux開發板&#xff0c;在開發的過程中發現需要用到tftp和nfs來幫助傳輸文件&#xff0c;故此記錄如何使用這兩種軟件。 TFTP&#xff08;Trivial File Transfer Protocol&#xff09; &#xff1a;是一種簡化的文件傳輸…

JS判斷變量是否為空的方法

在 JavaScript 中&#xff0c;判斷變量是否為空需要根據不同的數據類型和具體需求來處理。以下是常見場景的解決方案&#xff1a; 1. 基礎判斷&#xff1a;null 或 undefined javascript if (value null || value undefined) {// 變量為空 } 或簡寫為&#xff1a; javasc…

Linux更換掛載nfs遷移數據流程

當前&#xff1a;原nfs&#xff08;10.16.2.1:/myData&#xff09;掛載在/myData&#xff0c;新的nfs&#xff08;10.16.2.2:/myData&#xff09;未掛載 目標&#xff1a;把舊nfs的數據遷移到新的nfs上&#xff0c;并把新nfs掛載到/myData 步驟&#xff1a; 1、新nfs掛載到一…

深入解析音頻:格式、同步及封裝容器

物理音頻和數字音頻 物理音頻 定義&#xff1a;物理音頻就是聲音在自然界中的物理表現形式&#xff0c;本質上是一種機械波&#xff0c;通過空氣或其他介質傳播。例如&#xff0c;當我們說話、樂器演奏或物體碰撞時&#xff0c;都會產生振動&#xff0c;這些振動會引起周圍介…

AI與.NET技術實操系列(四):使用 Semantic Kernel 和 DeepSeek 構建AI應用

1. 引言 在人工智能技術飛速發展的今天&#xff0c;大型語言模型&#xff08;Large Language Models, LLMs&#xff09;已成為智能應用開發的核心驅動力。從智能客服到自動化內容生成&#xff0c;LLMs的應用正在深刻改變我們的工作和生活方式。 對于.NET開發者而言&#xff0c;…

導出cad實體所有信息到txt并打開(生成唯一文件名) ——c#cad二次開發

效果如下: 建議在保存時指定編碼為UTF-8&#xff1a; using (StreamWriter sw new StreamWriter(filePath, false, Encoding.UTF8)) { // 寫入內容 } 最終 using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD…

Redis 源碼硬核解析系列專題 - 第一篇:Redis源碼入門與整體架構

1. 引言 Redis作為一個高性能的內存鍵值數據庫,其源碼以簡潔高效著稱。通過解析Redis源碼,我們可以深入理解其單線程模型、事件驅動機制以及模塊化設計的精髓。本篇將從Redis的源碼目錄結構入手,剖析其整體架構,并聚焦啟動流程和事件循環的核心實現。 2. Redis源碼目錄結構…

異步加載+內存分析

異步加載 Resources和AB包的同步加載與異步加載對比代碼&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class AsyncLoad : MonoBehaviour {// Start is called before the first frame updatev…

將視頻m4s文件轉換為mp4格式

將視頻m4s文件轉換為mp4格式 一般情況&#xff1a;偏大的文件為視頻&#xff0c;偏小的文件為音頻。 環境要求&#xff1a;下載并安裝ffmpeg&#xff0c;并配置好環境變量&#xff0c;如下圖&#xff1a; 轉換代碼&#xff1a; import subprocessdef merge_m4s_to_mp4(vide…

EXCEL報錯:無法共享此工作薄,因表包含excel表或xml映射的解決方法

在分享工作薄是&#xff0c;如果出現了“無法共享此工作薄&#xff0c;因表包含excel表或xml映射”的報錯&#xff0c;那么有兩個原因&#xff1a; 1.包含Excel表格&#xff0c;這個也是相對比較常見的原因。 首先選中表格。如果你不知道表的位置在哪&#xff0c;那么在Excel左…

w2ui 水平滾動移動 虛擬列 數據丟失

https://w2ui.com/web/docs/1.5/w2grid.disableCVS https://github.com/vitmalina/w2ui/issues/1398 解決方案來源 問題現象: 窗口縮小 導致多列 出現水平滾動,滾動時觸發本地樣式重繪,導致record undefined,從而引發多列報錯 解決方案: 使用 disableCVS : true 一次加載到d…

在ensp進行OSPF+RIP+靜態網絡架構配置

一、實驗目的 1.Ospf與RIP的雙向引入路由消息 2.Ospf引入靜態路由信息 二、實驗要求 需求&#xff1a; 路由器可以互相ping通 實驗設備&#xff1a; 路由器router7臺 使用ensp搭建實驗壞境&#xff0c;結構如圖所示 三、實驗內容 1.配置R1、R2、R3路由器使用Ospf動態路由…

基于mediapipe深度學習和限定半徑最近鄰分類樹算法的人體摔倒檢測系統python源碼

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 4.1 Mediapipe人體姿態檢測原理 4.2 限定半徑最近鄰分類樹算法原理 5.算法完整程序工程 1.算法運行效果圖預覽 (完整程序運行后無水印) 2.算法運行軟件版本 人工智能算法python程序運行環…

deep-sync開源程序插件導出您的 DeepSeek 與 public 聊天

一、軟件介紹 文末提供下載 deep-sync開源程序插件導出您的 DeepSeek 與 public 聊天&#xff0c;這是一個瀏覽器擴展&#xff0c;它允許用戶公開、私下分享他們的聊天對話&#xff0c;并使用密碼或過期鏈接來增強 Deepseek Web UI。該擴展程序在 Deepseek 界面中添加了一個 “…

蘋果簽名是否一定安全呢?

蘋果簽名是一種數字簽名技術&#xff0c;用于驗證應用程序的來源和完整性。當開發者將應用程序提交到蘋果應用商店時&#xff0c;蘋果會對應用進行簽名&#xff0c;這個簽名包含了開發者的身份信息以及應用的相關數據。用戶安裝應用時&#xff0c;設備會驗證簽名的有效性&#…

Outlook客戶端無法連接到服務器,添加賬戶顯示“無網絡連接,請檢查你的網絡設置,然后重試。[2603]”

1、先切換一下到手機熱點或者其他網絡&#xff0c;判斷是不是現在所連接的網絡的問題。如果有VPN代理軟件&#xff0c;網銀軟件&#xff0c;加密軟件在后臺運行&#xff0c;麻煩退出一下。 2、打開電腦上的 控制面板——網絡和Internet——Internet選項——高級——先點擊還原…

Laravel 中使用 JWT 作用戶登錄,身份認證

什么是JWT&#xff1a; JWT 全名 JSON Web Token&#xff0c;是一種開放標準 (RFC 7519)。 用于在網絡應用環境間安全地傳輸信息作為 JSON 對象。 它是一種輕量級的認證和授權機制&#xff0c;特別適合分布式系統的身份驗證。 核心特點 緊湊格式&#xff1a;體積小&#x…