දර්ශනට්රාන්ස්ෆෝමර් (VIT)

මෙයඅ පයිටෝච් කඩදාසි ක්රියාත්මක කිරීම රූපයක් වටිනවා 16x16 වචන: පරිමාණයෙන් රූප හඳුනාගැනීම සඳහා ට්රාන්ස්ෆෝමර් .

දර්ශනට්රාන්ස්ෆෝමරය කිසිදු කැටි ගැසුණු ස්ථර නොමැතිව රූප සඳහා පිරිසිදු ට්රාන්ස්ෆෝමරයක් යොදයි. ඔවුන් රූපය පැච් බවට බෙදී ඇති අතර පැච් කාවැද්දීම් මත ට්රාන්ස්ෆෝමරයක් යොදයි. පැච් කාවැද්දීම් ජනනය කරනු ලබන්නේ පැච් වල පැතලි පික්සල් අගයන් සඳහා සරල රේඛීය පරිවර්තනයක් යෙදීමෙනි. එවිට සම්මත ට්රාන්ස්ෆෝමර් එන්කෝඩරයක් පැච් කාවැද්දීම් සමඟ වර්ගීකරණ ටෝකනයක් සමඟ පෝෂණය [CLS] වේ. රූපය එම්එල්පී සමඟ වර්ගීකරණය කිරීම සඳහා [CLS] ටෝකනයේ කේතනය භාවිතා කරයි.

පැච්සමඟ ට්රාන්ස්ෆෝමරය පෝෂණය කරන විට, පැච් කාවැද්දීම් වලට උගත් ස්ථානීය කාවැද්දීම් එකතු කරනු ලැබේ, මන්ද එම පැච් කාවැද්දීම් වලින් එම පැච් එක කොතැනද යන්න පිළිබඳ කිසිදු තොරතුරක් නොමැති බැවිනි. ස්ථානීය කාවැද්දීම් යනු එක් එක් පැච් ස්ථානය සඳහා දෛශික සමූහයක් වන අතර අනෙක් පරාමිතීන් සමඟ ශ්රේණියේ සම්භවය සමඟ පුහුණු වේ.

විශාලදත්ත කට්ටල පිළිබඳ පූර්ව පුහුණුව ලැබූ විට VITs හොඳින් ක්රියා කරයි. කඩදාසි යෝජනා කරන්නේ එම්එල්පී වර්ගීකරණ හිසක් සමඟ ඒවා පෙර පුහුණු කිරීම සහ හොඳින් සුසර කිරීමේදී තනි රේඛීය තට්ටුවක් භාවිතා කිරීමයි. කඩදාසි මිලියන 300 ක රූප දත්ත කට්ටලයක් මත පෙර පුහුණු කරන ලද VIT සමඟ SOTA පරාජය කරයි. පැච් ප්රමාණය එලෙසම තබා ගනිමින් අනුමානය අතරතුර ඔවුන් ඉහළ විභේදන රූප භාවිතා කරයි. නව පැච් ස්ථාන සඳහා ස්ථානීය කාවැද්දීම් ගණනය කරනු ලබන්නේ ස්ථානීය කාවැද්දීම් ඉගෙනීම අන්තර්ග්රහණය කිරීමෙනි.

CIFA-10 හි VIT පුහුණු කරන අත්හදා බැලීමක් මෙන්න. එය කුඩා දත්ත සමුදාය මත පුහුණු වෙනවා නිසා මෙය ඉතා හොඳින් කරන්නේ නැහැ. එය ඕනෑම කෙනෙකුට VITs සමඟ ධාවනය කර සෙල්ලම් කළ හැකි සරල අත්හදා බැලීමකි.

View Run

45import torch
46from torch import nn
47
48from labml_helpers.module import Module
49from labml_nn.transformers import TransformerLayer
50from labml_nn.utils import clone_module_list

පැච්කාවැද්දීම් ලබා ගන්න

කඩදාසිරූපය සමාන ප්රමාණයේ පැච් වලට බෙදී ඇති අතර එක් එක් පැච් එක සඳහා පැතලි පික්සල් මත රේඛීය පරිවර්තනයක් සිදු කරයි.

අපිඑකම දේ ක්රියාත්මක කිරීම සරල නිසා, කැටි ගැසුණු ස්ථරයක් හරහා ක්රියාත්මක කරමු.

53class PatchEmbeddings(Module):
  • d_model ට්රාන්ස්ෆෝමර් කාවැද්දීම් ප්රමාණය වේ
  • patch_size පැච් වල ප්රමාණයයි
  • in_channels ආදාන රූපයේ නාලිකා ගණන (rgb සඳහා 3)
65    def __init__(self, d_model: int, patch_size: int, in_channels: int):
71        super().__init__()

අපිකර්නල් ප්රමාණයෙන් හා ලප ප්රමාණය සමාන stride දිග සමග convolution ස්ථරය නිර්මාණය කරන්න. මෙය රූපය පැච් වලට බෙදීමට හා එක් එක් පැච් එකේ රේඛීය පරිවර්තනයක් කිරීමට සමාන වේ.

76        self.conv = nn.Conv2d(in_channels, d_model, patch_size, stride=patch_size)
  • x යනු හැඩයේ ආදාන රූපයයි [batch_size, channels, height, width]
78    def forward(self, x: torch.Tensor):

