රූපහඳුනාගැනීම සඳහා ගැඹුරු අවශේෂ ඉගෙනීම (රෙස්නෙට්)

මෙය PyTorch කඩදාසි ක්රියාත්මක කිරීම රූප හඳුනාගැනීම සඳහා ගැඹුරු අවශේෂ ඉගෙනීම .

පිරිහීමේගැටළුවමඟහරවා ගැනීම සඳහා අවශේෂ කාර්යයන් ලෙස රෙස්නෙට්ස් ස්ථර පුහුණු කරයි. පිරිහීමේ ගැටළුව වන්නේ ස්ථර ගණන ඉතා ඉහළ වන විට ගැඹුරු ස්නායුක ජාල පිරිහීමේ නිරවද්යතාවයයි. ස්ථර ගණන වැඩි වන විට නිරවද්යතාව වැඩි වන අතර පසුව සන්තෘප්ත වන අතර පසුව පිරිහීමට පටන් ගනී.

අමතරස්ථරවලට අනන්යතා සිතියම්ගත කිරීමක් සිදු කිරීමට ඉගෙන ගත හැකි නිසා ගැඹුරු ආකෘති අවම වශයෙන් මෙන්ම නොගැඹුරු ආකෘති ඉටු කළ යුතු බව කඩදාසි තර්ක කරයි.

අවශේෂඉගෙනීම

ස්ථරකිහිපයකින් ඉගෙන ගත යුතු සිතියම්කරණය නම් , ඒවා අවශේෂ ක්රියාකාරිත්වය පුහුණු කරයි

ඒවෙනුවට. මුල් කාර්යය බවට පත්වේ .

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

පරාමිතිකස්වරූපයෙන් මෙය ලිවිය හැකිය,

විශේෂාංගසිතියම් ප්රමාණ හා වෙනස් වූ විට කඩදාසි යෝජනා කරන්නේ ඉගෙනගත් බර සමඟ රේඛීය ප්රක්ෂේපණයක් කිරීමයි.

කඩදාසිරේඛීය ප්රක්ෂේපණ වෙනුවට ශුන්ය පෑඩින් සමඟ අත්හදා බැලූ අතර රේඛීය ප්රක්ෂේපණ වඩා හොඳින් ක්රියා කරන බව සොයා ගන්නා ලදී. විශේෂාංග සිතියම් ප්රමාණ ගැලපෙන විට අනන්යතා සිතියම්කරණය රේඛීය ප්රක්ෂේපණවලට වඩා හොඳ බව ඔවුන්ට පෙනී ගියේය.

එක් ස්ථරයකට වඩා තිබිය යුතුය, එසේ නොමැතිනම් එකතුවට රේඛීය නොවන නොවන අතර රේඛීය තට්ටුවක් මෙන් වනු ඇත.

CIFA-10හි රෙස්නෙට් පුහුණු කිරීම සඳහා පුහුණු කේතය මෙන්න.

View Run

57from typing import List, Optional
58
59import torch
60from torch import nn
61
62from labml_helpers.module import Module

කෙටිමංසම්බන්ධතාවය සඳහා රේඛීය ප්රක්ෂේපණ

ඉහතවිස්තර කර ඇති ප්රක්ෂේපණය මෙය සිදු කරයි.

65class ShortcutProjection(Module):
  • in_channels යනු නාලිකා ගණන
  • out_channels යනු නාලිකා ගණන
  • stride සඳහා convolution මෙහෙයුම දී stride දිග වේ. විශේෂාංග-සිතියම් ප්රමාණයට ගැලපෙන පරිදි අපි කෙටිමං සම්බන්ධතාවයේ එකම පියවර ගනිමු.
72    def __init__(self, in_channels: int, out_channels: int, stride: int):
79        super().__init__()

රේඛීයප්රක්ෂේපණය සඳහා සංයුක්ත ස්ථරය

82        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride)

කඩදාසිඑක් එක් convolution මෙහෙයුම පසු කණ්ඩායම සාමාන්යකරණය එකතු යෝජනා

84        self.bn = nn.BatchNorm2d(out_channels)
86    def forward(self, x: torch.Tensor):

සම්මුතිසහ කණ්ඩායම් සාමාන්යකරණය

