深度学习实践——模型部署优化实践

article/2025/11/2 9:30:54

系列实验
深度学习实践——卷积神经网络实践:裂缝识别
深度学习实践——循环神经网络实践
深度学习实践——模型部署优化实践
深度学习实践——模型推理优化练习

源码:
1. 对应的github地址 https://github.com/Asionm/streamlit_demo
2. 对应的gitee地址 https://gitee.com/asionm/streamlit_demo

模型部署优化实践

  • 模型部署优化实践
    • 通用识别模型部署
      • 图像物体识别部署过程
      • 视频物体识别推理部署
    • 算式识别模型部署
    • 模型性能反馈机制
    • demo链接
    • 参考资料

模型部署优化实践

通用识别模型部署

对于通用识别模型,我选择了Faster R-CNN,对应的卷积神经网络为restnet50。为了节省时间与资源,直接选择了预训练模型。而对于模型的部署我选择了具有不错的UI设计的streamlit开源web软件。对于模型的部署我首先是选择图像识别的,但是后面认为直接图像识别无比较多的新意,所以想着是否可以加多时间维度,识别一个视频里面的物体。于是部署步骤分为图像识别部署与视频识别部署,下面为详细的部署过程。

图像物体识别部署过程

图像识别的部署主要分为数据预处理、模型预测、web前端布置三个方面,其具体流程可以归纳为下面的流程图。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9UNLjBdk-1690718686863)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\图像物体识别流程图.drawio.svg)]

  • 安装并导入相应的包

    在requirements.txt对应的目录下打开终端,并输入下面指令进行安装,

    pip install -r requirements.txt
    

    安装完成后导入对应的包,

    from PIL import Image
    from torchvision import models, transforms
    from torchvision.utils import draw_bounding_boxes
    import torch
    import time
    import streamlit as st
    

    其中draw_bounding_boxes主要用于绘制识别框,而streamlit为对应的Web UI程序,而这里的time主要用来计时。

  • 导入预训练模型与相应标签

    model = models.detection.fasterrcnn_resnet50_fpn(pretrained=True,progress=True)
    

    导入标签以及对标签进行索引处理,

    inst_classes = ['__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus','train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign','parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow','elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A','handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball','kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket','bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl','banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza','donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table','N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone','microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book','clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
    ]
    inst_class_to_idx = {cls: idx for (idx, cls) in enumerate(inst_classes)}
    
  • 数据预处理

    将传入的图片处理为Tensor格式以用于预测,

    def data_preprocess(image):transform = transforms.Compose([transforms.ToTensor()])img = Image.open(image)batch_t = torch.unsqueeze(transform(img), 0)imgg = transform(img)return batch_t, imgg
    
  • 模型预测

    对图片进行预测,同时在预测时调用streamlit进行实时网页内容渲染,

    def predict(model,image):batch_t, img = data_preprocess(image)time_start = time.time()model.eval()outputs = model(batch_t)time_end = time.time()time_sum = time_end - time_startst.write('Just', time_sum, 'second!')st.write(outputs)time_start = time.time()# draw bboxes,labels on the raw input image for the object candidates with score larger than score_thresholdscore_threshold = .8st.write([inst_classes[label] for label in outputs[0]['labels'][outputs[0]['scores'] > score_threshold]])output_labels = [inst_classes[label] for label in outputs[0]['labels'][outputs[0]['scores'] > score_threshold]]output_boxes = outputs[0]['boxes'][outputs[0]['scores'] > score_threshold]images = img * 255.0;images = images.byte()result = draw_bounding_boxes(images, boxes=output_boxes, labels=output_labels, width=5)st.image(result.permute(1, 2, 0).numpy(), caption='Processed Image.', use_column_width=True)time_end = time.time()time_sum = time_end - time_startst.write('Draw', time_sum, 'second!')return outputs
    
  • 模型部署

    对网页进行Web UI设置,

    st.title("Simple Object Detection Application")
    st.write("")
    file_up = st.file_uploader("Upload an image", type = "jpg")
    if file_up is not None:# display image that user uploadedimage = Image.open(file_up)st.image(image, caption = 'Uploaded Image.', use_column_width = True)st.write("")labels = predict(file_up)
    

    对代码编辑完成后在终端中输入下面指令启动web服务,

    streamlit run deploy.py
    

    运行后下图为效果图,可以看到基本上都是可以进行上传并识别的,预训练模型的准确率较高,但是页面功能相对来说比较单调。于是对页面进行升级添加视频识别功能。

