-
>摘要:六一儿童节,快来训练一款自己的游戏 AI,用代码让马里奥从大反派酷霸王的魔掌里救回桃花公主。 本文分享自华为云社区《[儿童节,和 AI 一起通关 “超级马里奥兄弟”](https://bbs.huaweicloud.com/blogs/357378?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=other&utm_content=content)》,作者:华为云社区精选。 在蘑菇王国,流传着这样一个故事: 某天,操纵着强力魔法的大乌龟酷霸王一族侵略了蘑菇们居住的和平王国。蘑菇一族都被酷霸王变成了岩石、砖块等形状,蘑菇王国即将灭亡。 只有蘑菇王国的桃花公主,才能解开魔法,让蘑菇们苏醒。 然而,她却被大魔王酷霸王所捉住。 为了打倒乌龟一族、救出桃花公主、给蘑菇王国带回和平,水管工马里奥决定站出来,向酷霸王发起挑战。 是的,这就是童年游戏《超级马里奥》的故事。 你是不是仍旧对马里奥这个游戏记忆犹新,是不是仍旧对过关焦头烂额,**六一儿童节,快来训练一款自己的游戏 AI,用代码让马里奥从大反派酷霸王的魔掌里救回桃花公主。** # 当 AI 玩起超级马里奥 基于华为云一站式AI开发平台ModelArts,利用强化学习中的 PPO 算法来玩超级马里奥,对于绝大部分关卡,训练出来的 AI 智能体都可以在 1500 个 episode 内学会过关。 ModelArts 是面向开发者的一站式 AI 平台,支持海量数据预处理及交互式智能标注、大规模分布式训练、自动化模型生成,及端 - 边 - 云模型按需部署能力,可以让 AI 应用开发到商用部署缩短为分钟级别。 就算不懂代码,也可以按照教程案例,通过简单的调参,一步步实现游戏 AI 开发,成为超级马里奥闯关王者。 话不多说,先来看看实际的效果:  超级马里奥游戏 AI 的整体开发流程为:**创建马里奥环境 -> 构建 PPO 算法 -> 训练 -> 推理 -> 可视化效果,目前可以在AI Gallery上免费体验。** AI Gallery 是在 ModelArts 的基础上构建的开发者生态社区, 支持算法、模型、数据集、Notebook 案例和技术文章的共享。 下面,童年回忆杀走起。 # PPO 算法科普 因为这个游戏 AI 是基于 PPO 算法来训练的,所以先简单科普一下强化学习算法。PPO 算法有两种主要形式:PPO-Penalty 和 PPO-Clip (PPO2)。在这里,我们讨论 PPO-Clip(OpenAI 使用的主要形式)。 PPO 的主要特点如下: - PPO 属于 on-policy 算法 - PPO 同时适用于离散和连续的动作空间 - 损失函数 PPO-Clip 算法最精髓的地方就是加入了一项比例用以描绘新老策略的差异,通过超参数 ϵ 限制策略的更新步长:  - 更新策略:  - 探索策略 PPO 采用随机探索策略。 - 优势函数 表示在状态 s 下采取动作 a,相较于其他动作有多少优势,如果 > 0, 则当前动作比平均动作好,反之,则差  算法主要流程大致如下:  看起来有点复杂,不用担心,**即便你不懂这些算法,有了华为云 ModelArts,可以跟着下面的步骤轻松实现超级马里奥游戏 AI 的强化学习。** # 开发步骤 本案例运行环境为 Pytorch-1.0.0,且需使用 GPU 运行,开始之前一定要选择对应的硬件规格。在 ModelArts Jupyter 中,只要点击代码前面的箭头,就能自动运行。  ## 1. 程序初始化 ### 第 1 步:安装基础依赖 ``` !pip install -U pip !pip install gym==0.19.0 !pip install tqdm==4.48.0 !pip install nes-py==8.1.0 !pip install gym-super-mario-bros==7.3.2 ``` ### 第 2 步:导入相关的库 ``` import os import shutil import subprocess as sp from collections import deque import numpy as np import torch import torch.nn as nn import torch.nn.functional as F import torch.multiprocessing as _mp from torch.distributions import Categorical import torch.multiprocessing as mp from nes_py.wrappers import JoypadSpace import gym_super_mario_bros from gym.spaces import Box from gym import Wrapper from gym_super_mario_bros.actions import SIMPLE_MOVEMENT, COMPLEX_MOVEMENT, RIGHT_ONLY import cv2 import matplotlib.pyplot as plt from IPython import display import moxing as mox ``` ## 2. 训练参数初始化 此处划重点,该部分参数可以自己调整,以训练出更好的效果。 ``` opt={ "world": 1, # 可选大关:1,2,3,4,5,6,7,8 "stage": 1, # 可选小关:1,2,3,4 "action_type": "simple", # 动作类别:"simple","right_only", "complex" 'lr': 1e-4, # 建议学习率:1e-3,1e-4, 1e-5,7e-5 'gamma': 0.9, # 奖励折扣 'tau': 1.0, # GAE参数 'beta': 0.01, # 熵系数 'epsilon': 0.2, # PPO的Clip系数 'batch_size': 16, # 经验回放的batch_size 'max_episode':10, # 最大训练局数 'num_epochs': 10, # 每条经验回放次数 "num_local_steps": 512, # 每局的最大步数 "num_processes": 8, # 训练进程数,一般等于训练机核心数 "save_interval": 5, # 每{}局保存一次模型 "log_path": "./log", # 日志保存路径 "saved_path": "./model", # 训练模型保存路径 "pretrain_model": True, # 是否加载预训练模型,目前只提供1-1关卡的预训练模型,其他需要从零开始训练 "episode":5 } ``` 如果你想选择其他关卡时,记得调整参数 world 和 stage ,这里默认的是第一关。 ## 3. 创建环境 **结束标志:** - 胜利:mario 到达本关终点 - 失败:mario 受到敌人的伤害、坠入悬崖或者时间用完 **奖励函数:** - 得分:收集金币、踩扁敌人、结束时夺旗 - 扣分:受到敌人伤害、掉落悬崖、结束时未夺旗 ``` #创建环境 def create_train_env(world, stage, actions, output_path=None): # 创建基础环境 env = gym_super_mario_bros.make("SuperMarioBros-{}-{}-v0".format(world, stage)) env = JoypadSpace(env, actions) # 对环境自定义 env = CustomReward(env, world, stage, monitor=None) env = CustomSkipFrame(env) return env # 对原始环境进行修改,以获得更好的训练效果 class CustomReward(Wrapper): def __init__(self, env=None, world=None, stage=None, monitor=None): super(CustomReward, self).__init__(env) self.observation_space = Box(low=0, high=255, shape=(1, 84, 84)) self.curr_score = 0 self.current_x = 40 self.world = world self.stage = stage if monitor: self.monitor = monitor else: self.monitor = None def step(self, action): state, reward, done, info = self.env.step(action) if self.monitor: self.monitor.record(state) state = process_frame(state) reward += (info["score"] - self.curr_score) / 40. self.curr_score = info["score"] if done: if info["flag_get"]: reward += 50 else: reward -= 50 if self.world == 7 and self.stage == 4: if (506 = info["x_pos"] = 832 and info["y_pos"] > 127) or ( 832 info["x_pos"] = 1064 and info["y_pos"] 80) or ( 1113 info["x_pos"] = 1464 and info["y_pos"] 191) or ( 1579 info["x_pos"] = 1943 and info["y_pos"] 191) or ( 1946 info["x_pos"] = 1964 and info["y_pos"] >= 191) or ( 1984 info["x_pos"] = 2060 and (info["y_pos"] >= 191 or info["y_pos"] 127)) or ( 2114 info["x_pos"] 2440 and info["y_pos"] 191) or info["x_pos"] self.current_x - 500: reward -= 50 done = True if self.world == 4 and self.stage == 4: if (info["x_pos"] = 1500 and info["y_pos"] 127) or ( 1588 = info["x_pos"] 2380 and info["y_pos"] >= 127): reward = -50 done = True self.current_x = info["x_pos"] return state, reward / 10., done, info def reset(self): self.curr_score = 0 self.current_x = 40 return process_frame(self.env.reset()) class MultipleEnvironments: def __init__(self, world, stage, action_type, num_envs, output_path=None): self.agent_conns, self.env_conns = zip(*[mp.Pipe() for _ in range(num_envs)]) if action_type == "right_only": actions = RIGHT_ONLY elif action_type == "simple": actions = SIMPLE_MOVEMENT else: actions = COMPLEX_MOVEMENT self.envs = [create_train_env(world, stage, actions, output_path=output_path) for _ in range(num_envs)] self.num_states = self.envs[0].observation_space.shape[0] self.num_actions = len(actions) for index in range(num_envs): process = mp.Process(target=self.run, args=(index,)) process.start() self.env_conns[index].close() def run(self, index): self.agent_conns[index].close() while True: request, action = self.env_conns[index].recv() if request == "step": self.env_conns[index].send(self.envs[index].step(action.item())) elif request == "reset": self.env_conns[index].send(self.envs[index].reset()) else: raise NotImplementedError def process_frame(frame): if frame is not None: frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) frame = cv2.resize(frame, (84, 84))[None, :, :] / 255. return frame else: return np.zeros((1, 84, 84)) class CustomSkipFrame(Wrapper): def __init__(self, env, skip=4): super(CustomSkipFrame, self).__init__(env) self.observation_space = Box(low=0, high=255, shape=(skip, 84, 84)) self.skip = skip self.states = np.zeros((skip, 84, 84), dtype=np.float32) def step(self, action): total_reward = 0 last_states = [] for i in range(self.skip): state, reward, done, info = self.env.step(action) total_reward += reward if i >= self.skip / 2: last_states.append(state) if done: self.reset() return self.states[None, :, :, :].astype(np.float32), total_reward, done, info max_state = np.max(np.concatenate(last_states, 0), 0) self.states[:-1] = self.states[1:] self.states[-1] = max_state return self.states[None, :, :, :].astype(np.float32), total_reward, done, info def reset(self): state = self.env.reset() self.states = np.concatenate([state for _ in range(self.skip)], 0) return self.states[None, :, :, :].astype(np.float32) ``` ## 4. 定义神经网络 神经网络结构包含四层卷积网络和一层全连接网络,提取的特征输入 critic 层和 actor 层,分别输出 value 值和动作概率分布。 ``` class Net(nn.Module): def __init__(self, num_inputs, num_actions): super(Net, self).__init__() self.conv1 = nn.Conv2d(num_inputs, 32, 3, stride=2, padding=1) self.conv2 = nn.Conv2d(32, 32, 3, stride=2, padding=1) self.conv3 = nn.Conv2d(32, 32, 3, stride=2, padding=1) self.conv4 = nn.Conv2d(32, 32, 3, stride=2, padding=1) self.linear = nn.Linear(32 * 6 * 6, 512) self.critic_linear = nn.Linear(512, 1) self.actor_linear = nn.Linear(512, num_actions) self._initialize_weights() def _initialize_weights(self): for module in self.modules(): if isinstance(module, nn.Conv2d) or isinstance(module, nn.Linear): nn.init.orthogonal_(module.weight, nn.init.calculate_gain('relu')) nn.init.constant_(module.bias, 0) def forward(self, x): x = F.relu(self.conv1(x)) x = F.relu(self.conv2(x)) x = F.relu(self.conv3(x)) x = F.relu(self.conv4(x)) x = self.linear(x.view(x.size(0), -1)) return self.actor_linear(x), self.critic_linear(x) ``` ## 5. 定义 PPO 算法 ``` def evaluation(opt, global_model, num_states, num_actions,curr_episode): print('start evalution !') torch.manual_seed(123) if opt['action_type'] == "right": actions = RIGHT_ONLY elif opt['action_type'] == "simple": actions = SIMPLE_MOVEMENT else: actions = COMPLEX_MOVEMENT env = create_train_env(opt['world'], opt['stage'], actions) local_model = Net(num_states, num_actions) if torch.cuda.is_available(): local_model.cuda() local_model.eval() state = torch.from_numpy(env.reset()) if torch.cuda.is_available(): state = state.cuda() plt.figure(figsize=(10,10)) img = plt.imshow(env.render(mode='rgb_array')) done=False local_model.load_state_dict(global_model.state_dict()) #加载网络参数\ while not done: if torch.cuda.is_available(): state = state.cuda() logits, value = local_model(state) policy = F.softmax(logits, dim=1) action = torch.argmax(policy).item() state, reward, done, info = env.step(action) state = torch.from_numpy(state) img.set_data(env.render(mode='rgb_array')) # just update the data display.display(plt.gcf()) display.clear_output(wait=True) if info["flag_get"]: print("flag getted in episode:{}!".format(curr_episode)) torch.save(local_model.state_dict(), "{}/ppo_super_mario_bros_{}_{}_{}".format(opt['saved_path'], opt['world'], opt['stage'],curr_episode)) opt.update({'episode':curr_episode}) env.close() return True return False def train(opt): #判断cuda是否可用 if torch.cuda.is_available(): torch.cuda.manual_seed(123) else: torch.manual_seed(123) if os.path.isdir(opt['log_path']): shutil.rmtree(opt['log_path']) os.makedirs(opt['log_path']) if not os.path.isdir(opt['saved_path']): os.makedirs(opt['saved_path']) mp = _mp.get_context("spawn") #创建环境 envs = MultipleEnvironments(opt['world'], opt['stage'], opt['action_type'], opt['num_processes']) #创建模型 model = Net(envs.num_states, envs.num_actions) if opt['pretrain_model']: print('加载预训练模型') if not os.path.exists("ppo_super_mario_bros_1_1_0"): mox.file.copy_parallel( "obs://modelarts-labs-bj4/course/modelarts/zjc_team/reinforcement_learning/ppo_mario/ppo_super_mario_bros_1_1_0", "ppo_super_mario_bros_1_1_0") if torch.cuda.is_available(): model.load_state_dict(torch.load("ppo_super_mario_bros_1_1_0")) model.cuda() else: model.load_state_dict(torch.load("ppo_super_mario_bros_1_1_0",torch.device('cpu'))) else: model.cuda() model.share_memory() optimizer = torch.optim.Adam(model.parameters(), lr=opt['lr']) #环境重置 [agent_conn.send(("reset", None)) for agent_conn in envs.agent_conns] #接收当前状态 curr_states = [agent_conn.recv() for agent_conn in envs.agent_conns] curr_states = torch.from_numpy(np.concatenate(curr_states, 0)) if torch.cuda.is_available(): curr_states = curr_states.cuda() curr_episode = 0 #在最大局数内训练 while curr_episode0 and curr_episode > 0: torch.save(model.state_dict(), "{}/ppo_super_mario_bros_{}_{}_{}".format(opt['saved_path'], opt['world'], opt['stage'], curr_episode)) curr_episode += 1 old_log_policies = [] actions = [] values = [] states = [] rewards = [] dones = [] #一局内最大步数 for _ in range(opt['num_local_steps']): states.append(curr_states) logits, value = model(curr_states) values.append(value.squeeze()) policy = F.softmax(logits, dim=1) old_m = Categorical(policy) action = old_m.sample() actions.append(action) old_log_policy = old_m.log_prob(action) old_log_policies.append(old_log_policy) #执行action if torch.cuda.is_available(): [agent_conn.send(("step", act)) for agent_conn, act in zip(envs.agent_conns, action.cpu())] else: [agent_conn.send(("step", act)) for agent_conn, act in zip(envs.agent_conns, action)] state, reward, done, info = zip(*[agent_conn.recv() for agent_conn in envs.agent_conns]) state = torch.from_numpy(np.concatenate(state, 0)) if torch.cuda.is_available(): state = state.cuda() reward = torch.cuda.FloatTensor(reward) done = torch.cuda.FloatTensor(done) else: reward = torch.FloatTensor(reward) done = torch.FloatTensor(done) rewards.append(reward) dones.append(done) curr_states = state _, next_value, = model(curr_states) next_value = next_value.squeeze() old_log_policies = torch.cat(old_log_policies).detach() actions = torch.cat(actions) values = torch.cat(values).detach() states = torch.cat(states) gae = 0 R = [] #gae计算 for value, reward, done in list(zip(values, rewards, dones))[::-1]: gae = gae * opt['gamma'] * opt['tau'] gae = gae + reward + opt['gamma'] * next_value.detach() * (1 - done) - value.detach() next_value = value R.append(gae + value) R = R[::-1] R = torch.cat(R).detach() advantages = R - values #策略更新 for i in range(opt['num_epochs']): indice = torch.randperm(opt['num_local_steps'] * opt['num_processes']) for j in range(opt['batch_size']): batch_indices = indice[ int(j * (opt['num_local_steps'] * opt['num_processes'] / opt['batch_size'])): int((j + 1) * ( opt['num_local_steps'] * opt['num_processes'] / opt['batch_size']))] logits, value = model(states[batch_indices]) new_policy = F.softmax(logits, dim=1) new_m = Categorical(new_policy) new_log_policy = new_m.log_prob(actions[batch_indices]) ratio = torch.exp(new_log_policy - old_log_policies[batch_indices]) actor_loss = -torch.mean(torch.min(ratio * advantages[batch_indices], torch.clamp(ratio, 1.0 - opt['epsilon'], 1.0 + opt['epsilon']) * advantages[ batch_indices])) critic_loss = F.smooth_l1_loss(R[batch_indices], value.squeeze()) entropy_loss = torch.mean(new_m.entropy()) #损失函数包含三个部分:actor损失,critic损失,和动作entropy损失 total_loss = actor_loss + critic_loss - opt['beta'] * entropy_loss optimizer.zero_grad() total_loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5) optimizer.step() print("Episode: {}. Total loss: {}".format(curr_episode, total_loss)) finish=False for i in range(opt["num_processes"]): if info[i]["flag_get"]: finish=evaluation(opt, model,envs.num_states, envs.num_actions,curr_episode) if finish: break if finish: break ``` ## 6. 训练模型 训练 10 Episode,耗时约 5 分钟 ``` train(opt) ``` ## 7. 使用模型推理游戏 定义推理函数 ``` def infer(opt): if torch.cuda.is_available(): torch.cuda.manual_seed(123) else: torch.manual_seed(123) if opt['action_type'] == "right": actions = RIGHT_ONLY elif opt['action_type'] == "simple": actions = SIMPLE_MOVEMENT else: actions = COMPLEX_MOVEMENT env = create_train_env(opt['world'], opt['stage'], actions) model = Net(env.observation_space.shape[0], len(actions)) if torch.cuda.is_available(): model.load_state_dict(torch.load("{}/ppo_super_mario_bros_{}_{}_{}".format(opt['saved_path'],opt['world'], opt['stage'],opt['episode']))) model.cuda() else: model.load_state_dict(torch.load("{}/ppo_super_mario_bros_{}_{}_{}".format(opt['saved_path'], opt['world'], opt['stage'],opt['episode']), map_location=torch.device('cpu'))) model.eval() state = torch.from_numpy(env.reset()) plt.figure(figsize=(10,10)) img = plt.imshow(env.render(mode='rgb_array')) while True: if torch.cuda.is_available(): state = state.cuda() logits, value = model(state) policy = F.softmax(logits, dim=1) action = torch.argmax(policy).item() state, reward, done, info = env.step(action) state = torch.from_numpy(state) img.set_data(env.render(mode='rgb_array')) # just update the data display.display(plt.gcf()) display.clear_output(wait=True) if info["flag_get"]: print("World {} stage {} completed".format(opt['world'], opt['stage'])) break if done and info["flag_get"] is False: print('Game Failed') break infer(opt) World 1 stage 1 completed ```  # 最后 六一儿童节,快来华为云 AI Gallery 上体验 AI 闯关超级马里奥,无需考虑计算资源,环境的搭建,在 ModelArts 里跟着运行代码,[点击链接](https://developer.huaweicloud.com/develop/aigallery/usecase/detail?id=3390253c-a00f-4c2a-92b6-08384ec31693)在ModelArts里运行简单几行代码,手把手带你5分钟速成游戏王。
-
5月26日,2022中国国际大数据产业博览会(以下简称“数博会”)线上正式开幕。数博会是全球首个以大数据为主题的博览会,由国家发展和改革委员会、工业和信息化部、国家互联网信息办公室和贵州省人民政府共同主办,是助力全球大数据技术应用和产业发展的重要平台。大会开幕式上,华为高级副总裁、华为云CEO张平安发表主题演讲。聚焦大会主题“抢数字新机,享数字价值”,他在演讲中主张,发挥数据的集聚规模效应,以数智融合重塑数据价值,围绕“一切皆服务”帮助更多企业容易上云、方便上云、用好云:让数据资源在集聚中实现效益最优“东数西算”是把握数字经济发展机遇期、构建算力新格局的重要举措。为加快推动“东数西算”建设,全力打造“中国数谷”,华为云已在贵州布局全球总部和最大的云数据中心,持续发挥数据资源集聚的规模效应,提升资源使用效率。以“数智融合”重塑数据价值数字时代,数据是千行百业重要的生产要素和资产,目前数据的价值仍未充分得以利用,实现高效的数据治理、促进“数智融合”仍是业界难题。华为云着力打造“数智融合”云平台,打通数据治理生产线、AI开发生产线,构建统一的开发环境、统一的元数据管理、统一的存储,让数据开发效率由“周”级提升到“小时”级,大幅降低数据存储成本,让数据和AI开发进入现代化的生产阶段。一切皆服务,让千行百业真正用好云为帮助千行百业的客户容易上云、方便上云、用好云,华为云提出“一切皆服务”,把基础设施、技术以及经验云化、服务化。例如,不少企业缺乏专家和训练数据,未能有效地将AI能力与业务场景结合,因此难以快速开发出AI应用;为此华为云已将AI、大数据,音视频等核心技术云化,集成海量开发工具,让所有客户随取随用,高效开发。同时,华为云持续深耕政府、金融、工业等行业,将华为与伙伴、客户的合作创新以及数字化转型经验沉淀成为云服务,已陆续开放了50多个应用场景,提供超过2万个API服务,让更多企业就不必重复“造轮子”,通过云服务即获得全行业最优秀的数字化经验。本届数博会上,华为云还斩获了多项大奖,涵盖从数据库、数据湖、到数据和AI融合分析的技术创新,以及运用湖仓库AI技术支持的梦饷集团创新实践入选“十佳大数据案例”,充分证明了业界对华为云数据领域技术创新的认可:在数博会的重头戏——“数博发布”特色活动中,华为云GaussDB(for openGauss)分布式数据库斩获领先科技成果“新产品”奖。该奖项是数博会的最高奖项,同时也是唯一以大数据为主题的社会科技奖励,其专业性、权威性、引领性获业界一致认可。 华为云GaussDB(for openGauss) 基于华为主导的开放生态openGauss而打造,是主打政企核心业务负载的金融级分布式数据库旗舰产品。 例如,在工商银行核心交易系统分布式改造过程中,华为云GaussDB提供了完备的一站式数据迁移解决方案,实现高可用、性能线性扩展、弹性部署三大核心价值,助力客户数据库选型安心、迁移放心、管理省心,让核心交易系统可靠性得到了大幅度提升,持续满足未来长期业务发展需求。 华为云数智融合平台为企业在云上打造了统一的数据底座,把原本散落在各个部门和组织的数据统一汇聚到数据湖中,省去开发者关注各种底层的琐碎文件管理,以及大量、复杂的分析引擎、AI引擎和管理运维工作,支持开发者在集成的开发平台上,便捷地使用最新的算法模型挖掘各种数据的潜在价值。 例如,平台助力T3出行将多套集群架构优化至湖仓一体的存算分离架构,同时支撑数据分析的BI和数据智能的AI场景,不仅使TCO降低20%以上,更解决了出行场景下“长尾支付”系统更新慢的难题,数据处理效率提升150%。数智融合,让企业像管理代码一样管理数据,让机器学习的效率更高,提升乘客的安全体验。华为云FusionInsight MRS IoTDB聚焦工业物联网领域的工业复杂时序数据的处理,解决通用数据库在超大规模复杂时序场景的功能短板和性能瓶颈,形成跨越端、边、云的工业物联网大数据的利器。 目前,清华大学和华为云已开展合作,以Apache IoTDB开源组件为基础,持续探索新型的、基于开源社区的“产、学、研”合作模式,加快在华为云FusionInsight MRS云原生数据湖服务中完成IoTDB商用版本开发和集成,进一步完善MRS“三湖一集市”能力,为工业海量时序数据分析提供企业级的时序数据库。IoTDB相关技术已在交通、制造等众多工业级时序数据分析应用中落地。 作为“新电商”领域创新者,梦饷集团全面拥抱云、大数据、AI技术,与华为云合作数据创新,让200万“宝妈”不需要投入成本、无需复杂的数字技术背景,即可利用碎片时间进行数字圈层电商营销。以数据智能进行业务创新和社会价值创造,该案例也入选联合国可持续发展目标(SDGs)最佳案例。在数智融合实践中,梦饷集团实现了TCO下降30%,实时分析能力提升50%。其中,华为云DWS提供涵盖T+1批量分析、流式分析、小微实时分析、IoT分析、交互式分析以及复杂高维业务分析等;华为数仓技术提供了100PB级数据容量,以超大集群、混合负载的关键能力,保障多租户、高并发场景可为用户输出持续稳定的SLA,让梦饷集团轻松应对电商高并发业务挑战。基于超过10年的数据领域研发与投入,华为云以成熟的全生命周期数据治理能力,持续帮助电商、游戏、金融、保险、物流、零售等行业客户实现业务智能,释放企业数据价值。围绕“一切皆服务”,华为云面携手客户、合作伙伴和开发者持续创新,帮助千行百业的客户容易上云、方便上云、用好云。
-
文章来源于当交通遇上机器学习 ,作者CY1.文章信息论文链接:https://www.mdpi.com/2071-1050/14/9/4930/htm2.摘要针对森林火灾图像中小目标、类火目标和类烟目标的检测,以及不同自然光下的火灾检测,提出了一种改进的Fire-YOLO深度学习算法。Fire-YOLO检测模型从三维扩展了特征提取网络,增强了火灾小目标识别的特征传播,提高了网络性能,减少了模型参数。进一步,通过特征金字塔的提升,得到了性能最好的预测框。与最先进的目标检测网络相比,Fire-YOLO取得了优异的结果,尤其是在火灾和烟雾的小目标检测方面。总体而言,Fire-YOLO检测模型可以有效地处理小火源目标、类火和类烟目标的检测。当输入图像尺寸为416 × 416分辨率时,平均检测时间为0.04 s /帧,可以提供实时的森林火灾检测。此外,文章提出的算法也可以应用于其他复杂情况下的小目标检测。3.简介火灾探测对于保护森林资源、保护人民生命财产至关重要。近年来,随着火灾图像探测成为研究热点,图像探测具有探测时间早、精度高、系统安装灵活、能有效探测大空间复杂建筑结构火灾等优点。一类方法基于火灾发生时的颜色识别,但基于颜色的方法对亮度和阴影非常敏感。因此,这些方法产生的假警报数量很高。随着机器学习的发展,深度学习技术已广泛应用于检测。有学者提出了一种使用微调卷积神经网络(CNN)的早期火灾探测框架,但该模型具有较高的计算成本。有的学者使用深度融合CNN进行烟雾探测,它结合了注意机制、特征级和决策级融合模块。然而,仍有一些小目标未能实现。有的学者使用了一种基于区域的快速卷积神经网络(R-CNN),根据空间特征检测可疑火灾区域(SRoF)和非火灾区域。这可以通过减少错误探测成功地提高火灾探测精度,但探测速度相对较慢。有的学者提出了一种基于YOLO-V3和YOLO-V4的森林烟雾检测算法。与YOLO-V4相比,YOLO-V3的模型更小,更易于部署。在此基础上,文章选择了YOLO-V3模型作为整体算法,并对其进行了改进。提出了对YOLO-V3算法的改进。网络中加入了空心卷积和DenseNet,提高了火灾早期小规模火焰的探测效果。然而,方法存在火焰定位不准确和屏蔽性能差的问题。I-YOLOv3-tiny模型通过网络结构优化、多尺度融合和K-均值聚类来提高检测精度,但检测速度有待提高。通过提高特征图的分辨率,它减少了火灾探测中的误差,但由于计算量的增加,相应的处理时间也增加了。将分类模型和目标检测模型结合用于火灾探测的方法降低了计算成本,提高了探测精度。尽管如此,它不适用于火灾早期小目标的探测场景。有的学者通过将原始网络结构中的两步降采样卷积网络替换为图像双分割和双线性上采样网络,扩大了小目标的特征,提高了小目标的检测精度。虽然这会增加参数的数量,但计算成本也会增加。对于具有实时性要求的火灾探测,仍需进一步改进。这些问题给火灾场景中小目标的检测带来了巨大的挑战。4.模型A. YOLO-V3YOLO- v3是由YOLO和YOLOV2网络演化而来的对象检测模型。与Faster R-CNN相比,YOLO- v3是单级检测算法,这意味着YOLO网络不需要Regional Proposal network (RPN),而是直接检测图像中的目标。这样既考虑了检测速度和检测精度,又减小了模型参数的尺寸。YOLO-V3对每个类别独立使用逻辑回归,取代了DarkENT-19到DarkENT-53的特征提取网络。YOLO-V3几乎与其他目标检测算法一样精确,但速度至少是后者的两倍。YOLO-V3的特征提取网络为Darknet-53。Darknet-53通过不断地使用卷积、标准化、池化等操作,提取输入到YOLO-V3网络的火灾图像的特征,并通过卷积不断地对火灾图像进行特征提取。这种方法广泛应用于其他各种网络模型中,ResNet也通过增加网络的深度来提高网络的精度。虽然可以同时缩放两个或三个维度,但由于深度和宽度之间有一定的关系,需要进行复杂的手动调整,也就是说只能调整深度和宽度才能达到更好的精度。目前,YOLO-V3模型在火灾探测中并未得到广泛应用。B.Fire-YOLOFire-YOLO是一种单阶段检测模型。FireYOLO用于火灾探测的步骤如下所示。首先,网络输入火灾图像分为S×S网格,和检测在每个探测单元格:是否有火焰或者烟雾的中心目标是发现落在S2的网格,网格负责检测目标被检测出来。然后,每个网格预测3个边界框,并给出这些边界框的置信度。置信计算的定义如下。当目标落在网格中时Pγ = 1,否则Pγ = 0。IoU表示预测边界框与真实边界框的重合。置信度反映了网格中是否存在对象以及包含对象时预测边界框的准确性。当多个包围盒同时检测到同一目标时,YOLO网络将使用非最大抑制(Non-Maximum Suppression, NMS)方法选择最佳包围盒。利用卷积神经网络对视频中的火情和烟雾进行分类来检测火情,具有良好的准确率。文章提出的Fire-YOLO模型从深度、宽度和分辨率三个维度考虑,实现了更加均衡的网络架构。Fire-YOLO火灾探测步骤如下图所示。将输入图像划分为S×S网格,每个网格预测三个边界框和置信度分数。然后,使用非最大值抑制方法选择最佳边界框。Effentnet的提出为设计一种标准化的卷积神经网络尺度方法提供了可能。通过平衡网络深度、宽度和分辨率这三个维度,可以在深度、宽度和分辨率这三个维度上实现更均衡的网络架构,而无需复杂的人工调整。由于火灾数据集中大量的检测对象为小火焰和烟雾,这种简单高效的复合尺度变换方法相对于其他的一维尺度变换方法可以进一步提高火灾的检测精度,并能充分节约计算资源。最终,文章使用的改进后的Effentnet比精度相同的卷积神经网络速度更快,参数更少,模型更小,具有明显的优势。提出的Fire-YOLO火灾探测模型网络结构如下图所示。与YOLO-V3中特征提取网络Darknet53中使用的残块不同,Fire-YOLO的特征提取网络使用了一个移动倒瓶颈卷积(MBConv),该卷积由深度卷积和挤压-激活网络(SENet)组成。MBConv块的结构,最重要的是,一个1×1卷积内核用于增加图像的维数,接下来通过切除卷积和SENet反过来,最后用1×1卷积内核来减少图像的维数输出。输入图像经过特征提取网络并上采样后,得到对应的特征图,即图像对应的向量特征矩阵。为了获得小目标的高层特征信息,特征图将经过卷积集处理,卷积集由5个卷积层组成,卷积核交替为1 × 1和3 × 3。然后利用池化层将高维向量扁平化为一维向量,由激活函数进行处理。将这些向量输入到激活函数中,得到相应的分类结果,并选择最有可能的结果作为特征提取网络输出。针对Darknet-53特征提取网络在深度、宽度和分辨率三个维度平衡方面的性能缺陷,文章在文章提出的fire数据集上使用改进的Effecentnet特征提取网络,弥补了Darknet-53在小目标检测方面的性能不足,提高了小目标检测的特征提取能力。对于输入的小目标图像,增强了小目标特征的学习能力,提高了小目标特征提取网络的性能。为了更好地处理小目标图像,Fire-YOLO模型首先将输入图像缩放到416 × 416像素,然后使用Effecentnet从图像中提取特征。经过多层的深度可分卷积、全局平均池化、特征压缩和特征扩展,对深度可分卷积学习到的特征映射进行上采样。通过特征金字塔处理得到不同尺度的预测框。文章提出的Fire-YOLO模型预测了13 × 13、26 × 26、52 × 52三种不同尺度的边界盒。用于小目标检测的深度可分离卷积结合了逐条通道卷积和逐级点卷积两种级别,提取不同粒度的小目标特征。深度可分卷积的结构如下图所示。通过比较YOLO-V3中使用的Darknet-53特征提取网络、快速R-CNN中使用的RPN目标建议网络和Fire YOLO中使用的深度可分离卷积,发现深度可分离卷积在计算复杂度方面具有优异的性能。这种卷积结构加快了模型的训练速度,提高了模型的检测精度。在火灾探测模型的实际应用中,可以加快网络的处理速度,如果计算量较小,可以达到实时图像处理的目的,从而实现火灾危险的实时探测。同时,该模型的硬件要求也降低了,以便于部署。SENet主要由两个阶段组成。第一个阶段是挤压阶段。第二个阶段是激发阶段。在获得挤压的矢量后,使用完全连接的层,并预测每个通道的重要性。随后,将其应用于与初始特征映射相对应的信道,以便小目标的特征信息将被赋予更高的优先级。SENet的结构如下图所示。在深度学习网络模型中,激活函数是一个连续可导的非线性函数,可以拟合非线性关系。激活函数及其导数的形式比较简单,可以加快网络的学习速度。正确使用激活函数对模型的训练和模型对目标预测的准确性都具有重要意义。活化函数的导数不宜过大或过小,最好稳定在1左右。文章提出的模型使用了Swish激活函数,其表达式为:其中β是常数或可训练参数。Swish具有无上界、无下界、光滑、非单调的特点。Swish在深度模式上比ReLU要好。乙状结肠的饱和函数很容易导致梯度的消失,借鉴ReLU的影响,当它是非常大的,它将方法,但当x→∞,函数的一般趋势比ReLU ReLU相似但更复杂。Swish函数可以看作是一个介于线性函数和ReLU函数之间的平滑函数。C. 性能指标文章利用训练后的Fire-YOLO模型对测试图像进行一系列实验,验证算法的性能。评价神经网络模型有效性的相关指标有:precision, recall, F1, AP值。在二元分类问题中,根据真类别和预测类别的组合,样本可分为四种类型:真阳性(TP)、假阳性(FP)、真阴性(TN)和假阴性(FN)。分类结果的混淆矩阵如下表所示。其余指标的公式根据混淆矩阵计算如下:5.实验分析本节介绍训练网络的实验环境、数据集、模型效果评价指标以及实验结果分析。通过一系列不同模型的对比实验,分析了文章提出的新模型的优越性。实验过程中使用了火数据集和小目标数据集。通过fire数据集对目标检测网络的准确性进行了验证和评估,在不同光照条件、类火烟雾目标等复杂环境下具有良好的检测效果;在小目标火力数据集上验证了该检测方法。结果证实,Fire-YOLO更容易检测到较小的目标。Fire-YOLO检测模型接收416 × 416像素图像作为输入,由于GPU性能限制,批处理大小设为8,每个模型训练100 epoch,初始学习速率为10−3,50 epoch后除以10。A. 数据采集实验中使用的数据集是通过采集消防公益平台上的消防图片来构建的。将fire数据集和小目标数据集分别划分为训练集、验证集和测试集,以便在相同的实验设置下对不同的模型进行训练。第一个数据集为火焰数据集,文章使用的图像数据是公共网站上收集的火灾和烟雾图像。这19819张原始图像包括不同天气和光线线下的火焰和烟雾。在对以上数据集图像进行编号后,使用LabelImg工具进行手动标记,包括绘制边框和分类类别。考虑到标签与数据的对应关系,为保证数据集分布均匀,将数据集按70%、20%、10%的比例随机分为训练集、验证集和测试集。为了保证实验环境相同,最终数据集以PASCAL VOC数据集格式存储。为了防止神经网络中过拟合,对于像素区域不清晰的阳性样本不进行标记。完成的数据集如下表所示。第二个数据集为小目标检测数据集,文章自制了370张图像的数据集。数据集的内容都是包含小目标的火焰和烟雾。通过将250 × 250像素的火焰图像嵌入到1850 × 1850像素的图像中,可以使被探测目标在图像中的面积非常小。最后使用LabelImg工具手工标注小目标。B. 算法的比较分析为了验证模型的性能,文章使用火焰和烟雾图像作为训练集。将所提出的模型与YOLO-V3和Faster R-CNN检测方法进行了比较。三种模型在试验过程中的P-R曲线如图5所示。准确率、召回率、F1评分和mAP值如下表所示。基于以上结果,文章提出的Fire-YOLO在检测性能上优于YOLO-V3和Faster R-CNN。Fire-YOLO模型的精度为0.915,F1的值为0.73,mAP的值为0.802,高于其他两个模型,体现了该模型的优越性。同时Fire-YOLO降低了计算成本,节约了资源,更有利于社会的可持续发展。C. 小目标的检测性能在火灾探测过程中,由于摄像机离火源太远,实际的火源位置在捕获的图像中只占很小的区域,这将导致网络模型对火焰和烟雾的探测非常差。通过比较三种不同的目标检测模型在小目标火灾数据集上的准确率、召回率和mAP,可以得出文章提出的Fire-YOLO模型对非常小的目标对象的检测效率优于Faster R-CNN和未改进的YOLO-V3网络。训练于射击小目标数据集的Fire-YOLO对待检测小目标图像在深度、宽度和分辨率三个维度上进行自适应调整,增强了信息之间的交互作用。从而增强了Fire-YOLO提取小目标特征的能力,提高了小目标物体的检测精度。下表给出了三种模型方法对小目标射击数据集评价指标的具体结果。三种不同模型对小目标火力数据集的检测效率差异较大。文章提出的Fire-YOLO模型的准确率和召回率比其他模型更显著。准确率可达75.48%,可实现对小目标的检测。森林火灾的早期及时发现可以大大减少对生态环境的破坏,减少火灾造成的经济损失,促进生态环境的可持续发展。训练后Fire-YOLO网络模型具有良好的火力目标探测效率。文章使用Fire-YOLO模型来检测非常小的火力目标,并将检测结果图形化显示。较小的射击目标是小目标射击数据集中验证数据集中的所有图像。对Fire-YOLO进行了30多个验证插图的验证,最终的图像检测结果如下图所示。Fire-YOLO可以检测到图片中所有的火和烟,而YOLO-V3和Faster R-CNN在检测结果中只能检测到图像中的部分目标。D. 类火和类烟目标的探测性能通过对比模型对丰富的类火和类烟图像的检测性能,可以发现Fire-YOLO对类火和类烟目标具有更好的检测效率。除了Fire-YOLO,其他模型分别将图像中的光和云误判为火和烟。显然,Fire-YOLO对图像纹理特征更加敏感,这是由于在特征提取网络中结合了1 × 1卷积核和SE模块。最后,提高了该模型在探测混淆目标时的鲁棒性。三种模型的类火和类烟检测结果如下图所示。在上述情况下,Fire-YOLO模型大大减少了误检的发生,减少了劳动力消耗,节约了社会资源。E. 模型在不同自然光下的检测性能本节通过对比不同自然光照条件下的多幅火灾图像,测试Fire-YOLO在真实环境中的性能。在实际火灾探测现场,会出现光线不足或光线很强的情况。在这种场景下,会对火灾探测产生一定的影响。使用大尺度feature map对模型进行改进,识别小目标对象,但在弱光条件下存在误判。检测结果如下图所示。通过比较FasterR-CNN、YOLO-V3和Fire-YOLO模型的检测性能,结果表明该模型在不同光照条件下具有良好的性能,对光照变化具有较强的鲁棒性。Fire-YOLO模式的这些优势可以减少火灾对森林的危害,减少温室效应对人类的影响,促进可持续发展文章提出的Fire- YOLO模型在小目标、类火、类烟探测以及不同明度下的火灾探测等方面都取得了令人满意的效果。在实际应用中,该方法不仅具有实时性,而且具有良好的鲁棒性。然而文章检测算法仍然存在检测精度低、检测半遮挡目标具有挑战性的问题。这可能是由于在实际环境中探测火焰时,火灾的可变性和火灾蔓延的复杂性,造成了火灾检查的困境,如下图所示。.
-
在ModelArts中创建训练作业,并完成模型训练,在得到满意的模型后,可以将训练后得到的模型导入至模型管理,方便统一管理,同时支持将模型快速部署上线为服务。背景信息如果使用ModelArts训练作业生成的模型,请确保训练作业已运行成功,且模型已存储至对应OBS目录下。针对使用订阅算法的训练作业,无需推理代码和配置文件,其生成的模型可直接导入ModelArts。针对使用常用框架或自定义镜像创建的训练作业,需根据模型包规范介绍,将推理代码和配置文件上传至模型的存储目录中。确保您使用的OBS目录与ModelArts在同一区域。创建AI应用操作步骤登录ModelArts管理控制台,在左侧导航栏中选择“AI应用管理 > AI应用”,进入AI应用列表页面。单击左上角的“创建”,进入“创建AI应用”页面。在“创建AI应用”页面,填写相关参数。写元模型来源及其相关参数。当“元模型来源”选择“从训练中选择”时,其相关的参数配置如下确认信息填写无误,单击“立即创建”,完成AI应用的创建。在AI应用列表中,您可以查看刚创建的AI应用及其对应的版本。当AI应用状态变更为“正常”时,表示AI应用导入成功。在此页面,您还可以创建新版本、快速部署服务、发布AI应用等操作。后续操作部署服务:在“AI应用列表”中,单击AI应用名称左侧的小三角,打开此AI应用下的所有版本。在对应版本所在行,单击“操作”列的“部署”,在下拉框中选择部署类型,可以将AI应用部署上线为创建AI应用时所选择的部署类型。
-
AI开发和调优往往需要大量的迭代和调试,数据集、训练代码或参数的变化都可能会影响模型的质量,如不能统一管理开发流程元数据,可能会出现无法重现最优模型的现象。ModelArtsAI应用管理可导入所有训练生成的元模型,可对所有迭代和调试的AI应用进行统一管理。使用限制和说明自动学习项目中,在完成模型部署后,其生成的模型也将自动上传至AI应用管理列表中。但是自动学习生成的AI应用无法下载,只能用于部署上线。创建AI应用、管理AI应用版本、模型转换等功能目前是免费开放给所有用户,使用此功能不会产生费用。创建AI应用的几种场景从训练中选择:在ModelArts中创建训练作业,并完成模型训练,在得到满意的模型后,可以将训练后得到的模型创建为AI应用,用于部署服务。从模板中选择:相同功能的模型配置信息重复率高,将相同功能的配置整合成一个通用的模板,通过使用该模板,可以方便快捷的导入模型,创建为AI应用,而不用编写config.json配置文件。从容器镜像中选择:针对ModelArts目前不支持的AI引擎,可以通过自定义镜像的方式将编写的模型镜像导入ModelArts,创建为AI应用,用于部署服务。从OBS中选择:如果您使用常用框架在本地完成模型开发和训练,可以将模型导入至ModelArts中,创建为AI应用,直接用于部署服务。AI应用管理的功能描述
-
实验准备:华为云账号(已实名认证),如没有账号信息,请先先注册华为云账号信息,参考实名认证介绍_帐号中心_用户指南_实名认证_华为云 (huaweicloud.com)电脑Chrome浏览器实验过程:点击API Explorer_开发者社区-华为云 (huaweicloud.com),进入API Explorer页面,选择【语音交互服务--语音合成接口--RunTts】在Body体的text输入想要转换的内容,再点击调试按钮。(注意红色*为必填项)调试成功后,会提示提示成功或者失败。失败的话,请仔细查看对应的错误码信息,按照下方链接,找到对应的解决方法错误码_语音交互服务 SIS_API参考_附录_华为云 (huaweicloud.com)在成功界面,复制响应体内容,再打开华为云内置的CloudIDE,体验项目。(若未开通CloudIDE,进入CloudIDE_集成开发环境_WebIDE_华为云 (huaweicloud.com)点击【立即体验】免费开通即可)双击json文件,将上一步复制的响应体内容粘贴进去点击运行温馨提示:刚才复制的响应体内容,建议先下载,在赋值。小编刚通过自带的复制按钮,复制的不全,导致JSON格式异常,运行报错。运行成功后,返回到Explorer下,选择mp3文件,右键,选择download。在电脑中找到刚下载的文件,打开,就能听到转换后的语音内容了。实验过程到此结束,赶快体验吧,5分钟真的可以实现文本到语音的转换,转换后还是个美女小姐姐的声音哦。
-
端午至,粽子香佳节到,祈福愿送上一份有“声”的祝福 敢于开口,方能出“粽”文字转语音,MP3文件上传到回帖,再配上您的体验感受即可具体方法可查看体验API Explore,花样玩转AI语音合成接口期望看到大家精彩的评论:1、体验过程中有哪些优化建议2、还能在哪些场景中使用AI语音合成接口3、期待华为云开发其他哪些接口?【本期微话题】AI语音佳节祈福【活动时间】22年5月28日~22年6月10日【参与方式】1、直接回复本帖,就微话题题目进行回答讨论2、为你觉得优质回复的楼层点赞或发表评论【本期奖品】优质回复奖:奖品抽取数量有效回复楼层数需达到华为三脚架自拍杆无线Pro版(黑色)120华为智选欧普读写台灯 白色140幸运回复奖:奖品抽取数量有效回复楼层数需达到华为云定制雨伞220华为云定制笔记本套装340【活动规则】1、开发者用户回复的内容,必须与本期的微话题相关,回复其他内容均视为无效内容,否则取消该用户获奖资格2、开发者用户回复内容的字数需≥100字,禁止复制其他楼层内容或改编自其它楼层内容(包括本人发布在其他楼层的内容),如经发现,取消该用户获奖资格3、本次活动不限用户的总回复数及连续回复数,但需保证回复质量,如华为云社区小编认定参与用户有恶意刷楼嫌疑,则取消该用户获奖资格 【评奖方式】1、在本帖所有有效回复的用户中抽取若干名幸运开发者获得幸运回复奖,奖品及数量见上方示例。2、在所有参加回复的用户中,根据其回复质量及被回复的数量,综合评选优秀奖,奖品见上方示例。3、本次活动将根据实际参与情况发放奖励,包括但不限于用户百分之百中奖或奖项轮空的情况。4、每期活动预计于结束后三天内完成奖项公示,并于结束后15个工作日内完成邮寄。 【温馨提示】1、请务必使用个人实名账号参与活动(IAM、企业账号等账号参与无效)。如一个实名认证对应多个账号,只有一个账号可领取奖励,若同一账号填写多个不同收件人或不同账号填写同一收件人,均不予发放奖励。2、所有获得奖品的获奖用户,请于获奖后3日内完成实名认证,否则视为放弃奖励。
-
本课内容预览:华为云一体机产品能力;华为云AI产品能力;开发环境和调试方式;
-
2022年5月11日晚,由华为云HCDE与EI开发者支持团队、福建DTSE团队联合举办的“华为云HCDE上云之路人工智能行业解决方案闭门会”于线上举行。本次会议,华为云EI开发者生态总监林旅强、华为云EI高级工程师杜奇、华为云EI生态经理陈桢、上海麦图信息科技有限公司CTO李鑫与来自多个行业中导入人工智能的各企业CEO、CTO、技术总监等三十多位专家伙伴齐聚线上,就此展开了一场华为云高端技术圈层的精彩思想碰撞和技术落地方案交流。华为云EI高级工程师 零一华为云EI高级工程师零一老师进行了主题为“后疫情时代下,如何加速AI行业开发和落地,实现智能化转型?”的分享。疫情加速人工智能的落地,根据相关统计,疫情期间,具有以下两类特征的企业在疫情期间展现出显著优势:1)能够基于传统 IT 软件,提供叠加人工智能技术拓展其功能边界的企业。2)应用场景清晰,为行业直接提供垂直解决方案的人工智能技术企业。AI产业未来趋势将从局部应用到千行百业,预计2025年,企业对AI的采用率86%。AI助力行业升级的三大主要场景包括:海量重复场景(Repetitive, high-volume work)、专家经验场景(Expert experience)、多域协同场景(Multi-domain collaboration),通过AI技术能使的这些场景实现效率提升、专业传承、突破极限。AI落地短期是为了替代重复劳动解放生产力,长期是为了突破智力极限发现新知识。在落地过程中会面临三大挑战:1)数据敏感,难以适应长尾分布;2)模型敏感,通常需求巨大算力;3)缺乏知识, 算法可解释性较差。这也导致了AI落地的可复制性弱,开发成本居高不下。华为云高效开发平台ModelArts,通过超强预训练大模型、高效数据扩增和生成、模型按需抽取、自动优化和部署等能力,使得AI在落地过程中实现数据高效、模型高效、知识高效。华为云EI生态经理Dino华为云EI生态经理Dino,基于零一老师老师对人工智能行业的分析与洞察,进行了主题为“华为云ModelArts 轻松助力企业降本增效”的产品分享。华为云构筑AI生态圈,助力千行百业智能升级。华为云ModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处理及交互式智能标注、大规模分布式 训练、自动化模型生成,及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期AI工作流ModelArts也是千行百业实现智能升级的AI使能平台。基于华为云的先进算法和快速训练能力,ModelArts提供大量预置行业 工作流和模型,降低开发应用难度,将大部分定制场景自动化,提升企业AI应用的落地效率。在异构分布式资源调度引擎的加持下, 算力得到极致利用,通过AI社区 AI Gallery 承载的天筹(OptVerse)求解器、知识计算、科学计算、盘古大模型和来自生态伙伴的丰富行业组件/工具,企业可轻松实现极简、高效的智能系统开发。华为云与客户和伙伴一起探索AI在千行百业的实践,为构筑AI开发者生态,提供丰富的AI基础服务及行业化解决方案。与梦饷集团一起基于ModelArts搭建推荐平台,开拓电商新价值,店主人数突破200万,月GMV突破10亿元。HEXA IoT开发人员基于华为云ModelArts开发辣椒识别模型,统一辣椒分拣标准,有效减少了人工筛选带来的判断误差,使得整体分拣效率提升50%。华为云为AI开发者伙伴提供技术、商业孵化、营销等全流程生态支持,与伙伴共创AI应用生态,助力伙伴商业成功。上海麦图科技有限公司CTO 李鑫上海麦图科技有限公司CTO李鑫,分享了以“AI助力民航,坚守安全底线,优化流程保障”为题的行业AI应用经验。分享中讲述了如何利用视频目标识别技术在民航领域实现机坪放冲突与流程保障节点采集的工作,给出了一种利用华为云EI的ModelArts线上训练+线下离线部署的解决方案,支持Atlas等多种硬件架构执行AI应用。该方案充分利用了ModelArts在数据管理、数据协同标注、模型订阅训练与转换等多种功能,实现高效率低成本的行业AI应用,为到场的各位提供了华为云EI在生产项目的一线经验。活动的最后,进行了线上圆桌交流环节,多位华为云专家与来自人工智能行业的工程师、公司CEO、CTO等三十多位伙伴围绕“疫情下的危与机,AI行业技术管理者如何发现机遇、迎接挑战、输出解法?”主题进行了探讨。多位伙伴分别提出了对AI行业、场景解决方案以及华为云相关的产品的问题,华为云专家们针对问题与伙伴们展开了激烈的探讨,将本场活动气氛推向了高潮。与此同时,华为云HCDE上云之路人工智能行业解决方案闭门顺利落下了帷幕。华为云致力于搭建技术交流平台、机遇共创的通道,全面助力每一位开发者、每一位合作伙伴,期待下期活动再次相会。如想了解参加更多华为云HCDE相关活动或有AI合作需求请联系小助手(微信号:hwyzj123)
-
人工智能规划决策系统的发展,一度是以棋类游戏为载体的。最早在18世纪的时候,就出现一台能下棋的机器,击败了当时几乎所有的人类棋手,包括拿破仑和富兰克林等。不过最终被发现**机器里藏着一个人类高手**,通过复杂的机器结构以混淆观众的视线,只是一场骗局而已。 真正基于人工智能的规划决策系统出现在电子计算机诞生之后,1962年时,Arthur Samuel制作的**西洋跳棋**程序Checkers经过屡次改进后,终于战胜了州冠军。当时的程序虽然还算不上智能,但已经具备了初步的自我学习能力,这场胜利在当时引起了巨大的轰动,毕竟是机器首次在智力的角逐中战胜人类。 这也让人们发出了乐观的预言:“机器将在十年内战胜人类象棋冠军”。但人工智能所面临的困难比人们想象得要大很多,跳棋程序在此之后也败给了国家冠军,未能更上一层楼。而与跳棋相比,国际象棋要复杂得多,在当时的计算能力下,机器若想通过暴力计算战胜人类象棋棋手,每步棋的平均计算时长是以年为单位的。人们也意识到,只有尽可能减少计算复杂度,才可能与人类一决高下。 于是,“剪枝法”被应用到了估值函数中,通过剔除掉低可能性的走法,优化最终的估值函数计算。在“剪枝法”的作用下,西北大学开发的象棋程序Chess4.5在1976年首次击败了顶尖人类棋手。进人80年代,随着算法上的不断优化,机器象棋程序在关键胜负手上的判断能力和计算速度上大幅提升,已经能够击败几乎所有的顶尖人类棋手。到了90年代,硬件性能、算法能力等都得到了大幅提升,在1997年那场著名的人机大战中,IBM研发的深蓝(Deep Blue)战胜国际象棋大师卡斯帕罗夫,人们意识到在象游戏中人类已经很难战胜机器了。 到了2016年,硬件层面出现了基于GPU、TPU的并行计算,算法层面出现了蒙特卡洛决策树与深度神经网络的结合。4:1战胜李世石;在野狐围棋对战顶尖棋手60连胜;3:0战胜世界排名第一的围棋选手柯洁,随着棋类游戏最后的堡垒--围棋也被AlphaGo所攻克,人类在完美信息博弈的游戏中已彻底输给机器,只能在**不完美信息的德州扑克和麻将中**苟延残喘。 人们从棋类游戏中积累的知识和经验,也被应用在更广泛的需要决策规划的领域,包括机器人控制、无人车等等。棋类游戏完成了它的历史使命,带领人工智能到达了一个新的历史起点。
-
【功能模块】深度学习模型部署【操作步骤&问题现象】1、深度学习模型(如检测、跟踪)部署时,是选用c++还是培养python?mdc300 mini上能否pip安装?python是否支持和c++程序之间的通信?2、modelzoo给的模型大部分是基于python的,是否能支持转换为om模型?算子是否支持?
-
【功能模块】ModelArts产品AI应用服务ID 7bb213cc-d27c-4f25-88db-d15b7a79fd66【操作步骤&问题现象】1、原yolov5 提供了模型集成,但在obs中上传两个模型文件(.pt)后推理错误。模型(pt)的读入是不公开的,无法修改推理文件完成Ensemble Inference。2、官方要求的文件路径如下OBS桶/目录名 |── resnet | ├── model 必选: 固定子目录名称,用于放置模型相关文件 | │ ├── <<自定义Python包>> 可选:用户自有的Python包,在模型推理代码中可以直接引用 | │ ├── resnet50.pth 必选,pytorch模型保存文件,保存为“state_dict”,存有权重变量等信息。 | │ ├──config.json 必选:模型配置文件,文件名称固定为config.json, 只允许放置一个 | │ ├──customize_service.py 必选:模型推理代码,文件名称固定为customize_service.py, 只允许放置一个,customize_service.py依赖的文件可以直接放model目录下3、我的OBS【日志信息】(可选,上传日志内容或者附件)
-
AI从2012年开始热度一直居高不下,俨然成为IT行业的新宠,与各行各业的结合也成为AI落地进程中的主流方向。AI技术如今已经成为IT行业的新宠,与各行各业的结合也成为AI落地进程中的主流方向,智慧城市的最新发展和现状是怎样的?如何更好地实现云上强大AI能力的价值落地?NLP(自然语言处理)和对话机器人有哪些典型落地场景和未来趋势?2019年12月21日上午,在AICon全球人工智能与机器学习技术大会"华为云AI技术应用和实践专场"上,来自华为云EI(企业智能)的三位技术专家分别就"华为云自然语言和对话机器人技术详解和应用场景"、"AI+城市智能体:聚焦新一代智慧城市的PISC架构"、"华为云HiLens:端云协同AI平台,助力企业快速智能化转型"主题详解了相关技术与应用。一、自然语言、对话机器人技术详解及应用场景随着智能助理、对话机器人、智能音箱等产品的兴起,NLP的风口正在到来,NLP领域突破不断,预训练模型的出现,迁移学习和多模态被越来越多的普遍使用,企业市场也涌现出丰富的应用场景。语言理解成为人工智能皇冠上的明珠。在华为云的演讲中,整体梳理了华为云自然语言、对话机器人技术详解及应用场景。(一)语音语义技术发展历程人类使用自然语言沟通的逻辑是:听到——>理解——>回答,而从计算机的角度,要想实现语音语义识别,需要4项技术与之对应:语音识别ASR、语言理解NLU、语言生成NLG和语音合成TTS。1、语音识别的发展:1952~1990年是模板匹配阶段,主要针对小词汇量、孤立词识别;1990~2010年,开始用统计模型做语音的识别;到了2010年以后,基于神经网络的模型如CTC出现,让语音识别的模型变得非常清晰简单;最近几年出现的attention demo,效果可以达到商业化应用标准。2、语音语义技术在行业的应用:一方面是虚拟的个人助手,另一项重要应用是智能客服,三是公司内部IT热线。(二)智能语言和对话机器人的应用华为EI语音语义团队基本上覆盖了三方面的线上服务,一是自然语言处理服务,包括NLP基础能力如分词,文本相似度等,也包括语言生成、语言理解、知识图谱、机器翻译等高阶能力;二是语音交互服务,包括语音识别,语音合成、语音扩展的能力;三是更加智能的交互技术,包括多轮问答、电话机器人等。1、对话式智能在企业场景中的应用对话式智能在企业中的应用,包括售前引导、售后服务以及智能外呼。其中,售前引导通过智能导购多轮对话,增加商业机会并减少运营成本;售后服务通过故障问答、售后咨询等提高客服效率,提升服务体验;而智能外呼由机器人自动执行外呼电话任务,例如营销、满意度回访,预约等,并自动生成呼叫语义报告,提升企业运营效率和客户满意度。在构建整个解决方案时,迁移学习在NLP领域可以解决很多场景的问题,这一点被越来越看好。比如开发者训练了某一个特定领域的模型,并积累了大量数据,但是当进入新领域时必然面临到现有数据少的难题,而通过迁移学习则可以把训练好的模型迁移到新的场景上,用现有的、较少的数据训练出好的模型,从而解决客户的问题。2、智能对话分析/质检在呼叫中心里,尤其是呼叫量比较大的时候,需要分析客服与客户的互动是否符合规范,以前都由专门的质检人员监听录音反馈信息。现在可以用机器替代人工,用自然语言理解和语音识别去做全量质检,不仅可以得到质检的结果,还可以得到商业的分析,用客户提供的反馈优化产品。3、自然语言的情感分析华为VMALL商城里面有大量的用户评价,对于一个公司来说,了解用户真实的反馈是非常有价值的,对商品评论自动过滤,负面评论供人工审核解决问题;对于属性级别的情感分析,辅助细粒度商业分析和决策。(三)语音语义未来发展趋势NLP会迎来黄金10年。华为云致力于把学术界最前沿的技术应用到商业场景里面,解决客户的具体问题。1、Voice UI会成为下一个趋势,聊天机器人将无处不在。现在越来越多的应用场景,各种不同的垂直领域都会有聊天机器人代替人工做一些工作,无论是售前咨询、售后服务、辅助购买等都会有机器人去引导你,辅助你把这个流程走完。所以习惯与机器人互动是接下来每个人要做的事。2、未来五到十年,机器人会具备分析大量文本的能力。从阅读、分析、理解到最后生成一个总结报告,所有的内容都是由机器人去完成。3、情感化、个性化的定制成为流行。高德地图中,使用明星语音引导就是例子,未来会有越来越多定制化的语音需求,满足不同场景的应用。二、AI+城市智能体:聚焦新一代智慧城市的PISC架构第二位华为专家从城市智能体的角度,以智能交通为例,系统地介绍了基于人工智能技术的PISC架构在交通态势感知(Perception)、推理(Inference) 到决策(Strategy)和控制(Control)上的应用。此外,他还详细讲解了基于胶囊投影的深度学习算法(Capsule Projection Networks)、交通图计算(Graph Computing)以及各种交通策略以及控制算法的实现。(一)智慧城市发展现状智慧城市最早起源于2008年11月RBM提出的智慧星球,直到2012年,RBM陆续从智慧星球概念中推出智慧城市。也是在2012年深度学习技术在计算机视觉取得非常大的成果后,智慧城市的落地应用才变得可行起来。有一个最经典的智慧城市解决方案——PC,P就是感知,C就是控制。通过对交通路网上的交通流进行实时分析,对交通流在不同的入口,甚至精确到不同的车道上的情况都有一个精确的感知结果。根据感知分析的结果,对路口的红绿灯进行流量控制,比如通过调节感应率的时间,实现最小化等待时间,防止出现二次排队的现象,从而制定合适的红绿灯方案。但PC结构是有本质上的缺点。一是PC得到的感知结果实际上是局部的,缺少对全局交通态势的认识。二是对于交通动态变化的分析和控制,由于规则不固定,很难做到最优的策略。三是认知与决策的鸿沟。也就是如何把感知上升到认知,并且把认知翻译成能够执行的策略和控制的方法。为了解决这三个问题,华为云在PC结构基础上构建出一个PISC。(二)PISC总体架构PISC就是在PC结构基础上,在P与C之间加入I(推理)和S(决策)。1、加入I(推理),目的是把局部的感知信号叠在一起形成全局交通态势的认知。比如对单点的交通流的信息推理,如何发现拥堵的区域,如何找到早高峰的数据,如何发现出入口的拥堵,不仅需要对当前态势进行推断,还要对交通态势随着时间的变化进行预测。2、把认知结果翻译成S(决策)。在决策里非常需要交警的专业知识和经验的引入。结合AI的控制技术、控制手段,形成一整套策略,并把策略通过红绿灯信号或者是导流屏或者导流短信实施下来。现在最常用的感知技术是摄像头技术,在此基础上提出新的一种更加高效的、精度更高的深度学习框架——胶囊投影。其思路是:分类,对每一个类别做一个胶囊子空间,每个子空间有特定识别的语义。做投影之后,它的长度跟角度利用胶囊网络最核心的思想,可以得到胶囊投影进行分类。在不改变网络复杂度的情况下,以网络的容量、参数规模和运算时间来做度量复杂度。在同样复杂度下能够比其他深度学习的网络分类准确率提高20%以上。另外,利用多模态的数据对多模态进行感知。选择多模态。一是因为电警数据有死角,需要结合其他多传感器的数据,比如地磁跟雷达数据,扩大探测范围,形成互补;二是要采集浮动车数据。利用浮动车数据,把浮动车低采样、低密度的数据恢复成高采样、全路网的数据。智能交通决策控制是把认知的信号通过推理的方法上升到感知跟语义信号的高度之后,就可以识别出来拥堵区。为了把语义地图转换成可以执行的控制交通策略,首先要把语义地图做一个表达,通过语义地图原始输入的data,把它翻译成交通地图做一个全景表达的representation,在这个过程中可以把专家的知识输入进去,就是Graph作为输入,然后专家的指挥数据作为一个输出,作为有监督的训练,这种方法是一种模仿型的自动决策的方法。除了模仿型方法之外,我们也可以利用强化学习的方法,强化学习仍然是基于Graph Representation全局的表达,但是这个时候不是用专家的知识,而是用全区的可以评估的指标。这两种方法可以融合起来,既可以把专家给出来的指挥策略作为信号,也可以用AI技术、强化学习来训练神经网络。PISC方案已经在很多城市进行试点,有的已经进行全方案的部署。以一个北京路口为例,利用TrafficGO系统把平均延误时间下降25%,全干道平均延误下降15%,这是用第三方浮动车数据测出来的结果,可见人工智能技术在试点的路口已经取得了好的结果。华为专家在演讲中提到,随着智慧城市建设的大力投入和深入开展,EI人工智能技术在高效疏导交通拥堵,提高城市出行效率,及时响应交通事故和其他紧急事件,快速建立应急车辆的绿色通道,以及保障和提高民生, 建成人和生态环境和谐发展的智能城市体等方面发挥关键性的作用。三、华为云HiLens:端云协同AI平台在AI技术实际落地过程中,诸多场景如摄像头智能监控、医疗影像分析、智能车载系统等遇到数据上云成本高、计算延时大、隐私风险、AI应用开发上手困难、AI应用本地维护困难等挑战,极大的阻碍了云上强大AI能力的价值落地。因此,将云上AI能力便利的部署到离应用场景更近的边缘或终端设备上,能很好解决这一系列问题。在2018年10月召开的华为全联接大会上,华为云重磅发布了一站式视觉AI应用开发、部署和管理服务平台——HiLens,以解决当下"端-边-云"场景下亟待解决的开发问题。在本次大会现场,华为云HiLens研发负责人也带来了相关演讲,详细拆解了HiLens平台架构及关键能力。演讲伊始,他先整体讲解了华为云EI布局,并引入对 HiLens的介绍。目前,云上AI服务落地依然存在很多的问题和挑战,主要的五项包括成本、延时、场景、隐私及边缘端侧AI应用的部署和维护难。针对高成本、低延时、复杂场景、数据安全和部署维护等问题,华为云推出了HiLens平台服务。其主要能力包括:一、可以管理高达百万量级的设备;二、通过在算法和业务层面将AI的应用拆分成端的部分和云的部分。以摄像头监控行业为例,在家用摄像头上可以做人形、人脸比对、家庭成员的搜索等等,华为将预处理或者基础的能力放在低成本的摄像头上,然后输出小图传输到云侧进行比对,并在端侧把大量的数据忽略掉,所以成本会大幅降低;三、HiLens平台构建的也是一个Skill Market的生态,到2019年,华为和第三方合作伙伴开发的针对各个行业的几百个技能、应用,都会放到Skill Market里。HiLens的整个平台架构主要分为三个部分,最上层是针对行业已经实现的应用,下层分成端侧和云侧,端侧主要是基于不同的芯片、不同OS系统开发的整个AI技能在端侧运营的软件,包括算法成本和库、基本图像、语音处理的部分软件等,通过一套叫Skill Framework的服务提供给开发者,开发者可以简单高效地可以在端侧运行应用或技能;云侧主要提供边缘设备的管理,也包括应用开发和数据的管理。例如,在设备上产生的数据可以从端侧软件推到云侧做一个视觉化存储。HiLens平台包含以下几大特性和关键能力:1、针对Skill生态的开发者做Skill服务。模型依然是AI应用开发的核心,在华为云上, 模型的开发可以使用ModelArts,或者通过线下的导入到上面来,然后通过Framework将模型打包成技能,就可以下发到HiLens支持的边缘或者终端设备上。2、端侧算法开发框架Skill Framework检测。Skill Framework封装了视频分析算法基础组件,如图像处理、推理、日志等,开发者通过少量代码即可开发自己的Skill,同时,HiLens还可结合芯片进行性能优化,提供Python和C++接口,在HiLens平台上开发的Skill可以运行到任何基于华为海思芯片的设备上。3、模型优化、自动模型转换及压缩能力。包括网络蒸馏、通道剪枝、权重稀疏化、量化、模型转换等。4、上文中所提到的丰富的Skill Market,方便模型快速构建。5、设备实时采集视频流传输到云端,可视化管理多路视频流。目前,HiLens具备非常丰富的应用场景。例如,在智能园区中可精准追踪行人轨迹、识别车牌&车型等;在智慧家庭中实现陌生人告警、异常声音检测等;此外,在智能车载、智慧工地等场景中,HiLens也可以发挥其功用,达成对疲劳驾驶检测、安全和姿态监测等。本文转自:今日头条原文链接:https://www.toutiao.com/i6644031954968642056/
-
ModelArts是面向AI开发者的一站式开发平台,提供海量数据预处理及半自动化标注、大规模分布式训练、自动化模型生成及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期AI工作流。“一站式”是指AI开发的各个环节,包括数据处理、算法开发、模型训练、模型部署都可以在ModelArts上完成。从技术上看,ModelArts底层支持各种异构计算资源,开发者可以根据需要灵活选择使用,而不需要关心底层的技术。同时,ModelArts支持Tensorflow、PyTorch、MindSpore等主流开源的AI开发框架,也支持开发者使用自研的算法框架,匹配您的使用习惯。ModelArts的理念就是让AI开发变得更简单、更方便。面向不同经验的AI开发者,提供便捷易用的使用流程。例如,面向业务开发者,不需关注模型或编码,可使用自动学习流程快速构建AI应用;面向AI初学者,不需关注模型开发,使用预置算法构建AI应用;面向AI工程师,提供多种开发环境,多种操作流程和模式,方便开发者编码扩展,快速构建模型及应用。产品架构ModelArts是一个一站式的开发平台,能够支撑开发者从数据到AI应用的全流程开发过程。包含数据处理、模型训练、模型管理、模型部署等操作,并且提供AI Gallery功能,能够在市场内与其他开发者分享模型。ModelArts支持应用到图像分类、物体检测、视频分析、语音识别、产品推荐、异常检测等多种AI应用场景。ModelArts特色功能数据治理支持数据筛选、标注等数据处理,提供数据集版本管理,特别是深度学习的大数据集,让训练结果可重现。极“快”致“简”模型训练自研的MoXing深度学习框架,更高效更易用,大大提升训练速度。云边端多场景部署支持模型部署到多种生产环境,可部署为云端在线推理和批量推理,也可以直接部署到端和边。自动学习支持多种自动学习能力,通过“自动学习”训练模型,用户不需编写代码即可完成自动建模、一键部署。AI Gallery预置常用算法和常用数据集,支持模型在企业内部共享或者公开共享。
-
第一个基于电子计算语音识别统出现在1952年,AT&T贝尔实验室开发了一款Audrey的语音识别系统,能够识别10个英文数字,正确率高达98%。 70年代开始出现了大规模的语音识别研究,但当时的技术还处于萌芽阶段,停留在对孤立词、小词汇量句子的识别上。 80年代是技术取得突破的时代,一个重要原因是**全球性的电传业务**积累了大量文本,这些文本可作为机读语料用于模型的训练和统计。研究的重点也逐渐转向大词汇量、非特定人的连续语音识别。那时最主要的变化来自用**基于统计的思路**替代传统的基于匹配的思路,其中的一个关键进展是隐马尔科夫模型(HMM)的理论和应用都趋于完善。工业界也出现了广泛的应用,德州仪器研发了名为Speak&Spell语音学习机,语音识别服务商SpeechWorks成立,美国国防部高级研究计划局(DARPA)也赞助支持了一系列语音相关的项目。 90年代是语音识别基本成熟的时期,主流的高斯混合模型GMM-HMM框架逐渐趋于稳定,但与实用还有一定距离,语音识别研究的进展也逐渐趋缓。由于80年代末90年代初神经网络技术的热潮,神经网络也被用于语音识别,提出了多层感知器一隐马尔科夫模型(MLP-HMM)混合模型。但是性能上无法超越GMMHMM框架。 突破的产生始于深度学习的出现。随着深度神经网络(DNN)被应用到语音的声学建模中,人们陆续在音素识别任务和大词汇量连续语音识别任务上取得突破。基于GMM-HMM的语音识别框架被基于DNN-HMM的语音识别系统所替代,而随着系统的持续改进,又出现了深层卷积神经网络和引人长短时记忆模块(LSTM)的循环神经网络(RNN),识别效果得到了进一步提升,在许多(尤其是近场)语音识别任务上达到了可以进人人们日常生活的标准。于是我们看到以Apple Siri为首的智能语音助手、以Echo为首的智能硬件人口等等。而这些应用的普及,又进一步扩充了语料资源的收集渠道,为语言和声学模型的训练储备了丰富的燃料,使得构建大规模通用语言模型和声学模型成为可能。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签