import%20marimo%0A%0A__generated_with%20%3D%20%220.23.16%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20METADATA%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22id%22%3A%20%22backpropagation%22%2C%0A%20%20%20%20%20%20%20%20%22name%22%3A%20%22Backpropagation%22%2C%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22concept%22%2C%0A%20%20%20%20%20%20%20%20%22difficulty%22%3A%20%22intermediate%22%2C%0A%20%20%20%20%20%20%20%20%22status%22%3A%20%22complete%22%2C%0A%20%20%20%20%20%20%20%20%22topics%22%3A%20%5B%22neural_networks%22%2C%20%22backpropagation%22%2C%20%22optimization%22%5D%2C%0A%20%20%20%20%20%20%20%20%22related_models%22%3A%20%5B%22mlp%22%2C%20%22tcn%22%2C%20%22transformer%22%2C%20%22diffusion_model%22%5D%2C%0A%20%20%20%20%20%20%20%20%22prerequisites%22%3A%20%5B%22perceptron%22%2C%20%22loss_optimization%22%5D%2C%0A%20%20%20%20%7D%0A%20%20%20%20mo.md(f%22%23%20%7BMETADATA%5B'name'%5D%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20In%20one%20sentence%0A%0A%20%20%20%20Backpropagation%20sends%20the%20prediction%20error%20backward%20through%20a%20network%20to%20measure%20how%20much%20each%20parameter%20contributed%20to%20it.%0A%0A%20%20%20%20%23%23%20Mental%20model%0A%0A%20%20%20%20The%20forward%20pass%20produces%20a%20prediction.%20The%20loss%20measures%20the%20error.%20The%20backward%20pass%20distributes%20**blame**%20from%20the%20loss%20to%20every%20weight%20using%20the%20chain%20rule.%20An%20optimizer%20then%20nudges%20each%20weight%20in%20the%20direction%20that%20reduces%20the%20loss.%0A%0A%20%20%20%20Backpropagation%20computes%20gradients%3B%20gradient%20descent%20uses%20them.%0A%0A%20%20%20%20%23%23%20Why%20it%20matters%0A%0A%20%20%20%20A%20deep%20network%20may%20contain%20millions%20of%20parameters.%20Backpropagation%20reuses%20local%20derivatives%20so%20all%20their%20gradients%20can%20be%20computed%20efficiently%20in%20one%20backward%20sweep.%0A%0A%20%20%20%20%23%23%20Experiment%0A%0A%20%20%20%20**Question%3A**%20how%20does%20one%20error%20signal%20travel%20backward%20through%20a%20tiny%20two-layer%20network%3F%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%0A%20%20%20%20input_value%20%3D%201.4%0A%20%20%20%20target_value%20%3D%200.85%0A%20%20%20%20parameters%20%3D%20%7B%22w1%22%3A%200.25%2C%20%22b1%22%3A%200.05%2C%20%22w2%22%3A%20-0.35%2C%20%22b2%22%3A%200.15%7D%0A%0A%20%20%20%20def%20forward(current)%3A%0A%20%20%20%20%20%20%20%20hidden_input%20%3D%20current%5B%22w1%22%5D%20*%20input_value%20%2B%20current%5B%22b1%22%5D%0A%20%20%20%20%20%20%20%20hidden_value%20%3D%20np.tanh(hidden_input)%0A%20%20%20%20%20%20%20%20prediction%20%3D%20current%5B%22w2%22%5D%20*%20hidden_value%20%2B%20current%5B%22b2%22%5D%0A%20%20%20%20%20%20%20%20loss%20%3D%200.5%20*%20(prediction%20-%20target_value)%20**%202%0A%20%20%20%20%20%20%20%20return%20hidden_input%2C%20hidden_value%2C%20prediction%2C%20loss%0A%0A%20%20%20%20def%20backward(current%2C%20cache)%3A%0A%20%20%20%20%20%20%20%20hidden_input%2C%20hidden_value%2C%20prediction%2C%20_loss%20%3D%20cache%0A%20%20%20%20%20%20%20%20d_prediction%20%3D%20prediction%20-%20target_value%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22w2%22%3A%20d_prediction%20*%20hidden_value%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22b2%22%3A%20d_prediction%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22w1%22%3A%20d_prediction%20*%20current%5B%22w2%22%5D%20*%20(1%20-%20np.tanh(hidden_input)%20**%202)%20*%20input_value%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22b1%22%3A%20d_prediction%20*%20current%5B%22w2%22%5D%20*%20(1%20-%20np.tanh(hidden_input)%20**%202)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22hidden%22%3A%20d_prediction%20*%20current%5B%22w2%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22hidden_input%22%3A%20d_prediction%20*%20current%5B%22w2%22%5D%20*%20(1%20-%20np.tanh(hidden_input)%20**%202)%2C%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20initial_cache%20%3D%20forward(parameters)%0A%20%20%20%20initial_gradients%20%3D%20backward(parameters%2C%20initial_cache)%0A%20%20%20%20trained_parameters%20%3D%20parameters.copy()%0A%20%20%20%20loss_history%20%3D%20%5B%5D%0A%20%20%20%20prediction_history%20%3D%20%5B%5D%0A%20%20%20%20learning_rate%20%3D%200.35%0A%0A%20%20%20%20for%20_step%20in%20range(28)%3A%0A%20%20%20%20%20%20%20%20cache%20%3D%20forward(trained_parameters)%0A%20%20%20%20%20%20%20%20gradients%20%3D%20backward(trained_parameters%2C%20cache)%0A%20%20%20%20%20%20%20%20loss_history.append(cache%5B3%5D)%0A%20%20%20%20%20%20%20%20prediction_history.append(cache%5B2%5D)%0A%20%20%20%20%20%20%20%20for%20parameter_name%20in%20(%22w1%22%2C%20%22b1%22%2C%20%22w2%22%2C%20%22b2%22)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20trained_parameters%5Bparameter_name%5D%20-%3D%20learning_rate%20*%20gradients%5Bparameter_name%5D%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20initial_cache%2C%0A%20%20%20%20%20%20%20%20initial_gradients%2C%0A%20%20%20%20%20%20%20%20input_value%2C%0A%20%20%20%20%20%20%20%20loss_history%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20plt%2C%0A%20%20%20%20%20%20%20%20prediction_history%2C%0A%20%20%20%20%20%20%20%20target_value%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(%0A%20%20%20%20initial_cache%2C%0A%20%20%20%20initial_gradients%2C%0A%20%20%20%20input_value%2C%0A%20%20%20%20loss_history%2C%0A%20%20%20%20np%2C%0A%20%20%20%20plt%2C%0A%20%20%20%20prediction_history%2C%0A%20%20%20%20target_value%2C%0A)%3A%0A%20%20%20%20from%20matplotlib.patches%20import%20Circle%2C%20FancyArrowPatch%2C%20FancyBboxPatch%0A%0A%20%20%20%20ink%20%3D%20%22%2317324D%22%0A%20%20%20%20blue%20%3D%20%22%233A7CA5%22%0A%20%20%20%20coral%20%3D%20%22%23E76F51%22%0A%20%20%20%20teal%20%3D%20%22%232A9D8F%22%0A%20%20%20%20gold%20%3D%20%22%23E9C46A%22%0A%20%20%20%20paper%20%3D%20%22%23FAF7F0%22%0A%20%20%20%20grid_color%20%3D%20%22%23DCE3E8%22%0A%0A%20%20%20%20hidden_input%2C%20hidden_value%2C%20initial_prediction%2C%20initial_loss%20%3D%20initial_cache%0A%20%20%20%20node_data%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(0.8%2C%20%22input%22%2C%20input_value)%2C%0A%20%20%20%20%20%20%20%20(2.7%2C%20%22hidden%22%2C%20hidden_value)%2C%0A%20%20%20%20%20%20%20%20(4.6%2C%20%22prediction%22%2C%20initial_prediction)%2C%0A%20%20%20%20%20%20%20%20(6.5%2C%20%22loss%22%2C%20initial_loss)%2C%0A%20%20%20%20%5D%0A%0A%20%20%20%20fig%2C%20axes%20%3D%20plt.subplots(1%2C%203%2C%20figsize%3D(15%2C%204.8)%2C%20facecolor%3Dpaper)%0A%20%20%20%20for%20axis%20in%20axes%3A%0A%20%20%20%20%20%20%20%20axis.set_facecolor(paper)%0A%0A%20%20%20%20%23%201%20%E2%80%94%20forward%20pass%0A%20%20%20%20ax%20%3D%20axes%5B0%5D%0A%20%20%20%20ax.set(xlim%3D(0%2C%207.4)%2C%20ylim%3D(0%2C%205.8))%0A%20%20%20%20ax.axis(%22off%22)%0A%20%20%20%20for%20index%2C%20(x_pos%2C%20label%2C%20value)%20in%20enumerate(node_data)%3A%0A%20%20%20%20%20%20%20%20color%20%3D%20%5Bblue%2C%20gold%2C%20teal%2C%20coral%5D%5Bindex%5D%0A%20%20%20%20%20%20%20%20box%20%3D%20FancyBboxPatch((x_pos%20-%200.65%2C%202.15)%2C%201.3%2C%201.25%2C%20boxstyle%3D%22round%2Cpad%3D0.16%22%2C%20facecolor%3Dcolor%2C%20edgecolor%3Dink%2C%20linewidth%3D1.2)%0A%20%20%20%20%20%20%20%20ax.add_patch(box)%0A%20%20%20%20%20%20%20%20text_color%20%3D%20ink%20if%20index%20%3D%3D%201%20else%20%22white%22%0A%20%20%20%20%20%20%20%20ax.text(x_pos%2C%202.95%2C%20label%2C%20ha%3D%22center%22%2C%20va%3D%22center%22%2C%20color%3Dtext_color%2C%20fontsize%3D9%2C%20weight%3D%22bold%22)%0A%20%20%20%20%20%20%20%20ax.text(x_pos%2C%202.55%2C%20f%22%7Bvalue%3A.3f%7D%22%2C%20ha%3D%22center%22%2C%20va%3D%22center%22%2C%20color%3Dtext_color%2C%20fontsize%3D10)%0A%20%20%20%20%20%20%20%20if%20index%20%3C%20len(node_data)%20-%201%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.add_patch(FancyArrowPatch((x_pos%20%2B%200.68%2C%202.78)%2C%20(node_data%5Bindex%20%2B%201%5D%5B0%5D%20-%200.68%2C%202.78)%2C%20arrowstyle%3D%22-%7C%3E%22%2C%20mutation_scale%3D13%2C%20color%3Dblue%2C%20linewidth%3D1.8))%0A%20%20%20%20ax.text(2.7%2C%201.35%2C%20r%22%24h%3D%5Ctanh(w_1x%2Bb_1)%24%22%2C%20ha%3D%22center%22%2C%20color%3Dink%2C%20fontsize%3D10)%0A%20%20%20%20ax.text(5.55%2C%201.35%2C%20r%22%24L%3D%5Cfrac%7B1%7D%7B2%7D(%5Chat%20y-y)%5E2%24%22%2C%20ha%3D%22center%22%2C%20color%3Dink%2C%20fontsize%3D10)%0A%20%20%20%20ax.text(3.65%2C%204.35%2C%20%22data%20flows%20forward%20%E2%86%92%22%2C%20ha%3D%22center%22%2C%20color%3Dblue%2C%20fontsize%3D12%2C%20weight%3D%22bold%22)%0A%20%20%20%20ax.set_title(%221.%20Make%20a%20prediction%22%2C%20color%3Dink%2C%20fontsize%3D14%2C%20loc%3D%22left%22%2C%20pad%3D12)%0A%0A%20%20%20%20%23%202%20%E2%80%94%20backward%20pass%0A%20%20%20%20ax%20%3D%20axes%5B1%5D%0A%20%20%20%20ax.set(xlim%3D(0%2C%207.4)%2C%20ylim%3D(0%2C%205.8))%0A%20%20%20%20ax.axis(%22off%22)%0A%20%20%20%20for%20index%2C%20(x_pos%2C%20label%2C%20_value)%20in%20enumerate(node_data)%3A%0A%20%20%20%20%20%20%20%20circle%20%3D%20Circle((x_pos%2C%202.8)%2C%200.55%2C%20facecolor%3D%22white%22%2C%20edgecolor%3Dink%2C%20linewidth%3D1.4)%0A%20%20%20%20%20%20%20%20ax.add_patch(circle)%0A%20%20%20%20%20%20%20%20ax.text(x_pos%2C%202.8%2C%20label%5B0%5D.upper()%2C%20ha%3D%22center%22%2C%20va%3D%22center%22%2C%20color%3Dink%2C%20fontsize%3D11%2C%20weight%3D%22bold%22)%0A%20%20%20%20%20%20%20%20if%20index%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20previous_x%20%3D%20node_data%5Bindex%20-%201%5D%5B0%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.add_patch(FancyArrowPatch((x_pos%20-%200.58%2C%202.8)%2C%20(previous_x%20%2B%200.58%2C%202.8)%2C%20arrowstyle%3D%22-%7C%3E%22%2C%20mutation_scale%3D13%2C%20color%3Dcoral%2C%20linewidth%3D2.1))%0A%20%20%20%20ax.text(3.65%2C%204.35%2C%20%22%E2%86%90%20gradients%20flow%20backward%22%2C%20ha%3D%22center%22%2C%20color%3Dcoral%2C%20fontsize%3D12%2C%20weight%3D%22bold%22)%0A%20%20%20%20ax.text(5.55%2C%203.55%2C%20rf%22error%20%3D%20%7Binitial_prediction%20-%20target_value%3A%2B.3f%7D%22%2C%20ha%3D%22center%22%2C%20color%3Dcoral%2C%20fontsize%3D10)%0A%20%20%20%20ax.text(3.65%2C%201.65%2C%20rf%22%24%5Cpartial%20L%2F%5Cpartial%20w_2%3D%7Binitial_gradients%5B'w2'%5D%3A%2B.3f%7D%24%22%2C%20ha%3D%22center%22%2C%20color%3Dink%2C%20fontsize%3D10)%0A%20%20%20%20ax.text(1.75%2C%200.95%2C%20rf%22%24%5Cpartial%20L%2F%5Cpartial%20w_1%3D%7Binitial_gradients%5B'w1'%5D%3A%2B.3f%7D%24%22%2C%20ha%3D%22center%22%2C%20color%3Dink%2C%20fontsize%3D10)%0A%20%20%20%20ax.text(3.65%2C%200.35%2C%20%22each%20arrow%20applies%20one%20local%20derivative%22%2C%20ha%3D%22center%22%2C%20color%3D%22%23647783%22%2C%20fontsize%3D9)%0A%20%20%20%20ax.set_title(%222.%20Assign%20the%20blame%22%2C%20color%3Dink%2C%20fontsize%3D14%2C%20loc%3D%22left%22%2C%20pad%3D12)%0A%0A%20%20%20%20%23%203%20%E2%80%94%20repeated%20updates%0A%20%20%20%20ax%20%3D%20axes%5B2%5D%0A%20%20%20%20steps%20%3D%20np.arange(len(loss_history))%0A%20%20%20%20ax.plot(steps%2C%20loss_history%2C%20color%3Dcoral%2C%20linewidth%3D2.6%2C%20marker%3D%22o%22%2C%20markersize%3D3%2C%20label%3D%22loss%22)%0A%20%20%20%20ax.fill_between(steps%2C%20loss_history%2C%20color%3Dcoral%2C%20alpha%3D0.12)%0A%20%20%20%20ax.set(xlabel%3D%22gradient%20updates%22%2C%20ylabel%3D%22loss%22)%0A%20%20%20%20ax.set_yscale(%22log%22)%0A%20%20%20%20ax.grid(color%3Dgrid_color%2C%20linewidth%3D0.8%2C%20alpha%3D0.8)%0A%20%20%20%20ax.set_axisbelow(True)%0A%20%20%20%20ax.spines%5B%5B%22top%22%2C%20%22right%22%5D%5D.set_visible(False)%0A%20%20%20%20ax.spines%5B%5B%22left%22%2C%20%22bottom%22%5D%5D.set_color(%22%239AAAB5%22)%0A%20%20%20%20ax.set_title(%223.%20Repeat%3A%20the%20loss%20falls%22%2C%20color%3Dink%2C%20fontsize%3D14%2C%20loc%3D%22left%22%2C%20pad%3D12)%0A%20%20%20%20final_prediction%20%3D%20prediction_history%5B-1%5D%0A%20%20%20%20ax.text(%0A%20%20%20%20%20%20%20%200.55%2C%200.82%2C%0A%20%20%20%20%20%20%20%20f%22prediction%5Cn%7Binitial_prediction%3A.2f%7D%20%20%E2%86%92%20%20%7Bfinal_prediction%3A.2f%7D%5Cntarget%20%3D%20%7Btarget_value%3A.2f%7D%22%2C%0A%20%20%20%20%20%20%20%20transform%3Dax.transAxes%2C%20ha%3D%22center%22%2C%20va%3D%22center%22%2C%20color%3Dink%2C%20fontsize%3D11%2C%0A%20%20%20%20%20%20%20%20bbox%3D%7B%22boxstyle%22%3A%20%22round%2Cpad%3D0.55%22%2C%20%22facecolor%22%3A%20%22white%22%2C%20%22edgecolor%22%3A%20grid_color%7D%2C%0A%20%20%20%20)%0A%0A%20%20%20%20fig.suptitle(%22Backpropagation%3A%20forward%20values%2C%20backward%20gradients%22%2C%20x%3D0.04%2C%20y%3D1.04%2C%20ha%3D%22left%22%2C%20color%3Dink%2C%20fontsize%3D18%2C%20weight%3D%22bold%22)%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20fig%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Common%20mistake%0A%0A%20%20%20%20Saying%20that%20backpropagation%20itself%20updates%20the%20weights.%20Backpropagation%20computes%20gradients%3B%20the%20optimizer%20chooses%20how%20to%20use%20those%20gradients%20to%20update%20parameters.%0A%0A%20%20%20%20%23%23%20Diagnosis%0A%0A%20%20%20%20Inspect%20the%20loss%20curve%20and%20gradient%20magnitudes.%20Near-zero%20gradients%20can%20stop%20early%20layers%20from%20learning%2C%20while%20extremely%20large%20gradients%20can%20make%20training%20unstable.%0A%0A%20%20%20%20%23%23%20Practical%20rule%0A%0A%20%20%20%20Read%20a%20neural%20training%20step%20in%20three%20parts%3A%20forward%20pass%2C%20loss%2C%20backward%20pass.%20If%20you%20can%20track%20one%20value%20forward%20and%20one%20gradient%20backward%2C%20the%20larger%20network%20is%20the%20same%20idea%20repeated.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
562f278a812613d737a0e5840ba6e389