视频物体识别推理部署

上面的部署均只是基于照片的,那是否可以添加时间维度来进行物体识别呢,于是就尝试识别视频中的物体。下面为基于图像物体识别的视频识别推理的部署流程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbBbp0LV-1690718587849)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\视频物体识别流程图.drawio.svg)]

对于视频物体识别其实本质上的部署方法与图片的基本一致,它只是抽取视频的每一帧进行推理预测,然后再将识别框与标签添加会帧中并写入视频文件中,最后完成整个视频的物体识别。相对图片来说视频的物体识别所需要的计算资源更加多,所以对于视频的效果我只是随便拍了6s钟的视频进行预测。

下图为效果图:

以下为代码部分(主要参考于:https://blog.csdn.net/weixin_42618420/article/details/125577321):

代码基本与图像物体识别的一致,但是在此基础上添加了内容,在网页上添加了一些选择框。具体可见源码文件。

  • 主体运行函数

    def start_video(path):# cv2.namedWindow(window_name)cap = cv2.VideoCapture(path)  # 打开视频流(若path=0表示开启摄像头流)width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取原视频的宽height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取原视频的搞fps = int(cap.get(cv2.CAP_PROP_FPS))  # 帧率fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))  # 视频的编码# 视频对象的输出out = cv2.VideoWriter('./123.mp4', fourcc, 20.0, (width, height))while cap.isOpened():# 读取一帧数据,一帧就是一张图ok, frame = cap.read()if not ok:breakframe = object_detection_api(frame, 0.8)try:if len(frame) == 1:print(frame.all())continueexcept (AttributeError, TypeError):if frame == 0:continue# 输入'q'退出程序# cv2.imshow(window_name, frame)out.write(frame)c = cv2.waitKey(1)  # 延时1ms切换到下一帧图像if c & 0xFF == ord('q'):break# 释放摄像头并销毁所有窗口cap.release()# out.release()cv2.destroyAllWindows()
    
  • 每帧物体识别接口

    def object_detection_api(img, threshold=0.5, rect_th=3, text_size=1, text_th=3):boxes, pred_cls = get_prediction(img, threshold)  # Get predictionsif boxes == 0:return 0for i in range(len(boxes)):# Draw Rectangle with the coordinatesboxes[i][0] = tuple(map(lambda x:int(x),boxes[i][0]))boxes[i][1] = tuple(map(lambda x: int(x), boxes[i][1]))cv2.rectangle(img, boxes[i][0], boxes[i][1], color=(0, 255, 0), thickness=rect_th)# Write the prediction classcv2.putText(img, pred_cls[i], boxes[i][0], cv2.FONT_HERSHEY_SIMPLEX, text_size, (0, 255, 0), thickness=text_th)return img
    
  • 获取预测框与标签

    def get_prediction(img, threshold):model.eval()transform = transforms.Compose([transforms.ToTensor()])  # Defing PyTorch Transformimg = transform(img)  # Apply the transform to the imageimg = img.to(DEVICE)# model的返回结果pred = model([img])  # pred包含了预测的边框顶点、类型和置信度# 预测的类型pred_class = [inst_classes[i] for i in list(pred[0]['labels'].cpu().numpy())]  # Get the Prediction Score# 方框的位置pred_boxes = [[(i[0], i[1]), (i[2], i[3])] for i in list(pred[0]['boxes'].detach().cpu().numpy())]  # Bounding boxes# 置信度(注意此处分数已经按从高到低排列)pred_score = list(pred[0]['scores'].detach().cpu().numpy())try:pred_t = [pred_score.index(x) for x in pred_score if x > threshold][-1]# Get list of index with score greater than threshold.pred_boxes = pred_boxes[:pred_t + 1]pred_class = pred_class[:pred_t + 1]return pred_boxes, pred_classexcept IndexError:return 0, 0
    

运行指令:

streamlit run video_deplot.py

算式识别模型部署

  • yolo训练

    对于算式识别,我预先利用了群里的数据集与yolov5进行训练。其训练的主要流程如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9RAtCgLJ-1690718587851)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\yolo训练过程.svg)]

    对于yolo的训练,主要在于转换格式,因为yolo的只支持自身的Yolo格式,转换完成后只需要改写yaml配置文件即可直接根据官网提供的训练命令行进行训练。最后结果输出至run文件夹中。

    • 数据类型转换 (代码参考于:https://blog.csdn.net/Thebest_jack/article/details/125637099)

      # 该脚本文件需要修改第10行(classes)即可
      # -*- coding: utf-8 -*-
      import xml.etree.ElementTree as ET
      from tqdm import tqdm
      import os
      from os import getcwdsets = ['train', 'test', 'val']
      # 这里使用要改成自己的类别
      classes = ['equation']def convert(size, box):dw = 1. / (size[0])dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhx = round(x, 6)w = round(w, 6)y = round(y, 6)h = round(h, 6)return x, y, w, h# 后面只用修改各个文件夹的位置
      def convert_annotation(image_id):# try:in_file = open('./Annotations/%s.xml' % (image_id), encoding='utf-8')out_file = open('./labels/%s.txt' % (image_id), 'w', encoding='utf-8')tree = ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult) == 1:continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))b1, b2, b3, b4 = b# 标注越界修正if b2 > w:b2 = wif b4 > h:b4 = hb = (b1, b2, b3, b4)bb = convert((w, h), b)out_file.write(str(cls_id) + " " +" ".join([str(a) for a in bb]) + '\n')# 这一步生成的txt文件写在data.yaml文件里
      wd = getcwd()
      for image_set in sets:if not os.path.exists('./labels/'):os.makedirs('./labels/')image_ids = open('./Imagesets/%s.txt' %(image_set)).read().strip().split()list_file = open('./%s.txt' % (image_set), 'w')for image_id in tqdm(image_ids):list_file.write('./JPEGImages/%s.jpg\n' % (image_id))convert_annotation(image_id)list_file.close()
    • yaml文件编写

      path: ../datasets/custom
      train: images/train
      val: images/train names:0: equation
      
    • 训练指令

      python train.py --data test.yaml --weights yolov5s.pt --img 640
      
  • yolo算式模型部署

    在训练完成后,同样依靠于streamlit进行模型部署,其部署流程图如下,基本上与通用识别模型的一致。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wqoa3Qyw-1690718587853)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\yolo部署.svg)]

    与通用模型的不同的是yolo中使用的是cv2对图片进行处理,而不是直接利用torch的函数进行处理的,然后模型导入的方式也不同,是通过hub将整个yolo源码进行了导入。下面为详细的代码模块。

    • 模型导入

      模型是以Hub的方式导入的。

      model_equation = torch.hub.load('./yolov5-master', 'custom', source ='local', path='best.pt',force_reload=True)
      
    • 部署主函数

      部署函数整体的运行逻辑包括了前端一些元素的布置以及预测的调用。

      def equation_run():st.title("算式识别")st.write("")file_up = st.file_uploader("请上传图片", type="jpg")place_holder = st.empty()if file_up is not None:# display image that user uploadedimage = Image.open(file_up)place_holder.image(image, caption='已上传的图片', use_column_width=True)place_holder.write("")frame = np.array(image)frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)results = detectx(frame, model=model_equation)  ### DETECTION HAPPENING HEREframe = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)frame = plot_boxes(results, frame)place_holder.empty()place_holder.image(frame)
      
    • 预测函数

      预测函数主要返回标签与坐标。

      def detectx (frame, model):frame = [frame]print(f"[INFO] Detecting. . . ")results = model(frame)labels, cordinates = results.xyxyn[0][:, -1], results.xyxyn[0][:, :-1]return labels, cordinates
      
    • 绘制框函数

      绘制框函数主要是通过输入框的坐标位置与图片,然后用opencv来绘制框与文字,最后返回加工过的图片。

      def plot_boxes(results, frame):"""--> This function takes results, frame and classes--> results: contains labels and coordinates predicted by model on the given frame--> classes: contains the strting labels"""labels, cord = resultsn = len(labels)x_shape, y_shape = frame.shape[1], frame.shape[0]print(f"[INFO] Total {n} detections. . . ")print(f"[INFO] Looping through all detections. . . ")### looping through the detectionsfor i in range(n):row = cord[i]if row[4] >= 0.55: ### threshold value for detection. We are discarding everything below this valueprint(f"[INFO] Extracting BBox coordinates. . . ")x1, y1, x2, y2 = int(row[0]*x_shape), int(row[1]*y_shape), int(row[2]*x_shape), int(row[3]*y_shape) ## BBOx coordniatescv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) ## BBoxcv2.rectangle(frame, (x1, y1-20), (x2, y1), (0, 255,0), -1) ## for text label backgroundcv2.putText(frame, "equation", (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(255,255,255), 2)return frame
      

      最后的运行的效果图如下,具体只需要将图片进行上传即可自动进行算式识别,并将识别出来标签坐标以框与文本的形式加工至原图片中,然后再渲染回web前端。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n7a2SHYH-1690718587855)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\image-20221122113643423.png)]

模型性能反馈机制

在部署完上面的模型后,我想对web前端再添加一功能那就是反馈功能。由于有一些预测结果其实并不准确的,而机器是无法发现是否正确的,那么就需要使用者来提供相关的信息,使得模型后续可以优化改进。

而对于反馈机制,我的想法是在预测结果的页面中添加一个输入框,让使用者在发现异常的时候可以提供一些信息。而这些信息是对于对应的图片的,那么当使用者提供反馈的同时也要保存相应的预测结果以便后面分析。于是根据此思路,反馈机制的代码逻辑可见下面的流程图,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FQ1EtoJO-1690718587856)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\反馈机制.drawio.svg)]

反馈机制主要是对图像预测之后才会出现,当图像未被预测前是不会出现反馈输入框的。对应反馈机制的代码实现,主要通过添加函数来实现,函数主要涉及到的操作是文件的读写。下面为函数代码内容:

def feedback(p_image,type="pic"):st.write("")st.title("问题反馈:")feedinput = st.text_input("", "若发现预测存在问题可以在下面的输入框中为我们提供相关信息,您所提供的信息将对我们帮助很大!")confirm_bnt = st.button("确认反馈")if confirm_bnt:if type == "pic":img = Image.fromarray(p_image)name = f"./feedback/pictures/{time.time()}.jpg"img.save(name)with open(f"./feedback/"f"{time.localtime().tm_mday}.md", 'a+') as f:f.write(f"## {feedinput} <br>")f.write(f"![]({name[11:]})")st.success('反馈成功!感谢您的支持!', icon="✅")elif type=="video":name = f"./feedback/videos/{time.time()}.mp4"shutil.copy(p_image, name)with open(f"./feedback/"f"{time.localtime().tm_mday}.md", 'a+') as f:f.write(f"## {feedinput}")f.write(f"<video src=\"name\"></video>")st.success('反馈成功!感谢您的支持!', icon="✅")

最后以算式识别为例来测试其效果,下面为效果图。下面这张图是输入反馈内容并提交后所截取的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JRmiWofn-1690718587857)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\image-20221122170733376.png)]

对于反馈功能不能仅仅只是在前端摆设,而应该在后端有所记录,所以当提交反馈后,后端会记录对于的反馈内容与相应的预测结果。结果会保存至一markdown文件中如下图所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GDPnF5hC-1690718587858)(D:\学习资料\大三上\大三上资料\大三上资料\深度学习实践\作业\实验\实验4\识别模型部署.assets\image-20221122170754497.png)]

最后的运行只要运行feedback_deploy.py即可,其他文件均是迭代文件。

streamlit run feedback_deploy.py

demo链接

  1. 对应的github地址 https://github.com/Asionm/streamlit_demo
  2. 对应的gitee地址 https://gitee.com/asionm/streamlit_demo

文件说明(主文件为feedback_deploy.py):

  1. yolov5-master 官方源文件用于导入模型

  2. feedback文件夹用于存储反馈信息

  3. 123.mp4视频预测的结果视频

  4. best.pt算式识别权重文件

  5. openh264-1.8.0-win64.dll用于解决opencv的一些问题

  6. voc2yolo.py voc格式转yolo格式

  7. pic_deploy.py 图片识别推理部署代码

  8. video_deploy.py 在7基础上添加视频

  9. yolo_deploy.py 在8的基础上添加算式识别模块

  10. feedback_deploy.py在9的基础上添加反馈模块

