详解视频中动作识别模型与代码实践

摘要:本案例将为大家介绍视频动作识别领域的经典模型并进行代码实践。

本文分享自华为云社区《视频动作识别》,作者:HWCloudAI。实验目标

通过本案例的学习:

  • 掌握 C3D 模型训练和模型推理、I3D 模型推理的方法;

注意事项

  1. 本案例推荐使用TensorFlow-1.13.1,需使用 GPU 运行,请查看《ModelArts JupyterLab 硬件规格使用指南》了解切换硬件规格的方法;
  2. 如果您是第一次使用 JupyterLab,请查看《ModelArts JupyterLab使用指导》了解使用方法;
  3. 如果您在使用 JupyterLab 过程中碰到报错,请参考《ModelArts JupyterLab常见问题解决办法》尝试解决问题。

实验步骤

案例内容介绍

视频动作识别是指对一小段视频中的内容进行分析,判断视频中的人物做了哪种动作。视频动作识别与图像领域的图像识别,既有联系又有区别,图像识别是对一张静态图片进行识别,而视频动作识别不仅要考察每张图片的静态内容,还要考察不同图片静态内容之间的时空关系。比如一个人扶着一扇半开的门,仅凭这一张图片无法判断该动作是开门动作还是关门动作。

视频分析领域的研究相比较图像分析领域的研究,发展时间更短,也更有难度。视频分析模型完成的难点首先在于,需要强大的计算资源来完成视频的分析。视频要拆解成为图像进行分析,导致模型的数据量十分庞大。视频内容有很重要的考虑因素是动作的时间顺序,需要将视频转换成的图像通过时间关系联系起来,做出判断,所以模型需要考虑时序因素,加入时间维度之后参数也会大量增加。

得益于 PASCAL VOC、ImageNet、MS COCO 等数据集的公开,图像领域产生了很多的经典模型,那么在视频分析领域有没有什么经典的模型呢?答案是有的,本案例将为大家介绍视频动作识别领域的经典模型并进行代码实践。

1. 准备源代码和数据

这一步准备案例所需的源代码和数据,相关资源已经保存在 OBS 中,我们通过ModelArts SDK将资源下载到本地,并解压到当前目录下。解压后,当前目录包含 data、dataset_subset 和其他目录文件,分别是预训练参数文件、数据集和代码文件等。

import os
import moxing as mox
if not os.path.exists('videos'):
 mox.file.copy("obs://ai-course-common-26-bj4-v2/video/video.tar.gz", "./video.tar.gz")
 # 使用tar命令解压资源包
 os.system("tar xf ./video.tar.gz")
 # 使用rm命令删除压缩包
 os.system("rm ./video.tar.gz")
INFO:root:Using MoXing-v1.17.3-
INFO:root:Using OBS-Python-SDK-3.20.7

上一节课我们已经介绍了视频动作识别有 HMDB51、UCF-101 和 Kinetics 三个常用的数据集,本案例选用了 UCF-101 数据集的部分子集作为演示用数据集,接下来,我们播放一段 UCF-101 中的视频:

video_name = "./data/v_TaiChi_g01_c01.avi"

from IPython.display import clear_output, Image, display, HTML
import time
import cv2
import base64
import numpy as np
def arrayShow(img):
 _,ret = cv2.imencode('.jpg', img) 
 return Image(data=ret) 
cap = cv2.VideoCapture(video_name)
while True:
 try:
 clear_output(wait=True)
        ret, frame = cap.read()
 if ret:
 tmp = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 img = arrayShow(frame)
            display(img)
 time.sleep(0.05)
 else:
 break
 except KeyboardInterrupt:
 cap.release()
cap.release()

2. 视频动作识别模型介绍

在图像领域中,ImageNet 作为一个大型图像识别数据集,自 2010 年开始,使用此数据集训练出的图像算法层出不穷,深度学习模型经历了从 AlexNet 到 VGG-16 再到更加复杂的结构,模型的表现也越来越好。在识别千种类别的图片时,错误率表现如下:

在图像识别中表现很好的模型,可以在图像领域的其他任务中继续使用,通过复用模型中部分层的参数,就可以提升模型的训练效果。有了基于 ImageNet 模型的图像模型,很多模型和任务都有了更好的训练基础,比如说物体检测、实例分割、人脸检测、人脸识别等。

那么训练效果显著的图像模型是否可以用于视频模型的训练呢?答案是 yes,有研究证明,在视频领域,如果能够复用图像模型结构,甚至参数,将对视频模型的训练有很大帮助。但是怎样才能复用上图像模型的结构呢?首先需要知道视频分类与图像分类的不同,如果将视频视作是图像的集合,每一个帧将作为一个图像,视频分类任务除了要考虑到图像中的表现,也要考虑图像间的时空关系,才可以对视频动作进行分类。

为了捕获图像间的时空关系,论文 I3D 介绍了三种旧的视频分类模型,并提出了一种更有效的 Two-Stream Inflated 3D ConvNets(简称 I3D)的模型,下面将逐一简介这四种模型,更多细节信息请查看原论文。

旧模型一:卷积网络 + LSTM

模型使用了训练成熟的图像模型,通过卷积网络,对每一帧图像进行特征提取、池化和预测,最后在模型的末端加一个 LSTM 层(长短期记忆网络),如下图所示,这样就可以使模型能够考虑时间性结构,将上下文特征联系起来,做出动作判断。这种模型的缺点是只能捕获较大的工作,对小动作的识别效果较差,而且由于视频中的每一帧图像都要经过网络的计算,所以训练时间很长。

旧模型二:3D 卷积网络

3D 卷积类似于 2D 卷积,将时序信息加入卷积操作。虽然这是一种看起来更加自然的视频处理方式,但是由于卷积核维度增加,参数的数量也增加了,模型的训练变得更加困难。这种模型没有对图像模型进行复用,而是直接将视频数据传入 3D 卷积网络进行训练。

旧模型三:Two-Stream 网络

Two-Stream 网络的两个流分别为 1 张 RGB 快照和 10 张计算之后的光流帧画面组成的栈。两个流都通过 ImageNet 预训练好的图像卷积网络,光流部分可以分为竖直和水平两个通道,所以是普通图片输入的 2 倍,模型在训练和测试中表现都十分出色。

