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

213 lines
9.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Copyright (c) 2024 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.
# [AUTO-GENERATED] Unit test for paddle.nn.initializer.Orthogonal
# 自动生成的单测,覆盖 paddle.nn.initializer.orthogonal 模块中未覆盖的代码
# Target: cover uncovered lines 157-271 in paddle/python/paddle/nn/initializer/orthogonal.py
"""
测试模块:paddle.nn.initializer.Orthogonal
Test Module: paddle.nn.initializer.Orthogonal
本测试覆盖以下功能:
This test covers the following functions:
1. Orthogonal 初始化器在动态图模式下的使用 / Orthogonal initializer in dynamic graph mode
- rows > cols 情况:列向量正交 / rows > cols case: columns are orthogonal
- rows < cols 情况:行向量正交 / rows < cols case: rows are orthogonal
- rows == cols 情况:行列均正交 / rows == cols case: both rows and columns are orthogonal
- gain 参数测试 / gain parameter test
2. Orthogonal 初始化器在静态图模式下的使用 / Orthogonal initializer in static graph mode
- 覆盖静态图代码路径 lines 157-271 / covers static graph code path
覆盖的未覆盖行:157, 161, 167, 181, 187, 193, 204, 210, 218-219, 226, 234, 240-241, 247, 254, 256, 264, 271
注意:paddle.nn.Linear(in, out) 的weight形状为 [in, out]
Note: paddle.nn.Linear(in, out) weight shape is [in, out]
所以 Linear(10, 15) → weight [10, 15]rows=10 < cols=15
"""
import unittest
import numpy as np
import paddle
class TestOrthogonalInitializerDynamic(unittest.TestCase):
"""测试动态图模式下Orthogonal初始化器
Test Orthogonal initializer in dynamic graph mode"""
def setUp(self):
"""设置测试环境 / Set up test environment"""
paddle.disable_static()
def test_rows_greater_than_cols(self):
"""测试rows > cols的情况,weight [15, 10],列向量应正交
Test rows > cols case, weight [15, 10], columns should be orthogonal
Linear(10, 15) → weight shape [10, 15], rows=10 < cols=15
So we use Linear(15, 10) → weight shape [15, 10], rows=15 > cols=10"""
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal()
)
# Linear(out=10, in=15) → weight [15, 10], but Paddle Linear(in, out)
# Linear(15, 10) → weight [15, 10], rows=15 > cols=10
linear = paddle.nn.Linear(15, 10, weight_attr=weight_attr)
weight = linear.weight.numpy()
self.assertEqual(weight.shape, (15, 10))
# W^T * W 应接近单位矩阵 / W^T * W should be close to identity (10x10)
wtw = np.matmul(weight.T, weight)
identity = np.eye(10)
np.testing.assert_allclose(wtw, identity, atol=1e-5)
def test_rows_less_than_cols(self):
"""测试rows < cols的情况,weight [10, 15],行向量应正交
Test rows < cols case, weight [10, 15], rows should be orthogonal
Linear(10, 15) → weight [10, 15], rows=10 < cols=15"""
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal()
)
linear = paddle.nn.Linear(10, 15, weight_attr=weight_attr)
weight = linear.weight.numpy()
self.assertEqual(weight.shape, (10, 15))
# W * W^T 应接近单位矩阵 / W * W^T should be close to identity (10x10)
wwt = np.matmul(weight, weight.T)
identity = np.eye(10)
np.testing.assert_allclose(wwt, identity, atol=1e-5)
def test_square_matrix(self):
"""测试rows == cols的情况(10x10),行列均正交
Test rows == cols case (10x10), both rows and columns are orthogonal"""
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal()
)
linear = paddle.nn.Linear(10, 10, weight_attr=weight_attr)
weight = linear.weight.numpy()
self.assertEqual(weight.shape, (10, 10))
# W * W^T 应接近单位矩阵 / W * W^T should be close to identity
wwt = np.matmul(weight, weight.T)
identity = np.eye(10)
np.testing.assert_allclose(wwt, identity, atol=1e-5)
def test_with_gain(self):
"""测试带gain参数的Orthogonal初始化
Test Orthogonal initialization with gain parameter"""
gain = 2.0
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal(gain=gain)
)
linear = paddle.nn.Linear(10, 10, weight_attr=weight_attr)
weight = linear.weight.numpy()
# W * W^T / gain^2 应接近单位矩阵
# W * W^T / gain^2 should be close to identity
wwt = np.matmul(weight, weight.T) / (gain**2)
identity = np.eye(10)
np.testing.assert_allclose(wwt, identity, atol=1e-5)
def test_conv2d_orthogonal(self):
"""测试在Conv2D上使用Orthogonal初始化(维度>2
Test Orthogonal initialization on Conv2D (dimension > 2)"""
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal()
)
conv = paddle.nn.Conv2D(3, 8, 3, weight_attr=weight_attr)
weight = conv.weight.numpy()
self.assertEqual(len(weight.shape), 4) # [out_c, in_c, kH, kW]
class TestOrthogonalInitializerStatic(unittest.TestCase):
"""测试静态图模式下的Orthogonal初始化器,覆盖未覆盖的静态图代码路径
Test Orthogonal initializer in static graph mode, covering uncovered static paths"""
def test_static_graph_rows_greater_cols(self):
"""测试静态图模式下rows > cols的Orthogonal初始化
Test Orthogonal init with rows > cols in static graph mode
Linear(15, 8) → weight [15, 8], rows=15 > cols=8"""
paddle.enable_static()
try:
main_prog = paddle.static.Program()
startup_prog = paddle.static.Program()
with paddle.static.program_guard(main_prog, startup_prog):
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal()
)
linear = paddle.nn.Linear(15, 8, weight_attr=weight_attr)
exe = paddle.static.Executor(paddle.CPUPlace())
exe.run(startup_prog)
result = exe.run(main_prog, fetch_list=[linear.weight])
weight = result[0]
self.assertEqual(weight.shape, (15, 8))
# W^T * W 应接近单位矩阵 / W^T * W should be close to identity (8x8)
wtw = np.matmul(weight.T, weight)
identity = np.eye(8)
np.testing.assert_allclose(wtw, identity, atol=1e-4)
finally:
paddle.disable_static()
def test_static_graph_rows_less_cols(self):
"""测试静态图模式下rows < cols的Orthogonal初始化(触发transpose分支)
Test Orthogonal init with rows < cols in static graph (triggers transpose branch)
Linear(8, 15) → weight [8, 15], rows=8 < cols=15"""
paddle.enable_static()
try:
main_prog = paddle.static.Program()
startup_prog = paddle.static.Program()
with paddle.static.program_guard(main_prog, startup_prog):
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal()
)
linear = paddle.nn.Linear(8, 15, weight_attr=weight_attr)
exe = paddle.static.Executor(paddle.CPUPlace())
exe.run(startup_prog)
result = exe.run(main_prog, fetch_list=[linear.weight])
weight = result[0]
self.assertEqual(weight.shape, (8, 15))
# W * W^T 应接近单位矩阵 / W * W^T should be close to identity (8x8)
wwt = np.matmul(weight, weight.T)
identity = np.eye(8)
np.testing.assert_allclose(wwt, identity, atol=1e-4)
finally:
paddle.disable_static()
def test_static_graph_with_gain(self):
"""测试静态图模式下带gain参数的Orthogonal初始化
Test Orthogonal init with gain parameter in static graph mode"""
paddle.enable_static()
try:
gain = 1.5
main_prog = paddle.static.Program()
startup_prog = paddle.static.Program()
with paddle.static.program_guard(main_prog, startup_prog):
weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.Orthogonal(gain=gain)
)
linear = paddle.nn.Linear(6, 6, weight_attr=weight_attr)
exe = paddle.static.Executor(paddle.CPUPlace())
exe.run(startup_prog)
result = exe.run(main_prog, fetch_list=[linear.weight])
weight = result[0]
# W * W^T / gain^2 应接近单位矩阵
# W * W^T / gain^2 should be close to identity
wwt = np.matmul(weight, weight.T) / (gain**2)
identity = np.eye(6)
np.testing.assert_allclose(wwt, identity, atol=1e-4)
finally:
paddle.disable_static()
if __name__ == '__main__':
unittest.main()