88        return self.bn(self.conv(x))

අවශේෂකොටස

මෙයකඩදාසි විස්තර කර ඇති අවශේෂ කොටස ක්රියාත්මක කරයි. එය කැටි ගැසුණු ස්ථර දෙකක් ඇත.

Residual Block

පළමුconvolution ස්ථරය සිතියම් out_channels , අපි stride දිග සමග ලක්ෂණය සිතියම් ප්රමාණය අඩු කරන in_channels විට වඩා වැඩි කොහෙද in_channels out_channels වඩා විශාල .

සිට out_channels දෙවන convolution ස්ථරය සිතියම් out_channels හා සෑම විටම 1 ක stride දිග ඇත.

සංවහනස්ථර දෙකම කණ්ඩායම් සාමාන්යකරණය කිරීමෙන් පසුව සිදු වේ.

91class ResidualBlock(Module):
  • in_channels යනු නාලිකා ගණන
  • out_channels ප්රතිදාන නාලිකා ගණන වේ
  • stride මෙම convolution මෙහෙයුම දී stride දිග වේ.
112    def __init__(self, in_channels: int, out_channels: int, stride: int):
118        super().__init__()

පළමු සංවහන ස්තරය, මෙය සිතියම් ගත කරයි out_channels

121        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1)

පළමුකැටි ගැසීමෙන් පසු කණ්ඩායම් සාමාන්යකරණය

123        self.bn1 = nn.BatchNorm2d(out_channels)

පළමුසක්රිය කිරීමේ කාර්යය (RELU)

125        self.act1 = nn.ReLU()

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

128        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)

දෙවනකැටි ගැසීම්වලින් පසු කණ්ඩායම් සාමාන්යකරණය

130        self.bn2 = nn.BatchNorm2d(out_channels)

නාලිකාගණන වෙනස් වුවහොත් ස්ට්රයිඩ් දිග නොවේ නම් කෙටිමං සම්බන්ධතාවය ප්රක්ෂේපණයක් විය යුතුය

134        if stride != 1 or in_channels != out_channels:

ප්රක්ෂේපණය

136            self.shortcut = ShortcutProjection(in_channels, out_channels, stride)
137        else:

අනන්යතාවය

139            self.shortcut = nn.Identity()

දෙවනසක්රිය කිරීමේ කාර්යය (RelU) (කෙටිමඟ එකතු කිරීමෙන් පසු)

142        self.act2 = nn.ReLU()
  • x හැඩයේ ආදානය වේ [batch_size, in_channels, height, width]
144    def forward(self, x: torch.Tensor):

කෙටිමංසම්බන්ධතාවය ලබා ගන්න

149        shortcut = self.shortcut(x)

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

151        x = self.act1(self.bn1(self.conv1(x)))

දෙවනකැටි ගැසිම

153        x = self.bn2(self.conv2(x))

කෙටිමඟඑකතු කිරීමෙන් පසු සක්රිය කිරීමේ කාර්යය

155        return self.act2(x + shortcut)

අවශේෂබාධක කොටස

මෙයකඩදාසි වල විස්තර කර ඇති බාධක කොටස ක්රියාත්මක කරයි. එය , සහ කැටි ගැසුණු ස්ථර ඇත.

Bottlenext Block

පළමුconvolution ස්ථරය වඩා අඩු කොහෙද convolution, bottleneck_channels සමග සිට in_channels සිතියම් bottleneck_channels in_channels .

දෙවන කැටි ගැසුණු ස්ථරය සිතියම් bottleneck_channels සිට bottleneck_channels . විශේෂාංග සිතියම් ප්රමාණය සම්පීඩනය කිරීමට අපට අවශ්ය වන විට වඩා විශාල දිගක් මෙයට තිබිය හැකිය.

තෙවන, අවසාන කැටි ගැසුණු ස්ථරය සිතියම් වෙත out_channels . out_channels මෙම stride දිග වඩා වැඩි in_channels නම් වඩා වැඩි ය ; එසේ නොමැති නම්, සමාන වේ in_channels .

bottleneck_channels වඩා අඩු වන in_channels අතර මෙම හැකිලී අවකාශය මත කැටි කිරීම සිදු කරනු ලැබේ (එබැවින් බාධකය). සංවහන දෙක අඩු වන අතර නාලිකා ගණන වැඩි කරයි.

