Files
paddlepaddle--paddle/test/ai_edited_test/test_ai_model_structure.py
T
2026-07-13 12:40:42 +08:00

155 lines
5.2 KiB
Python

# Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
模型剪枝和压缩测试 / Model Pruning and Compression Tests
测试目标 / Test Target:
paddle.nn 模型结构操作
覆盖的模块 / Covered Modules:
- nn.Layer.parameters(): 参数访问
- nn.Layer.sublayers(): 子层访问
- nn.Layer.named_parameters(): 命名参数
- 模型迭代和修改
作用 / Purpose:
补充模型结构操作API的测试,提升覆盖率。
"""
import unittest
import numpy as np
import paddle
from paddle import nn
paddle.disable_static()
class TestModelStructure(unittest.TestCase):
"""测试模型结构 / Test model structure"""
def setUp(self):
"""设置测试模型 / Setup test model"""
self.model = nn.Sequential(
nn.Linear(4, 8),
nn.ReLU(),
nn.Linear(8, 4),
nn.ReLU(),
nn.Linear(4, 2),
)
def test_parameters_count(self):
"""测试参数数量 / Test parameter count"""
params = list(self.model.parameters())
# 3 Linear layers, each with weight and bias = 6 params
self.assertEqual(len(params), 6)
def test_named_parameters(self):
"""测试命名参数 / Test named parameters"""
named_params = dict(self.model.named_parameters())
self.assertIn('0.weight', named_params)
self.assertIn('0.bias', named_params)
def test_sublayers(self):
"""测试子层 / Test sublayers"""
sublayers = self.model.sublayers()
self.assertEqual(len(sublayers), 5) # 3 Linear + 2 ReLU
def test_named_sublayers(self):
"""测试命名子层 / Test named sublayers"""
named_sublayers = dict(self.model.named_sublayers())
self.assertIn('0', named_sublayers)
self.assertIn('2', named_sublayers)
def test_total_params_count(self):
"""测试总参数量 / Test total parameter count"""
total = sum(p.numel() for p in self.model.parameters())
# Linear(4,8): 4*8+8=40, Linear(8,4): 8*4+4=36, Linear(4,2): 4*2+2=10 = 86
self.assertEqual(total, 86)
class TestModelModification(unittest.TestCase):
"""测试模型修改 / Test model modification"""
def test_freeze_parameters(self):
"""测试冻结参数 / Test freezing parameters"""
model = nn.Linear(4, 2)
# Freeze all parameters
for param in model.parameters():
param.stop_gradient = True
# Verify all frozen
for param in model.parameters():
self.assertTrue(param.stop_gradient)
def test_selective_freeze(self):
"""测试选择性冻结 / Test selective freeze"""
model = nn.Sequential(nn.Linear(4, 8), nn.Linear(8, 2))
# Freeze first layer only
for param in model[0].parameters():
param.stop_gradient = True
# First layer frozen
for param in model[0].parameters():
self.assertTrue(param.stop_gradient)
# Second layer not frozen
for param in model[1].parameters():
self.assertFalse(param.stop_gradient)
def test_parameter_count_with_frozen(self):
"""测试带冻结参数的训练 / Test training with frozen parameters"""
model = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 2))
# Freeze first linear
for param in model[0].parameters():
param.stop_gradient = True
# Only second linear should have trainable params
trainable = [p for p in model.parameters() if not p.stop_gradient]
# Linear(8,2): 8*2+2=18 trainable params
self.assertEqual(sum(p.numel() for p in trainable), 18)
class TestModelClone(unittest.TestCase):
"""测试模型克隆 / Test model cloning"""
def test_model_copy(self):
"""测试模型复制 / Test model copy"""
import copy
model1 = nn.Linear(4, 2)
model2 = copy.deepcopy(model1)
# Verify weights are the same
np.testing.assert_allclose(model1.weight.numpy(), model2.weight.numpy())
# Modify model2 and verify model1 is unchanged
with paddle.no_grad():
model2.weight[:] = paddle.zeros_like(model2.weight)
self.assertFalse(
np.allclose(model1.weight.numpy(), model2.weight.numpy())
)
def test_sequential_access(self):
"""测试Sequential层访问 / Test Sequential layer access"""
model = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 2))
# Access layers by index
first_layer = model[0]
self.assertIsInstance(first_layer, nn.Linear)
last_layer = model[-1]
self.assertIsInstance(last_layer, nn.Linear)
if __name__ == '__main__':
unittest.main()