කැටිගැසුණු ස්ථරය යොදන්න

83        x = self.conv(x)

හැඩයලබා ගන්න.

85        bs, c, h, w = x.shape

හැඩයටනැවත සකස් කරන්න [patches, batch_size, d_model]

87        x = x.permute(2, 3, 0, 1)
88        x = x.view(h * w, bs, c)

පැච්කාවැද්දීම් ආපසු ලබා දෙන්න

91        return x

පරාමිතිකරණයකළ ස්ථානීය කේතීකරණ එකතු කරන්න

මෙයපැච් කාවැද්දීම් සඳහා උගත් ස්ථානීය කාවැද්දීම් එකතු කරයි.

94class LearnedPositionalEmbeddings(Module):
  • d_model ට්රාන්ස්ෆෝමර් කාවැද්දීම් ප්රමාණය වේ
  • max_len පැච් වල උපරිම ගණන
103    def __init__(self, d_model: int, max_len: int = 5_000):
108        super().__init__()

එක්එක් ස්ථානය සඳහා ස්ථානීය කාවැද්දීම්

110        self.positional_encodings = nn.Parameter(torch.zeros(max_len, 1, d_model), requires_grad=True)
  • x හැඩයේ පැච් කාවැද්දීම් වේ [patches, batch_size, d_model]
112    def forward(self, x: torch.Tensor):

දීඇති පැච් සඳහා ස්ථානීය කාවැද්දීම් ලබා ගන්න

117        pe = self.positional_encodings[:x.shape[0]]

පැච්කාවැද්දීම් වලට එකතු කර ආපසු යන්න

119        return x + pe

එම්එල්පීවර්ගීකරණ හිස

[CLS] ටෝකන් කාවැද්දීම මත පදනම්ව රූපය වර්ගීකරණය කිරීම සඳහා ස්ථර දෙකේ එම්එල්පී හිස මෙයයි.

122class ClassificationHead(Module):
  • d_model ට්රාන්ස්ෆෝමර් කාවැද්දීම ප්රමාණය වේ
  • n_hidden සැඟවුණු ස්ථරයේ ප්රමාණයයි
  • n_classes වර්ගීකරණ කාර්යයේ පන්ති ගණන වේ
130    def __init__(self, d_model: int, n_hidden: int, n_classes: int):
136        super().__init__()

පළමුස්ථරය

138        self.linear1 = nn.Linear(d_model, n_hidden)

සක්‍රීයකිරීම

140        self.act = nn.ReLU()

දෙවනස්ථරය

142        self.linear2 = nn.Linear(n_hidden, n_classes)
  • x [CLS] ටෝකනය සඳහා ට්රාන්ස්ෆෝමර් කේතනය වේ
144    def forward(self, x: torch.Tensor):

පළමුස්ථරය සහ සක්රිය කිරීම

149        x = self.act(self.linear1(x))

දෙවනස්ථරය

151        x = self.linear2(x)

154        return x
157class VisionTransformer(Module):
165    def __init__(self, transformer_layer: TransformerLayer, n_layers: int,
166                 patch_emb: PatchEmbeddings, pos_emb: LearnedPositionalEmbeddings,
167                 classification: ClassificationHead):
176        super().__init__()

පැච්කාවැද්දීම්

178        self.patch_emb = patch_emb
179        self.pos_emb = pos_emb

වර්ගීකරණහිස

181        self.classification = classification

ට්රාන්ස්ෆෝමර්ස්ථරයේ පිටපත් සාදන්න

183        self.transformer_layers = clone_module_list(transformer_layer, n_layers)

[CLS] කාවැද්දීම ටෝකනය

186        self.cls_token_emb = nn.Parameter(torch.randn(1, 1, transformer_layer.size), requires_grad=True)

අවසානසාමාන්යකරණ ස්තරය

188        self.ln = nn.LayerNorm([transformer_layer.size])
  • x යනු හැඩයේ ආදාන රූපයයි [batch_size, channels, height, width]
190    def forward(self, x: torch.Tensor):

පැච්කාවැද්දීම් ලබා ගන්න. මෙය හැඩයේ ආතතිකයක් ලබා දෙයි [patches, batch_size, d_model]

195        x = self.patch_emb(x)

ස්ථානීයකාවැද්දීම් එකතු කරන්න

197        x = self.pos_emb(x)

ට්රාන්ස්ෆෝමරයපෝෂණය කිරීමට පෙර [CLS] ටෝකන් කාවැද්දීම් සංයුක්ත කරන්න

199        cls_token_emb = self.cls_token_emb.expand(-1, x.shape[1], -1)
200        x = torch.cat([cls_token_emb, x])

කිසිදුඅවධානයක් ආවරණ සහිත ට්රාන්ස්ෆෝමර් ස්ථර හරහා ගමන් කරන්න

203        for layer in self.transformer_layers:
204            x = layer(x=x, mask=None)

[CLS] ටෝකනයේ ට්රාන්ස්ෆෝමර් ප්රතිදානය ලබා ගන්න (එය අනුපිළිවෙලෙහි පළමු වේ).

207        x = x[0]

ස්ථරයසාමාන්යකරණය

210        x = self.ln(x)

වර්ගීකරණහිස, පිවිසුම් ලබා ගැනීමට

213        x = self.classification(x)

216        return x