Video Caption Classification CNN - 视频字幕分类模型
基于 Mocode 深度学习引擎训练的视频字幕分类模型,支持 20 种视频描述主题分类。
模型概览
| 属性 |
值 |
| 模型名称 |
video-caption-classification-cnn |
| 格式 |
GGUF v3 |
| 架构 |
CNN (5 Conv Blocks + GAP + 2 Dense) |
| 任务 |
视频描述分类 (Video Caption Classification) |
| 输入 |
24 通道 (8帧 × 3RGB), 64×64 |
| 输出 |
20 类视频描述主题 |
| 参数量 |
4.99M (4,993,172) |
| 张量数 |
49 |
| 文件大小 |
19.06 MB |
| 精度 |
F32 (float32) |
| 训练准确率 |
100% |
| 最佳 epoch |
3 |
| 训练时间 |
34.7 秒 |
| 训练设备 |
CUDA GPU |
| 框架 |
Mocode DeepLearningEngine (PyTorch) |
| License |
Apache-2.0 |
数据集
源数据集
注: 由于源数据集规模巨大(数百GB),本模型使用合成数据进行训练验证。合成数据模拟了 20 种视频描述主题的视觉特征(颜色、运动、纹理等)。
训练数据规格
| 项目 |
值 |
| 训练样本 |
2000 (100/类 × 20类) |
| 测试样本 |
600 (30/类 × 20类) |
| 总样本数 |
2600 |
| 每视频帧数 |
8 |
| 每帧尺寸 |
64×64×3 |
| 输入通道 |
24 (8帧 × 3RGB) |
| 数据格式 |
NPZ (Numpy) |
20 类视频描述主题
| 编号 |
类别 |
描述 |
| 0 |
人物活动 |
人物在进行各种活动 |
| 1 |
自然风光 |
山川湖海等自然景观 |
| 2 |
城市建筑 |
城市风光和建筑 |
| 3 |
动物世界 |
各种动物 |
| 4 |
美食烹饪 |
美食制作和展示 |
| 5 |
运动健身 |
体育运动和健身 |
| 6 |
科技产品 |
科技产品和设备 |
| 7 |
艺术创作 |
艺术创作过程 |
| 8 |
日常生活 |
日常生活场景 |
| 9 |
旅行探险 |
旅行和探险 |
| 10 |
汽车交通 |
汽车和交通工具 |
| 11 |
时尚穿搭 |
时尚和服装 |
| 12 |
音乐舞蹈 |
音乐和舞蹈 |
| 13 |
教育学习 |
教育和学习 |
| 14 |
医疗健康 |
医疗和健康 |
| 15 |
商业办公 |
商业和办公场景 |
| 16 |
家庭亲子 |
家庭和亲子互动 |
| 17 |
节日庆典 |
节日和庆典 |
| 18 |
夜景灯光 |
夜景和灯光 |
| 19 |
海洋水下 |
海洋和水下世界 |
模型架构
整体结构
Input (24ch × 64×64)
│
├─ Block 1: Conv(24→32) + BN + Conv(32→32) + MaxPool(2×2)
│ 输出: 32ch × 32×32
│
├─ Block 2: Conv(32→64) + BN + Conv(64→64) + MaxPool(2×2)
│ 输出: 64ch × 16×16
│
├─ Block 3: Conv(64→128) + BN + Conv(128→128) + MaxPool(2×2)
│ 输出: 128ch × 8×8
│
├─ Block 4: Conv(128→256) + BN + Conv(256→256) + MaxPool(2×2)
│ 输出: 256ch × 4×4
│
├─ Block 5: Conv(256→512) + BN + Conv(512→512) + MaxPool(2×2)
│ 输出: 512ch × 2×2
│
├─ AdaptiveAvgPool2d(1×1)
│ 输出: 512ch × 1×1
│
├─ Flatten
│ 输出: 512
│
├─ Dense(512 → 512) + ReLU
│
└─ Dense(512 → 20) + Linear
输出: 20 (分类logits)
详细参数
| 层 |
类型 |
输入 |
输出 |
参数说明 |
| layers.0 |
Conv2d |
24ch × 64×64 |
32ch × 64×64 |
3×3 kernel, stride=1, padding=1 |
| layers.1 |
BatchNorm2d |
32ch |
32ch |
- |
| layers.2 |
Conv2d |
32ch × 64×64 |
32ch × 64×64 |
3×3 kernel, stride=1, padding=1 |
| layers.3 |
MaxPool2d |
32ch × 64×64 |
32ch × 32×32 |
2×2 kernel |
| layers.4 |
Conv2d |
32ch × 32×32 |
64ch × 32×32 |
3×3 kernel |
| layers.5 |
BatchNorm2d |
64ch |
64ch |
- |
| layers.6 |
Conv2d |
64ch × 32×32 |
64ch × 32×32 |
3×3 kernel |
| layers.7 |
MaxPool2d |
64ch × 32×32 |
64ch × 16×16 |
2×2 kernel |
| layers.8 |
Conv2d |
64ch × 16×16 |
128ch × 16×16 |
3×3 kernel |
| layers.9 |
BatchNorm2d |
128ch |
128ch |
- |
| layers.10 |
Conv2d |
128ch × 16×16 |
128ch × 16×16 |
3×3 kernel |
| layers.11 |
MaxPool2d |
128ch × 16×16 |
128ch × 8×8 |
2×2 kernel |
| layers.12 |
Conv2d |
128ch × 8×8 |
256ch × 8×8 |
3×3 kernel |
| layers.13 |
BatchNorm2d |
256ch |
256ch |
- |
| layers.14 |
Conv2d |
256ch × 8×8 |
256ch × 8×8 |
3×3 kernel |
| layers.15 |
MaxPool2d |
256ch × 8×8 |
256ch × 4×4 |
2×2 kernel |
| layers.16 |
Conv2d |
256ch × 4×4 |
512ch × 4×4 |
3×3 kernel |
| layers.17 |
BatchNorm2d |
512ch |
512ch |
- |
| layers.18 |
Conv2d |
512ch × 4×4 |
512ch × 4×4 |
3×3 kernel |
| layers.19 |
MaxPool2d |
512ch × 4×4 |
512ch × 2×2 |
2×2 kernel |
| layers.20 |
AdaptiveAvgPool2d |
512ch × 2×2 |
512ch × 1×1 |
output_size=(1,1) |
| layers.21 |
Flatten |
512ch × 1×1 |
512 |
- |
| layers.22 |
Dense + ReLU |
512 |
512 |
Linear(512, 512) |
| layers.23 |
Dense + Linear |
512 |
20 |
Linear(512, 20) |
总参数量: 4,993,172 (4.99M)
训练配置
| 配置项 |
值 |
| 优化器 |
Adam |
| 学习率 |
0.001 |
| 损失函数 |
CrossEntropyLoss |
| LR 调度器 |
Cosine Annealing |
| Batch Size |
16 |
| Epochs |
50 (早停于 13) |
| Early Stop |
10 epochs |
| Weight Decay |
1e-4 |
| 训练设备 |
CUDA GPU |
| 训练时间 |
34.7 秒 |
性能指标
| 指标 |
值 |
| 最佳准确率 |
100% |
| 最佳 epoch |
3 |
| 早停 epoch |
13 |
训练曲线
| Epoch |
Loss |
Accuracy |
LR |
| 1 |
0.9402 |
70.0% |
0.000999 |
| 2 |
0.6538 |
95.0% |
0.000994 |
| 3 |
0.4263 |
100.0% |
0.000986 |
| 5 |
0.2346 |
100.0% |
0.000957 |
| 10 |
0.1370 |
100.0% |
0.000750 |
| 13 (早停) |
- |
- |
- |
GGUF 格式详情
文件结构
GGUF Header
├── Magic (4B): 0x46554747
├── Version (4B): 3
├── Tensor Count (8B): 49
├── Metadata Count (8B): 8
├── Metadata KV Pairs
├── Tensor Info (name, dims, type, offset)
├── 32-byte Alignment Padding
└── Tensor Data (F32, 32-byte aligned)
元数据
| Key |
Value |
general.name |
video-caption-classification-cnn |
general.architecture |
mocode |
general.description |
视频字幕分类CNN模型 |
general.file_type |
F32 |
general.parameter_count |
4993172 |
general.tensor_count |
49 |
mocode.task |
image_classification |
mocode.num_classes |
20 |
张量命名
所有层使用 layers.{idx}.layer.{sub_layer} 命名:
- 卷积权重:
layers.{idx}.layer.weight (4D: out_ch, in_ch, kH, kW)
- BatchNorm:
weight, bias, running_mean, running_var, num_batches_tracked
- 全连接:
layers.{idx}.layer.0.weight/bias
使用方式
Python 推理
import numpy as np
import struct
GGUF_MAGIC = 0x46554747
GGML_TYPE_F32 = 0
def read_gguf_string(f):
length = struct.unpack('<Q', f.read(8))[0]
return f.read(length).decode('utf-8')
def load_gguf_tensors(file_path):
"""加载GGUF文件中的所有权重张量"""
with open(file_path, 'rb') as f:
magic = struct.unpack('<I', f.read(4))[0]
assert magic == GGUF_MAGIC, "Invalid GGUF magic"
version = struct.unpack('<I', f.read(4))[0]
tensor_count = struct.unpack('<Q', f.read(8))[0]
metadata_count = struct.unpack('<Q', f.read(8))[0]
# 跳过元数据
for _ in range(metadata_count):
read_gguf_string(f)
vtype = struct.unpack('<I', f.read(4))[0]
if vtype == 9: # ARRAY
struct.unpack('<I', f.read(4))
n = struct.unpack('<Q', f.read(8))[0]
for _ in range(n):
struct.unpack('<Q', f.read(8))
else:
f.read(8)
# 读取张量信息
tensor_infos = []
for _ in range(tensor_count):
name = read_gguf_string(f)
n_dims = struct.unpack('<I', f.read(4))[0]
dims = [struct.unpack('<Q', f.read(8))[0] for _ in range(n_dims)]
dims = dims[::-1]
ggml_type = struct.unpack('<I', f.read(4))[0]
offset = struct.unpack('<Q', f.read(8))[0]
tensor_infos.append((name, dims, ggml_type, offset))
pos = f.tell()
aligned = (pos + 31) & ~31
f.seek(aligned)
data_start = f.tell()
tensors = {}
for name, dims, ggml_type, offset in tensor_infos:
f.seek(data_start + offset)
shape = tuple(dims)
n_elements = 1
for d in shape:
n_elements *= d
data = f.read(n_elements * 4)
tensors[name] = np.frombuffer(data, dtype=np.float32).reshape(shape).copy()
return tensors
# 加载权重
tensors = load_gguf_tensors('video_caption_cnn.gguf')
print(f"加载了 {len(tensors)} 个张量")
PyTorch 推理
import torch
import torch.nn as nn
import numpy as np
class VideoCaptionCNN(nn.Module):
def __init__(self, num_classes=20):
super().__init__()
self.layers = nn.Sequential(
# Block 1
nn.Conv2d(24, 32, 3, padding=1),
nn.BatchNorm2d(32),
nn.Conv2d(32, 32, 3, padding=1),
nn.MaxPool2d(2),
# Block 2
nn.Conv2d(32, 64, 3, padding=1),
nn.BatchNorm2d(64),
nn.Conv2d(64, 64, 3, padding=1),
nn.MaxPool2d(2),
# Block 3
nn.Conv2d(64, 128, 3, padding=1),
nn.BatchNorm2d(128),
nn.Conv2d(128, 128, 3, padding=1),
nn.MaxPool2d(2),
# Block 4
nn.Conv2d(128, 256, 3, padding=1),
nn.BatchNorm2d(256),
nn.Conv2d(256, 256, 3, padding=1),
nn.MaxPool2d(2),
# Block 5
nn.Conv2d(256, 512, 3, padding=1),
nn.BatchNorm2d(512),
nn.Conv2d(512, 512, 3, padding=1),
nn.MaxPool2d(2),
# GAP + Classifier
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, num_classes),
)
def forward(self, x):
return self.layers(x)
# 创建模型并加载权重
model = VideoCaptionCNN(num_classes=20)
# 从GGUF加载权重并映射到PyTorch state_dict...
model.eval()
# 推理: 输入 8 帧视频,64×64
# video_frames: (8, 64, 64, 3) 的 numpy 数组
# 合并为 24 通道输入
input_tensor = np.concatenate([video_frames[i] for i in range(8)], axis=2)
input_tensor = input_tensor.transpose(2, 0, 1) # (24, 64, 64)
input_tensor = torch.from_numpy(input_tensor).float().unsqueeze(0)
with torch.no_grad():
output = model(input_tensor)
probabilities = torch.softmax(output, dim=1)
predicted_class = torch.argmax(output, dim=1).item()
class_names = [
"人物活动", "自然风光", "城市建筑", "动物世界", "美食烹饪",
"运动健身", "科技产品", "艺术创作", "日常生活", "旅行探险",
"汽车交通", "时尚穿搭", "音乐舞蹈", "教育学习", "医疗健康",
"商业办公", "家庭亲子", "节日庆典", "夜景灯光", "海洋水下"
]
print(f"预测类别: {class_names[predicted_class]}")
Mocode 训练框架
本模型使用 Mocode 深度学习引擎 训练,这是一个基于 PyTorch 的自定义深度学习框架,集成于 Mocode 脚本语言解释器中。
核心特性
- 支持 MLP / CNN / U-Net / Transformer 等多种网络架构
- 支持分类和回归任务
- 内置学习率调度器 (Cosine / Linear / Exponential)
- 支持早停机制
- 支持 GPU (CUDA) 加速训练
- 直接支持 GGUF 格式模型导出
Mocode 脚本语法
// 创建视频分类CNN网络
network video_caption_cnn : image_network(
input_channels=24,
input_size=64,
layers=[
conv2d(out_channels=32),
batchnorm2d(num_features=32),
conv2d(out_channels=32),
maxpool2d(kernel_size=2),
conv2d(out_channels=64),
batchnorm2d(num_features=64),
conv2d(out_channels=64),
maxpool2d(kernel_size=2),
conv2d(out_channels=128),
batchnorm2d(num_features=128),
conv2d(out_channels=128),
maxpool2d(kernel_size=2),
conv2d(out_channels=256),
batchnorm2d(num_features=256),
conv2d(out_channels=256),
maxpool2d(kernel_size=2),
conv2d(out_channels=512),
batchnorm2d(num_features=512),
conv2d(out_channels=512),
maxpool2d(kernel_size=2),
adaptiveavgpool2d(output_size=[1, 1]),
flatten(),
dense(out_features=512, activation="relu"),
dense(out_features=20, activation="linear")
]
)
// 加载数据集
dataset video_caption_data : image_dataset(
"video_caption_data.npz",
type="classification"
)
// 训练
train video_caption_cnn on video_caption_data with {
epochs: 50,
batch_size: 16,
optimizer: "Adam",
learning_rate: 0.001,
lr_scheduler: "cosine",
early_stop: 10
}
// 导出 GGUF
export_gguf video_caption_cnn to "video_caption_cnn.gguf"
注意事项
- 输入格式: 视频帧需归一化到 0, 1 范围,通道顺序 (C, H, W)
- 多帧输入: 8 帧图像在通道维度拼接为 24 通道输入
- 输入尺寸: 64×64 像素
- 输出格式: 最后一层为 Linear 激活(原始 logits),需手动加 softmax 获取概率
- GGUF 维度: GGUF 格式维度为反序(row-major),读取时需反转
- 数据对齐: 张量数据按 32 字节对齐
- 适用场景: 适用于视频内容理解、视频检索、视频标签生成等任务
相关模型
| 模型 |
任务 |
架构 |
参数量 |
| mocode-mini-gguf |
统一多模型 (4个子模型) |
Multi-Model |
16.46M |
| GOPRO Deblur |
图像去模糊 |
U-Net |
7.77M |
| VINS Classification |
图像编辑分类 (13类) |
CNN |
0.46M |
| NOOB2EDIT Classification |
动漫CG编辑分类 (15类) |
CNN |
0.46M |
| VFI Interpolation |
视频帧插值 |
U-Net |
7.77M |
版本历史
| 版本 |
日期 |
说明 |
| 1.0.0 |
2026-07-17 |
初始版本,20类视频描述分类 |
License
Apache License 2.0