1.はじめに
MNISTなどの画像データにノイズを加えると、復元や識別が難しくなる。
本記事では、通常の実数MLPと虚部を付与して高次元化した複素MLPを比較。
目的は「ノイズ耐性」と「情報的エントロピー増大の抑制」を観察すること。
2. 手法の概要
実数MLP
・通常の多層パーセプトロン
・入力 28 * 28 -> 隠れ層512 ->出力 28 * 28
・活性化:LeakyReLU + Sigmoid
複素MLP (高次元化)
・入力を複素数化
・実部:元の画像
・虚部:非線形変換x^2
・層構造は複素線形層 + ReLU
・出力は実部のみを復元
ポイント
虚部による次元拡張で、noiseの影響を緩和->情報的な意味でのエントロピー増大を抑制
複素線形層
class ComplexLinear(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.real = nn.Linear(in_features, out_features)
self.imag = nn.Linear(in_features, out_features)
def forward(self, x):
xr, xi = x.real, x.imag
real = self.real(xr) - self.imag(xi)
imag = self.real(xi) + self.imag(xr)
return torch.complex(real, imag)
複素ReLU
class ComplexReLU(nn.Module):
def forward(self, x):
return torch.complex(torch.relu(x.real), torch.relu(x.imag))
複素MLP(虚部に x^2 を入れ高次元化)
class ComplexMLP(nn.Module):
def __init__(self, n_dim=28*28, hidden_dim=2048):
super().__init__()
self.fc1 = ComplexLinear(n_dim, hidden_dim)
self.fc2 = ComplexLinear(hidden_dim, hidden_dim)
self.fc3 = ComplexLinear(hidden_dim, n_dim)
self.act = ComplexReLU()
def forward(self, x_real):
# 入力が実数なら虚部を作る
if torch.is_floating_point(x_real):
x_imag = x_real ** 2
x = torch.complex(x_real, x_imag)
else:
x = x_real # すでに複素数の場合はそのまま
x = self.act(self.fc1(x))
x = self.act(self.fc2(x))
x = self.fc3(x)
return torch.sigmoid(x.real)
3.noiseの種類
・salt_and_pepper_noiseを使用(平均0, 標準偏差を変更)
・画像にランダムに加えることで、復元性能の違いを観察
4. 実験結果
比較対象: オリジナル、ノイズ画像、実数MLP復元、複素MLP復元
ノイズレベル: 0.1, 0.2, 0.5, 0.7, 0.8
Original | Noise 0.1 | Real MLP | Complex MLP | Noise 0.2 | Real MLP | Complex MLP | ...
学習ログ例:
=== Training Real MLP ===
Epoch 1: train_loss=0.051901
Epoch 2: train_loss=0.037169
Epoch 3: train_loss=0.034488
Epoch 4: train_loss=0.033245
Epoch 5: train_loss=0.032376
=== Training Complex MLP ===
Epoch 1: train_loss=0.041796
Epoch 2: train_loss=0.033277
Epoch 3: train_loss=0.031940
Epoch 4: train_loss=0.031089
Epoch 5: train_loss=0.030629
評価結果:
0.1
Real MLP: MSE=0.02822, PSNR=15.49 dB
Complex MLP: MSE=0.02681, PSNR=15.72 dB
0.2
Real MLP: MSE=0.02725, PSNR=15.65 dB
Complex MLP: MSE=0.02621, PSNR=15.82 dB
0.5
Real MLP: MSE=0.02526, PSNR=15.97 dB
Complex MLP: MSE=0.02443, PSNR=16.12 dB
0.7
Real MLP: MSE=0.02596, PSNR=15.86 dB
Complex MLP: MSE=0.02474, PSNR=16.07 dB
0.8
Real MLP: MSE=0.02715, PSNR=15.66 dB
Complex MLP: MSE=0.02588, PSNR=15.87 dB
結果
・このように複素MLPのほうが若干精度が高い
・高次元化により情報保持が改善される可能性を示唆
6. まとめ
・虚部にx^2を入れた複素数MLPは、高次元表現を利用して情報保持が若干改善する
・ノイズに対してわずかでも性能向上が見られることは、学習アルゴリズムや表現力の改善の証拠になる
・今後はソルト&ペッパーなど他のノイズにも適用し、ノイズ耐性の一般性を確認することが望ましい
6. コード・データの公開
本記事で紹介した 複素MLPの学習・復元コード や ノイズ付加スクリプト は GitHub に公開しています。
https://github.com/chacha20-poly/High-Dimensional-Noise-filter