ResSkip 的 Depthwise Convolution + Pointwise Convolution (MobileNetV2 風格)

針對只有兩種字型風格轉換(Noto Sans → Zen Maru Gothic)的任務,我們來比較這兩個 ResSkip 類別,並分析它們對推論的影響以及建議使用的類別。

第一個 ResSkip 類別:

Python

class ResSkip(nn.Module):
    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.depthwise = nn.Conv2d(in_channels, in_channels, 3, padding=1, groups=in_channels)
        self.pointwise = nn.Conv2d(in_channels, out_channels, 1)
        self.norm = nn.InstanceNorm2d(out_channels)
        self.act = nn.SiLU()
        self.skip = nn.Conv2d(in_channels, out_channels, 1) if in_channels != out_channels else nn.Identity()

    def forward(self, x):
        identity = self.skip(x)
        out = self.depthwise(x)
        out = self.pointwise(out)
        out = self.act(self.norm(out))
        return out + identity

第二個 ResSkip 類別:

Python

import torch.nn as nn
import torch.nn.functional as F

class ResSkip(nn.Module):
    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, 3, padding=1)
        self.norm1 = nn.BatchNorm2d(out_channels)
        self.act1 = nn.SiLU()
        self.conv2 = nn.Conv2d(out_channels, out_channels, 3, padding=1)
        self.norm2 = nn.BatchNorm2d(out_channels)
        self.act2 = nn.SiLU()

    def forward(self, x):
        identity = x
        out = self.act1(self.norm1(self.conv1(x)))
        out = self.act2(self.norm2(self.conv2(out)))
        if identity.shape != out.shape:
            identity = F.interpolate(identity, size=out.shape[2:], mode='bilinear', align_corners=False)
            if identity.shape[1] != out.shape[1]:
                identity = nn.Conv2d(identity.shape[1], out.shape[1], 1)(identity)
        return out + identity

比較:

特性第一個 ResSkip第二個 ResSkip
卷積層Depthwise Convolution + Pointwise Convolution (MobileNetV2 風格)標準 Convolution (兩層)
歸一化層Instance Normalization (IN)Batch Normalization (BN)
激活函數SiLUSiLU (兩次)
Skip 連接1×1 卷積 (channel 數不同時) 或 Identity直接相加,必要時進行插值和 1×1 卷積調整 channel 數
參數效率通常較低 (Depthwise 分離卷積)通常較高
計算複雜度通常較低通常較高
對輸入變化的魯棒性Instance Normalization 對批次大小不敏感,對風格遷移可能更魯棒Batch Normalization 依賴批次統計,對不同風格的輸入可能表現不穩定

對推論的影響:

  • 第一個 ResSkip
    • 速度: 由於使用了 Depthwise 和 Pointwise 卷積,其計算量通常比標準卷積少,因此在推論時可能更快。
    • 記憶體佔用: 參數數量通常較少,因此模型在推論時的記憶體佔用可能更低。
    • 風格適應性: Instance Normalization 在風格轉換任務中可能更具優勢,因為它獨立地歸一化每個樣本的每個通道,減少了批次統計對風格的影響。這對於只學習兩種字型風格的轉換可能不是決定性因素,但 IN 的特性使其對輸入分佈的變化更魯棒。
  • 第二個 ResSkip
    • 速度: 使用了兩層標準卷積,計算量通常較大,推論速度可能較慢。
    • 記憶體佔用: 參數數量通常較多,模型在推論時的記憶體佔用可能更高。
    • 風格適應性: Batch Normalization 在訓練和測試數據分佈一致時表現良好。然而,在風格轉換任務中,如果目標風格與訓練風格有顯著差異,BN 的性能可能會下降。這裡的任務只有兩種固定的字型風格,如果訓練資料涵蓋了這兩種風格,BN 也可能表現良好。但如果模型需要泛化到這兩種風格之間或之外的風格,IN 可能更穩定。
    • Skip 連接的處理: 第二個類別在 skip 連接的 channel 數或尺寸不匹配時,使用了插值和 1×1 卷積來進行調整。這增加了計算量,但在網路結構設計上提供了更大的靈活性。

建議:

針對只有兩種字型風格轉換(Noto Sans → Zen Maru Gothic)的特定任務,並且假設訓練資料能夠充分涵蓋這兩種風格:

  • 如果推論速度和模型大小是主要考量第一個 ResSkip 類別 可能更適合。其 Depthwise 分離卷積的效率更高,Instance Normalization 在只有兩種固定風格的轉換下,其潛在的風格適應性優勢可能不會被顯著放大,但也不會帶來負面影響。
  • 第二個 ResSkip 類別 由於使用了更深層的標準卷積和 Batch Normalization,可能具有更強的學習能力來捕捉這兩種風格之間的細微差異。然而,這也可能導致過擬合,尤其是在數據量有限的情況下。其 skip 連接的靈活性在網路結構設計上可能更有用,但在這個只有兩種風格轉換的簡單任務中,可能不是必需的額外複雜性。

最終建議:

在只有兩種字型風格轉換的任務中,我傾向於建議使用第一個 ResSkip 類別。理由如下:

  1. 效率: Depthwise 分離卷積通常更有效率,可以實現更快的推論速度和更小的模型尺寸。
  2. 簡單性: 結構更簡單,減少了潛在的過擬合風險。
  3. 風格魯棒性: Instance Normalization 在風格轉換任務中通常被認為更魯棒,即使在這個只有兩種固定風格的任務中,它也不會帶來負面影響。

然而,最終的選擇應該基於實驗結果。可以嘗試使用這兩個 ResSkip 類別構建模型,並在驗證集上比較它們的性能(例如,轉換後的字型與目標字型的相似度)。如果第二個 ResSkip 類別在性能上有顯著提升,那麼即使犧牲一些效率也是值得的。

總結:

對於這個特定的雙字型風格轉換任務,第一個 ResSkip 類別在效率和潛在的風格魯棒性方面可能更具優勢。但強烈建議進行實驗驗證,以確定哪個類別在實際應用中能提供更好的性能。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *