Add interactive learning rate experiments and comparison visualizations
Co-authored-by: leestott <2511341+leestott@users.noreply.github.com>
This commit is contained in:
parent
d7ae722726
commit
0ece1a2b6e
|
|
@ -384,6 +384,119 @@
|
|||
"plot_boundary(pos_examples,neg_examples,wts)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Experimenting with Learning Rates\n",
|
||||
"\n",
|
||||
"Now let's explore how different learning rates affect the training process. The learning rate controls the step size in gradient descent - a crucial hyperparameter that affects both convergence speed and stability.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Compare different learning rates\n",
|
||||
"learning_rates = [0.001, 0.01, 0.1, 1.0]\n",
|
||||
"fig, axes = pylab.subplots(2, 2, figsize=(12, 10))\n",
|
||||
"fig.suptitle('Effect of Different Learning Rates', fontsize=16)\n",
|
||||
"\n",
|
||||
"for idx, lr in enumerate(learning_rates):\n",
|
||||
" ax = axes[idx // 2, idx % 2]\n",
|
||||
" \n",
|
||||
" # Train with this learning rate\n",
|
||||
" weights_lr = train(pos_examples, neg_examples, num_iterations=100, learning_rate=lr)\n",
|
||||
" \n",
|
||||
" # Plot decision boundary\n",
|
||||
" if np.isclose(weights_lr[1], 0):\n",
|
||||
" if np.isclose(weights_lr[0], 0):\n",
|
||||
" x = y = np.array([-6, 6], dtype='float32')\n",
|
||||
" else:\n",
|
||||
" y = np.array([-6, 6], dtype='float32')\n",
|
||||
" x = -(weights_lr[1] * y + weights_lr[2])/weights_lr[0]\n",
|
||||
" else:\n",
|
||||
" x = np.array([-6, 6], dtype='float32')\n",
|
||||
" y = -(weights_lr[0] * x + weights_lr[2])/weights_lr[1]\n",
|
||||
" \n",
|
||||
" ax.set_xlim(-6, 6)\n",
|
||||
" ax.set_ylim(-6, 6)\n",
|
||||
" ax.plot(pos_examples[:, 0], pos_examples[:, 1], 'bo', label='Positive', alpha=0.7)\n",
|
||||
" ax.plot(neg_examples[:, 0], neg_examples[:, 1], 'ro', label='Negative', alpha=0.7)\n",
|
||||
" ax.plot(x, y, 'g-', linewidth=2)\n",
|
||||
" ax.set_title(f'Learning Rate = {lr}')\n",
|
||||
" ax.set_xlabel('Feature 1')\n",
|
||||
" ax.set_ylabel('Feature 2')\n",
|
||||
" ax.legend()\n",
|
||||
" ax.grid(True, alpha=0.3)\n",
|
||||
"\n",
|
||||
"pylab.tight_layout()\n",
|
||||
"pylab.show()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Interactive Learning Rate Experiment\n",
|
||||
"\n",
|
||||
"Use the slider below to interactively experiment with different learning rates and see how they affect the decision boundary:\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def train_and_plot_with_lr(learning_rate=0.01):\n",
|
||||
" \"\"\"Train perceptron with specified learning rate and plot results\"\"\"\n",
|
||||
" weights_lr = train(pos_examples, neg_examples, num_iterations=100, learning_rate=learning_rate)\n",
|
||||
" \n",
|
||||
" fig, (ax1, ax2) = pylab.subplots(1, 2, figsize=(14, 5))\n",
|
||||
" \n",
|
||||
" # Plot 1: Decision boundary\n",
|
||||
" if np.isclose(weights_lr[1], 0):\n",
|
||||
" if np.isclose(weights_lr[0], 0):\n",
|
||||
" x = y = np.array([-6, 6], dtype='float32')\n",
|
||||
" else:\n",
|
||||
" y = np.array([-6, 6], dtype='float32')\n",
|
||||
" x = -(weights_lr[1] * y + weights_lr[2])/weights_lr[0]\n",
|
||||
" else:\n",
|
||||
" x = np.array([-6, 6], dtype='float32')\n",
|
||||
" y = -(weights_lr[0] * x + weights_lr[2])/weights_lr[1]\n",
|
||||
" \n",
|
||||
" ax1.set_xlim(-6, 6)\n",
|
||||
" ax1.set_ylim(-6, 6)\n",
|
||||
" ax1.plot(pos_examples[:, 0], pos_examples[:, 1], 'bo', label='Positive', s=100, alpha=0.6)\n",
|
||||
" ax1.plot(neg_examples[:, 0], neg_examples[:, 1], 'ro', label='Negative', s=100, alpha=0.6)\n",
|
||||
" ax1.plot(x, y, 'g-', linewidth=3, label='Decision Boundary')\n",
|
||||
" ax1.set_title(f'Decision Boundary (lr={learning_rate})', fontsize=14)\n",
|
||||
" ax1.set_xlabel('Feature 1')\n",
|
||||
" ax1.set_ylabel('Feature 2')\n",
|
||||
" ax1.legend()\n",
|
||||
" ax1.grid(True, alpha=0.3)\n",
|
||||
" \n",
|
||||
" # Plot 2: Weight values\n",
|
||||
" ax2.bar(['w0', 'w1', 'bias'], weights_lr.flatten(), color=['blue', 'green', 'red'], alpha=0.7)\n",
|
||||
" ax2.set_title('Final Weight Values', fontsize=14)\n",
|
||||
" ax2.set_ylabel('Weight Value')\n",
|
||||
" ax2.grid(True, alpha=0.3, axis='y')\n",
|
||||
" ax2.axhline(y=0, color='black', linestyle='-', linewidth=0.5)\n",
|
||||
" \n",
|
||||
" pylab.tight_layout()\n",
|
||||
" pylab.show()\n",
|
||||
" \n",
|
||||
" print(f\"Final weights: {weights_lr.flatten()}\")\n",
|
||||
"\n",
|
||||
"# Create interactive widget\n",
|
||||
"interact(train_and_plot_with_lr, \n",
|
||||
" learning_rate=widgets.FloatSlider(value=0.01, min=0.001, max=1.0, step=0.001, \n",
|
||||
" description='Learning Rate:', continuous_update=False))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue