समस्या
बैकप्रोपेगेशन चेन रूल को लेयर दर लेयर लागू करता है, आउटपुट से वापस इनपुट की ओर। नेटवर्क में n इनपुट, h हिडन न्यूरॉन और एक आउटपुट है, सभी sigmoid एक्टिवेशन (σ(z) = 1 / (1 + e^(-z))) के साथ:
- हिडन: a_j = σ(inputs · hidden_weights[j] + hidden_biases[j])
- आउटपुट: y = σ(a · output_weights + output_bias)
- लॉस: L = (y - target)²
ग्रेडिएंट:
- delta_out = 2 × (y - target) × y × (1 - y)
- आउटपुट लेयर: dL/doutput_weights[j] = delta_out × a_j और dL/doutput_bias = delta_out
- delta_j = delta_out × output_weights[j] × a_j × (1 - a_j)
- हिडन लेयर: dL/dhidden_weights[j][i] = delta_j × inputs[i] और dL/dhidden_biases[j] = delta_j
backprop_gradients(inputs, hidden_weights, hidden_biases, output_weights, output_bias, target) लागू करें।
आउटपुट
h + 1 पंक्तियों वाला मैट्रिक्स लौटाएँ:
- पंक्ति j (हर हिडन न्यूरॉन j के लिए, क्रम से):
hidden_weights[j]के n ग्रेडिएंट, फिरhidden_biases[j]का ग्रेडिएंट। - आखिरी पंक्ति:
output_weightsके h ग्रेडिएंट, फिरoutput_biasका ग्रेडिएंट।
सीमाएँ
1 ≤ n, h ≤ 20
-5 ≤ हर इनपुट, वेट और बायस ≤ 5
0 ≤ target ≤ 1
उदाहरण
इनपुट:
inputs = [1.0]
target = 1.0
output_bias = 0.0
hidden_biases = [0.0]
hidden_weights = [
[0.0]
]
output_weights = [0.0]
अपेक्षित आउटपुट:
expected = [
[0.0, 0.0],
[-0.125, -0.25]
]
इनपुट:
std::vector<double> inputs = {1.0};
double target = 1.0;
double output_bias = 0.0;
std::vector<double> hidden_biases = {0.0};
std::vector<std::vector<double>> hidden_weights = {
{0.0}
};
std::vector<double> output_weights = {0.0};
अपेक्षित आउटपुट:
std::vector<std::vector<double>> expected = {
{0.0, 0.0},
{-0.125, -0.25}
};
इनपुट:
double[] inputs = new double[] {1.0};
double target = 1.0;
double output_bias = 0.0;
double[] hidden_biases = new double[] {0.0};
double[][] hidden_weights = new double[][] {
new double[] {0.0}
};
double[] output_weights = new double[] {0.0};
अपेक्षित आउटपुट:
double[][] expected = new double[][] {
new double[] {0.0, 0.0},
new double[] {-0.125, -0.25}
};
व्याख्या
a = σ(0) = 0.5 और y = σ(0) = 0.5। delta_out = 2 × (0.5 - 1) × 0.25 = -0.25। आउटपुट पंक्ति: [-0.25 × 0.5, -0.25] = [-0.125, -0.25]। delta_1 = -0.25 × 0 × 0.25 = 0, इसलिए हिडन पंक्ति [0, 0] है: शून्य आउटपुट वेट ग्रेडिएंट को रोक देता है।
इनपुट:
inputs = [1.0, 0.0]
target = 0.0
output_bias = -1.0
hidden_biases = [0.0, 0.0]
hidden_weights = [
[0.0, 1.0],
[0.0, -1.0]
]
output_weights = [1.0, 1.0]
अपेक्षित आउटपुट:
expected = [
[0.0625, 0.0, 0.0625],
[0.0625, 0.0, 0.0625],
[0.125, 0.125, 0.25]
]
इनपुट:
std::vector<double> inputs = {1.0, 0.0};
double target = 0.0;
double output_bias = -1.0;
std::vector<double> hidden_biases = {0.0, 0.0};
std::vector<std::vector<double>> hidden_weights = {
{0.0, 1.0},
{0.0, -1.0}
};
std::vector<double> output_weights = {1.0, 1.0};
अपेक्षित आउटपुट:
std::vector<std::vector<double>> expected = {
{0.0625, 0.0, 0.0625},
{0.0625, 0.0, 0.0625},
{0.125, 0.125, 0.25}
};
इनपुट:
double[] inputs = new double[] {1.0, 0.0};
double target = 0.0;
double output_bias = -1.0;
double[] hidden_biases = new double[] {0.0, 0.0};
double[][] hidden_weights = new double[][] {
new double[] {0.0, 1.0},
new double[] {0.0, -1.0}
};
double[] output_weights = new double[] {1.0, 1.0};
अपेक्षित आउटपुट:
double[][] expected = new double[][] {
new double[] {0.0625, 0.0, 0.0625},
new double[] {0.0625, 0.0, 0.0625},
new double[] {0.125, 0.125, 0.25}
};
व्याख्या
दोनों हिडन मान σ(0) = 0.5 हैं, इसलिए y = σ(0.5 + 0.5 - 1) = 0.5 और delta_out = 2 × 0.5 × 0.25 = 0.25। आउटपुट पंक्ति: [0.125, 0.125, 0.25]। हर delta_j = 0.25 × 1 × 0.25 = 0.0625, जिससे हिडन पंक्तियाँ [0.0625, 0, 0.0625] बनती हैं (दूसरा इनपुट 0 है)।
कैसे हल करें
पहले खुद कोशिश करें, फिर एक-एक करके संकेत खोलें।
संकेत 1
पहले output neuron से backward चलें, फिर उसी signal को reuse करके हर hidden neuron का contribution निकालें.
संकेत 2
आपको output layer के लिए एक delta और हर hidden neuron के लिए एक delta चाहिए, दोनों sigmoid derivatives पर based.
संकेत 3
Error वापस भेजते समय हर hidden neuron के अपने output weight का उपयोग करना न भूलें.
अपेक्षित जटिलता
समय O(hn), अतिरिक्त स्थान O(hn)
संदर्भ
यह चुनौती CodeUtility के लिए अनुकूलित की गई है। ऊपर दिए गए स्टेटमेंट और सीमाओं का पालन करें।