158class BottleneckResidualBlock(Module):
  • in_channels යනු නාලිකා ගණන
  • bottleneck_channels යනු සංවහන සඳහා නාලිකා ගණන
  • out_channels ප්රතිදාන නාලිකා ගණන වේ
  • stride මෙම convolution මෙහෙයුම දී stride දිග වේ.
186    def __init__(self, in_channels: int, bottleneck_channels: int, out_channels: int, stride: int):
193        super().__init__()

පළමු සංවහන ස්තරය, මෙය සිතියම් ගත කරයි bottleneck_channels

196        self.conv1 = nn.Conv2d(in_channels, bottleneck_channels, kernel_size=1, stride=1)

පළමුකැටි ගැසීමෙන් පසු කණ්ඩායම් සාමාන්යකරණය

198        self.bn1 = nn.BatchNorm2d(bottleneck_channels)

පළමුසක්රිය කිරීමේ කාර්යය (RELU)

200        self.act1 = nn.ReLU()

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

203        self.conv2 = nn.Conv2d(bottleneck_channels, bottleneck_channels, kernel_size=3, stride=stride, padding=1)

දෙවනකැටි ගැසීම්වලින් පසු කණ්ඩායම් සාමාන්යකරණය

205        self.bn2 = nn.BatchNorm2d(bottleneck_channels)

දෙවනසක්රිය කිරීමේ ශ්රිතය (RelU)

207        self.act2 = nn.ReLU()

තෙවන සංවහන ස්තරය, මෙම සිතියම් වෙත out_channels .

210        self.conv3 = nn.Conv2d(bottleneck_channels, out_channels, kernel_size=1, stride=1)

දෙවනකැටි ගැසීම්වලින් පසු කණ්ඩායම් සාමාන්යකරණය

212        self.bn3 = nn.BatchNorm2d(out_channels)

නාලිකාගණන වෙනස් වුවහොත් ස්ට්රයිඩ් දිග නොවේ නම් කෙටිමං සම්බන්ධතාවය ප්රක්ෂේපණයක් විය යුතුය

216        if stride != 1 or in_channels != out_channels:

ප්රක්ෂේපණය

218            self.shortcut = ShortcutProjection(in_channels, out_channels, stride)
219        else:

අනන්යතාවය

221            self.shortcut = nn.Identity()

දෙවනසක්රිය කිරීමේ කාර්යය (RelU) (කෙටිමඟ එකතු කිරීමෙන් පසු)

224        self.act3 = nn.ReLU()
  • x හැඩයේ ආදානය වේ [batch_size, in_channels, height, width]
226    def forward(self, x: torch.Tensor):

කෙටිමංසම්බන්ධතාවය ලබා ගන්න

231        shortcut = self.shortcut(x)

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

233        x = self.act1(self.bn1(self.conv1(x)))

දෙවනකැටි ගැසිම සහ සක්රිය කිරීම

235        x = self.act2(self.bn2(self.conv2(x)))

තෙවනකැටි ගැසිම

237        x = self.bn3(self.conv3(x))

කෙටිමඟඑකතු කිරීමෙන් පසු සක්රිය කිරීමේ කාර්යය

239        return self.act3(x + shortcut)

රෙස්නෙට්ආකෘතිය

මෙයවර්ගීකරණය සඳහා අවසාන රේඛීය ස්තරය සහ සොෆ්ට්මැක්ස් නොමැතිව රෙස්නෙට් ආකෘතියේ පාදමකි.

රෙස්නෙට්සෑදී ඇත්තේ ගොඩගැසී ඇති අවශේෂ කුට්ටි හෝ බාධක අවශේෂ කුට්ටි වලින් ය. විශේෂාංග සිතියම් ප්රමාණය අඩක් පමණ දිග බ්ලොක් කිහිපයකින් පසුව අඩක් පමණ වේ. විශේෂාංග සිතියම් ප්රමාණය අඩු වූ විට නාලිකා ගණන වැඩි වේ. අවසාන වශයෙන් විශේෂාංග සිතියම දෛශික නිරූපණයක් ලබා ගැනීම සඳහා සාමාන්යයෙන් සකස් කර ඇත.