参考资料

【1】http://172.31.70.106/dlcourse/html/ModelDeploy/modeldeployIntro.html

【2】https://github.com/streamlit/demo-self-driving/blob/master/streamlit_app.py

【3】https://blog.csdn.net/weixin_42618420/article/details/125577321

【4】https://blog.csdn.net/Thebest_jack/article/details/125637099)


http://chatgpt.dhexx.cn/article/2EGtNgvQ.shtml

相关文章

基于python+pyqt+halcon实现视觉定位(halcon12.0)【附部分源码】

文章目录 前言演示视频一、项目文件目录讲解二、Qt Designer设置ui界面0.qrc资源文件的设置1.CtuImageMatching.ui的设置2.CameraSetting.ui的设置3.Calibration.ui的设置4.Helper.ui的设置 三、使用命令把qt文件转成py文件四、py文件解析1.CtuImageMatching.py重要函数解析2.C…

2019-10-28-dotnet-代码调试方法

titleauthordateCreateTimecategories dotnet 代码调试方法 lindexi 2019-10-28 08:50:11 0800 2019-6-5 9:4:44 0800 dotnet 本文将会从简单到高级&#xff0c;告诉大家如何调试 dotnet 的代码&#xff0c;特别是桌面端。本文将会使用到 VisualStudio 大量的功能&#xff0c;通…

2019-11-29-dotnet-代码调试方法

titleauthordateCreateTimecategories dotnet 代码调试方法 lindexi 2019-11-29 8:50:0 0800 2019-6-5 9:4:44 0800 dotnet 本文将会从简单到高级&#xff0c;告诉大家如何调试 dotnet 的代码&#xff0c;特别是桌面端。本文将会使用到 VisualStudio 大量的功能&#xff0c;通过…

前端开发 跨平台的构架GSOAP

前言&#xff1a;此文叙述了跨平台GSOAP&#xff0c;并对多线程在服务器上的实现做举例做了介绍 gSOAP是一个夸平台的&#xff0c;用于开发Web Service服务端和客户端的工具&#xff0c;在Windows、Linux、MAC OS和UNIX下使用C和C语言编码&#xff0c;集合了SSL功能。SOAP/XML…

【逆向】逆向练习及相关总结

文章目录 crakeme练习crackme1crackme2crackme3 解题步骤总结关键代码查找方法常见代码C类对象逆向分析C虚函数逆向分析系统dll文件的指令kernel32.dll、user32.dll、ntdll.dll文件TEB、PEB crakeme练习 crackme1 学到的知识点&#xff1a; main函数查找方法&#xff1a;运行…

JavaScript-js数组去重

1&#xff0c;利用Set()方法 let list [1,2,1,2,4,4,5] let Newlist Array.from(new Set(list)) console.log(Newlist)//输出[ 1, 2, 4, 5 ]2&#xff0c;新建一个数组&#xff0c;逐一保存原数组中的值&#xff0c;判断新数组中是否已有该数值&#xff0c;无则保存&#xff…

常用的JS数组去重方法大全

写在前面&#xff1a; 我们要想使用数组去重&#xff0c;那就必须对数组有一定的了解&#xff0c;关于JS数组的一些方法以及使用&#xff0c;可参考&#xff1a; ①JavaScript 内置对象之-Array ②ES5新增数组方法 ③浅谈JavaScript中ES6新增的Set和Map结构以及Array.from方法 …

js去重都有哪些方法?

1、去重方法一 arr.splice 2、去重方法二 借助新数组&#xff0c;判断新数组中是否存在该元素如果不存在则将此元素添加到新数组中(原数组长度不变但被按字符串顺序排序) 3、创建一个新数组&#xff0c;判断新数组中是否存在该元素如果不存在则将此元素添加到新数组中 4、借助i…

JS中数组去重的五种方法