光流视频 optical flow video

上面讲到了光流,在此对光流做一下介绍。光流是什么呢?名字很专业,感觉很陌生,但实际上这种视觉现象我们每天都在经历,我们坐高铁的时候,可以看到窗外的景物都在快速往后退,开得越快,就感受到外面的景物就是 “刷” 地一个残影,这种视觉上目标的运动方向和速度就是光流。光流从概念上讲,是对物体运动的观察,通过找到相邻帧之间的相关性来判断帧之间的对应关系,计算出相邻帧画面中物体的运动信息,获取像素运动的瞬时速度。在原始视频中,有运动部分和静止的背景部分,我们通常需要判断的只是视频中运动部分的状态,而光流就是通过计算得到了视频中运动部分的运动信息。

下面是一个经过计算后的原视频及光流视频。

原视频

光流视频

新模型:Two-Stream Inflated 3D ConvNets

新模型采取了以下几点结构改进:

  • 拓展 2D 卷积为 3D。直接利用成熟的图像分类模型,只不过将网络中二维 $ N × N 的 filters 和 pooling kernels 直接变成的 filters 和 poolingkernels 直接变成 N × N × N $;
  • 用 2D filter 的预训练参数来初始化 3D filter 的参数。上一步已经利用了图像分类模型的网络,这一步的目的是能利用上网络的预训练参数,直接将 2D filter 的参数直接沿着第三个时间维度进行复制 N 次,最后将所有参数值再除以 N;
  • 调整感受野的形状和大小。新模型改造了图像分类模型 Inception-v1 的结构,前两个 max-pooling 层改成使用 $ 1 × 3 × 3 kernels and stride 1 in time,其他所有 max-pooling 层都仍然使用对此的 kernel 和 stride,最后一个 average pooling 层使用 kernelsandstride1intime,其他所有 max−pooling 层都仍然使用对此的 kernel 和 stride,最后一个 averagepooling 层使用 2 × 7 × 7 $ 的 kernel。
  • 延续了 Two-Stream 的基本方法。用双流结构来捕获图片之间的时空关系仍然是有效的。

最后新模型的整体结构如下图所示:

好,到目前为止,我们已经讲解了视频动作识别的经典数据集和经典模型,下面我们通过代码来实践地跑一跑其中的两个模型:C3D 模型( 3D 卷积网络)以及 I3D 模型(Two-Stream Inflated 3D ConvNets)。

C3D 模型结构

我们已经在前面的 “旧模型二:3D 卷积网络” 中讲解到 3D 卷积网络是一种看起来比较自然的处理视频的网络,虽然它有效果不够好,计算量也大的特点,但它的结构很简单,可以构造一个很简单的网络就可以实现视频动作识别,如下图所示是 3D 卷积的示意图:

a) 中,一张图片进行了 2D 卷积, b) 中,对视频进行 2D 卷积,将多个帧视作多个通道, c) 中,对视频进行 3D 卷积,将时序信息加入输入信号中。

ab 中,output 都是一张二维特征图,所以无论是输入是否有时间信息,输出都是一张二维的特征图,2D 卷积失去了时序信息。只有 3D 卷积在输出时,保留了时序信息。2D 和 3D 池化操作同样有这样的问题。

如下图所示是一种 C3D 网络的变种:(如需阅读原文描述,请查看 I3D 论文 2.2 节)

C3D 结构,包括 8 个卷积层,5 个最大池化层以及 2 个全连接层,最后是 softmax 输出层。

所有的 3D 卷积核为 $ 3 × 3 × 3$ 步长为 1,使用 SGD,初始学习率为 0.003,每 150k 个迭代,除以 2。优化在 1.9M 个迭代的时候结束,大约 13epoch。

数据处理时,视频抽帧定义大小为:$ c × l × h × w,,c 为通道数量,为通道数量,l 为帧的数量,为帧的数量,h 为帧画面的高度,为帧画面的高度,w 为帧画面的宽度。3D 卷积核和池化核的大小为为帧画面的宽度。3D 卷积核和池化核的大小为 d × k × k,,d 是核的时间深度,是核的时间深度,k 是核的空间大小。网络的输入为视频的抽帧,预测出的是类别标签。所有的视频帧画面都调整大小为是核的空间大小。网络的输入为视频的抽帧,预测出的是类别标签。所有的视频帧画面都调整大小为 128 × 171 $,几乎将 UCF-101 数据集中的帧调整为一半大小。视频被分为不重复的 16 帧画面,这些画面将作为模型网络的输入。最后对帧画面的大小进行裁剪,输入的数据为 $16 × 112 × 112 $

3.C3D 模型训练

接下来,我们将对 C3D 模型进行训练,训练过程分为:数据预处理以及模型训练。在此次训练中,我们使用的数据集为 UCF-101,由于 C3D 模型的输入是视频的每帧图片,因此我们需要对数据集的视频进行抽帧,也就是将视频转换为图片,然后将图片数据传入模型之中,进行训练。

在本案例中,我们随机抽取了 UCF-101 数据集的一部分进行训练的演示,感兴趣的同学可以下载完整的 UCF-101 数据集进行训练。

UCF-101 下载

数据集存储在目录 dataset_subset 下

如下代码是使用 cv2 库进行视频文件到图片文件的转换

import cv2
import os
# 视频数据集存储位置
video_path = './dataset_subset/'
# 生成的图像数据集存储位置
save_path = './dataset/'
# 如果文件路径不存在则创建路径
if not os.path.exists(save_path):
 os.mkdir(save_path)
# 获取动作列表
action_list = os.listdir(video_path)
# 遍历所有动作
for action in action_list:
 if action.startswith(".")==False:
 if not os.path.exists(save_path+action):
 os.mkdir(save_path+action)
 video_list = os.listdir(video_path+action)
 # 遍历所有视频
 for video in video_list:
            prefix = video.split('.')[0]
 if not os.path.exists(os.path.join(save_path, action, prefix)):
 os.mkdir(os.path.join(save_path, action, prefix))
 save_name = os.path.join(save_path, action, prefix) + '/'
 video_name = video_path+action+'/'+video
 # 读取视频文件
 # cap为视频的帧
            cap = cv2.VideoCapture(video_name)
 # fps为帧率
            fps = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
 fps_count = 0
 for i in range(fps):
                ret, frame = cap.read()
 if ret:
 # 将帧画面写入图片文件中
                    cv2.imwrite(save_name+str(10000+fps_count)+'.jpg',frame)
 fps_count += 1

此时,视频逐帧转换成的图片数据已经存储起来,为模型训练做准备。

4. 模型训练

首先,我们构建模型结构。

C3D 模型结构我们之前已经介绍过,这里我们通过 keras 提供的 Conv3D,MaxPool3D,ZeroPadding3D 等函数进行模型的搭建。

from keras.layers import Dense,Dropout,Conv3D,Input,MaxPool3D,Flatten,Activation, ZeroPadding3D
from keras.regularizers import l2
from keras.models import Model, Sequential
# 输入数据为 112×112 的图片,16帧, 3通道
input_shape = (112,112,16,3)
# 权重衰减率
weight_decay = 0.005
# 类型数量,我们使用UCF-101 为数据集,所以为101
nb_classes = 101
# 构建模型结构
inputs = Input(input_shape)
x = Conv3D(64,(3,3,3),strides=(1,1,1),padding='same',
           activation='relu',kernel_regularizer=l2(weight_decay))(inputs)
x = MaxPool3D((2,2,1),strides=(2,2,1),padding='same')(x)
x = Conv3D(128,(3,3,3),strides=(1,1,1),padding='same',
           activation='relu',kernel_regularizer=l2(weight_decay))(x)
x = MaxPool3D((2,2,2),strides=(2,2,2),padding='same')(x)
x = Conv3D(128,(3,3,3),strides=(1,1,1),padding='same',
           activation='relu',kernel_regularizer=l2(weight_decay))(x)
x = MaxPool3D((2,2,2),strides=(2,2,2),padding='same')(x)
x = Conv3D(256,(3,3,3),strides=(1,1,1),padding='same',
           activation='relu',kernel_regularizer=l2(weight_decay))(x)
x = MaxPool3D((2,2,2),strides=(2,2,2),padding='same')(x)
x = Conv3D(256, (3, 3, 3), strides=(1, 1, 1), padding='same',
           activation='relu',kernel_regularizer=l2(weight_decay))(x)
x = MaxPool3D((2, 2, 2), strides=(2, 2, 2), padding='same')(x)
x = Flatten()(x)
x = Dense(2048,activation='relu',kernel_regularizer=l2(weight_decay))(x)
x = Dropout(0.5)(x)
x = Dense(2048,activation='relu',kernel_regularizer=l2(weight_decay))(x)
x = Dropout(0.5)(x)
x = Dense(nb_classes,kernel_regularizer=l2(weight_decay))(x)
x = Activation('softmax')(x)
model = Model(inputs, x)
Using TensorFlow backend.
/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint8 = np.dtype([("qint8", np.int8, 1)])
/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:527: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint8 = np.dtype([("quint8", np.uint8, 1)])
/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:528: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint16 = np.dtype([("qint16", np.int16, 1)])
/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:529: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint16 = np.dtype([("quint16", np.uint16, 1)])
/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:530: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint32 = np.dtype([("qint32", np.int32, 1)])
/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:535: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
 np_resource = np.dtype([("resource", np.ubyte, 1)])
WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.

通过 keras 提供的 summary () 方法,打印模型结构。可以看到模型的层构建以及各层的输入输出情况。

model.summary()

此处输出较长,省略

通过 keras 的 input 方法可以查看模型的输入形状,shape 分别为 (batch size, width, height, frames, channels) 。

model.input
<tf.Tensor 'input_1:0' shape=(?, 112, 112, 16, 3) dtype=float32>

可以看到模型的数据处理的维度与图像处理模型有一些差别,多了 frames 维度,体现出时序关系在视频分析中的影响。

接下来,我们开始将图片文件转为训练需要的数据形式。

# 引用必要的库
from keras.optimizers import SGD,Adam
from keras.utils import np_utils
import numpy as np
import random
import cv2
import matplotlib.pyplot as plt
# 自定义callbacks
from schedules import onetenth_4_8_12
INFO:matplotlib.font_manager:font search path ['/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf', '/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/afm', '/home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts']
INFO:matplotlib.font_manager:generated new fontManager

参数定义

img_path = save_path # 图片文件存储位置
results_path = './results' # 训练结果保存位置
if not os.path.exists(results_path):
 os.mkdir(results_path)

数据集划分,随机抽取 4/5 作为训练集,其余为验证集。将文件信息分别存储在 train_list 和 test_list 中,为训练做准备。

cates = os.listdir(img_path)
train_list = []
test_list = []
# 遍历所有的动作类型
for cate in cates:
    videos = os.listdir(os.path.join(img_path, cate))
    length = len(videos)//5
 # 训练集大小,随机取视频文件加入训练集
    train= random.sample(videos, length*4)
 train_list.extend(train)
 # 将余下的视频加入测试集
 for video in videos:
 if video not in train:
 test_list.append(video)
print("训练集为:") 
print( train_list)
print("共%d 个视频\n"%(len(train_list)))
print("验证集为:") 
print(test_list)
print("共%d 个视频"%(len(test_list)))

此处输出较长,省略

接下来开始进行模型的训练。

首先定义数据读取方法。方法 process_data 中读取一个 batch 的数据,包含 16 帧的图片信息的数据,以及数据的标注信息。在读取图片数据时,对图片进行随机裁剪和翻转操作以完成数据增广。

def process_data(img_path, file_list,batch_size=16,train=True):
    batch = np.zeros((batch_size,16,112,112,3),dtype='float32')
    labels = np.zeros(batch_size,dtype='int')
 cate_list = os.listdir(img_path)
 def read_classes():
        path = "./classInd.txt"
 with open(path, "r+") as f:
            lines = f.readlines()
        classes = {}
 for line in lines:
 c_id = line.split()[0]
 c_name = line.split()[1]
            classes[c_name] =c_id 
 return classes
 classes_dict = read_classes()
 for file in file_list:
        cate = file.split("_")[1]
 img_list = os.listdir(os.path.join(img_path, cate, file))
 img_list.sort()
 batch_img = []
 for i in range(batch_size):
            path = os.path.join(img_path, cate, file)
            label = int(classes_dict[cate])-1
            symbol = len(img_list)//16
 if train:
 # 随机进行裁剪
 crop_x = random.randint(0, 15)
 crop_y = random.randint(0, 58)
 # 随机进行翻转
 is_flip = random.randint(0, 1)
 # 以16 帧为单位
 for j in range(16):
 img = img_list[symbol + j]
                    image = cv2.imread( path + '/' + img)
                    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
                    image = cv2.resize(image, (171, 128))
 if is_flip == 1:
                        image = cv2.flip(image, 1)
                    batch[i][j][:][:][:] = image[crop_x:crop_x + 112, crop_y:crop_y + 112, :]
                    symbol-=1
 if symbol<0:
 break
                labels[i] = label
 else:
 for j in range(16):
 img = img_list[symbol + j]
                    image = cv2.imread( path + '/' + img)
                    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
                    image = cv2.resize(image, (171, 128))
                    batch[i][j][:][:][:] = image[8:120, 30:142, :]
                    symbol-=1
 if symbol<0:
 break
                labels[i] = label
 return batch, labels
batch, labels = process_data(img_path, train_list)
print("每个batch的形状为:%s"%(str(batch.shape)))
print("每个label的形状为:%s"%(str(labels.shape)))
每个batch的形状为:(16, 16, 112, 112, 3)
每个label的形状为:(16,)

定义 data generator, 将数据批次传入训练函数中。

def generator_train_batch(train_list, batch_size, num_classes, img_path):
 while True:
 # 读取一个batch的数据
 x_train, x_labels = process_data(img_path, train_list, batch_size=16,train=True)
        x = preprocess(x_train)
 # 形成input要求的数据格式
        y = np_utils.to_categorical(np.array(x_labels), num_classes)
        x = np.transpose(x, (0,2,3,1,4))
 yield x, y
def generator_val_batch(test_list, batch_size, num_classes, img_path):
 while True:
 # 读取一个batch的数据
 y_test,y_labels = process_data(img_path, train_list, batch_size=16,train=False)
        x = preprocess(y_test)
 # 形成input要求的数据格式
        x = np.transpose(x,(0,2,3,1,4))
        y = np_utils.to_categorical(np.array(y_labels), num_classes)
 yield x, y

定义方法 preprocess, 对函数的输入数据进行图像的标准化处理。

def preprocess(inputs):
 inputs[..., 0] -= 99.9
 inputs[..., 1] -= 92.1
 inputs[..., 2] -= 82.6
 inputs[..., 0] /= 65.8
 inputs[..., 1] /= 62.3
 inputs[..., 2] /= 60.3
 return inputs