242class ResNetBase(Module):
  • n_blocks යනු එක් එක් විශේෂාංග සිතියම් ප්රමාණය සඳහා කුට්ටි ගණන ලැයිස්තුවකි.
  • n_channels එක් එක් විශේෂාංග සිතියම් ප්රමාණය සඳහා නාලිකා ගණන වේ.
  • bottlenecks යනු බාධක වල නාලිකා ගණන වේ. මෙය නම් None , අවශේෂ කුට්ටි භාවිතා වේ.
  • img_channels යනු ආදානයේ ඇති නාලිකා ගණන වේ.
  • first_kernel_size ආරම්භක සංවලිත ස්ථරයේ කර්නල් ප්රමාණයයි
256    def __init__(self, n_blocks: List[int], n_channels: List[int],
257                 bottlenecks: Optional[List[int]] = None,
258                 img_channels: int = 3, first_kernel_size: int = 7):
267        super().__init__()

එක්එක් විශේෂාංග සිතියම් ප්රමාණය සඳහා බ්ලොක් ගණන සහ නාලිකා ගණන

270        assert len(n_blocks) == len(n_channels)

බාධක අවශේෂ කුට්ටි භාවිතා කරන්නේ නම්, එක් එක් විශේෂාංග සිතියම් ප්රමාණය සඳහා බාධක වල නාලිකා ගණන සැපයිය යුතුය

273        assert bottlenecks is None or len(bottlenecks) == len(n_channels)

පළමුඅවශේෂ කොටසෙහි නාලිකා ගණන img_channels දක්වා ආරම්භක සංවහන ස්ථර සිතියම් (n_channels[0] )

277        self.conv = nn.Conv2d(img_channels, n_channels[0],
278                              kernel_size=first_kernel_size, stride=2, padding=first_kernel_size // 2)

මූලිකකැටි ගැසීමෙන් පසු කණ්ඩායම් සම්මතය

280        self.bn = nn.BatchNorm2d(n_channels[0])

කුට්ටිලැයිස්තුව

283        blocks = []

පෙරස්ථරයෙන් (හෝ බ්ලොක්) නාලිකා ගණන

285        prev_channels = n_channels[0]

එක්එක් විශේෂාංග සිතියම් ප්රමාණය හරහා ලූප්

287        for i, channels in enumerate(n_channels):

නවවිශේෂාංග සිතියම් ප්රමාණය සඳහා වන පළමු කොටස, පළමු කොටස හැර දිගු දිගක් ඇත

290            stride = 2 if len(blocks) == 0 else 1
291
292            if bottlenecks is None:

සිට prev_channels සිතියම් ගත කරනඅවශේෂ කොටස් channels

294                blocks.append(ResidualBlock(prev_channels, channels, stride=stride))
295            else:

සිට prev_channels සිතියම්ගත කරන බාධක අවශේෂ කොටස් channels

298                blocks.append(BottleneckResidualBlock(prev_channels, bottlenecks[i], channels,
299                                                      stride=stride))

නාලිකාගණන වෙනස් කරන්න

302            prev_channels = channels

ඉතිරිකොටස් එකතු කරන්න - විශේෂාංග සිතියම් ප්රමාණය හෝ නාලිකා වල වෙනසක් නොමැත

304            for _ in range(n_blocks[i] - 1):
305                if bottlenecks is None:
307                    blocks.append(ResidualBlock(channels, channels, stride=1))
308                else:
310                    blocks.append(BottleneckResidualBlock(channels, bottlenecks[i], channels, stride=1))

කුට්ටිගොඩගසන්න

313        self.blocks = nn.Sequential(*blocks)
  • x හැඩය ඇත [batch_size, img_channels, height, width]
315    def forward(self, x: torch.Tensor):

මූලිකකැටි ගැසීම්සහ කණ්ඩායම් සාමාන්යකරණය

321        x = self.bn(self.conv(x))

අවශේෂ(හෝ බාධක) කුට්ටි

323        x = self.blocks(x)

x හැඩයෙන් වෙනස් [batch_size, channels, h, w] කරන්න [batch_size, channels, h * w]

325        x = x.view(x.shape[0], x.shape[1], -1)

ගෝලීයසාමාන්ය තටාක

327        return x.mean(dim=-1)