QuizGenerator 0.7.1__py3-none-any.whl → 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- QuizGenerator/contentast.py +6 -6
- QuizGenerator/generate.py +2 -1
- QuizGenerator/mixins.py +14 -100
- QuizGenerator/premade_questions/basic.py +24 -29
- QuizGenerator/premade_questions/cst334/languages.py +100 -99
- QuizGenerator/premade_questions/cst334/math_questions.py +112 -122
- QuizGenerator/premade_questions/cst334/memory_questions.py +621 -621
- QuizGenerator/premade_questions/cst334/persistence_questions.py +137 -163
- QuizGenerator/premade_questions/cst334/process.py +312 -322
- QuizGenerator/premade_questions/cst463/gradient_descent/gradient_calculation.py +34 -35
- QuizGenerator/premade_questions/cst463/gradient_descent/gradient_descent_questions.py +41 -36
- QuizGenerator/premade_questions/cst463/gradient_descent/loss_calculations.py +48 -41
- QuizGenerator/premade_questions/cst463/math_and_data/matrix_questions.py +285 -520
- QuizGenerator/premade_questions/cst463/math_and_data/vector_questions.py +149 -126
- QuizGenerator/premade_questions/cst463/models/attention.py +44 -50
- QuizGenerator/premade_questions/cst463/models/cnns.py +43 -47
- QuizGenerator/premade_questions/cst463/models/matrices.py +61 -11
- QuizGenerator/premade_questions/cst463/models/rnns.py +48 -50
- QuizGenerator/premade_questions/cst463/models/text.py +65 -67
- QuizGenerator/premade_questions/cst463/models/weight_counting.py +47 -46
- QuizGenerator/premade_questions/cst463/neural-network-basics/neural_network_questions.py +100 -156
- QuizGenerator/premade_questions/cst463/tensorflow-intro/tensorflow_questions.py +93 -141
- QuizGenerator/question.py +273 -202
- QuizGenerator/quiz.py +8 -5
- QuizGenerator/regenerate.py +14 -6
- {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/METADATA +30 -2
- {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/RECORD +30 -30
- {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/WHEEL +0 -0
- {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/entry_points.txt +0 -0
- {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -6,7 +6,7 @@ import logging
|
|
|
6
6
|
import re
|
|
7
7
|
import numpy as np
|
|
8
8
|
import sympy as sp
|
|
9
|
-
from typing import List, Tuple
|
|
9
|
+
from typing import List, Tuple
|
|
10
10
|
|
|
11
11
|
import QuizGenerator.contentast as ca
|
|
12
12
|
from QuizGenerator.question import Question, QuestionRegistry
|
|
@@ -39,8 +39,13 @@ class ParameterCountingQuestion(Question):
|
|
|
39
39
|
self.num_layers = kwargs.get("num_layers", None)
|
|
40
40
|
self.include_biases = kwargs.get("include_biases", True)
|
|
41
41
|
|
|
42
|
-
def
|
|
43
|
-
|
|
42
|
+
def _build_context(self, *, rng_seed=None, **kwargs):
|
|
43
|
+
if "num_layers" in kwargs:
|
|
44
|
+
self.num_layers = kwargs.get("num_layers", self.num_layers)
|
|
45
|
+
if "include_biases" in kwargs:
|
|
46
|
+
self.include_biases = kwargs.get("include_biases", self.include_biases)
|
|
47
|
+
|
|
48
|
+
self.rng.seed(rng_seed)
|
|
44
49
|
|
|
45
50
|
# Generate random architecture
|
|
46
51
|
if self.num_layers is None:
|
|
@@ -78,22 +83,11 @@ class ParameterCountingQuestion(Question):
|
|
|
78
83
|
|
|
79
84
|
self.total_params = self.total_weights + self.total_biases
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def _create_answers(self):
|
|
85
|
-
"""Create answer fields."""
|
|
86
|
-
self.answers = {}
|
|
87
|
-
|
|
88
|
-
self.answers["total_weights"] = ca.AnswerTypes.Int(self.total_weights, label="Total weights")
|
|
89
|
-
|
|
90
|
-
if self.include_biases:
|
|
91
|
-
self.answers["total_biases"] = ca.AnswerTypes.Int(self.total_biases, label="Total biases")
|
|
92
|
-
self.answers["total_params"] = ca.AnswerTypes.Int(self.total_params, label="Total trainable parameters")
|
|
93
|
-
else:
|
|
94
|
-
self.answers["total_params"] = ca.AnswerTypes.Int(self.total_params, label="Total trainable parameters")
|
|
86
|
+
context = dict(kwargs)
|
|
87
|
+
context["rng_seed"] = rng_seed
|
|
88
|
+
return context
|
|
95
89
|
|
|
96
|
-
def
|
|
90
|
+
def _build_body(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
97
91
|
"""Build question body and collect answers."""
|
|
98
92
|
body = ca.Section()
|
|
99
93
|
answers = []
|
|
@@ -124,35 +118,35 @@ class ParameterCountingQuestion(Question):
|
|
|
124
118
|
table_data = []
|
|
125
119
|
table_data.append(["Parameter Type", "Count"])
|
|
126
120
|
|
|
127
|
-
|
|
121
|
+
total_weights_answer = ca.AnswerTypes.Int(self.total_weights, label="Total weights")
|
|
122
|
+
total_biases_answer = None
|
|
123
|
+
total_params_answer = ca.AnswerTypes.Int(self.total_params, label="Total trainable parameters")
|
|
124
|
+
|
|
125
|
+
answers.append(total_weights_answer)
|
|
128
126
|
table_data.append([
|
|
129
127
|
"Total weights (connections between layers)",
|
|
130
|
-
|
|
128
|
+
total_weights_answer
|
|
131
129
|
])
|
|
132
130
|
|
|
133
131
|
if self.include_biases:
|
|
134
|
-
|
|
132
|
+
total_biases_answer = ca.AnswerTypes.Int(self.total_biases, label="Total biases")
|
|
133
|
+
answers.append(total_biases_answer)
|
|
135
134
|
table_data.append([
|
|
136
135
|
"Total biases",
|
|
137
|
-
|
|
136
|
+
total_biases_answer
|
|
138
137
|
])
|
|
139
138
|
|
|
140
|
-
answers.append(
|
|
139
|
+
answers.append(total_params_answer)
|
|
141
140
|
table_data.append([
|
|
142
141
|
"Total trainable parameters",
|
|
143
|
-
|
|
142
|
+
total_params_answer
|
|
144
143
|
])
|
|
145
144
|
|
|
146
145
|
body.add_element(ca.Table(data=table_data))
|
|
147
146
|
|
|
148
147
|
return body, answers
|
|
149
148
|
|
|
150
|
-
def
|
|
151
|
-
"""Build question body (backward compatible interface)."""
|
|
152
|
-
body, _ = self._get_body(**kwargs)
|
|
153
|
-
return body
|
|
154
|
-
|
|
155
|
-
def _get_explanation(self, **kwargs) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
149
|
+
def _build_explanation(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
156
150
|
"""Build question explanation."""
|
|
157
151
|
explanation = ca.Section()
|
|
158
152
|
|
|
@@ -221,11 +215,6 @@ class ParameterCountingQuestion(Question):
|
|
|
221
215
|
|
|
222
216
|
return explanation, []
|
|
223
217
|
|
|
224
|
-
def get_explanation(self, **kwargs) -> ca.Section:
|
|
225
|
-
"""Build question explanation (backward compatible interface)."""
|
|
226
|
-
explanation, _ = self._get_explanation(**kwargs)
|
|
227
|
-
return explanation
|
|
228
|
-
|
|
229
218
|
|
|
230
219
|
@QuestionRegistry.register()
|
|
231
220
|
class ActivationFunctionComputationQuestion(Question):
|
|
@@ -248,8 +237,13 @@ class ActivationFunctionComputationQuestion(Question):
|
|
|
248
237
|
self.vector_size = kwargs.get("vector_size", None)
|
|
249
238
|
self.activation = kwargs.get("activation", None)
|
|
250
239
|
|
|
251
|
-
def
|
|
252
|
-
|
|
240
|
+
def _build_context(self, *, rng_seed=None, **kwargs):
|
|
241
|
+
if "vector_size" in kwargs:
|
|
242
|
+
self.vector_size = kwargs.get("vector_size", self.vector_size)
|
|
243
|
+
if "activation" in kwargs:
|
|
244
|
+
self.activation = kwargs.get("activation", self.activation)
|
|
245
|
+
|
|
246
|
+
self.rng.seed(rng_seed)
|
|
253
247
|
|
|
254
248
|
# Generate random input vector
|
|
255
249
|
if self.vector_size is None:
|
|
@@ -276,8 +270,9 @@ class ActivationFunctionComputationQuestion(Question):
|
|
|
276
270
|
# Compute outputs
|
|
277
271
|
self.output_vector = self._compute_activation(self.input_vector)
|
|
278
272
|
|
|
279
|
-
|
|
280
|
-
|
|
273
|
+
context = dict(kwargs)
|
|
274
|
+
context["rng_seed"] = rng_seed
|
|
275
|
+
return context
|
|
281
276
|
|
|
282
277
|
def _compute_activation(self, inputs):
|
|
283
278
|
"""Compute activation function output."""
|
|
@@ -325,20 +320,7 @@ class ActivationFunctionComputationQuestion(Question):
|
|
|
325
320
|
|
|
326
321
|
return ""
|
|
327
322
|
|
|
328
|
-
def
|
|
329
|
-
"""Create answer fields."""
|
|
330
|
-
self.answers = {}
|
|
331
|
-
|
|
332
|
-
if self.activation == self.ACTIVATION_SOFTMAX:
|
|
333
|
-
# Softmax: single vector answer
|
|
334
|
-
self.answers["output"] = ca.AnswerTypes.Vector(self.output_vector, label="Output vector")
|
|
335
|
-
else:
|
|
336
|
-
# Element-wise: individual answers
|
|
337
|
-
for i, output in enumerate(self.output_vector):
|
|
338
|
-
key = f"output_{i}"
|
|
339
|
-
self.answers[key] = ca.AnswerTypes.Float(float(output), label=f"Output for input {self.input_vector[i]:.1f}")
|
|
340
|
-
|
|
341
|
-
def _get_body(self, **kwargs) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
323
|
+
def _build_body(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
342
324
|
"""Build question body and collect answers."""
|
|
343
325
|
body = ca.Section()
|
|
344
326
|
answers = []
|
|
@@ -367,10 +349,11 @@ class ActivationFunctionComputationQuestion(Question):
|
|
|
367
349
|
"Compute the output vector:"
|
|
368
350
|
]))
|
|
369
351
|
|
|
370
|
-
|
|
352
|
+
output_answer = ca.AnswerTypes.Vector(self.output_vector, label="Output vector")
|
|
353
|
+
answers.append(output_answer)
|
|
371
354
|
table_data = []
|
|
372
355
|
table_data.append(["Output Vector"])
|
|
373
|
-
table_data.append([
|
|
356
|
+
table_data.append([output_answer])
|
|
374
357
|
|
|
375
358
|
body.add_element(ca.Table(data=table_data))
|
|
376
359
|
|
|
@@ -383,7 +366,10 @@ class ActivationFunctionComputationQuestion(Question):
|
|
|
383
366
|
table_data.append(["Input", "Output"])
|
|
384
367
|
|
|
385
368
|
for i, x in enumerate(self.input_vector):
|
|
386
|
-
answer =
|
|
369
|
+
answer = ca.AnswerTypes.Float(
|
|
370
|
+
float(self.output_vector[i]),
|
|
371
|
+
label=f"Output for input {self.input_vector[i]:.1f}"
|
|
372
|
+
)
|
|
387
373
|
answers.append(answer)
|
|
388
374
|
table_data.append([
|
|
389
375
|
ca.Equation(f"{x:.1f}", inline=True),
|
|
@@ -394,12 +380,7 @@ class ActivationFunctionComputationQuestion(Question):
|
|
|
394
380
|
|
|
395
381
|
return body, answers
|
|
396
382
|
|
|
397
|
-
def
|
|
398
|
-
"""Build question body (backward compatible interface)."""
|
|
399
|
-
body, _ = self._get_body(**kwargs)
|
|
400
|
-
return body
|
|
401
|
-
|
|
402
|
-
def _get_explanation(self, **kwargs) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
383
|
+
def _build_explanation(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
403
384
|
"""Build question explanation."""
|
|
404
385
|
explanation = ca.Section()
|
|
405
386
|
|
|
@@ -470,11 +451,6 @@ class ActivationFunctionComputationQuestion(Question):
|
|
|
470
451
|
|
|
471
452
|
return explanation, []
|
|
472
453
|
|
|
473
|
-
def get_explanation(self, **kwargs) -> ca.Section:
|
|
474
|
-
"""Build question explanation (backward compatible interface)."""
|
|
475
|
-
explanation, _ = self._get_explanation(**kwargs)
|
|
476
|
-
return explanation
|
|
477
|
-
|
|
478
454
|
|
|
479
455
|
@QuestionRegistry.register()
|
|
480
456
|
class RegularizationCalculationQuestion(Question):
|
|
@@ -495,8 +471,11 @@ class RegularizationCalculationQuestion(Question):
|
|
|
495
471
|
|
|
496
472
|
self.num_weights = kwargs.get("num_weights", None)
|
|
497
473
|
|
|
498
|
-
def
|
|
499
|
-
|
|
474
|
+
def _build_context(self, *, rng_seed=None, **kwargs):
|
|
475
|
+
if "num_weights" in kwargs:
|
|
476
|
+
self.num_weights = kwargs.get("num_weights", self.num_weights)
|
|
477
|
+
|
|
478
|
+
self.rng.seed(rng_seed)
|
|
500
479
|
|
|
501
480
|
# Generate small network (2-4 weights for simplicity)
|
|
502
481
|
if self.num_weights is None:
|
|
@@ -538,20 +517,11 @@ class RegularizationCalculationQuestion(Question):
|
|
|
538
517
|
self.grad_reg_w0 = self.lambda_reg * self.weights[0]
|
|
539
518
|
self.grad_total_w0 = self.grad_base_w0 + self.grad_reg_w0
|
|
540
519
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
def _create_answers(self):
|
|
545
|
-
"""Create answer fields."""
|
|
546
|
-
self.answers = {}
|
|
547
|
-
|
|
548
|
-
self.answers["prediction"] = ca.AnswerTypes.Float(float(self.prediction), label="Prediction ŷ")
|
|
549
|
-
self.answers["base_loss"] = ca.AnswerTypes.Float(float(self.base_loss), label="Base MSE loss")
|
|
550
|
-
self.answers["l2_penalty"] = ca.AnswerTypes.Float(float(self.l2_penalty), label="L2 penalty")
|
|
551
|
-
self.answers["total_loss"] = ca.AnswerTypes.Float(float(self.total_loss), label="Total loss")
|
|
552
|
-
self.answers["grad_total_w0"] = ca.AnswerTypes.Float(float(self.grad_total_w0), label="Gradient ∂L/∂w₀")
|
|
520
|
+
context = dict(kwargs)
|
|
521
|
+
context["rng_seed"] = rng_seed
|
|
522
|
+
return context
|
|
553
523
|
|
|
554
|
-
def
|
|
524
|
+
def _build_body(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
555
525
|
"""Build question body and collect answers."""
|
|
556
526
|
body = ca.Section()
|
|
557
527
|
answers = []
|
|
@@ -604,46 +574,47 @@ class RegularizationCalculationQuestion(Question):
|
|
|
604
574
|
table_data = []
|
|
605
575
|
table_data.append(["Calculation", "Value"])
|
|
606
576
|
|
|
607
|
-
|
|
577
|
+
prediction_answer = ca.AnswerTypes.Float(float(self.prediction), label="Prediction ŷ")
|
|
578
|
+
base_loss_answer = ca.AnswerTypes.Float(float(self.base_loss), label="Base MSE loss")
|
|
579
|
+
l2_penalty_answer = ca.AnswerTypes.Float(float(self.l2_penalty), label="L2 penalty")
|
|
580
|
+
total_loss_answer = ca.AnswerTypes.Float(float(self.total_loss), label="Total loss")
|
|
581
|
+
grad_total_w0_answer = ca.AnswerTypes.Float(float(self.grad_total_w0), label="Gradient ∂L/∂w₀")
|
|
582
|
+
|
|
583
|
+
answers.append(prediction_answer)
|
|
608
584
|
table_data.append([
|
|
609
585
|
ca.Paragraph(["Prediction ", ca.Equation(r"\hat{y}", inline=True)]),
|
|
610
|
-
|
|
586
|
+
prediction_answer
|
|
611
587
|
])
|
|
612
588
|
|
|
613
|
-
answers.append(
|
|
589
|
+
answers.append(base_loss_answer)
|
|
614
590
|
table_data.append([
|
|
615
591
|
ca.Paragraph(["Base MSE loss: ", ca.Equation(r"L_{base} = (1/2)(y - \hat{y})^2", inline=True)]),
|
|
616
|
-
|
|
592
|
+
base_loss_answer
|
|
617
593
|
])
|
|
618
594
|
|
|
619
|
-
answers.append(
|
|
595
|
+
answers.append(l2_penalty_answer)
|
|
620
596
|
table_data.append([
|
|
621
597
|
ca.Paragraph(["L2 penalty: ", ca.Equation(r"L_{reg} = (\lambda/2)\sum w_i^2", inline=True)]),
|
|
622
|
-
|
|
598
|
+
l2_penalty_answer
|
|
623
599
|
])
|
|
624
600
|
|
|
625
|
-
answers.append(
|
|
601
|
+
answers.append(total_loss_answer)
|
|
626
602
|
table_data.append([
|
|
627
603
|
ca.Paragraph(["Total loss: ", ca.Equation(r"L_{total} = L_{base} + L_{reg}", inline=True)]),
|
|
628
|
-
|
|
604
|
+
total_loss_answer
|
|
629
605
|
])
|
|
630
606
|
|
|
631
|
-
answers.append(
|
|
607
|
+
answers.append(grad_total_w0_answer)
|
|
632
608
|
table_data.append([
|
|
633
609
|
ca.Paragraph(["Gradient: ", ca.Equation(r"\frac{\partial L_{total}}{\partial w_0}", inline=True)]),
|
|
634
|
-
|
|
610
|
+
grad_total_w0_answer
|
|
635
611
|
])
|
|
636
612
|
|
|
637
613
|
body.add_element(ca.Table(data=table_data))
|
|
638
614
|
|
|
639
615
|
return body, answers
|
|
640
616
|
|
|
641
|
-
def
|
|
642
|
-
"""Build question body (backward compatible interface)."""
|
|
643
|
-
body, _ = self._get_body(**kwargs)
|
|
644
|
-
return body
|
|
645
|
-
|
|
646
|
-
def _get_explanation(self, **kwargs) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
617
|
+
def _build_explanation(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
647
618
|
"""Build question explanation."""
|
|
648
619
|
explanation = ca.Section()
|
|
649
620
|
|
|
@@ -735,11 +706,6 @@ class RegularizationCalculationQuestion(Question):
|
|
|
735
706
|
|
|
736
707
|
return explanation, []
|
|
737
708
|
|
|
738
|
-
def get_explanation(self, **kwargs) -> ca.Section:
|
|
739
|
-
"""Build question explanation (backward compatible interface)."""
|
|
740
|
-
explanation, _ = self._get_explanation(**kwargs)
|
|
741
|
-
return explanation
|
|
742
|
-
|
|
743
709
|
|
|
744
710
|
@QuestionRegistry.register()
|
|
745
711
|
class MomentumOptimizerQuestion(Question, TableQuestionMixin, BodyTemplatesMixin):
|
|
@@ -760,12 +726,16 @@ class MomentumOptimizerQuestion(Question, TableQuestionMixin, BodyTemplatesMixin
|
|
|
760
726
|
self.num_variables = kwargs.get("num_variables", 2)
|
|
761
727
|
self.show_vanilla_sgd = kwargs.get("show_vanilla_sgd", True)
|
|
762
728
|
|
|
763
|
-
def
|
|
764
|
-
|
|
729
|
+
def _build_context(self, *, rng_seed=None, **kwargs):
|
|
730
|
+
if "num_variables" in kwargs:
|
|
731
|
+
self.num_variables = kwargs.get("num_variables", self.num_variables)
|
|
732
|
+
if "show_vanilla_sgd" in kwargs:
|
|
733
|
+
self.show_vanilla_sgd = kwargs.get("show_vanilla_sgd", self.show_vanilla_sgd)
|
|
734
|
+
|
|
735
|
+
self.rng.seed(rng_seed)
|
|
765
736
|
|
|
766
737
|
# Generate well-conditioned quadratic function
|
|
767
|
-
self.variables, self.function, self.gradient_function, self.equation =
|
|
768
|
-
generate_function(self.rng, self.num_variables, max_degree=2, use_quadratic=True)
|
|
738
|
+
self.variables, self.function, self.gradient_function, self.equation = generate_function(self.rng, self.num_variables, max_degree=2, use_quadratic=True)
|
|
769
739
|
|
|
770
740
|
# Generate current weights (small integers)
|
|
771
741
|
self.current_weights = [
|
|
@@ -809,24 +779,11 @@ class MomentumOptimizerQuestion(Question, TableQuestionMixin, BodyTemplatesMixin
|
|
|
809
779
|
for w, grad in zip(self.current_weights, self.gradients)
|
|
810
780
|
]
|
|
811
781
|
|
|
812
|
-
|
|
813
|
-
|
|
782
|
+
context = dict(kwargs)
|
|
783
|
+
context["rng_seed"] = rng_seed
|
|
784
|
+
return context
|
|
814
785
|
|
|
815
|
-
def
|
|
816
|
-
"""Create answer fields."""
|
|
817
|
-
self.answers = {}
|
|
818
|
-
|
|
819
|
-
# New velocity
|
|
820
|
-
self.answers["velocity"] = ca.AnswerTypes.Vector(self.new_velocity, label="New velocity")
|
|
821
|
-
|
|
822
|
-
# New weights with momentum
|
|
823
|
-
self.answers["weights_momentum"] = ca.AnswerTypes.Vector(self.new_weights, label="Weights (momentum)")
|
|
824
|
-
|
|
825
|
-
# Vanilla SGD weights for comparison
|
|
826
|
-
if self.show_vanilla_sgd:
|
|
827
|
-
self.answers["weights_sgd"] = ca.AnswerTypes.Vector(self.sgd_weights, label="Weights (vanilla SGD)")
|
|
828
|
-
|
|
829
|
-
def _get_body(self, **kwargs) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
786
|
+
def _build_body(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
830
787
|
"""Build question body and collect answers."""
|
|
831
788
|
body = ca.Section()
|
|
832
789
|
answers = []
|
|
@@ -889,38 +846,38 @@ class MomentumOptimizerQuestion(Question, TableQuestionMixin, BodyTemplatesMixin
|
|
|
889
846
|
table_data = []
|
|
890
847
|
table_data.append(["Update Type", "Formula", "Result"])
|
|
891
848
|
|
|
892
|
-
|
|
849
|
+
velocity_answer = ca.AnswerTypes.Vector(self.new_velocity, label="New velocity")
|
|
850
|
+
weights_momentum_answer = ca.AnswerTypes.Vector(self.new_weights, label="Weights (momentum)")
|
|
851
|
+
weights_sgd_answer = None
|
|
852
|
+
|
|
853
|
+
answers.append(velocity_answer)
|
|
893
854
|
table_data.append([
|
|
894
855
|
"New velocity",
|
|
895
856
|
ca.Equation(r"v' = \beta v + (1-\beta)\nabla f", inline=True),
|
|
896
|
-
|
|
857
|
+
velocity_answer
|
|
897
858
|
])
|
|
898
859
|
|
|
899
|
-
answers.append(
|
|
860
|
+
answers.append(weights_momentum_answer)
|
|
900
861
|
table_data.append([
|
|
901
862
|
"Weights (momentum)",
|
|
902
863
|
ca.Equation(r"w' = w - \alpha v'", inline=True),
|
|
903
|
-
|
|
864
|
+
weights_momentum_answer
|
|
904
865
|
])
|
|
905
866
|
|
|
906
867
|
if self.show_vanilla_sgd:
|
|
907
|
-
|
|
868
|
+
weights_sgd_answer = ca.AnswerTypes.Vector(self.sgd_weights, label="Weights (vanilla SGD)")
|
|
869
|
+
answers.append(weights_sgd_answer)
|
|
908
870
|
table_data.append([
|
|
909
871
|
"Weights (vanilla SGD)",
|
|
910
872
|
ca.Equation(r"w' = w - \alpha \nabla f", inline=True),
|
|
911
|
-
|
|
873
|
+
weights_sgd_answer
|
|
912
874
|
])
|
|
913
875
|
|
|
914
876
|
body.add_element(ca.Table(data=table_data))
|
|
915
877
|
|
|
916
878
|
return body, answers
|
|
917
879
|
|
|
918
|
-
def
|
|
919
|
-
"""Build question body (backward compatible interface)."""
|
|
920
|
-
body, _ = self._get_body(**kwargs)
|
|
921
|
-
return body
|
|
922
|
-
|
|
923
|
-
def _get_explanation(self, **kwargs) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
880
|
+
def _build_explanation(self, context) -> Tuple[ca.Section, List[ca.Answer]]:
|
|
924
881
|
"""Build question explanation."""
|
|
925
882
|
explanation = ca.Section()
|
|
926
883
|
|
|
@@ -1002,8 +959,3 @@ class MomentumOptimizerQuestion(Question, TableQuestionMixin, BodyTemplatesMixin
|
|
|
1002
959
|
]))
|
|
1003
960
|
|
|
1004
961
|
return explanation, []
|
|
1005
|
-
|
|
1006
|
-
def get_explanation(self, **kwargs) -> ca.Section:
|
|
1007
|
-
"""Build question explanation (backward compatible interface)."""
|
|
1008
|
-
explanation, _ = self._get_explanation(**kwargs)
|
|
1009
|
-
return explanation
|