数组去重的几种方法(JavaScript版&#xff09; 前言&#xff1a;你需要知道JavaScript中的 splice函数 的用法 splice函数介绍&#xff1a; splice函数用法&#xff1a;splice函数介绍看不懂没关系&#xff0c;怎么用一看例子一目了然 第一种&#xff1a;双重for循环去重 原…

js数组中对象去重的方法

一个数组中含有对象&#xff0c;并且去除数组中重复的对象 id相同的&#xff0c;保留第一个&#xff0c;其它的删除 let arr [{ id: 0, name: "张三" },{ id: 1, name: "李四" },{ id: 2, name: "王五" },{ id: 3, name: "赵六" },{…

js实现数组去重的方式(7种)

目录 JS数组去重的方式1.利用Set()Array.from()2.利用两层循环数组的splice方法3.利用数组的indexOf方法4.利用数组的includes方法5.利用数组的filter()indexOf()6.利用Map()7.利用对象 JS数组去重的方式 例&#xff1a;将下面数组去除重复元素&#xff08;以多种数据类型为例…

js数组去重(9种方法),你都会了吗?

以下共有九种数组去重的方式和详解&#xff08;包含对象数组去重&#xff09;&#xff1a; 1.利用Array.from(new Set)去重&#xff1a; // 1.利用set去重 // Set是es6新增的数据结构&#xff0c;似于数组&#xff0c;但它的一大特性就是所有元素都是唯一的&#xff0c;没有…

解决Linux没有ens33

#临时关闭 systemctl stop NetworkManager # 永久关闭网络管理命令 systemctl disable NetworkManager #开启网络服务 systemctl start network.service

【ubuntu虚拟机】ens33未出现在ifconfig问题

事情发生与2023年4月12日&#xff0c;windows上安装了docker-desktop&#xff0c;奈何wsl不好用&#xff0c;便卸载了&#xff0c;之后我的虚拟机ubuntu无法联网&#xff0c;于是开始解决之旅 事故原因 ifconfig查了一下&#xff0c;没有ens33网卡&#xff0c;于是用ip addres…

Centos开机后ens33网卡失效连不上网

今天使用xshell连接虚拟机一直失败 打开虚拟机ip addr 发现如下问题 解决方案 1.尝试重启网关 ifup ens33 &#xff08;无法解决&#xff09; # ifup ens332.停止网卡&#xff0c;设置disable后重新启动 &#xff08;依旧失败&#xff09; # systemctl stop NetworkManager…

centos7网络配置没有ens33文件

注意&#xff1a;此教程中的centos是已经能够上网的状态&#xff01; 问题来源 需要使用centos7来搭建一些服务器&#xff0c;由于我用的VMware总是自己变ip并且不能设置&#xff0c;所以只能从centos系统配置文件下手 。 从网上教程来看&#xff0c;centos7 的网卡名叫 ens33&…

Linux 初始化网络配置ens33

配置文件路径&#xff1a; [rootnode2 ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33 TYPEEthernet BOOTPROTOstatic DEFROUTEyes IPV4_FAILURE_FATALno #IPV6INITyes #IPV6_AUTOCONFyes #IPV6_DEFROUTEyes #IPV6_PEERDNSyes #IPV6_PEERROUTESyes #IPV6_FAILURE_FATALno…

怎么修改Linux网络名为ens33,Centos7更改ens33网卡名称为eth0

用ifconfig查看网卡名称为ens33&#xff0c;现在要将它修改成eth0 [rootlocalhost ~]# ifconfig ens33: flags4163 mtu 1500 inet 192.168.1.3 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 2409:8a02:9014:8440:20c:29ff:fe95:cc8f prefixlen 64 scopeid 0x0 inet6 f…

linux怎么修改ens33文件,linux 修改centos7的网卡ens33修改为eth0

Linux 操作系统的网卡设备的传统命名方式是 eth0、eth1、eth2等,而 CentOS7 提供了不同的命名规则,默认是基于固件、拓扑、位置信息来分配。这样做的优点是命名全自动的、可预知的,缺点是比 eth0、wlan0 更难读,比如 ens33 。 如果不习惯使用新的命名规则,可以恢复使用传统…

linux网卡ens33,如何解决Linux 系统下 ifconfig 命令无网络接口 ens33

今天我在做Redis的哨兵集群模式的时候&#xff0c;以前都是好的&#xff0c;也不知道从什么时候开始就无法连接Redis服务器了&#xff0c;就是运行如下命令&#xff0c;没有效果&#xff1a;redis-server redis.conf&#xff0c;然后在通过命令查看redis的状态&#xff0c;始终…