# 训练一个epoch大约需4分钟
# 类别数量
num_classes = 101
# batch大小
batch_size = 4
# epoch数量
epochs = 1
# 学习率大小
lr = 0.005
# 优化器定义
sgd = SGD(lr=lr, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
# 开始训练
history = model.fit_generator(generator_train_batch(train_list, batch_size, num_classes,img_path),
 steps_per_epoch= len(train_list) // batch_size,
                              epochs=epochs,
                              callbacks=[onetenth_4_8_12(lr)],
 validation_data=generator_val_batch(test_list, batch_size,num_classes,img_path),
 validation_steps= len(test_list) // batch_size,
                              verbose=1)
# 对训练结果进行保存
model.save_weights(os.path.join(results_path, 'weights_c3d.h5'))
WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
Epoch 1/1
20/20 [==============================] - 442s 22s/step - loss: 28.7099 - acc: 0.9344 - val_loss: 27.7600 - val_acc: 1.0000

5. 模型测试

接下来我们将训练之后得到的模型进行测试。随机在 UCF-101 中选择一个视频文件作为测试数据,然后对视频进行取帧,每 16 帧画面传入模型进行一次动作预测,并且将动作预测以及预测百分比打印在画面中并进行视频播放。

首先,引入相关的库。

from IPython.display import clear_output, Image, display, HTML
import time
import cv2
import base64
import numpy as np

构建模型结构并且加载权重。

from models import c3d_model
model = c3d_model()
model.load_weights(os.path.join(results_path, 'weights_c3d.h5'), by_name=True) # 加载刚训练的模型

定义函数 arrayshow,进行图片变量的编码格式转换。

def arrayShow(img):
 _,ret = cv2.imencode('.jpg', img) 
 return Image(data=ret) 

进行视频的预处理以及预测,将预测结果打印到画面中,最后进行播放。

# 加载所有的类别和编号
with open('./ucfTrainTestlist/classInd.txt', 'r') as f:
 class_names = f.readlines()
 f.close()
# 读取视频文件
video = './videos/v_Punch_g03_c01.avi'
cap = cv2.VideoCapture(video)
clip = []
# 将视频画面传入模型
while True:
 try:
 clear_output(wait=True)
        ret, frame = cap.read()
 if ret:
 tmp = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 clip.append(cv2.resize(tmp, (171, 128)))
 # 每16帧进行一次预测
 if len(clip) == 16:
                inputs = np.array(clip).astype(np.float32)
                inputs = np.expand_dims(inputs, axis=0)
 inputs[..., 0] -= 99.9
 inputs[..., 1] -= 92.1
 inputs[..., 2] -= 82.6
 inputs[..., 0] /= 65.8
 inputs[..., 1] /= 62.3
 inputs[..., 2] /= 60.3
                inputs = inputs[:,:,8:120,30:142,:]
                inputs = np.transpose(inputs, (0, 2, 3, 1, 4))
 # 获得预测结果
 pred = model.predict(inputs)
                label = np.argmax(pred[0])
 # 将预测结果绘制到画面中
                cv2.putText(frame, class_names[label].split(' ')[-1].strip(), (20, 20),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.6,
 (0, 0, 255), 1)
                cv2.putText(frame, "prob: %.4f" % pred[0][label], (20, 40),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.6,
 (0, 0, 255), 1)
 clip.pop(0)
 # 播放预测后的视频 
            lines, columns, _ = frame.shape
            frame = cv2.resize(frame, (int(columns), int(lines)))
 img = arrayShow(frame)
            display(img)
 time.sleep(0.02)
 else:
 break
 except:
 print(0)
cap.release()

6.I3D 模型

在之前我们简单介绍了 I3D 模型,I3D 官方 github 库提供了在 Kinetics 上预训练的模型和预测代码,接下来我们将体验 I3D 模型如何对视频进行预测。

首先,引入相关的包

import numpy as np
import tensorflow as tf
import i3d
WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.
For more information, please see:
 * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md
 * https://github.com/tensorflow/addons
If you depend on functionality not listed there, please file an issue.

进行参数的定义

# 输入图片大小
_IMAGE_SIZE = 224
#  视频的帧数
_SAMPLE_VIDEO_FRAMES = 79
# 输入数据包括两部分:RGB和光流
# RGB和光流数据已经经过提前计算
_SAMPLE_PATHS = {
 'rgb': 'data/v_CricketShot_g04_c01_rgb.npy',
 'flow': 'data/v_CricketShot_g04_c01_flow.npy',
}
# 提供了多种可以选择的预训练权重
# 其中,imagenet系列模型从ImageNet的2D权重中拓展而来,其余为视频数据下的预训练权重
_CHECKPOINT_PATHS = {
 'rgb': 'data/checkpoints/rgb_scratch/model.ckpt',
 'flow': 'data/checkpoints/flow_scratch/model.ckpt',
 'rgb_imagenet': 'data/checkpoints/rgb_imagenet/model.ckpt',
 'flow_imagenet': 'data/checkpoints/flow_imagenet/model.ckpt',
}
# 记录类别文件
_LABEL_MAP_PATH = 'data/label_map.txt'
# 类别数量为400
NUM_CLASSES = 400

定义参数:

  • imagenet_pretrained :如果为 True,则调用预训练权重,如果为 False,则调用 ImageNet 转成的权重
imagenet_pretrained = True
# 加载动作类型
kinetics_classes = [x.strip() for x in open(_LABEL_MAP_PATH)]
tf.logging.set_verbosity(tf.logging.INFO)

构建 RGB 部分模型

rgb_input = tf.placeholder(tf.float32, shape=(1, _SAMPLE_VIDEO_FRAMES, _IMAGE_SIZE, _IMAGE_SIZE, 3))
with tf.variable_scope('RGB', reuse=tf.AUTO_REUSE):
 rgb_model = i3d.InceptionI3d(NUM_CLASSES, spatial_squeeze=True, final_endpoint='Logits')
 rgb_logits, _ = rgb_model(rgb_input, is_training=False, dropout_keep_prob=1.0)
rgb_variable_map = {}
for variable in tf.global_variables():
 if variable.name.split('/')[0] == 'RGB':
 rgb_variable_map[variable.name.replace(':0', '')] = variable
rgb_saver = tf.train.Saver(var_list=rgb_variable_map, reshape=True)

构建光流部分模型

flow_input = tf.placeholder(tf.float32,shape=(1, _SAMPLE_VIDEO_FRAMES, _IMAGE_SIZE, _IMAGE_SIZE, 2))
with tf.variable_scope('Flow', reuse=tf.AUTO_REUSE):
 flow_model = i3d.InceptionI3d(NUM_CLASSES, spatial_squeeze=True, final_endpoint='Logits')
 flow_logits, _ = flow_model(flow_input, is_training=False, dropout_keep_prob=1.0)
flow_variable_map = {}
for variable in tf.global_variables():
 if variable.name.split('/')[0] == 'Flow':
 flow_variable_map[variable.name.replace(':0', '')] = variable
flow_saver = tf.train.Saver(var_list=flow_variable_map, reshape=True) 

将模型联合,成为完整的 I3D 模型

model_logits = rgb_logits + flow_logits
model_predictions = tf.nn.softmax(model_logits)

开始模型预测,获得视频动作预测结果。

预测数据为开篇提供的 RGB 和光流数据:

with tf.Session() as sess:
 feed_dict = {}
 if imagenet_pretrained:
 rgb_saver.restore(sess, _CHECKPOINT_PATHS['rgb_imagenet']) # 加载rgb流的模型
 else:
 rgb_saver.restore(sess, _CHECKPOINT_PATHS['rgb'])
 tf.logging.info('RGB checkpoint restored')
 if imagenet_pretrained:
 flow_saver.restore(sess, _CHECKPOINT_PATHS['flow_imagenet']) # 加载flow流的模型
 else:
 flow_saver.restore(sess, _CHECKPOINT_PATHS['flow'])
 tf.logging.info('Flow checkpoint restored') 
 start_time = time.time()
 rgb_sample = np.load(_SAMPLE_PATHS['rgb']) # 加载rgb流的输入数据
 tf.logging.info('RGB data loaded, shape=%s', str(rgb_sample.shape))
 feed_dict[rgb_input] = rgb_sample
 flow_sample = np.load(_SAMPLE_PATHS['flow']) # 加载flow流的输入数据
 tf.logging.info('Flow data loaded, shape=%s', str(flow_sample.shape))
 feed_dict[flow_input] = flow_sample
 out_logits, out_predictions = sess.run(
 [model_logits, model_predictions],
 feed_dict=feed_dict)
 out_logits = out_logits[0]
 out_predictions = out_predictions[0]
 sorted_indices = np.argsort(out_predictions)[::-1]
 print('Inference time in sec: %.3f' % float(time.time() - start_time))
 print('Norm of logits: %f' % np.linalg.norm(out_logits))
 print('\nTop classes and probabilities')
 for index in sorted_indices[:20]:
 print(out_predictions[index], out_logits[index], kinetics_classes[index])
WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-1.13.1/lib/python3.6/site-packages/tensorflow/python/training/saver.py:1266: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.
Instructions for updating:
Use standard file APIs to check for files with this prefix.
INFO:tensorflow:Restoring parameters from data/checkpoints/rgb_imagenet/model.ckpt
INFO:tensorflow:RGB checkpoint restored
INFO:tensorflow:Restoring parameters from data/checkpoints/flow_imagenet/model.ckpt
INFO:tensorflow:Flow checkpoint restored
INFO:tensorflow:RGB data loaded, shape=(1, 79, 224, 224, 3)
INFO:tensorflow:Flow data loaded, shape=(1, 79, 224, 224, 2)
Inference time in sec: 1.511
Norm of logits: 138.468643
Top classes and probabilities
1.0 41.813675 playing cricket
1.497162e-09 21.49398 hurling (sport)
3.8431236e-10 20.13411 catching or throwing baseball
1.549242e-10 19.22559 catching or throwing softball
1.1360187e-10 18.915354 hitting baseball
8.801105e-11 18.660116 playing tennis
2.4415466e-11 17.37787 playing kickball
1.153184e-11 16.627766 playing squash or racquetball
6.1318893e-12 15.996157 shooting goal (soccer)
4.391727e-12 15.662376 hammer throw
2.2134352e-12 14.9772005 golf putting
1.6307096e-12 14.67167 throwing discus
1.5456218e-12 14.618079 javelin throw
7.6690325e-13 13.917259 pumping fist
5.1929587e-13 13.527372 shot put
4.2681337e-13 13.331245 celebrating
2.7205462e-13 12.880901 applauding
1.8357015e-13 12.487494 throwing ball
1.6134511e-13 12.358444 dodgeball
1.1388395e-13 12.010078 tap dancing

点击关注,第一时间了解华为云新鲜技术~

相关推荐

鸿蒙案例上新啦 | 购物、听歌、健身:15个模板带你一键激活社交娱乐

页面层级如何组织、跨页共享状态如何同步、列表与详情及个人中心如何形成稳定闭环。鸿蒙开发实践中心将这些高频消费与互动场景沉淀为可参考的标准模板,提供从业务架构到界面实现的快捷实践入口。更多实战案例欢迎前往鸿蒙开发实践中心案例中心查看并开启云端体验。

华为云官方博客 361

鸿蒙案例上新啦 | 出门打车、到家上课:25个模板带你一屏打通日常生活

如何合理拆分页面组件、如何建立单一可信的状态源、如何让用户在每一步操作中都获得明确反馈。鸿蒙开发实践中心以标准化的应用与元服务模板为入口,将清晰的业务架构与可复用的代码结构直观呈现。不妨立即挑选一个感兴趣的方向进入云端环境,从页面布局、组件封装、状态管理到路由组织,亲手跑通你的鸿蒙实战项目。

华为云官方博客 340

LakeAgent:DWS数据仓库的第二大脑,告别 “翻译式运维”,迈入智能自治时代

和普通 SQL 改写工具不同,LakeAgent 自动做多方案代价对比,主动规避负优化陷阱:补充分区键过滤实现剪枝,扫描分区由 37 收敛至 1,执行代价从 758.28 降至 113.74;未来的数据仓库,将不止能算、能存,更能看懂自己、诊断自己、理解自己。长久以来,数仓的智能都依附于人:信号需要人解读,瓶颈需要人研判,经验困在个体里,无法随底座永续生长。CPU 高、CPU 告警、CPU 诊断、CPU 使用率过高、CPU 满。语法、错误码、计费、性能调优、最佳实践、故障处置等全场景内容。

华为云官方博客 565

如何使用RDS Supabase后端BaaS能力:文件存储(File Storage)

• product-images(公开桶,允许公共读取):策略名称"Public read for product-images",允许SELECT,目标角色anon,策略定义bucket_id = 'product-images'。上传/删除需另配INSERT/DELETE策略,详见SQL。• product-specs(私有桶,仅认证用户访问自己的文件夹):建议拆为上传、读取、删除三条策略,策略定义均为 bucket_id = 'product-specs' 且仅限本人文件夹(详见下文 SQL)。

华为云官方博客 490

如何使用RDS Supabase后端BaaS能力:实时订阅与推送(Realtime)

Realtime 把数据库的每次变更同步到客户端:表里增、删、改一行,订阅者无需刷新页面或主动请求即可秒级收到。三大能力各司其职:• Postgres Changes — 监听表的 INSERT/UPDATE/DELETE,变化即通知• Broadcast — 客户端之间直接互发,适合瞬时通知、协同编辑• Presence — 跟踪频道里“谁在线”典型场景有实时数据展示(订单、库存、监控指标即时刷新)、即时通讯(消息收发、在线名单、“对方正在输入”)、协同编辑与实时通知。

华为云官方博客 482

AI Agent如何通过MCP连接到华为云RDS Supabase应用平台

Schema元数据列出所有可访问的表(按schema分组)。Schema元数据列出表的列及元数据(类型/默认值/约束)。Schema元数据列出所有约束(PK/FK/UNIQUE/CHECK/EXCLUDE)。可按schema/表/类型过滤。Schema元数据列出所有外键关系。可按schema/表过滤。Schema元数据列出所有索引及定义和大小。可按schema/表过滤。Schema元数据列出已应用的数据库迁移记录。Schema元数据列出已安装的PostgreSQL扩展。

华为云官方博客 484

华为大数据Flink让每一 CU 算力,跑出开源 5.74 倍的性能

1. 开源Apache Flink 已成为业界流计算事实标准,但在极端重负载场景下存在性能瓶颈。2. 华为大数据Flink通过多项自研深度优化,在执行计划、算子执行、状态存储三个层面构建协同的优化体系。3. Nexmark Benchmark 测试结果:整体性能提升 5.74 倍,极端重负载场景性能领先最高 18.3 倍。4. 100% 兼容 Apache Flink 1.20,业务代码零改造,无缝迁移。

华为云官方博客 387

LakeAgent实战 | 业务分析篇从一句提问到业务分析

本文以“订单金额变化”分析为例,展示LakeAgent如何通过自然语言提问,结合DataArtsStudio的数据资产与专业技能,帮助业务人员快速定位数据、生成SQL、追踪血缘、生成报告。从问题出发,逐步实现数据发现、变化洞察、原因追溯与团队协作,最终形成可复用的分析流程与企业规则,显著提升数据分析效率与一致性。

华为云官方博客 399

华为云RDS Supabase AI应用已开放公测 :30分钟搭建AI应用后端

认证、存储、实时推送、数据库API——4个后端模块,传统开发需要数周。今天,你只需要30分钟。AI创业公司的全栈开发工程师。上周老板说"下周要上线的AI对话应用,后端你来搞"——认证鉴权、数据库接口、文件存储、实时推送,每一个模块都需要数周搭建,而市场不会等你。小张打开华为云RDS Supabase,30分钟搭好认证、数据库API、对象存储,剩下的时间全用来打磨AI交互体验。基于开源Supabase+华为云RDS PostgreSQL全托管能力,为开发者提供。

华为云官方博客 406

如何使用RDS Supabase后端BaaS能力:数据库函数(Database Function)

上一篇介绍了 Database Data API——建表即自动生成增删改查接口,解决单表读写,但聚合统计、跨表事务、字段自动维护等逻辑已超出其能力边界。本篇推进到数据库函数(Database Function):把业务逻辑封装进数据库,前端通过 .rpc() 调用,由触发器自动响应数据变更。上一篇中,小张基于 Data API 完成了产品目录的建表与基础读写。但新需求随之而来:按分类统计产品数与价格区间、上架新品同时写产品表与定价表、产品修改后自动刷新更新时间。

华为云官方博客 469

如何使用RDS Supabase后端BaaS能力:创表即生成API(Database Data API)

认证、存储、实时推送、数据库API——4个后端模块,传统开发要数周。本系列逐个拆解,首篇聚焦数据库API(Database Data API):建表即得 API,无需手写后端。小张,AI创业公司的全栈工程师。老板让他做个产品目录页,展示产品与价格、支持上下架。传统做法要搭后端、写接口、配权限,工期少说1-2周;而在华为云RDS Supabase,建两张表、应用 SDK 直连,几分钟增删改查全跑通。

华为云官方博客 487

从一句话到一个能出去的链接,AI开发者空间做了什么

自行搭建的 Agent、正在使用的开源项目、团队既有的工具,都可以接入,可以通过AI创建或者手动搭建环境;华为云 AI开发者空间——面向开发者的云端一站式开发平台,做的就是把这段路接上:环境免安装,浏览器打开即为完整的 Linux 运行环境,预置的 AI 智能体开箱即用。第一个任务建议选能出结果的:做一个游戏、生成一个页面、创建一台实例,从需求走到可访问的链接,一次就能看清这个环境在做什么。沙箱是一个完整的 Linux 环境,依赖、服务、端口都是真实的,不是模拟。环境释放后,权限随之失效。

华为云官方博客 430

华为云码道配置自定义大模型,四种方式完整实操

案例介绍。

华为云官方博客 636

图数据库:实现穿透式监管的数据基座

穿透式监管标志着国企监管从“管企业”向“管资本”转型过程中的关键一跃。而图数据库正是这一跃的技术支点。从股权穿透到资金链穿透,从供应链穿透到数据穿透,华为GES图数据库正在将“穿透式监管”从理念变为可落地、可操作的实践。无论是天眼查式的全量链路查询,还是某集团财经的税务规则判断,抑或是芯片供应链式的部件风险分析,乃至通过Palantir构建决策知识图谱,其底层逻辑都是一致的——用图的力量,穿透一切形式的“隔离层”,直抵风险本质与责任核心。

华为云官方博客 670

《公共云三十问》正式收官,奔赴企业AI百场景新征程

今年6月底,公共云产业联盟重点推出《公共云三十问》专栏,以每周三问的节奏,连载十周,解读《先进公共云》白皮书,分享国计民生系列案例,旨在凝聚共识、推动落地实践。同时,专栏分析公共云在产业升级、民生福祉、科技创新、全球发展等方面的作用,梳理中国特色公共云发展路径:以普惠云拓展用云广度,以智算云提升用云深度,以自主云夯实用云厚度,以全球云打开用云跨度。这十问从专属云、行业云切入,深入政务、金融、交通、电力、钢铁、化工、油气、制造等国计民生场景,回答公共云“怎么用”。

华为云官方博客 474

开发者小技巧|IAM配置,让码道代码智能体连续30天免登录

案例介绍。

华为云官方博客 650

码道深度对接CodeArts,让需求自动落地为代码

案例介绍。

华为云官方博客 723

【公共云三十问 之三十】拥抱AI,企业如何建设面向智能体的专属云?

企业可分阶段建设覆盖开发、运行、运营及安全的一体化智能体平台——从构建一站式、高低码协同的智能体开发平台,到打造高性能、极致弹性的运行时环境,再到搭建AgentOps驱动的持续运营与运维体系,同时构建端到端、多层次的全链路安全防护体系。在数据湖建设方面,遵循“存量复用、平滑演进、AI导向、分步迭代”原则,分三阶段推进——打造AI多模数据湖核心能力、完成存算分离与统一元数据管理、实现闭环赋能全面支撑智能体规模化落地,在保护既有投资的前提下将传统数据平台转型为AI数据专属供给平台。

华为云官方博客 825

【公共云三十问 之二十九】国计民生之制造:制造云如何重塑数智时代的新质生产力?

平台打通软件交付的完整路径,覆盖需求管理、代码托管、代码检查、编译构建、制品仓库、部署、测试等关键环节,支持大模型能力融入研发全流程,实现从需求到交付的端到端管理。通过构建“研发一朵云”,方案打破地域与组织壁垒,实现跨团队协同开发,有效缩短软件交付周期,助力工业制造企业从“传统研发”走向“敏捷研发”,加速数智化转型进程。当制造云真正成为数据流通的平台、AI创新的底座,公共云的社会价值将从基础设施层向生产场景层持续延伸,为新型工业化建设和制造强国战略注入源源不断的动力,重塑数智时代的中国制造新质生产力。

华为云官方博客 792

告别重复手工迁仓,码道MCP+Skill实现仓库批量迁移

案例介绍。

华为云官方博客 791

【公共云三十问 之二十八】国计民生之油气:智算云如何叩响数智时代的“地心蓝金”?

西南油气田以“向地球深部要资源”为战略方向,联合以华为云Stack为代表的公共云服务商共同打造统一算力底座,建设西南区域数据湖与通用技术平台,构建“勘探开发工程技术、天然气生产过程管控、天然气产运储销”等三个一体化协同应用场景,支撑油气勘探、开发生产、管输储运等全业务链的数智化转型。当智算云真正成为数据流通的平台、AI创新的底座,油气田得以将算力效能、数据价值与智能技术深度融入勘探开发全链条,将“看不见的算力”转化为“摸得着的储量”,以智能化手段持续降低勘探风险、缩短发现周期、提高采收效率,确保生产安全。

华为云官方博客 613

【公共云三十问 之二十七】国计民生之化工:数智云如何重塑传统化工新范式?

在架构方面,方案构建云边协同的统一体系,涵盖AI协同、数据协同与运营协同三大维度——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现“边用边学”的智能闭环,模型平均精度提升20%以上。此外,方案提供一站式企业级工业物联网平台、数据湖与数据治理平台,覆盖工业数据分析“采、存、算、管、用”全流程,打通生产现场与管理系统间的数据壁垒,有效消除数据孤岛。层面,方案充分发挥软硬协同优势,实现计算、存储、网络与云平台的深度协同,训练线性度超95%,为大模型训练推理提供强劲算力支撑。▲化工“数智”新模式。

华为云官方博客 664

【公共云三十问 之二十六】国计民生之钢铁:数智云如何淬炼中国钢铁新力量?

同时,构建云边端协同的统一架构,支撑集团总部与各生产基地两级协同发展——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现训推一体化的资源调度与高效协同,为钢铁行业的数智化转型构建了坚实的算力底座。层面,方案构建覆盖“工业数采→边缘IT/OT融合→统一数据湖→数据治理平台→数据应用”全链路的一站式数据治理与流通平台,打通生产现场与管理系统间的数据壁垒,让数据“采得到、流得动、用得好”,加速数据价值从生产现场向经营决策层流动释放。湘潭钢铁集团的钢铁数智云,是钢铁工业智能云建设的标杆案例。

华为云官方博客 526

LakeWatch——MRS 智能运维Agent

从资源池、队列、作业等多个维度,对集群CPU与内存资源进行精细化分析与对比,直观呈现不同时间段的空闲、满载等使用状态,识别资源浪费,指导治理优化,为扩缩容决策提供数据支撑。对HDFS存储进行多维度深度分析(目录、用户、用户组等),涵盖使用量、增量、文件大小分布及数据热度等指标,帮助快速识别增长较快的目录、长期未访问的文件,统计目录文件数量与小文件占比,评估HDFS总存储量与扩缩容需求,为存储治理与资源规划提供全面数据支撑。Agent主动巡检,识别异常趋势并提前预警,让运维从"事后处理"转向"事前预防"。

华为云官方博客 515

华为云专题文档发布:丰富的AI案例、选型指导和概念解读

发布 “云服务选型”、“云计算概念”专题,提供云服务选型指导,助您选择匹配业务的云服务,解读云计算相关概念,开启云上学习之路。开发者工具和文档专区上线,提供从学习、实践到反馈的全链路支持。帮助中心新增100余篇AI案例。

华为云官方博客 286

一个人,也能用AI做点“星东西”

华为云星耀创想者大赛-2026华为云OPC创意大赛等你来~

华为云官方博客 291

从需求到可执行工作项:MCP+Skill 让智能体规划真正落地

回顾整个体验,以前让智能体帮我拆需求,它是洋洋洒洒给我列了一大篇 Markdown,看着挺像那么回事,但最后还是得我一条条往 CodeArts Req 里搬,搬完再手动挂父子关系、排日期,拆需求五分钟,搬运两小时。现在好了,MCP 给智能体接上了"手",Skill 给它装上了"项目经理的脑子",一句话下去,34 个工作项连带排期、层级关系全给我建好了,甘特图一拉,齐刷刷都在两周内,节省了多少工作量啊,美滋滋。本次实操在码道代码智能体基础上,构建了一套"需求→可执行工作项"的自动化规划方案。

华为云官方博客 578

华为云码道「码力续航计划」更新!

✅上新GLM‑5.3‑Flash,高速响应,代码生成、工程解析、Agent调试高效输出。新增GLM‑5.3‑Flash福利模型,每日解锁1000万免费Tokens。● 本次活动共发放总量价值100万元Tokens,发完即止!把耗算力的编码重活,交给华为云码道代码智能体🚀🚀。● 每日额度准时刷新,当日清零、次日满血重置。✅复杂算法、大项目解析、批量代码生成随便跑。✅不用抠额度、不用算消耗,放开调试大胆迭代。✅无需额外操作,登录即送,直接切换模型使用。● 把算力交给码道,让撸码不再内耗👏🏻。

华为云官方博客 691

【公共云三十问 之二十四】国计民生之交通:交通云如何铺就数智通衢新坦途?

交通行业作为支撑实体经济的关键基础设施,涵盖公路、铁路、机场、港口、地铁等众多子领域,其中,公路网络作为综合交通运输体系的基础骨架,承担着全国超过70%的客货运量,其数字化、智能化转型的需求尤为迫切。方面,提供Agent开发框架、知识库管理、RAG工程、意图识别、静态应用编排及模型评测等能力,支持客户将行业知识、业务流程与AI能力深度融合,快速构建面向收费稽核、路网调度、应急处置等场景的智能应用。开发并实现落地应用,全面覆盖建设、管理、养护、运营、服务、安全、办公七大业务领域。

华为云官方博客 464

【公共云三十问 之二十五】国计民生之电力:电力云如何点亮数智电力新引擎?

方案构建了覆盖数据获取、质量评估到标准化处理的全链路能力。基于公共云服务商智算底座及气象大模型,通过时空图神经网络重新建模产流机制,中国华电建成超50TB多源融合数据集,突破时空建模与机理融合等五大关键技术,短期径流预测精度较传统机理模型提升5个百分点以上,实现15天中期径流预测精度超85%,推理效率达秒级。基于气象大模型的基础架构与预训练能力,客户可直接在大模型之上开展增量训练与微调,充分利用场站所在区域的高精度历史数据(如3公里、1公里分辨率),针对不同场站和区域的地形地貌与气候特征进行模型调优。

华为云官方博客 381
上一篇: 全球银行最大分布式核心系统全面上线,邮储银行做到了!
下一篇: 多线程安全问题原理和4种解决办法
华为云开发者联盟
华为云开发者联盟 企业官方账号 企业官方账号
博客等级 码龄10年 72万+粉丝 5985原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值