• [技术干货] 自然语言处理在虚拟助手中的创新应用
    自然语言处理在虚拟助手中的创新应用引言随着人工智能技术的飞速发展,虚拟助手已经成为人们日常生活中不可或缺的工具。从智能音响、聊天机器人到语音助手,虚拟助手通过语音、文本等交互方式为用户提供便捷的服务。自然语言处理(NLP)作为人工智能领域的重要分支,近年来在虚拟助手中的应用取得了显著的突破。通过利用自然语言处理技术,虚拟助手能够理解、生成和处理人类语言,极大地提升了用户体验和服务效率。本文将探讨自然语言处理在虚拟助手中的创新应用,分析其背后的技术进展,并探讨未来的发展方向。自然语言处理的基本原理自然语言处理是计算机科学与语言学交叉的领域,旨在使计算机能够理解、生成和操作人类语言。其核心任务包括语音识别、语义分析、情感分析、机器翻译等。通过NLP技术,虚拟助手能够解析用户输入的语音或文本信息,提取有用的信息并做出合理的回应。随着深度学习、神经网络等技术的成熟,NLP在虚拟助手中的应用也逐渐进入一个新的阶段。特别是预训练语言模型(如GPT、BERT等)的出现,使得虚拟助手在语境理解、语义推理和对话管理方面取得了重大突破。NLP在虚拟助手中的创新应用语音识别与语音合成语音识别技术是虚拟助手最基础的能力之一。通过NLP,虚拟助手能够将用户的语音转换为文本,并理解其中的含义。例如,Siri、Alexa、Google Assistant等语音助手能够精准地识别用户的语音指令,并根据语音内容执行相应的操作。随着深度学习的进步,语音识别系统的准确率得到了显著提高,尤其是在噪音环境下的表现也变得更加稳定。语音合成技术则使虚拟助手能够将生成的文本信息转化为自然流畅的语音,提供更加人性化的交互体验。现代的语音合成技术已经能够模仿不同人的语音特点,提供更加个性化的语音反馈。情感分析与个性化交互虚拟助手的交互不仅限于执行命令,还需要理解用户的情感和意图。情感分析技术通过分析用户的语音或文本,判断其情感状态(如愉悦、愤怒、焦虑等),并据此调整回应的语气和内容。例如,当用户表示焦虑时,虚拟助手会采取更加温和和安慰的语气回应,而当用户表现出愉快的情绪时,虚拟助手则可以表现出更加活泼和兴奋的语气。情感分析不仅能增强人机互动的自然感,还能够帮助虚拟助手提供更加个性化的服务。例如,虚拟助手可以根据用户的情绪变化,调整推荐内容或服务,例如,在用户情绪低落时推荐放松的音乐或安慰性的内容。多轮对话与上下文理解多轮对话是虚拟助手的一项重要能力,指的是虚拟助手能够理解并维持上下文,进行更长时间的交互。传统的虚拟助手只能处理单轮对话,即用户发出指令后,虚拟助手执行任务并结束交互。而现代虚拟助手则具备了多轮对话能力,能够理解和记住用户的意图,并根据上下文进行流畅的对话。例如,用户可能先询问天气,接着询问今天是否适合外出运动,虚拟助手能够结合先前的问题与答案,做出连贯的回应。通过NLP技术中的上下文理解,虚拟助手不仅能维持会话的连贯性,还能根据用户的历史交互记录提供更加精准的服务。例如,Google Assistant可以根据用户的日程安排、历史查询等信息,主动推荐相关的服务或信息。智能搜索与信息抽取虚拟助手不仅仅是执行用户指令的工具,它们还具备强大的信息查询和抽取能力。通过NLP技术,虚拟助手能够从互联网上获取大量的信息并进行整理,以便快速提供用户所需的答案。例如,当用户询问某个问题时,虚拟助手不仅能够回答问题,还能根据问题的语境提供相关的背景信息或建议。例如,当用户询问“今天纽约的天气怎么样?”时,虚拟助手能够通过智能搜索引擎实时获取天气信息,并在回答中提供准确的答案。同时,虚拟助手还能够根据用户的兴趣和需求,推送其他相关信息,如旅游建议、附近的餐馆推荐等。跨语言与多语言支持现代虚拟助手不仅支持单一语言的交互,还能够进行跨语言和多语言的对话。NLP技术中的机器翻译和多语言模型使得虚拟助手能够识别和理解多种语言,并根据需要进行即时翻译。这对于全球化的用户群体来说,极大地提升了虚拟助手的适用性和便利性。例如,Google Assistant和Amazon Alexa都支持多种语言,用户可以在不同的语言环境下与虚拟助手进行无缝对话,甚至可以在同一对话中切换语言。持续挑战与未来发展尽管NLP在虚拟助手中的应用已经取得了显著进展,但仍面临一些挑战。例如,语音识别和语义理解在复杂环境中的准确性仍然受到噪声和口音的影响;情感分析技术还需进一步提升其准确性和适应性;而多轮对话和上下文理解仍面临着推理能力和长时记忆的问题。未来,随着深度学习和神经网络技术的不断发展,虚拟助手的自然语言处理能力将更加精细和智能。虚拟助手不仅能够理解并回应用户的语言,还能理解用户的需求、情感和背景,从而提供更个性化、贴心的服务。结论自然语言处理技术的创新应用,正在推动虚拟助手向更加智能化和个性化的方向发展。无论是在语音识别、情感分析、多轮对话,还是智能搜索和跨语言支持方面,NLP技术都为虚拟助手提供了强大的技术支持。尽管面临一些挑战,随着技术的不断进步,虚拟助手在未来将变得更加智能、精准和人性化,成为用户日常生活中更加得力的助手。
  • [技术干货] 基于深度学习的智能医疗影像分析与诊断
    基于深度学习的智能医疗影像分析与诊断引言随着人工智能技术的快速发展,深度学习在医疗领域的应用逐渐成为研究的热点,尤其是在医疗影像分析与诊断方面。传统的医疗影像分析通常依赖于医生的经验和专业知识,但由于影像数据的复杂性和医生工作压力的增加,手工分析变得越来越困难。深度学习,尤其是卷积神经网络(CNN),因其在图像处理中的出色表现,被广泛应用于医疗影像的自动分析、诊断辅助、疾病预测等任务中,为医生提供强有力的技术支持,提升诊断效率和准确性。深度学习在医疗影像中的应用医学影像的自动化分析医疗影像,如X射线、CT、MRI和超声影像等,包含了大量的复杂信息,人工分析通常耗时且容易出错。深度学习,特别是卷积神经网络(CNN),通过模拟人类大脑对图像的处理方式,可以自动化地对医学影像进行分析。CNN通过多层的卷积和池化操作,从原始图像中提取特征,并进行分类、分割等任务。在肺部疾病、肿瘤筛查等方面,深度学习模型表现出了比传统方法更高的准确性和效率。例如,卷积神经网络被广泛应用于肺结节的检测与分类,通过对CT图像进行分析,自动识别肺部结节,并预测其良性或恶性的可能性。研究表明,深度学习模型的准确率已接近或甚至超过了放射科医生的水平,这对于大规模筛查具有重要意义。疾病的早期检测与预测早期诊断对许多疾病,尤其是癌症等恶性疾病的治疗至关重要。深度学习模型能够从医疗影像中提取微小的病变迹象,从而在疾病的早期阶段进行准确预测。例如,乳腺癌的检测,通过对乳腺X光图像的分析,深度学习算法可以自动识别潜在的肿瘤,并为医生提供有力的诊断依据。通过与传统影像分析方法相比,深度学习能够在更早期、更多样化的病变中发现异常,极大地提升了早期筛查的效果。此外,深度学习也在预测疾病发展方面表现出色。例如,在脑部影像分析中,深度学习模型能够对脑部CT和MRI影像进行分析,预测阿尔茨海默症等神经退行性疾病的早期症状,有助于医生及时采取干预措施。自动分割与定量分析医疗影像中的分割任务,即将影像中的感兴趣区域(如肿瘤、病灶等)从背景中分离出来,是分析和诊断的基础。深度学习模型,尤其是基于U-Net等架构的网络,已经在医学图像分割任务中取得了显著成果。这些模型能够自动分割出器官、肿瘤、病灶等区域,且精度高、速度快,避免了人工操作的繁琐和主观性。例如,在心脏CT影像分析中,深度学习可以自动分割出心脏各个部位,帮助医生量化心脏的各项指标,如左室容积、心室壁厚度等,为临床治疗提供精准的参考数据。这些自动分割与定量分析结果不仅节省了医生的时间,也提升了治疗方案的科学性。深度学习在智能医疗影像分析中的挑战数据问题尽管深度学习在医疗影像分析中表现出色,但其成功应用依赖于大量高质量的标注数据。然而,医学影像数据的标注工作复杂且耗时,需要专业医生参与。因此,数据获取和标注的困难使得深度学习模型的训练存在瓶颈。此外,不同医院或机构的影像数据存在差异,如何解决数据分布不一致的问题,也是深度学习在医疗影像分析中面临的挑战之一。模型的可解释性深度学习模型常被视为“黑盒”模型,尽管其预测结果准确,但缺乏足够的可解释性。在医疗领域,医生需要了解模型的决策过程,才能对结果进行验证与调整。因此,提高深度学习模型的可解释性,尤其是在影像分析中的应用,对于提升其临床价值至关重要。临床应用的标准化问题深度学习在医疗影像中的应用需要与现有的临床流程相结合。然而,不同医院和医疗机构的设备、影像质量、标注规范等差异,使得深度学习模型的推广和应用面临一定障碍。如何将深度学习技术有效地整合进实际医疗流程,并确保其广泛适用性,是一个亟待解决的问题。结论基于深度学习的智能医疗影像分析与诊断技术,凭借其强大的自动化处理能力和高准确性,已经成为现代医学中不可或缺的重要工具。通过对医疗影像的自动分析、疾病的早期预测、影像分割与定量分析等功能,深度学习技术不仅提升了诊断效率,也为早期发现疾病、制定个性化治疗方案提供了强有力的支持。然而,数据问题、模型可解释性以及临床应用的标准化等挑战仍需解决,未来随着技术的不断进步和数据共享的加速,深度学习将在医疗领域发挥更大的作用,为实现精准医疗和智慧医疗提供有力支持。
  • [技术干货] 强化学习在无人驾驶系统中的应用与挑战
    强化学习在无人驾驶系统中的应用与挑战引言近年来,随着人工智能技术的快速发展,尤其是在机器学习领域的突破,无人驾驶技术已经成为自动化领域的前沿课题。无人驾驶系统通过结合多种传感器、计算机视觉、决策规划等技术,能够实现对汽车的自主控制,逐步替代传统驾驶员的角色。而在众多算法中,强化学习(Reinforcement Learning, RL)因其在复杂环境下的决策能力而成为无人驾驶研究中的一项重要技术。强化学习是一种基于奖励与惩罚机制的学习方法,通过智能体与环境的交互,不断优化决策过程,从而最大化长期回报。在无人驾驶中,强化学习被广泛应用于路径规划、决策制定、自动控制等多个方面。然而,尽管强化学习在无人驾驶领域展现出巨大的潜力,它在实际应用中仍然面临一系列挑战。强化学习在无人驾驶中的应用路径规划与决策制定无人驾驶系统需要根据当前交通状况和道路环境做出实时决策,确保行车安全并高效到达目的地。传统的路径规划方法依赖于预定义的规则和地图,而强化学习则能够根据实时反馈进行动态调整。通过不断与环境交互,强化学习算法能够在复杂多变的交通环境中学会合理的决策策略。例如,在复杂的交通场景下,无人驾驶系统需要做出是否超车、变道、停车等决策,而这些决策通常无法仅依赖规则或规划路径来完成,强化学习通过奖励和惩罚机制引导智能体作出合理的决策。自动驾驶中的交通信号识别无人驾驶车辆需要识别交通信号灯、标志和行人等周围环境元素,及时做出反应。强化学习在这个过程中发挥了重要作用。通过训练智能体识别不同交通标志和信号,并根据这些信息调整行动,强化学习可以帮助无人驾驶系统不断优化识别算法,提高反应的准确性与效率。例如,系统可以根据交通信号灯的变化和行人的行为预测,判断是否停车或加速。动态控制与驾驶策略优化无人驾驶系统需要实时控制车辆的加速度、转向角度、刹车力度等参数,确保车辆平稳行驶并应对不同道路状况。强化学习可以通过实时采集车辆的行驶状态数据(如速度、加速度、油门和刹车的使用情况)和环境反馈,学习如何优化这些控制策略。例如,在拥堵的道路上,强化学习可以使无人驾驶车辆在保证安全的前提下选择最佳行驶策略,而不只是单纯跟随交通规则。多智能体协作在复杂的城市交通环境中,无人驾驶车辆需要与其他交通参与者(如其他车辆、行人、骑行者等)进行协作。强化学习在多智能体环境中的应用,能够帮助无人驾驶车辆学会与其他智能体协调行为,以避免碰撞并提高交通效率。例如,通过强化学习,智能体能够学习如何与其他车辆共享道路资源,协作变道、并行行驶等,减少交通冲突,提升道路利用率。强化学习在无人驾驶中的挑战尽管强化学习在无人驾驶系统中具有巨大的应用前景,但它的实际应用仍面临着许多挑战:高维度状态空间与动作空间无人驾驶系统需要处理大量的输入数据,包括来自传感器(如摄像头、雷达、激光雷达等)的信息、车辆状态、交通信息等。这些信息的维度非常高,导致强化学习面临的状态空间和动作空间也极其庞大。高维度的状态空间使得传统强化学习方法在训练时计算量非常大,训练时间长,且容易过拟合。此外,复杂的动作空间也增加了策略优化的难度。训练数据与环境模拟强化学习的成功应用依赖于大量的训练数据和环境模拟。然而,在无人驾驶的实际场景中,收集足够的高质量数据并进行模拟训练是一项艰巨的任务。虽然模拟器(如Carla、AirSim等)提供了一个较为安全的训练平台,但模拟环境与现实世界之间的差距仍然较大,导致模型在真实道路上的表现不如预期。此外,训练数据的多样性和质量直接影响到强化学习算法的训练效果,如何获得更加真实、广泛的训练数据是一个亟待解决的问题。安全性与可解释性无人驾驶系统在涉及到人命安全时,必须具备极高的可靠性和可解释性。强化学习在决策过程中往往是黑盒模型,缺乏可解释性,这在自动驾驶中可能带来安全隐患。例如,系统做出某个决策(如变道或刹车)的原因可能无法清晰解释,这使得我们很难确定其决策是否安全和合理。在实际应用中,为了提高系统的安全性,需要加强强化学习模型的可解释性,并引入可验证的安全保证机制。实时性要求无人驾驶系统要求决策过程能够实时进行,在交通密集、道路复杂的环境下,决策的时效性至关重要。强化学习算法通常需要较长的训练时间,且在推理阶段也存在一定的计算开销。在实时场景下,如何确保强化学习算法的决策过程足够快速,且不会影响车辆的反应速度和安全性,是一个重要挑战。长期奖励与短期决策之间的平衡强化学习的一个核心问题是如何在长期奖励和短期奖励之间找到平衡。无人驾驶系统需要在短期内做出即时反应(如刹车或加速),而这些反应可能会影响到长期的驾驶策略(如节省燃料、提高效率等)。如何设计合理的奖励机制,使得强化学习算法能够兼顾短期和长期的决策目标,是优化无人驾驶系统的关键问题。结论强化学习作为无人驾驶系统中的核心技术之一,展现了其在决策、路径规划、交通信号识别等多个方面的巨大潜力。然而,其应用面临高维度状态空间、训练数据和环境模拟的困难、安全性与可解释性的问题,以及实时性要求等多重挑战。未来,随着计算能力的提升、数据获取方式的改进以及算法优化的深入,强化学习在无人驾驶中的应用前景将更加广阔。通过解决这些挑战,强化学习将进一步推动无人驾驶技术的发展,最终实现更加安全、智能和高效的自动驾驶系统。
  • [行业动态] 【话题交流】华为天工计划:10亿元投资推动鸿蒙AI生态发展,大家怎么看。
    华为天工计划:10亿元投资推动鸿蒙AI生态发展,大家怎么看。 
  • [技术干货] 【朝推夜训】Ascend310p YOLOv8 NPU 训练和推理
    【朝推夜训】Ascend310p YOLOv8 NPU 训练和推理在华为昇思MindSpore框架的加持下,我们在OrangePi AI Studio Pro开发板上实现YOLOv8m模型的完整训练流程。在单块NPU上训练YOLOv8m模型,每轮训练7000张图像仅需6.92分钟,10轮训练总耗时约69分钟。从训练日志可以看出,模型损失值loss从第一轮的6.45逐步下降到最后一轮的2.58左右,表明模型训练效果良好。训练过程中,NPU的AICore利用率和内存占用情况都保持在合理水平,证明了Ascend 310P芯片在目标检测任务中的优异表现,其性能可与NVIDIA GPU相媲美,为开发者提供了另一种高效的AI计算平台选择。通过mindyolo开源仓库,其他开发者也可以复现这一成果并进行进一步的开发和优化。我们在昇腾310AI加速卡上使用昇思MindSpore把YOLOv8模型的NPU训练和推理给跑通了,性能不输于NVIDIA的GPU。OrangePi AI Stuido Pro与Atlas 300V Pro视频解析卡搭载是同款Ascend 310p芯片,总共是两块,每块有96G的内存,可以提供176TFlops的训练算力和352Tops的推理算力。上图是在单块NPU上训练yolov8m模型的AICore的利用率以及内存的占用情况,总共7000张图像每轮训练时长仅需6.92分钟:2025-09-24 16:47:11,931 [INFO] 2025-09-24 16:47:11,931 [INFO] Please check the above information for the configurations 2025-09-24 16:47:12,050 [WARNING] Parse Model, args: nearest, keep str type 2025-09-24 16:47:12,069 [WARNING] Parse Model, args: nearest, keep str type 2025-09-24 16:47:12,184 [INFO] number of network params, total: 25.896391M, trainable: 25.863252M 2025-09-24 16:47:16,786 [WARNING] Parse Model, args: nearest, keep str type 2025-09-24 16:47:16,807 [WARNING] Parse Model, args: nearest, keep str type 2025-09-24 16:47:16,920 [INFO] number of network params, total: 25.896391M, trainable: 25.863252M 2025-09-24 16:47:31,011 [INFO] ema_weight not exist, default pretrain weight is currently used. 2025-09-24 16:47:31,118 [INFO] Dataset Cache file hash/version check success. 2025-09-24 16:47:31,118 [INFO] Load dataset cache from [/home/orangepi/workspace/mindyolo/examples/finetune_visdrone/train.cache.npy] success. 2025-09-24 16:47:31,142 [INFO] Dataloader num parallel workers: [8] 2025-09-24 16:47:31,240 [INFO] Dataset Cache file hash/version check success. 2025-09-24 16:47:31,240 [INFO] Load dataset cache from [/home/orangepi/workspace/mindyolo/examples/finetune_visdrone/train.cache.npy] success. 2025-09-24 16:47:31,264 [INFO] Dataloader num parallel workers: [8] 2025-09-24 16:47:31,438 [INFO] 2025-09-24 16:47:31,445 [INFO] got 1 active callback as follows: 2025-09-24 16:47:31,445 [INFO] SummaryCallback() 2025-09-24 16:47:31,445 [WARNING] The first epoch will be compiled for the graph, which may take a long time; You can come back later :). 2025-09-24 16:50:38,076 [INFO] Epoch 1/10, Step 100/404, imgsize (640, 640), loss: 6.4507, lbox: 3.8446, lcls: 0.5687, dfl: 2.0375, cur_lr: 0.09257426112890244 2025-09-24 16:50:38,970 [INFO] Epoch 1/10, Step 100/404, step time: 1875.26 ms 2025-09-24 16:52:21,629 [INFO] Epoch 1/10, Step 200/404, imgsize (640, 640), loss: 4.8078, lbox: 3.0080, lcls: 0.4118, dfl: 1.3880, cur_lr: 0.08514851331710815 2025-09-24 16:52:21,653 [INFO] Epoch 1/10, Step 200/404, step time: 1026.83 ms 2025-09-24 16:54:04,347 [INFO] Epoch 1/10, Step 300/404, imgsize (640, 640), loss: 4.0795, lbox: 2.4281, lcls: 0.3466, dfl: 1.3048, cur_lr: 0.07772277295589447 2025-09-24 16:54:04,371 [INFO] Epoch 1/10, Step 300/404, step time: 1027.18 ms 2025-09-24 16:55:47,067 [INFO] Epoch 1/10, Step 400/404, imgsize (640, 640), loss: 3.8245, lbox: 2.1755, lcls: 0.3567, dfl: 1.2923, cur_lr: 0.07029703259468079 2025-09-24 16:55:47,091 [INFO] Epoch 1/10, Step 400/404, step time: 1027.19 ms 2025-09-24 16:55:52,087 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-1_404.ckpt 2025-09-24 16:55:52,087 [INFO] Epoch 1/10, epoch time: 8.34 min. 2025-09-24 16:57:34,759 [INFO] Epoch 2/10, Step 100/404, imgsize (640, 640), loss: 3.8083, lbox: 2.2584, lcls: 0.3404, dfl: 1.2095, cur_lr: 0.062162574380636215 2025-09-24 16:57:34,768 [INFO] Epoch 2/10, Step 100/404, step time: 1026.80 ms 2025-09-24 16:59:17,441 [INFO] Epoch 2/10, Step 200/404, imgsize (640, 640), loss: 3.7835, lbox: 2.2670, lcls: 0.3574, dfl: 1.1592, cur_lr: 0.05465514957904816 2025-09-24 16:59:17,450 [INFO] Epoch 2/10, Step 200/404, step time: 1026.82 ms 2025-09-24 17:01:00,127 [INFO] Epoch 2/10, Step 300/404, imgsize (640, 640), loss: 3.5251, lbox: 2.0144, lcls: 0.3210, dfl: 1.1898, cur_lr: 0.0471477210521698 2025-09-24 17:01:00,136 [INFO] Epoch 2/10, Step 300/404, step time: 1026.85 ms 2025-09-24 17:02:42,826 [INFO] Epoch 2/10, Step 400/404, imgsize (640, 640), loss: 3.5596, lbox: 2.0947, lcls: 0.3086, dfl: 1.1563, cur_lr: 0.03964029625058174 2025-09-24 17:02:42,835 [INFO] Epoch 2/10, Step 400/404, step time: 1026.99 ms 2025-09-24 17:02:47,745 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-2_404.ckpt 2025-09-24 17:02:47,745 [INFO] Epoch 2/10, epoch time: 6.93 min. 2025-09-24 17:04:30,489 [INFO] Epoch 3/10, Step 100/404, imgsize (640, 640), loss: 3.5524, lbox: 2.1004, lcls: 0.2938, dfl: 1.1582, cur_lr: 0.031090890988707542 2025-09-24 17:04:30,497 [INFO] Epoch 3/10, Step 100/404, step time: 1027.52 ms 2025-09-24 17:06:13,196 [INFO] Epoch 3/10, Step 200/404, imgsize (640, 640), loss: 3.8549, lbox: 2.2845, lcls: 0.3526, dfl: 1.2178, cur_lr: 0.02350178174674511 2025-09-24 17:06:13,205 [INFO] Epoch 3/10, Step 200/404, step time: 1027.07 ms 2025-09-24 17:07:55,875 [INFO] Epoch 3/10, Step 300/404, imgsize (640, 640), loss: 3.6236, lbox: 2.1016, lcls: 0.3113, dfl: 1.2106, cur_lr: 0.015912672504782677 2025-09-24 17:07:55,883 [INFO] Epoch 3/10, Step 300/404, step time: 1026.78 ms 2025-09-24 17:09:38,572 [INFO] Epoch 3/10, Step 400/404, imgsize (640, 640), loss: 3.5586, lbox: 2.0730, lcls: 0.3314, dfl: 1.1542, cur_lr: 0.008323564194142818 2025-09-24 17:09:38,581 [INFO] Epoch 3/10, Step 400/404, step time: 1026.97 ms 2025-09-24 17:09:43,528 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-3_404.ckpt 2025-09-24 17:09:43,529 [INFO] Epoch 3/10, epoch time: 6.93 min. 2025-09-24 17:11:26,211 [INFO] Epoch 4/10, Step 100/404, imgsize (640, 640), loss: 3.3767, lbox: 1.9760, lcls: 0.2928, dfl: 1.1079, cur_lr: 0.007029999978840351 2025-09-24 17:11:26,218 [INFO] Epoch 4/10, Step 100/404, step time: 1026.90 ms 2025-09-24 17:13:08,899 [INFO] Epoch 4/10, Step 200/404, imgsize (640, 640), loss: 3.4213, lbox: 1.9382, lcls: 0.3052, dfl: 1.1779, cur_lr: 0.007029999978840351 2025-09-24 17:13:08,908 [INFO] Epoch 4/10, Step 200/404, step time: 1026.89 ms 2025-09-24 17:14:51,583 [INFO] Epoch 4/10, Step 300/404, imgsize (640, 640), loss: 2.8313, lbox: 1.5666, lcls: 0.2380, dfl: 1.0267, cur_lr: 0.007029999978840351 2025-09-24 17:14:51,591 [INFO] Epoch 4/10, Step 300/404, step time: 1026.83 ms 2025-09-24 17:16:34,277 [INFO] Epoch 4/10, Step 400/404, imgsize (640, 640), loss: 3.2905, lbox: 1.9274, lcls: 0.2889, dfl: 1.0741, cur_lr: 0.007029999978840351 2025-09-24 17:16:34,285 [INFO] Epoch 4/10, Step 400/404, step time: 1026.94 ms 2025-09-24 17:16:39,232 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-4_404.ckpt 2025-09-24 17:16:39,232 [INFO] Epoch 4/10, epoch time: 6.93 min. 2025-09-24 17:18:21,892 [INFO] Epoch 5/10, Step 100/404, imgsize (640, 640), loss: 3.1534, lbox: 1.7844, lcls: 0.2581, dfl: 1.1109, cur_lr: 0.006039999891072512 2025-09-24 17:18:21,900 [INFO] Epoch 5/10, Step 100/404, step time: 1026.67 ms 2025-09-24 17:20:04,596 [INFO] Epoch 5/10, Step 200/404, imgsize (640, 640), loss: 3.1152, lbox: 1.7685, lcls: 0.2518, dfl: 1.0949, cur_lr: 0.006039999891072512 2025-09-24 17:20:04,604 [INFO] Epoch 5/10, Step 200/404, step time: 1027.04 ms 2025-09-24 17:21:47,284 [INFO] Epoch 5/10, Step 300/404, imgsize (640, 640), loss: 3.3179, lbox: 1.8412, lcls: 0.2888, dfl: 1.1880, cur_lr: 0.006039999891072512 2025-09-24 17:21:47,292 [INFO] Epoch 5/10, Step 300/404, step time: 1026.88 ms 2025-09-24 17:23:29,968 [INFO] Epoch 5/10, Step 400/404, imgsize (640, 640), loss: 3.2193, lbox: 1.8366, lcls: 0.2620, dfl: 1.1207, cur_lr: 0.006039999891072512 2025-09-24 17:23:29,976 [INFO] Epoch 5/10, Step 400/404, step time: 1026.84 ms 2025-09-24 17:23:34,954 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-5_404.ckpt 2025-09-24 17:23:34,954 [INFO] Epoch 5/10, epoch time: 6.93 min. 2025-09-24 17:25:17,530 [INFO] Epoch 6/10, Step 100/404, imgsize (640, 640), loss: 2.7642, lbox: 1.5834, lcls: 0.2164, dfl: 0.9643, cur_lr: 0.005049999803304672 2025-09-24 17:25:17,538 [INFO] Epoch 6/10, Step 100/404, step time: 1025.84 ms 2025-09-24 17:27:00,125 [INFO] Epoch 6/10, Step 200/404, imgsize (640, 640), loss: 2.6854, lbox: 1.4272, lcls: 0.2080, dfl: 1.0502, cur_lr: 0.005049999803304672 2025-09-24 17:27:00,134 [INFO] Epoch 6/10, Step 200/404, step time: 1025.96 ms 2025-09-24 17:28:42,720 [INFO] Epoch 6/10, Step 300/404, imgsize (640, 640), loss: 2.7541, lbox: 1.5028, lcls: 0.2171, dfl: 1.0342, cur_lr: 0.005049999803304672 2025-09-24 17:28:42,728 [INFO] Epoch 6/10, Step 300/404, step time: 1025.94 ms 2025-09-24 17:30:25,315 [INFO] Epoch 6/10, Step 400/404, imgsize (640, 640), loss: 2.8092, lbox: 1.5545, lcls: 0.2121, dfl: 1.0427, cur_lr: 0.005049999803304672 2025-09-24 17:30:25,323 [INFO] Epoch 6/10, Step 400/404, step time: 1025.95 ms 2025-09-24 17:30:30,293 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-6_404.ckpt 2025-09-24 17:30:30,294 [INFO] Epoch 6/10, epoch time: 6.92 min. 2025-09-24 17:32:12,881 [INFO] Epoch 7/10, Step 100/404, imgsize (640, 640), loss: 3.0997, lbox: 1.8226, lcls: 0.2402, dfl: 1.0369, cur_lr: 0.00406000018119812 2025-09-24 17:32:12,890 [INFO] Epoch 7/10, Step 100/404, step time: 1025.96 ms 2025-09-24 17:33:55,477 [INFO] Epoch 7/10, Step 200/404, imgsize (640, 640), loss: 2.8140, lbox: 1.5979, lcls: 0.2143, dfl: 1.0018, cur_lr: 0.00406000018119812 2025-09-24 17:33:55,485 [INFO] Epoch 7/10, Step 200/404, step time: 1025.96 ms 2025-09-24 17:35:38,072 [INFO] Epoch 7/10, Step 300/404, imgsize (640, 640), loss: 3.0294, lbox: 1.6439, lcls: 0.2544, dfl: 1.1310, cur_lr: 0.00406000018119812 2025-09-24 17:35:38,081 [INFO] Epoch 7/10, Step 300/404, step time: 1025.95 ms 2025-09-24 17:37:20,660 [INFO] Epoch 7/10, Step 400/404, imgsize (640, 640), loss: 2.8015, lbox: 1.5686, lcls: 0.2252, dfl: 1.0077, cur_lr: 0.00406000018119812 2025-09-24 17:37:20,669 [INFO] Epoch 7/10, Step 400/404, step time: 1025.88 ms 2025-09-24 17:37:25,643 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-7_404.ckpt 2025-09-24 17:37:25,644 [INFO] Epoch 7/10, epoch time: 6.92 min. 2025-09-24 17:39:08,227 [INFO] Epoch 8/10, Step 100/404, imgsize (640, 640), loss: 2.5091, lbox: 1.3373, lcls: 0.1711, dfl: 1.0007, cur_lr: 0.0030700000934302807 2025-09-24 17:39:08,236 [INFO] Epoch 8/10, Step 100/404, step time: 1025.92 ms 2025-09-24 17:40:50,818 [INFO] Epoch 8/10, Step 200/404, imgsize (640, 640), loss: 2.5926, lbox: 1.4141, lcls: 0.1923, dfl: 0.9863, cur_lr: 0.0030700000934302807 2025-09-24 17:40:50,826 [INFO] Epoch 8/10, Step 200/404, step time: 1025.91 ms 2025-09-24 17:42:33,392 [INFO] Epoch 8/10, Step 300/404, imgsize (640, 640), loss: 2.5341, lbox: 1.3811, lcls: 0.1869, dfl: 0.9660, cur_lr: 0.0030700000934302807 2025-09-24 17:42:33,400 [INFO] Epoch 8/10, Step 300/404, step time: 1025.74 ms 2025-09-24 17:44:15,994 [INFO] Epoch 8/10, Step 400/404, imgsize (640, 640), loss: 3.0024, lbox: 1.6379, lcls: 0.2284, dfl: 1.1361, cur_lr: 0.0030700000934302807 2025-09-24 17:44:16,002 [INFO] Epoch 8/10, Step 400/404, step time: 1026.02 ms 2025-09-24 17:44:20,974 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-8_404.ckpt 2025-09-24 17:44:20,975 [INFO] Epoch 8/10, epoch time: 6.92 min. 2025-09-24 17:46:03,561 [INFO] Epoch 9/10, Step 100/404, imgsize (640, 640), loss: 3.0890, lbox: 1.8395, lcls: 0.2321, dfl: 1.0174, cur_lr: 0.0020800000056624413 2025-09-24 17:46:03,569 [INFO] Epoch 9/10, Step 100/404, step time: 1025.94 ms 2025-09-24 17:47:46,157 [INFO] Epoch 9/10, Step 200/404, imgsize (640, 640), loss: 2.9621, lbox: 1.6608, lcls: 0.2360, dfl: 1.0652, cur_lr: 0.0020800000056624413 2025-09-24 17:47:46,166 [INFO] Epoch 9/10, Step 200/404, step time: 1025.96 ms 2025-09-24 17:49:28,755 [INFO] Epoch 9/10, Step 300/404, imgsize (640, 640), loss: 2.4801, lbox: 1.3320, lcls: 0.1753, dfl: 0.9728, cur_lr: 0.0020800000056624413 2025-09-24 17:49:28,763 [INFO] Epoch 9/10, Step 300/404, step time: 1025.97 ms 2025-09-24 17:51:11,359 [INFO] Epoch 9/10, Step 400/404, imgsize (640, 640), loss: 2.8075, lbox: 1.5971, lcls: 0.1995, dfl: 1.0109, cur_lr: 0.0020800000056624413 2025-09-24 17:51:11,367 [INFO] Epoch 9/10, Step 400/404, step time: 1026.03 ms 2025-09-24 17:51:16,330 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-9_404.ckpt 2025-09-24 17:51:16,331 [INFO] Epoch 9/10, epoch time: 6.92 min. 2025-09-24 17:52:58,913 [INFO] Epoch 10/10, Step 100/404, imgsize (640, 640), loss: 2.6278, lbox: 1.4529, lcls: 0.1860, dfl: 0.9889, cur_lr: 0.0010900000343099236 2025-09-24 17:52:58,921 [INFO] Epoch 10/10, Step 100/404, step time: 1025.90 ms 2025-09-24 17:54:41,521 [INFO] Epoch 10/10, Step 200/404, imgsize (640, 640), loss: 2.7550, lbox: 1.5724, lcls: 0.2083, dfl: 0.9742, cur_lr: 0.0010900000343099236 2025-09-24 17:54:41,529 [INFO] Epoch 10/10, Step 200/404, step time: 1026.08 ms 2025-09-24 17:56:24,125 [INFO] Epoch 10/10, Step 300/404, imgsize (640, 640), loss: 2.4470, lbox: 1.2448, lcls: 0.1758, dfl: 1.0263, cur_lr: 0.0010900000343099236 2025-09-24 17:56:24,133 [INFO] Epoch 10/10, Step 300/404, step time: 1026.03 ms 2025-09-24 17:58:06,727 [INFO] Epoch 10/10, Step 400/404, imgsize (640, 640), loss: 2.5783, lbox: 1.3733, lcls: 0.1848, dfl: 1.0202, cur_lr: 0.0010900000343099236 2025-09-24 17:58:06,736 [INFO] Epoch 10/10, Step 400/404, step time: 1026.02 ms 2025-09-24 17:58:11,744 [INFO] Saving model to ./runs/2025.09.24-16.47.11/weights/yolov8m-10_404.ckpt 2025-09-24 17:58:11,745 [INFO] Epoch 10/10, epoch time: 6.92 min. 2025-09-24 17:58:12,149 [INFO] End Train. 2025-09-24 17:58:12,561 [INFO] Training completed.以下是模型训练了10个epoch的使用NPU在测试集图片上的推理结果:2025-09-24 18:13:24,511 [WARNING] Parse Model, args: nearest, keep str type 2025-09-24 18:13:24,532 [WARNING] Parse Model, args: nearest, keep str type 2025-09-24 18:13:24,639 [INFO] number of network params, total: 25.896391M, trainable: 25.863252M 2025-09-24 18:13:29,405 [INFO] Load checkpoint from [/home/orangepi/workspace/mindyolo/runs/2025.09.24-16.47.11/weights/yolov8m-10_404.ckpt] success. 2025-09-24 18:13:53,915 [INFO] Predict result is: {'category_id': [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 4, 4, 5, 10, 4, 1, 4, 2, 4, 1, 5, 10, 4, 2, 4, 1], 'bbox': [[866.402, 359.922, 125.209, 179.961], [619.836, 379.246, 140.848, 229.434], [704.238, 192.678, 102.631, 112.359], [572.588, 189.689, 108.707, 103.76], [80.484, 471.75, 334.953, 243.844], [739.99, 15.987, 60.305, 60.944], [1179.242, 68.017, 143.637, 56.163], [1220.215, 154.843, 138.523, 76.782], [1217.559, 108.026, 140.516, 63.733], [822.475, 15.34, 56.744, 75.039], [621.438, 70.781, 19.938, 55.292], [1106.859, 128.463, 79.986, 95.99], [773.168, 90.047, 71.42, 95.293], [773.467, 88.951, 70.988, 95.924], [1122.158, 371.145, 48.12, 90.512], [1168.982, 2.274, 83.141, 77.081], [723.45, 65.277, 21.877, 51.017], [1145.906, 0.556, 76.467, 46.708], [672.513, 71.818, 25.857, 46.933], [488.816, 350.559, 107.844, 117.605], [672.778, 71.918, 26.172, 48.194], [1106.826, 128.612, 79.621, 96.239], [1058.831, 319.314, 35.087, 75.056], [1146.62, 0.365, 54.586, 48.643], [1124.963, 370.945, 42.359, 66.473], [1148.197, 1.046, 92.537, 51.581], [526.153, 87.349, 29.123, 37.91]], 'score': [0.93223, 0.92336, 0.90671, 0.90539, 0.84414, 0.83682, 0.83292, 0.75641, 0.74857, 0.74295, 0.72221, 0.63341, 0.62439, 0.5829, 0.50411, 0.48259, 0.42391, 0.42188, 0.42185, 0.36533, 0.29963, 0.29451, 0.29264, 0.28265, 0.26525, 0.2585, 0.25038]} 2025-09-24 18:13:53,915 [INFO] Speed: 24481.6/5.7/24487.3 ms inference/NMS/total per 640x640 image at batch-size 1; 2025-09-24 18:13:53,915 [INFO] Detect a image success. 2025-09-24 18:13:53,924 [INFO] Infer completed.模型训练和推理代码可以从mindyolo仓库上下载:https://github.com/mindspore-lab/mindyolo
  • [技术干货] 如何在OrangePi Studio Pro上升级CANN以及的Pytorch和MindSpore
    如何在OrangePi Studio Pro上升级CANN以及的Pytorch和MindSpore1. 安装 CANN 和 Pytorch首先我们在昇腾资源下载中心硬件信息中产品系列选择:加速卡,产品型号选择:Atlas 300V Pro 视频解析卡,CANN版本选择:8.2.RC1,下载CANN相关软件包,获取Pytorch源码。下载完成后,就安装CANN以及Pytorch了,我使用的OrangePi制作的预装好AI环境的Ubuntu22.04测试镜像,因此只需要升级Ascend-cann-toolkit_8.2.RC1_linux-x86_64.run和Ascend-cann-kernels-310p_8.2.RC1_linux-x86_64.run以及torch_npu-2.1.0.post13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl。首先我们切换到root用户安装更新依赖包列表安装g++-12:sudo apt update sudo apt install -y g++-12之后进入CANN软件包下载目录,依次执行下面的命令进行安装:chmod +x ./Ascend-cann-toolkit_8.2.RC1_linux-x86_64.run ./Ascend-cann-toolkit_8.2.RC1_linux-x86_64.run --full --quiet chmod +x ./Ascend-cann-kernels-310p_8.2.RC1_linux-x86_64.run ./Ascend-cann-kernels-310p_8.2.RC1_linux-x86_64.run --install --quiet pip3 install torch_npu-2.1.0.post13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl执行如下命令,验证是cann和torch_npu是否安装成功:source /usr/local/Ascend/ascend-toolkit/set_env.sh python3 -c "import torch;import torch_npu; a = torch.randn(3, 4).npu(); print(a + a);" 2. 升级 MindSpore 版本我们访问MindSpore官网,CANN版本选择我们刚刚安装的CANN 8.2.RC1,其他配置根据自己的设备选择:切换到root用户执行如下安装命令:sudo su pip3 install mindspore==2.7.0 -i https://repo.mindspore.cn/pypi/simple --trusted-host repo.mindspore.cn --extra-index-url https://repo.huaweicloud.com/repository/pypi/simple安装完成后我们可以执行如下验证命令测试是否安装成功:source /usr/local/Ascend/ascend-toolkit/set_env.sh python3 -c "import mindspore;mindspore.set_context(device_target='Ascend');mindspore.run_check()" 如果输出下面的结果就证明 MindSpore 安装成功了![WARNING] ME(1621400:139701939115840,MainProcess):2025-09-24-10:46:21.978.000 [mindspore/context.py:1412] For 'context.set_context', the parameter 'device_target' will be deprecated and removed in a future version. Please use the api mindspore.set_device() instead. MindSpore version: 2.7.0 [WARNING] GE_ADPT(1621400,7f0e18710640,python3):2025-09-24-10:46:23.323.570 [mindspore/ops/kernel/ascend/acl_ir/op_api_exec.cc:169] GetAscendDefaultCustomPath] Checking whether the so exists or if permission to access it is available: /usr/local/Ascend/ascend-toolkit/latest/opp/vendors/customize_vision/op_api/lib/libcust_opapi.so The result of multiplication calculation is correct, MindSpore has been installed on platform [Ascend] successfully! 3. 小结本文详细介绍了在OrangePi Studio Pro开发板上升级CANN、PyTorch和MindSpore AI框架的完整流程。通过本文的指导,开发者可以轻松地将这些关键的AI组件升级到最新版本,从而充分发挥OrangePi Studio Pro硬件平台的AI计算能力。
  • [技术干货] 华为云开发者空间基于昇腾NPU实现CT肺炎影像分割模型训练与推理
    华为云开发者空间基于昇腾NPU实现CT肺炎影像分割模型训练与推理本案例将介绍如何在华为云开发者空间的AI Notebook环境中,利用昇腾NPU 910B4硬件资源训练和推理一个用于CT肺炎影像分割的深度学习模型,涵盖从数据准备、预处理、模型构建、训练到推理可视化的完整深度学习工作流。首先,从OBS存储桶下载并解压了COVID-19 CT扫描数据集,该数据集包含原始CT扫描图像、肺部掩码、感染区域掩码以及肺部和感染区域的组合掩码。import os import zipfile # 下载数据集 if not os.path.exists('Covid-19.zip'): os.system('wget -q https://orangepi-ai-studio.obs.cn-north-4.myhuaweicloud.com/Covid-19.zip') # 解压数据集 if not os.path.exists('Covid-19'): zip_file = zipfile.ZipFile('Covid-19.zip') zip_file.extractall() zip_file.close() 读取数据集中的元数据并显示前5行:import pandas as pd data = pd.read_csv('Covid-19/metadata.csv') data.head() ct_scanlung_maskinfection_masklung_and_infection_mask0…/input/covid19-ct-scans/ct_scans/coronacases……/input/covid19-ct-scans/lung_mask/coronacase……/input/covid19-ct-scans/infection_mask/coron……/input/covid19-ct-scans/lung_and_infection_m…1…/input/covid19-ct-scans/ct_scans/coronacases……/input/covid19-ct-scans/lung_mask/coronacase……/input/covid19-ct-scans/infection_mask/coron……/input/covid19-ct-scans/lung_and_infection_m…2…/input/covid19-ct-scans/ct_scans/coronacases……/input/covid19-ct-scans/lung_mask/coronacase……/input/covid19-ct-scans/infection_mask/coron……/input/covid19-ct-scans/lung_and_infection_m…3…/input/covid19-ct-scans/ct_scans/coronacases……/input/covid19-ct-scans/lung_mask/coronacase……/input/covid19-ct-scans/infection_mask/coron……/input/covid19-ct-scans/lung_and_infection_m…4…/input/covid19-ct-scans/ct_scans/coronacases……/input/covid19-ct-scans/lung_mask/coronacase……/input/covid19-ct-scans/infection_mask/coron……/input/covid19-ct-scans/lung_and_infection_m…我们分别获取原始图像、肺部mask、感染mask、肺部和感染mask的文件路径:# 原始图像 ct_scan_sample_file = data.loc[0,'ct_scan'].replace('../input/covid19-ct-scans','Covid-19') # 肺部mask lung_mask_sample_file = data.loc[0,'lung_mask'].replace('../input/covid19-ct-scans','Covid-19') # 感染mask infection_mask_sample_file = data.loc[0,'infection_mask'].replace('../input/covid19-ct-scans','Covid-19') # 肺部和感染mask lung_and_infection_mask_sample_file = data.loc[0,'lung_and_infection_mask'].replace('../input/covid19-ct-scans','Covid-19') 安装nibabel库读取NIfTI格式的医学影像文件,使用matplotlib库进行可视化展示:!pip install nibabelimport numpy as np import nibabel as nib # 读取nifti文件 def read_nii_file(fileName): img = nib.load(fileName) img_data = img.get_fdata() img_data = np.rot90(np.array(img_data)) return img_data # 读取 ct_scan_imgs = read_nii_file(ct_scan_sample_file) lung_mas_imgs = read_nii_file(lung_mask_sample_file) infection_mask_imgs = read_nii_file(infection_mask_sample_file) lung_and_infection_mas_imgs = read_nii_file(lung_and_infection_mask_sample_file) # 查看大小 print(ct_scan_imgs.shape) print(lung_mas_imgs.shape) (512, 512, 301) (512, 512, 301) # 绘制 import matplotlib.pyplot as plt %matplotlib inline color_map = 'spring' layer_index = 180 fig = plt.figure(figsize=(20, 4)) plt.subplot(1, 4, 1) plt.imshow(ct_scan_imgs[:,:,layer_index], cmap='bone') plt.title('Original Image') plt.axis('off') plt.subplot(1,4,2) plt.imshow(ct_scan_imgs[:,:,layer_index], cmap='bone') mask_ = np.ma.masked_where(lung_mas_imgs[:,:,layer_index]== 0, lung_mas_imgs[:,:,layer_index]) plt.imshow(mask_, alpha=0.8, cmap=color_map) plt.title('Lung Mask') plt.axis('off') plt.subplot(1,4,3) plt.imshow(ct_scan_imgs[:,:,layer_index], cmap='bone') mask_ = np.ma.masked_where(infection_mask_imgs[:,:,layer_index]== 0, infection_mask_imgs[:,:,layer_index]) plt.imshow(mask_, alpha=0.8, cmap=color_map) plt.title('Infection Mask') plt.axis('off') plt.subplot(1,4,4) plt.imshow(ct_scan_imgs[:,:,layer_index], cmap='bone') mask_ = np.ma.masked_where(lung_and_infection_mas_imgs[:,:,layer_index]== 0, lung_and_infection_mas_imgs[:,:,layer_index]) plt.imshow(mask_, alpha=0.8, cmap=color_map) plt.title('Lung and Infection Mask') plt.axis('off') plt.show() 之后对数据进行标准化和归一化,划分训练集和测试集,并统一缩放到256x256的大小保存为npy文件。标准化x′=x−mean(x)σx'= \frac{x-mean(x)}{\sigma} x′=σx−mean(x)​归一化x′=x−min(x)max(x)−min(x)x'= \frac{x-min(x)}{max(x)-min(x)} x′=max(x)−min(x)x−min(x)​# 标准化 def standardize(data): # 计算均值 mean = data.mean() # 计算标准差 std = np.std(data) # 计算结果 standardized = (data - mean) / std return standardized # 归一化 def normalize(data): # 计算最大最小值 max_val = data.max() min_val = data.min() normalized = (data - min_val) / (max_val - min_val) return normalized std = standardize(ct_scan_imgs) normalize(std).max(),normalize(std).min() (1.0, 0.0) # 处理所有文件 import cv2 import glob train_file_list =[file_path.replace('../input/covid19-ct-scans','Covid-19') for file_path in data.loc[:,'ct_scan']] train_label_list = [file_path.replace('../input/covid19-ct-scans','Covid-19') for file_path in data.loc[:,'infection_mask']] train_file_list[:5], len(train_label_list), train_label_list[:5], len(train_file_list) (['Covid-19/ct_scans/coronacases_org_001.nii', 'Covid-19/ct_scans/coronacases_org_002.nii', 'Covid-19/ct_scans/coronacases_org_003.nii', 'Covid-19/ct_scans/coronacases_org_004.nii', 'Covid-19/ct_scans/coronacases_org_005.nii'], 20, ['Covid-19/infection_mask/coronacases_001.nii', 'Covid-19/infection_mask/coronacases_002.nii', 'Covid-19/infection_mask/coronacases_003.nii', 'Covid-19/infection_mask/coronacases_004.nii', 'Covid-19/infection_mask/coronacases_005.nii'], 20) from tqdm import tqdm for index in tqdm(range(len(train_file_list))): # 读取 img = nib.load(train_file_list[index]) mask = nib.load(train_label_list[index]) img_data = img.get_fdata() mask_data = mask.get_fdata().astype(np.uint8) # 标准化和归一化 std = standardize(img_data) normalized = normalize(std) # 分为训练数据和测试数据 if index < 17: save_dir = 'processed/train/' else: save_dir = 'processed/test/' # 遍历所有层,分层存入文件夹,存储路径格式:'processed/train/0/img_0.npy','processed/train/0/label_0.npy', layer_num = normalized.shape[-1] for i in range(layer_num): layer = normalized[:,:,i] mask = mask_data[:,:,i] # 缩放 layer = cv2.resize(layer, (256, 256)) mask = cv2.resize(mask, (256, 256), interpolation=cv2.INTER_NEAREST) # 创建文件夹 img_dir = save_dir + str(index) if not os.path.exists(img_dir): os.makedirs(img_dir) # 保存为npy文件 np.save(img_dir+'/img_'+str(i), layer) np.save(img_dir+'/label_'+str(i), mask) 100%|██████████| 20/20 [01:08<00:00, 3.44s/it] 同时采用imgaug库进行数据增强,包括图像的缩放、旋转和弹性变换等操作,以提升模型的泛化能力。!pip install imgaugimport imgaug as ia import imgaug.augmenters as iaa from torch.utils.data import Dataset from imgaug.augmentables.segmaps import SegmentationMapsOnImage class SegmentDataset(Dataset): def __init__(self,where='train',seq=None): # 获取数据 self.img_list = glob.glob('processed/{}/*/img_*'.format(where)) self.mask_list = glob.glob('processed/{}/*/img_*') # 数据增强pipeline self.seq = seq def __len__(self): # 返回数据大小 return len(self.img_list) def __getitem__(self, idx): # 获取具体每一个数据 # 获取图片 img_file = self.img_list[idx] mask_file = img_file.replace('img','label') img = np.load(img_file) # 获取mask mask = np.load(mask_file) # 如果需要数据增强 if self.seq: segmap = SegmentationMapsOnImage(mask, shape=mask.shape) img,mask = seq(image=img, segmentation_maps=segmap) # 直接获取数组内容 mask = mask.get_arr() # 灰度图扩张维度成张量 return np.expand_dims(img,0) , np.expand_dims(mask,0) # 数据增强处理流程 seq = iaa.Sequential([ iaa.Affine(scale=(0.8, 1.2), # 缩放 rotate=(-45, 45)), # 旋转 iaa.ElasticTransformation() # 变换 ]) 创建dataloader,开启8个线程一次加载16张图片进行处理。import torch import torch_npu from torch_npu.contrib import transfer_to_npu # 使用dataloader加载 batch_size = 16 num_workers = 8 train_dataset = SegmentDataset('train', seq) test_dataset = SegmentDataset('test', None) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=False) 我们可以查看单张图像增强后的效果:# 对同一个图片显示多次 fig = plt.figure(figsize=(12, 12)) for i in range(16): plt.subplot(4, 4, i+1) img , mask = train_dataset[101] plt.imshow(img[0], cmap='bone') mask_ = np.ma.masked_where(mask[0]== 0, mask[0]) plt.imshow(mask_, alpha=0.8, cmap="spring") plt.axis('off') plt.show() 数据准备完成后,我们开始从头构建Unet的网络结构。U-Net是一种经典的编码器-解码器结构,特别适用于医学图像分割任务。网络包含四个编码层和四个解码层,通过跳跃连接将编码器的特征图与解码器对应层进行融合,保留了丰富的空间信息。# 定义两次卷积操作 class ConvBlock(torch.nn.Module): def __init__(self,in_channels,out_channels): super().__init__() self.step = torch.nn.Sequential( # 第一次卷积 torch.nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=3,padding=1,stride=1), # ReLU torch.nn.ReLU(), # 第二次卷积 torch.nn.Conv2d(in_channels=out_channels,out_channels=out_channels,kernel_size=3,padding=1,stride=1), # ReLU torch.nn.ReLU() ) def forward(self,x): return self.step(x) class UNet(torch.nn.Module): def __init__(self): super().__init__() # 定义左侧编码器的操作 self.layer1 = ConvBlock(1,64) self.layer2 = ConvBlock(64,128) self.layer3 = ConvBlock(128,256) self.layer4 = ConvBlock(256,512) # 定义右侧解码器的操作 self.layer5 = ConvBlock(256+512,256) self.layer6 = ConvBlock(128+256,128) self.layer7 = ConvBlock(64+128,64) #最后一个卷积 self.layer8 = torch.nn.Conv2d(in_channels=64,out_channels=1,kernel_size=1,padding=0,stride=1) # 定一些其他操作 # 池化 self.maxpool = torch.nn.MaxPool2d(kernel_size=2) #上采样 self.upsample = torch.nn.Upsample(scale_factor=2,mode='bilinear') # sigmoid self.sigmoid = torch.nn.Sigmoid() def forward(self,x): # 对输入数据进行处理 # 定义下采样部分 # input:1X256x256, output: 64x256x256 x1 = self.layer1(x) # input:64x256x256, output: 64 x 128 x 128 x1_p = self.maxpool(x1) # input: 64 x 128 x 128 , output: 128 x 128 x 128 x2 = self.layer2(x1_p) # input:128 x 128 x 128 , output: 128 x 64 x 64 x2_p = self.maxpool(x2) # input: 128 x 64 x 64, output: 256 x 64 x 64 x3 = self.layer3(x2_p) #input:256 x 64 x 64, output: 256 x 32 x 32 x3_p = self.maxpool(x3) #input: 256 x 32 x 32, output: 512 x 32 x 32 x4 = self.layer4(x3_p) # 定义上采样 # input: 512 x 32 x 32,output: 512 x 64 x 64 x5 = self.upsample(x4) # 拼接,output: 768x 64 x 64 x5 = torch.cat([x5,x3],dim=1) # input: 768x 64 x 64,output: 256 x 64 x 64 x5 = self.layer5(x5) # input: 256 x 64 x 64,output: 256 x 128 x 128 x6 = self.upsample(x5) # 拼接,output: 384 x 128 x 128 x6 = torch.cat([x6,x2],dim=1) # input: 384 x 128 x 128, output: 128 x 128 x 128 x6 = self.layer6(x6) # input:128 x 128 x 128, output: 128 x 256 x 256 x7 = self.upsample(x6) # 拼接, output: 192 x 256 x256 x7 = torch.cat([x7,x1],dim=1) # input: 192 x 256 x256, output: 64 x 256 x 256 x7 = self.layer7(x7) # 最后一次卷积,input: 64 x 256 x 256, output: 1 x 256 x 256 x8 = self.layer8(x7) #sigmoid # x9= self.sigmoid(x8) return x8网络定义完成后我们可以安装torchsummary库将搭建好的模型可视化。!pip install torchsummary# 模型架构可视化 from torchsummary import summary # device device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model = UNet().to(device) summary(model,(1, 256, 256)) [W compiler_depend.ts:623] Warning: expandable_segments currently defaults to false. You can enable this feature by `export PYTORCH_NPU_ALLOC_CONF = expandable_segments:True`. (function operator()) ---------------------------------------------------------------- Layer (type) Output Shape Param # ================================================================ Conv2d-1 [-1, 64, 256, 256] 640 ReLU-2 [-1, 64, 256, 256] 0 Conv2d-3 [-1, 64, 256, 256] 36,928 ReLU-4 [-1, 64, 256, 256] 0 ConvBlock-5 [-1, 64, 256, 256] 0 MaxPool2d-6 [-1, 64, 128, 128] 0 Conv2d-7 [-1, 128, 128, 128] 73,856 ReLU-8 [-1, 128, 128, 128] 0 Conv2d-9 [-1, 128, 128, 128] 147,584 ReLU-10 [-1, 128, 128, 128] 0 ConvBlock-11 [-1, 128, 128, 128] 0 MaxPool2d-12 [-1, 128, 64, 64] 0 Conv2d-13 [-1, 256, 64, 64] 295,168 ReLU-14 [-1, 256, 64, 64] 0 Conv2d-15 [-1, 256, 64, 64] 590,080 ReLU-16 [-1, 256, 64, 64] 0 ConvBlock-17 [-1, 256, 64, 64] 0 MaxPool2d-18 [-1, 256, 32, 32] 0 Conv2d-19 [-1, 512, 32, 32] 1,180,160 ReLU-20 [-1, 512, 32, 32] 0 Conv2d-21 [-1, 512, 32, 32] 2,359,808 ReLU-22 [-1, 512, 32, 32] 0 ConvBlock-23 [-1, 512, 32, 32] 0 Upsample-24 [-1, 512, 64, 64] 0 Conv2d-25 [-1, 256, 64, 64] 1,769,728 ReLU-26 [-1, 256, 64, 64] 0 Conv2d-27 [-1, 256, 64, 64] 590,080 ReLU-28 [-1, 256, 64, 64] 0 ConvBlock-29 [-1, 256, 64, 64] 0 Upsample-30 [-1, 256, 128, 128] 0 Conv2d-31 [-1, 128, 128, 128] 442,496 ReLU-32 [-1, 128, 128, 128] 0 Conv2d-33 [-1, 128, 128, 128] 147,584 ReLU-34 [-1, 128, 128, 128] 0 ConvBlock-35 [-1, 128, 128, 128] 0 Upsample-36 [-1, 128, 256, 256] 0 Conv2d-37 [-1, 64, 256, 256] 110,656 ReLU-38 [-1, 64, 256, 256] 0 Conv2d-39 [-1, 64, 256, 256] 36,928 ReLU-40 [-1, 64, 256, 256] 0 ConvBlock-41 [-1, 64, 256, 256] 0 Conv2d-42 [-1, 1, 256, 256] 65 ================================================================ Total params: 7,781,761 Trainable params: 7,781,761 Non-trainable params: 0 ---------------------------------------------------------------- Input size (MB): 0.25 Forward/backward pass size (MB): 706.50 Params size (MB): 29.69 Estimated Total Size (MB): 736.44 ----------------------------------------------------------------random_input = torch.randn(1, 1, 256, 256).to(device) output = model(random_input) output.shapetorch.Size([1, 1, 256, 256]) 最后定义损失函数和优化器,编写模型的训练代码,在昇腾NPU上训练50轮,使用Adam优化器和BCEWithLogitsLoss损失函数,并通过ReduceLROnPlateau调度器动态调整模型的学习率,每轮训练结束后保存模型的最优权重。import time from torch.optim.lr_scheduler import ReduceLROnPlateau # 定义损失 loss_fn = torch.nn.BCEWithLogitsLoss() # 定义优化器 optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) # 动态减少LR scheduler = ReduceLROnPlateau(optimizer, 'min') # 计算测试集的loss def check_test_loss(loader,model): loss = 0 # 不记录梯度 with torch.no_grad(): for i, (x, y) in enumerate(loader): # 图片 x = x.to(device,dtype=torch.float32) # 标签 y = y.to(device,dtype=torch.float32) # 预测值 y_pred = model(x) #计算损失 loss_batch = loss_fn(y_pred, y) loss += loss_batch return loss / len(loader) !pip install tensorboard progressbar# 使用tensorboard记录参数 from torch.utils.tensorboard import SummaryWriter # 使用progressbar打印进度 from progressbar import ProgressBar, Percentage, Bar, Timer, ETA, FileTransferSpeed # 记录变量 writer = SummaryWriter(log_dir='./log') # 打印进度 widgets = ['Progress: ', Percentage(), ' ', Bar('#'), ' ', Timer(), ' ', ETA(), ' ', FileTransferSpeed()] # 训练100个epoch EPOCH_NUM = 50 # 记录最好的测试acc best_test_loss = 10 # 保存训练结果 train_loss_results = [] test_loss_results = [] for epoch in range(EPOCH_NUM): # 获取批次图像 print('Epoch:{}'.format(epoch+1)) start_time = time.time() loss = 0 progress = ProgressBar(widgets=widgets) for (x, y) in progress(train_loader): # !!!每次update前清空梯度 model.zero_grad() # 获取数据 # 图片 x = x.to(device,dtype=torch.float32) # 标签 y = y.to(device,dtype=torch.float32) # 预测值 y_pred = model(x) #计算损失 loss_batch = loss_fn(y_pred, y) # 计算梯度 loss_batch.backward() optimizer.step() optimizer.zero_grad() # 记录每个batch的train loss loss_batch = loss_batch.detach().cpu() loss += loss_batch # 每个epoch的loss loss = loss / len(train_loader) # 如果降低LR:如果loss连续10个epoch不再下降,就减少LR scheduler.step(loss) # 计算测试集的loss test_loss = check_test_loss(test_loader, model) # tensorboard 记录 Loss/train writer.add_scalar('Loss/train', loss, epoch) # tensorboard 记录 Loss/test writer.add_scalar('Loss/test', test_loss, epoch) #保存信息 train_loss_results.append(loss.item()) test_loss_results.append(test_loss.item()) # 保存最新模型 torch.save(model.state_dict(), 'unet_latest.pt') # 记录最好的测试loss,并保存模型 if best_test_loss > test_loss: print('test loss improved from {:.4f} to {:.4f}'.format(best_test_loss, test_loss.item())) best_test_loss = test_loss # 保存模型 torch.save(model.state_dict(), 'unet_best.pt') Epoch:1 Progress: 0% | | Elapsed Time: 0:00:00 ETA: --:--:-- 0.00 B/s . Progress: 100% |##############| Elapsed Time: 0:00:29 Time: 0:00:29 7.17 B/s test loss improved from 50.0000 to 0.1825 Epoch:2 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.90 B/s test loss improved from 0.1825 to 0.1356 Epoch:3 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.88 B/s test loss improved from 0.1356 to 0.1190 Epoch:4 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.88 B/s test loss improved from 0.1190 to 0.1071 Epoch:5 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.99 B/s test loss improved from 0.1071 to 0.0826 Epoch:6 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.98 B/s test loss improved from 0.0826 to 0.0783 Epoch:7 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.00 B/s Epoch:8 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.01 B/s test loss improved from 0.0783 to 0.0564 Epoch:9 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.01 B/s Epoch:10 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.02 B/s Epoch:11 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.96 B/s Epoch:12 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.00 B/s Epoch:13 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.99 B/s test loss improved from 0.0564 to 0.0546 Epoch:14 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.99 B/s Epoch:15 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.89 B/s Epoch:16 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.99 B/s Epoch:17 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.01 B/s Epoch:18 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.01 B/s test loss improved from 0.0546 to 0.0502 Epoch:19 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.02 B/s Epoch:20 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.00 B/s Epoch:21 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.98 B/s Epoch:22 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.00 B/s test loss improved from 0.0502 to 0.0434 Epoch:23 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.00 B/s Epoch:24 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.98 B/s Epoch:25 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.99 B/s Epoch:26 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.94 B/s Epoch:27 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.84 B/s Epoch:28 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.93 B/s Epoch:29 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.89 B/s Epoch:30 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.96 B/s Epoch:31 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.94 B/s Epoch:32 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.92 B/s Epoch:33 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.88 B/s Epoch:34 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.93 B/s Epoch:35 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.97 B/s Epoch:36 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.92 B/s Epoch:37 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.91 B/s Epoch:38 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.93 B/s Epoch:39 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.91 B/s Epoch:40 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.89 B/s Epoch:41 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.87 B/s Epoch:42 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.96 B/s Epoch:43 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.97 B/s Epoch:44 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.97 B/s test loss improved from 0.0434 to 0.0378 Epoch:45 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.96 B/s Epoch:46 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.91 B/s Epoch:47 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.00 B/s Epoch:48 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.99 B/s Epoch:49 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 7.98 B/s Epoch:50 Progress: 100% |##############| Elapsed Time: 0:00:26 Time: 0:00:26 8.00 B/s 在模型的训练过程中,我们可以在另一个终端中查看NPU的利用率:训练结束后我们使用matplotlib绘制模型的损失曲线,观察在训练过程中loss的收敛情况。plt.plot(range(1, len(train_loss_results)+1), train_loss_results, label='train_loss') plt.plot(range(1, len(test_loss_results)+1), test_loss_results, label='test_loss') plt.title('Model Loss') plt.legend() 这里我们加载模型在训练过程中的最优权重在测试集上评估模型的训练效果:model.load_state_dict(torch.load('unet_best.pt')) model.eval() UNet( (layer1): ConvBlock( (step): Sequential( (0): Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU() ) ) (layer2): ConvBlock( (step): Sequential( (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU() ) ) (layer3): ConvBlock( (step): Sequential( (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU() ) ) (layer4): ConvBlock( (step): Sequential( (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU() ) ) (layer5): ConvBlock( (step): Sequential( (0): Conv2d(768, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU() ) ) (layer6): ConvBlock( (step): Sequential( (0): Conv2d(384, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU() ) ) (layer7): ConvBlock( (step): Sequential( (0): Conv2d(192, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): ReLU() (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (3): ReLU() ) ) (layer8): Conv2d(64, 1, kernel_size=(1, 1), stride=(1, 1)) (maxpool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (upsample): Upsample(scale_factor=2.0, mode='bilinear') (sigmoid): Sigmoid() ) class SegmentDataset(Dataset): def __init__(self,where='train',seq=None): # 获取数据 self.img_list =natsorted(glob.glob('processed/{}/*/img_*'.format(where))) self.mask_list =natsorted( glob.glob('processed/{}/*/img_*') ) # 数据增强pipeline self.seq = seq def __len__(self): # 返回数据大小 return len(self.img_list) def __getitem__(self, idx): # 获取具体每一个数据 # 获取图片 img_file = self.img_list[idx] mask_file = img_file.replace('img','label') img = np.load(img_file) # 获取mask mask = np.load(mask_file) # 如果需要数据增强 if self.seq: segmap = SegmentationMapsOnImage(mask, shape=mask.shape) img,mask = seq(image=img, segmentation_maps=segmap) # 直接获取数组内容 mask = mask.get_arr() # 灰度图扩张维度成张量 return np.expand_dims(img,0) , np.expand_dims(mask,0) !pip install natsortfrom natsort import natsorted # 使用dataloader加载 batch_size = 12 num_workers = 8 test_dataset = SegmentDataset('test',None) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=False) !pip install celluloidfrom tqdm import tqdm from celluloid import Camera from IPython.display import Image # 将每层画面制作成视频 fig = plt.figure(figsize=(10, 10)) camera = Camera(fig) # 遍历所有数据 index = 0 for x, y in tqdm(test_dataset): # 输出输入 input = torch.tensor([x]).to(device,dtype=torch.float32) # 推理 y_pred = model(input) # 获取mask mask_data = (y_pred.detach().cpu().numpy()[0][0] > 0.5) plt.subplot(1, 2, 1) plt.imshow(x[0], cmap='bone') mask_ = np.ma.masked_where(y[0] == 0, y[0]) plt.imshow(mask_, alpha=0.8, cmap="spring") plt.title('truth') plt.axis('off') plt.subplot(1, 2, 2) plt.imshow(x[0], cmap='bone') mask_ = np.ma.masked_where(mask_data == 0, mask_data) plt.imshow(mask_, alpha=0.8, cmap="spring") plt.title('prediction') plt.axis('off') camera.snap() index +=1 if index > 500: break animation = camera.animate() 0%| | 0/177 [00:00<?, ?it/s]/home/service/.local/lib/python3.10/site-packages/torch_npu/contrib/transfer_to_npu.py:151: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at /pytorch/torch/csrc/utils/tensor_new.cpp:261.) return fn(*args, **kwargs) 100%|██████████| 177/177 [00:06<00:00, 29.07it/s] # convert the animation to a video animation.save('animation.gif', writer='imagemagick') Image(open('animation.gif','rb').read()) 可以看到,模型准确地分割出肺炎的病变区域,为医疗诊断提供决策支持。本案例充分体现了华为云昇腾AI平台在医学图像处理领域的强大计算能力和易用性,为医疗AI应用的开发提供了完整的实践范例。
  • [技术干货] 破解目标检测中的“隐形杀手”:样本失衡难题攻克之道
    破解目标检测中的“隐形杀手”:样本失衡难题攻克之道在目标检测领域,样本失衡是困扰工程师和研究者的“隐形杀手”。它普遍存在于现实场景中:背景区域远多于目标区域、常见类别目标(如行人、车辆)的样本量远超稀有类别(如交通锥、特定动物)。这种失衡会导致模型严重偏向多数类,对稀有目标的检测性能急剧下降,直接影响模型的实用价值。那么,如何有效攻克这一难题?以下是一些关键策略:数据层面:开源与增流重采样: 核心思路是调整训练数据的分布。过采样: 复制稀有目标样本或应用高级技巧(如SMOTE及其变种)在特征空间合成新样本。需警惕单纯复制导致的过拟合。欠采样: 随机或有策略地减少多数类样本(如背景或大类别)。优点是加速训练,但可能损失重要信息。通常结合其他方法使用。数据增强: 对少数类样本应用更积极、多样化的增强(旋转、缩放、裁剪、色彩变换、MixUp、CutMix等),显著增加其“曝光度”和多样性,提高模型鲁棒性。算法层面:加权与重构损失函数改造:Focal Loss: 这是针对样本失衡的里程碑式解决方案。它通过降低易分类样本(通常是多数类)的权重,让模型更关注难分类样本(通常是少数类或困难正样本),有效缓解失衡问题。代价敏感学习: 在损失函数中为不同类别的错误预测分配不同的惩罚权重。通常对误检稀有目标的惩罚远大于误检背景,迫使模型重视小类。模型结构调整: 针对高度失衡问题(如背景占绝对主导),可考虑两阶段策略(先粗筛疑似目标区域,再精细分类)或引入在线困难样本挖掘机制,让模型在训练中自动聚焦于那些分类困难的样本(常包含小目标)。评估与调优:洞察全局选用合适的评估指标: 单纯追求高mAP可能掩盖问题。需特别关注小类、稀有类的精确率、召回率以及F1-Score。mAP@0.5:0.95、P-R曲线能更全面反映模型在类别不平衡下的性能。消融实验: 严格测试不同策略(单独或组合)的效果,记录它们对各类别性能的影响,找到最优解。实用技巧:知己知彼: 开始前,务必可视化数据集,精确掌握每个类别的样本数量和分布特点。组合拳出击: 单一方法往往效果有限。结合使用数据增强(针对小类)、Focal Loss(或加权损失) 是目前最常见有效的组合。持续监控: 在验证集和测试集上,持续跟踪各个类别的单独表现,特别是那些你关心的关键少数类。拥抱新技术: Few-Shot Learning、自监督预训练、域适应等技术在缓解小样本问题方面展现出潜力,值得持续关注。小结:攻克目标检测样本失衡,本质上是对数据进行深度理解和智慧干预。需要在数据的源头(采样、增强)、模型学习的核心(损失函数)以及最终的评估环节(指标选择)进行系统性优化。没有“银弹”,但通过科学组合上述策略,并辅以细致的分析调优,我们完全能够显著提升模型在真实、复杂场景下的均衡检测能力,让“隐形杀手”无所遁形。
  • [新特性] 版本速递 | 华为云Versatile智能体平台 新增特性介绍(2025年9月发布)
     < 华为云Versatile智能体平台 体验入口>华为开发者空间--开发平台--Versatile Agent (请在PC端打开)  版本概览 Versatile 920版本总结:新增27个特性,优化增强8个功能,新增多模态交互(图像、语音),新增敏感内容审查和风控,新增提示词管理,支持查看Trace调用链,查看使用量等统计指标,在运营运维、安全审查等企业级特性上有大幅提升。  华为云Versatile智能体平台 功能模块介绍  01 资产中心Versatile资产中心提供应用、MCP、插件、提示词等AI资产的共享,包括系统预置资产、开发者上传资产等,加速AI应用的开发以及公共资产的沉淀。 02 Versatile空间Versatile空间集成通用型AI助手以及各专家Agent,打造企业级智能协作统一入口,通过自主任务规划及多工具协同等,帮助用户完成复杂任务。 03 开发中心Versatile支持单智能体、工作流和多智能体三种应用开发方式,平台集成盘古大模型及DeepSeek等第三方模型,提供角色设定、插件扩展、工作流编排等功能,支持知识库管理、RAG检索和智能提示词优化,确保交互精准可靠。同时支持通过API、网页多渠道发布应用,助力开发者高效打造专业级智能体应用。04 模型中心模型中心提供标准化API接口,支持盘古大模型与业界主流模型的接入与管理,提供多种路由策略,实现模型无感切换和灵活调度,支持NLP与多模态理解模型的在线调测及参数配置。 05 运营运维运营运维包括调用链管理、运营统计,开展全维度Agent观测,实现对Agent调用的多维指标监控运营。 06 空间管理空间管理助力团队高效便捷地协作开发应用,多重权限控制提升企业资产数据安全。  新增重点特性介绍一、企业级特性 团队空间管理· 支持多团队空间的管理与资源隔离,成员角色权限管理,跨空间资产的复制业务价值:方便企业内进行资产、数据管理,同时能方便多人协作 应用管理· 支持配置敏感内容审查和风控:支持配置敏感词,触发后可以进行过滤、替换以及设置兜底回复,确保输出合规。业务价值:提供确定性保证,满足合规性与数据防泄露· 支持集成APIG,通过APIG发布Agent API业务价值:提供企业级API网关能力,可以为Agent的能力提供安全保障、运维能力、商业能力· 支持应用部署、升级、停止、启动、重启、删除等操作业务价值:提供应用的全生命周期标准化管理 调用链管理· 支持Trace调用链统计: 支持查看智能体、工作流的调用情况(时间、tokens消耗、input,output)业务价值1:技术运维与保障价值——技术人员可以快速定位问题、进行性能瓶颈分析等,确保系统稳定、可靠、可用业务价值2:安全合规与审计价值——记录每次调用的详细信息,实现全过程可追溯 指标统计· 支持查看运营数据:支持查看智能体、工作流的各项运营指标统计:基础指标功能(使用次数、服务QPS、模型QPS等)、质量统计指标功能(模型调用错误率、调用错误率、模型调用平均耗时、链路整体耗时、服务请求成功率等)、成本指标功能(tokens消耗等)业务价值:迭代优化价值——可以根据性能、错误指标等数据对智能体、工作流进行多轮迭代与优化  后台逻辑相关特性· 支持开发和测试环境分离部署,支持开发环境资产发布到生产环境业务价值1:保障生产环境稳定,确保正在服务线上客户的生产环境不会因新功能开发或测试而宕机或出错。业务价值2:可以并行开发与协作,开发、运营团队可以同时在各自的环境中进行工作,互不干扰,提升协同效率。· 支持单实例多Agent共享模式和单Agent 多实例独占模式业务价值:优化资源利用,降低成本。共享模式适用于大量轻量级、低并发的Agent,独占模式适用于核心、高并发、高性能要求的Agent,企业可以根据不同Agent的业务重要性、流量特征和性能要求,灵活选择部署模式,实现成本与性能的最佳平衡。· 支持多环境管理,集成开通Serverless运行环境业务价值:极致敏捷与弹性伸缩,提升了开发测试的敏捷性;降低了环境管理成本· 支持与凭据加密服务对接,通过配置凭据保障密钥安全业务价值:杜绝敏感信息泄露,增强安全合规性  二、多模态能力 应用管理· 新增语音交互:单智能体/工作流支持开启语音交互,支持选择不同种类的音色业务价值:满足业务个性化需求,丰富交互形式,让用户体验更流畅· 新增多模态大模型能力:单智能体、工作流-大模型节点支持接入多模态大模型业务价值:新增交互场景,在需要快速获取信息或进行复杂任务处理场景能显著提升用户体验  三、模型管理 模型服务· 支持接入用户自己第三方模型服务业务价值1:增加灵活性,提升用户体验业务价值2:企业可以根据自己的业务选择适合的模型,实现最佳功能匹配 路由策略· 支持配置路由策略业务价值:实现智能负载均衡与成本控制,构建高可用的容灾方案 模型调测· 支持模型调测,对比不同模型的效果业务价值:可以快速了解不同模型在当前任务下的效果,帮助用户进行模型选型  四、数据能力 知识库· 支持接入外部(第三方)知识库业务价值:实现各个系统中的数据贯通,增加架构的灵活性 应用管理· Agent问答支持知识切片溯源,支持配置多个知识库(最多3个)业务价值:构建信任与确保合规,实现答案的可验证与可审计  五、组件能力 提示词· 支持提示词管理,支持提示词效果对比,新增多模态提示词业务价值1:提供提示词统一管理、开发能力,实现高效运维;业务价值2:支持多模态数据,拓宽应用场景 MCP· 支持NPX、UVX方式部署和SSE接口接入服务业务价值:极致简化体验,简化集成复杂度 点击可前往>>华为云Versatile智能体平台 官网
  • [问题求助] 如何申请16卡910B的算力资源
    我想在notebook上微调qwen32B的模型,但是目前最大规格8卡910B无法满足需求,请问怎样可以申请到16卡的算力资源
  • [互动交流] 如何在Linux系统上安装OBS桶?
    如何在Linux系统上安装OBS桶实现数据集上传下载以及分享URL等操作?
  • [技术干货] VLA:具身智能的“神经中枢”,如何打通机器认知与行动的最后一公里?
    VLA:具身智能的“神经中枢”,如何打通机器认知与行动的最后一公里?当机器人听到“请把桌上的红色杯子拿给我”时,它需要瞬间完成环境感知、意图解析、动作规划三重任务——这一看似简单的指令,实则是具身智能(Embodied AI) 落地的终极挑战。而 VLA(Vision-Language-Action Models) 正成为解决这一难题的革命性框架,它将视觉、语言与行动能力熔于一炉,让机器首次真正实现“知行合一”。一、技术实现层:构建“感知→理解→行动”的闭环飞轮传统机器人技术采用模块化堆叠:视觉模块识别物体→自然语言模块解析指令→控制模块生成动作。这种架构存在三大断层:信息衰减:模块间传递数据时丢失关键细节(如杯子的精确位姿);误差累积:视觉定位2mm偏差可能导致抓取失败;响应延迟:多模块串联处理耗时远超人类反射速度(>500ms)。VLA的破局之道:通过端到端Transformer架构,直接将原始像素(Vision)和语言指令(Language)映射为动作参数(Action)。例如处理“拿红色杯子”指令时:视觉编码器实时构建场景的3D语义地图,定位杯子坐标(精度±0.5cm);语言模型解构“拿给我”包含的原子动作:接近→抓握→移动→递送;动作生成器输出关节扭矩序列,同时预测执行风险(如避让障碍物)。突破性案例:谷歌RT-2模型在真实场景的动作成功率提升40%+,关键在感知与执行的联合优化二、能力整合层:统一模型如何克服“行动鸿沟”?具身智能的核心矛盾在于:物理世界的无限复杂性 vs 机器认知的有限性。VLA通过两项革新弥合差距:1. 跨模态对齐:从符号到实体的精准锚定当用户说“红色杯子”时,模型需将语言符号与视觉实体绑定:颜色检测(HSV值过滤干扰反光)材质识别(陶瓷vs塑料影响抓取力度)空间关系(“桌上”排除地面误判)技术支撑:CLIP对比学习使文本-图像嵌入空间对齐误差<3%2. 具身推理引擎:语言指令的物理转化器指令“拿给我”隐含物理约束:抓握策略:杯柄需拇指和食指对捏(避免包裹式抓取遮挡视线)路径规划:移动轨迹避开手部与身体的碰撞人机交互:递送高度匹配人类手臂自然位置(离地70-90cm)行业突破:斯坦福VoxPoser用LLM生成机器人运动代码,实现零编程动作生成三、场景实践:从实验室到真实世界的跨越VLA正催化三大场景的具身智能革命:应用领域传统方案痛点VLA解决方案家庭服务无法理解“清洁洒落的牛奶”视觉定位液体范围→生成吸拭+擦拭动作链医疗手术机械臂需预设千种动作模板听指令“切除2cm肿瘤”实时规划切割深度仓储物流分拣系统依赖固定坐标响应“搬走右侧第三箱货品”自主导航典型案例进化:早期机器人执行“拿杯子”需预设代码200行,如今VLA模型仅凭单次指令:视觉定位:通过多视角3D重建(NeRF技术)克服遮挡触觉校准:电子皮肤反馈力度(陶瓷杯抓取力限0.5-1.2N)防溢策略:动作加速度控制(倾斜角<15°防液体泼洒)四、未来挑战:VLA如何成为具身智能的“终极大脑”?当前仍需突破三大瓶颈:场景泛化:在陌生环境(如布满障碍的厨房)执行长序列任务;物理常识:理解“易碎品轻拿轻放”等抽象约束;实时安全性:10ms级动作中断响应(防止碰撞儿童)。突破方向:仿真训练革命:NVIDIA Omniverse构建百万级物理场景训练集神经符号融合:LLM生成动作逻辑+神经网络微调参数脑机协同:通过EEG信号实时修正动作(杜克大学实验成功率达85%)结语:具身智能追求让机器“像人一样理解并改造世界”,而VLA正在成为实现这一愿景的神经中枢。当视觉识别、语言理解与动作控制不再是割裂的模块,而是同一模型涌现的能力时,我们距离真正自主的智能体已不再遥远——未来十年,每一台接入VLA的机器人,都将成为物理世界的“行动思想家”。
  • [技术干货] VLA:让机器“看懂”世界并行动的革命性技术
    VLA:让机器“看懂”世界并行动的革命性技术VLA(Vision-Language-Action Models,视觉-语言-动作模型) 是人工智能领域的颠覆性范式,它通过统一视觉感知、语言理解与物理动作控制,赋予机器“知行合一”的能力。与传统多模态模型仅实现“看与说”不同,VLA的核心在于构建 “感知-认知-执行”的闭环系统,推动机器人、自动驾驶等领域的智能化跃迁。一、VLA是什么?—— 三位一体的认知革命VLA将三大能力融合于单一架构中:视觉感知:解析摄像头、激光雷达等传感器输入的物理世界信息;语言理解:解读人类自然语言指令(如“把红色积木放进蓝色盒子”);动作生成:将抽象指令转化为具体动作序列(如移动、抓取、放置)。本质突破:打破传统AI“感知”与“行动”的割裂,实现“看懂即会做”的类人智能。二、技术架构:从数据到动作的流水线VLA的运作依赖三层核心技术:层级关键技术功能实例感知层多模态Transformer将图像像素与文本指令对齐为统一表征认知层具身推理引擎理解“避开障碍物取水杯”的空间逻辑执行层运动控制神经网络生成机械臂抓取轨迹与力度参数典型案例:谷歌RT-2模型在真实场景中执行“扔掉垃圾”指令的成功率比前代提升48%。三、应用场景:物理世界的智能革命家庭服务机器人:理解“清洁洒在桌面的咖啡渍”并执行擦拭、回收动作;工业自动化:通过语音指令调整机械臂装配流程(如“将螺丝拧紧三圈”);医疗辅助:根据医生指令精准操作手术器械(“切除左下方2cm肿瘤组织”);自动驾驶:响应“在便利店门口靠边停车”的复杂路况决策。四、关键挑战与突破方向挑战类型具体问题前沿探索感知-动作对齐二维图像到三维动作的映射偏差神经辐射场(NeRF)构建3D环境模型长时序规划多步骤任务中的误差累积分层强化学习(HRL)架构物理仿真差异模拟训练与现实执行的性能鸿沟零样本迁移学习(如Open-X Embodiment)突破性进展:斯坦福VoxPoser模型通过大语言模型生成机器人动作代码,实现无需编程的指令响应五、未来展望:从工具到伙伴的进化随着多模态大模型(如GPT-4V)与神经形态硬件(如Loihi芯片)的发展,VLA将经历三重进化:通用化:单一模型适配千万级场景(Meta的Habitat 3.0仿真平台已支持10万+家庭环境);安全可信:建立物理行动的风险预测机制(如动作因果链追溯);人机共生:实现自然对话式协作(“帮我修水管——好的,需要扳手和密封胶”)。结语:VLA不仅是一项技术,更是人机交互范式的重构。当机器能够真正“理解意图并自主行动”,我们将迎来从“工具执行者”到“智能协作者”的文明级转折。
  • [互动交流] 有哪些好用的具身智能平台?
    寻求一个好用的具身智能平台,可以控制机械臂在真实环境中向人类一样完成物体分拣等操作
  • [技术干货] 具身智能的三大核心技术路径:从感知到行动的闭环革命
    具身智能的三大核心技术路径:从感知到行动的闭环革命具身智能(Embodied AI)被视为人工智能的“下一跳”,其核心在于让AI像人类一样拥有“身体”,通过与物理世界的实时交互学习进化。要实现这一目标,需突破三大技术路径的协同闭环:多模态感知融合、认知决策建模、动作控制与反馈优化。路径一:多模态感知——物理世界的“五感”重建具身智能需通过传感器阵列(视觉、听觉、触觉等)实时解析环境信息。跨模态对齐:将图像、声音、触觉信号统一编码为可理解的时空表征(如通过Transformer融合RGB-D相机与力反馈数据)。情境建模:构建动态3D场景地图(如NeRF技术),实时追踪物体运动轨迹(如目标检测+SLAM)。痛点突破:解决光线遮挡、噪声干扰下的感知鲁棒性问题,如通过自监督学习补偿缺失信息。案例:MIT研发的“触觉手套”可识别20种物体材质,误差率<5%。路径二:认知决策——从数据到意图的“大脑”进化在感知基础上,AI需理解任务目标并生成行动计划:具身推理引擎:结合知识图谱(如ConceptNet)与物理规律模型(如PyBullet仿真引擎),预判动作后果(如“推倒积木塔是否可行?”)。分层任务规划:将复杂指令拆解为原子动作(如“泡茶”→【拿杯子】【倒水】),通过强化学习优化决策树。人机协作意图理解:通过自然语言指令解析人类意图(如LLMs+视觉定位技术)。进展:谷歌RT-2模型将语言指令转化为机器人动作的准确率提升40%。路径三:动作控制——机械系统的“肢体”协调最终需将决策转化为精准的物理动作:仿生驱动设计:采用柔性执行器(如波士顿动力的液压关节)模拟肌肉弹性,适应非结构化环境。实时运动控制:通过模型预测控制(MPC)调整动作轨迹,应对突发干扰(如行走时地面晃动)。触觉反馈闭环:利用电子皮肤(如斯坦福的神经形态触觉芯片)实现微力控制(如捏鸡蛋不破碎)。难点:机械臂抓取不规则物体的成功率仍不足70%,需继续攻克灵巧操作。未来挑战:打破“三大断层”感知-认知断层:环境动态变化导致决策滞后(如突然出现的障碍物);仿真-现实断层:仿真训练无法完全模拟物理摩擦、形变等复杂效应;单机-群体断层:多智能体协作需分布式强化学习框架支持。结论:具身智能的成熟需构建“感知-思考-行动”的闭环飞轮。随着神经形态计算芯片(如Loihi 3)与多模态大模型(如GPT-4o)的进化,物理智能体的规模化落地已进入倒计时——十年内,我们将见证从“云端大脑”到“实体助手”的颠覆性跨越。
总条数:7868 到第
上滑加载中