न्यूरल नेटवर्क आर्किटेक्चर विस्तृत व्याख्या
यह लेख KataGo न्यूरल नेटवर्क के पूर्ण आर्किटेक्चर की गहन व्याख्या करता है, इनपुट फीचर एनकोडिंग से लेकर मल्टी-हेड आउटपुट डिज़ाइन तक।
KataGo एकल न्यूरल नेटवर्क और मल्टी-हेड आउटपुट का डिज़ाइन अपनाता है: मुख्य आधार के रूप में रेसिडुअल टावर (20 से 60 रेसिडुअल ब्लॉक तथा ग्लोबल पूलिंग लेयर) इनपुट फीचर प्लेन से फीचर निकालता है, और फिर Policy (चाल की प्रायिकता), Value (जीत दर), Score (अंकों का अंतर) तथा Ownership (क्षेत्र का स्वामित्व) इन चार आउटपुट हेड में विभाजित होता है।
आर्किटेक्चर अवलोकन
KataGo एकल न्यूरल नेटवर्क, मल्टी-हेड आउटपुट डिज़ाइन का उपयोग करता है:
इनपुट फीचर एनकोडिंग
फीचर प्लेन अवलोकन
KataGo 22 फीचर प्लेन (19×19×22) का उपयोग करता है, प्रत्येक प्लेन एक 19×19 मैट्रिक्स है:
| प्लेन | सामग्री | विवरण |
|---|---|---|
| 0 | अपने पत्थर | 1 = अपना पत्थर है, 0 = नहीं |
| 1 | प्रतिद्वंद्वी के पत्थर | 1 = प्रतिद्वंद्वी का पत्थर है, 0 = नहीं |
| 2 | खाली बिंदु | 1 = खाली, 0 = पत्थर है |
| 3-10 | इतिहास स्थिति | पिछली 8 चालों के बोर्ड परिवर्तन |
| 11 | को निषिद्ध बिंदु | 1 = यहाँ को है, 0 = खेल सकते हैं |
| 12-17 | लिबर्टी एनकोडिंग | 1-लिबर्टी, 2-लिबर्टी, 3-लिबर्टी... समूह |
| 18-21 | नियम एनकोडिंग | चीनी/जापानी नियम, कोमी आदि |
इतिहास स्थिति स्टैकिंग
न्यूरल नेटवर्क को स्थिति के गतिशील परिवर्तनों को समझने देने के लिए, KataGo पिछली 8 चालों की बोर्ड स्थिति स्टैक करता है:
# इतिहास स्थिति एनकोडिंग (अवधारणा)
def encode_history(game_history, current_player):
features = []
for t in range(8): # पिछली 8 चालें
if t < len(game_history):
board = game_history[-(t+1)]
# उस समय बिंदु पर अपने/प्रतिद्वंद्वी के पत्थर एनकोड करें
features.append(encode_board(board, current_player))
else:
# इतिहास अपर्याप्त, शून्य भरें
features.append(np.zeros((19, 19)))
return np.stack(features, axis=0)
नियम एनकोडिंग
KataGo कई नियमों का समर्थन करता है, फीचर प्लेन के माध्यम से न्यूरल नेटवर्क को सूचित करता है:
# नियम एनकोडिंग (अवधारणा)
def encode_rules(rules, komi):
rule_features = np.zeros((4, 19, 19))
# नियम प्रकार (one-hot)
if rules == "chinese":
rule_features[0] = 1.0
elif rules == "japanese":
rule_features[1] = 1.0
# कोमी नॉर्मलाइज़ेशन
normalized_komi = komi / 15.0 # [-1, 1] में नॉर्मलाइज़ करें
rule_features[2] = normalized_komi
# वर्तमान खिलाड़ी
rule_features[3] = 1.0 if current_player == BLACK else 0.0
return rule_features
मुख्य नेटवर्क: रेसिड्यूअल टावर
रेसिड्यूअल ब्लॉक संरचना
KataGo Pre-activation ResNet संरचना का उपयोग करता है:
कोड उदाहरण
class ResidualBlock(nn.Module):
def __init__(self, channels):
super().__init__()
self.bn1 = nn.BatchNorm2d(channels)
self.conv1 = nn.Conv2d(channels, channels, 3, padding=1)
self.bn2 = nn.BatchNorm2d(channels)
self.conv2 = nn.Conv2d(channels, channels, 3, padding=1)
def forward(self, x):
residual = x
out = self.bn1(x)
out = F.relu(out)
out = self.conv1(out)
out = self.bn2(out)
out = F.relu(out)
out = self.conv2(out)
return out + residual # रेसिड्यूअल कनेक्शन
ग्लोबल पूलिंग लेयर
KataGo की प्रमुख नवाचारों में से एक: रेसिड्यूअल ब्लॉक में ग्लोबल पूलिंग जोड़ना, नेटवर्क को वैश्विक जानकारी देखने देता है:
class GlobalPoolingBlock(nn.Module):
def __init__(self, channels):
super().__init__()
self.conv = nn.Conv2d(channels, channels, 3, padding=1)
self.fc = nn.Linear(channels, channels)
def forward(self, x):
# लोकल पाथ
local = self.conv(x)
# ग्लोबल पाथ
global_pool = x.mean(dim=[2, 3]) # ग्लोबल एवरेज पूलिंग
global_fc = self.fc(global_pool)
global_broadcast = global_fc.unsqueeze(2).unsqueeze(3)
global_broadcast = global_broadcast.expand(-1, -1, 19, 19)
# मर्ज करें
return local + global_broadcast
ग्लोबल पूलिंग क्यों आवश्यक है?
पारंपरिक कन्वोल्यूशन केवल लोकल (3×3 रिसेप्टिव फील्ड) देखता है, कई लेयर स्टैक करने के बाद भी, वैश्विक जानकारी की धारणा सीमित रहती है। ग्लोबल पूलिंग नेटवर्क को सीधे "देखने" देता है:
- पूरे बोर्ड पर पत्थरों का अंतर
- वैश्विक प्रभाव वितरण
- समग्र स्थिति आकलन
आउटपुट हेड डिज़ाइन
Policy Head (रणनीति हेड)
प्रत्येक स्थिति की चाल प्रायिकता आउटपुट करता है:
class PolicyHead(nn.Module):
def __init__(self, in_channels):
super().__init__()
self.conv = nn.Conv2d(in_channels, 2, 1) # 1×1 कन्वोल्यूशन
self.bn = nn.BatchNorm2d(2)
self.fc = nn.Linear(2 * 19 * 19, 362) # 361 + pass
def forward(self, x):
out = F.relu(self.bn(self.conv(x)))
out = out.view(out.size(0), -1)
out = self.fc(out)
return F.softmax(out, dim=1) # प्रायिकता वितरण
आउटपुट प्रारूप: 362-आयामी वेक्टर
- इंडेक्स 0-360: बोर्ड पर 361 स्थानों की चाल प्रायिकता
- इंडेक्स 361: पास की प्रायिकता
Value Head (मूल्य हेड)
वर्तमान स्थिति की जीत दर आउटपुट करता है:
class ValueHead(nn.Module):
def __init__(self, in_channels):
super().__init__()
self.conv = nn.Conv2d(in_channels, 1, 1)
self.bn = nn.BatchNorm2d(1)
self.fc1 = nn.Linear(19 * 19, 256)
self.fc2 = nn.Linear(256, 1)
def forward(self, x):
out = F.relu(self.bn(self.conv(x)))
out = out.view(out.size(0), -1)
out = F.relu(self.fc1(out))
out = torch.tanh(self.fc2(out)) # -1 से +1 आउटपुट
return out
आउटपुट प्रारूप: एकल मान [-1, +1]
- +1: अपनी निश्चित जीत
- -1: प्रतिद्वंद्वी की निश्चित जीत
- 0: समान स्थिति
Score Head (अंक हेड)
KataGo विशेष, अंतिम अंक अंतर का पूर्वानुमान:
class ScoreHead(nn.Module):
def __init__(self, in_channels):
super().__init__()
self.conv = nn.Conv2d(in_channels, 1, 1)
self.bn = nn.BatchNorm2d(1)
self.fc1 = nn.Linear(19 * 19, 256)
self.fc2 = nn.Linear(256, 1)
def forward(self, x):
out = F.relu(self.bn(self.conv(x)))
out = out.view(out.size(0), -1)
out = F.relu(self.fc1(out))
out = self.fc2(out) # अप्रतिबंधित आउटपुट
return out
आउटपुट प्रारूप: एकल मान (अंक)
- धनात्मक संख्या: अपनी बढ़त
- ऋणात्मक संख्या: प्रतिद्वंद्वी की बढ़त
Ownership Head (स्वामित्व हेड)
प्रत्येक बिंदु के अंतिम स्वामित्व का पूर्वानुमान:
class OwnershipHead(nn.Module):
def __init__(self, in_channels):
super().__init__()
self.conv1 = nn.Conv2d(in_channels, 32, 1)
self.bn = nn.BatchNorm2d(32)
self.conv2 = nn.Conv2d(32, 1, 1)
def forward(self, x):
out = F.relu(self.bn(self.conv1(x)))
out = torch.tanh(self.conv2(out)) # प्रत्येक बिंदु -1 से +1
return out.view(out.size(0), -1) # 361 में फ्लैटन करें
आउटपुट प्रारूप: 361-आयामी वेक्टर, प्रत्येक मान [-1, +1] में
- +1: यह बिंदु अपने क्षेत्र का है
- -1: यह बिंदु प्रतिद्वंद्वी के क्षेत्र का है
- 0: तटस्थ या विवादित क्षेत्र
AlphaZero से अंतर
| पहलू | AlphaZero | KataGo |
|---|---|---|
| आउटपुट हेड | 2 (Policy + Value) | 4 (+ Score + Ownership) |
| ग्लोबल पूलिंग | नहीं | हाँ |
| इनपुट फीचर्स | 17 प्लेन | 22 प्लेन (नियम एनकोडिंग सहित) |
| रेसिड्यूअल ब्लॉक | मानक ResNet | Pre-activation + ग्लोबल पूलिंग |
| मल्टी-रूल समर्थन | नहीं | हाँ (फीचर एनकोडिंग के माध्यम से) |
मॉडल स्केल
KataGo विभिन्न स्केल के मॉडल प्रदान करता है:
| मॉडल | रेसिड्यूअल ब्लॉक | चैनल | पैरामीटर | उपयोग परिदृश्य |
|---|---|---|---|---|
| b10c128 | 10 | 128 | ~5M | CPU, त्वरित परीक्षण |
| b18c384 | 18 | 384 | ~75M | सामान्य GPU |
| b40c256 | 40 | 256 | ~95M | उच्च-स्तरीय GPU |
| b60c320 | 60 | 320 | ~200M | टॉप-टियर GPU |
नामकरण नियम: b{रेसिड्यूअल ब्लॉक संख्या}c{चैनल संख्या}
पूर्ण नेटवर्क कार्यान्वयन
class KataGoNetwork(nn.Module):
def __init__(self, num_blocks=18, channels=384):
super().__init__()
# प्रारंभिक कन्वोल्यूशन
self.initial_conv = nn.Conv2d(22, channels, 3, padding=1)
self.initial_bn = nn.BatchNorm2d(channels)
# रेसिड्यूअल टावर
self.residual_blocks = nn.ModuleList([
ResidualBlock(channels) for _ in range(num_blocks)
])
# ग्लोबल पूलिंग ब्लॉक (हर कुछ रेसिड्यूअल ब्लॉक के बाद एक डालें)
self.global_pooling_blocks = nn.ModuleList([
GlobalPoolingBlock(channels) for _ in range(num_blocks // 6)
])
# आउटपुट हेड
self.policy_head = PolicyHead(channels)
self.value_head = ValueHead(channels)
self.score_head = ScoreHead(channels)
self.ownership_head = OwnershipHead(channels)
def forward(self, x):
# प्रारंभिक कन्वोल्यूशन
out = F.relu(self.initial_bn(self.initial_conv(x)))
# रेसिड्यूअल टावर
gp_idx = 0
for i, block in enumerate(self.residual_blocks):
out = block(out)
# हर 6 रेसिड्यूअल ब्लॉक के बाद ग्लोबल पूलिंग डालें
if (i + 1) % 6 == 0 and gp_idx < len(self.global_pooling_blocks):
out = self.global_pooling_blocks[gp_idx](out)
gp_idx += 1
# आउटपुट हेड
policy = self.policy_head(out)
value = self.value_head(out)
score = self.score_head(out)
ownership = self.ownership_head(out)
return {
'policy': policy,
'value': value,
'score': score,
'ownership': ownership
}
आगे पढ़ें
- MCTS कार्यान्वयन विवरण — सर्च और न्यूरल नेटवर्क का संयोजन
- KataGo प्रशिक्षण तंत्र विश्लेषण — नेटवर्क को कैसे प्रशिक्षित करें
- मुख्य पेपर गाइड — मूल पेपर की गणितीय व्युत्पत्ति