1
0

Compare commits

...

10 Commits

Author SHA1 Message Date
c162bd9728 250316 2025-03-16 20:29:33 +08:00
9a471ddedb 250315 2025-03-16 00:59:51 +08:00
c707f9eb9b 250314 2025-03-14 19:30:54 +08:00
b7a98bc257 250313 2025-03-13 20:26:57 +08:00
ef679e98da 250313 2025-03-13 18:14:01 +08:00
f138818abc routine 2025-01-25 22:33:14 +08:00
81367980c1 routine 2025-01-11 13:56:41 +08:00
c0d101ca1b routine 2025-01-04 18:14:57 +08:00
f75690be28 routine 2025-01-04 00:28:28 +08:00
0d00e1deb4 routine 2024-12-30 18:49:59 +08:00
104 changed files with 3162 additions and 9642 deletions

5
.gitignore vendored
View File

@@ -7,3 +7,8 @@
.idea
**/.ipynb_checkpoints
.vscode
lab/data
lab/models

View File

@@ -1,32 +1,49 @@
# pytorch study
# AI-Learning
- 所有的ipynb结果均为最优保存
## BASE ENV
```shell
conda create -n pt python=3.10 -y
conda activate pt
```
## MAC
```shell
conda create -n ail python=3.10 -y
conda activate ail
# 安装 pytorch v1.12版本已经正式支持了用于mac m1芯片gpu加速的mps后端
conda install pytorch::pytorch torchvision torchaudio -c pytorch -y
# tensorflow mac apple silicon
pip install tensorflow-macos==2.15.0
pip install tensorflow-metal
pip install -r requirements.txt
```
## linux
```shell
conda create -n ail-tf python=3.10 -y
conda create -n ail-pt python=3.10 -y
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
# tensorflow 需要cudnn支持
pip install tensorflow
pip install -r requirements.txt
```
## Jupyter
## windows
```shell
# env
pip install jupyter
conda create -n ail-tf python=3.9 -y
conda create -n ail-pt python=3.9 -y
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
# tf需要安装 CUDA 和 cuDNN
conda install cudatoolkit=11.8 cudnn=8.9 -c nvidia -y
pip install tensorflow
pip install -r requirements.txt
```
## 安装graphviz - 绘制模型图
```shell
jupyter notebook
brew install graphviz
```

View File

@@ -1,15 +0,0 @@
import torch
from torch import autograd
device = torch.device('mps')
x = torch.tensor(1.)
a = torch.tensor(2., requires_grad=True)
b = torch.tensor(2., requires_grad=True)
c = torch.tensor(3., requires_grad=True)
y = a ** 2 * x + b * x + c ** 3
print('before:', a.grad, b.grad, c.grad)
grads = autograd.grad(y, [a, b, c])
print('after:', grads[0], grads[1], grads[2])

73
lab/0_mathImage.ipynb Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,260 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [],
"source": [
"# 引入库\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import os\n",
"from sklearn.preprocessing import StandardScaler"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 检查os位置\n",
"print(os.getcwd())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"生成数据方式\n",
"$$ x_1 = x, x_2 = x^2, x_3 = \\sqrt{x} $$\n",
"$$ y = 1.35x_1 + 0.75x_2 + 2.1x_3 + 2.89 $$"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [],
"source": [
"# 生成数据\n",
"def generate_data():\n",
" w = np.array([1.35, 0.75, 2.1]) # 权重\n",
" b = 2.89 # 偏置\n",
" x_min = 1\n",
" x_max = 9\n",
" x = np.linspace(x_min, x_max, 10) # 均匀分布\n",
" X = np.array([x, x**2, np.sqrt(x)]) # 特征矩阵3x10\n",
" y = np.dot(w, X) + b # 1x10 一维向量不区分行向量和列向量\n",
" y += np.random.normal(scale=0.5, size=y.shape)\n",
" data = np.column_stack((X.T, y)) # 10x4\n",
" return data\n",
"\n",
"# 保存数据\n",
"def save_data(filename, data):\n",
" np.savetxt(filename, data, delimiter=',')\n",
" print(f\"{filename} 已成功创建并写入数据。\")\n",
"\n",
"# 生成并保存数据\n",
"data = generate_data()\n",
"#save_data('./1_data.txt', data)"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [],
"source": [
"# 读取数据\n",
"#points = np.genfromtxt(\"./1_data.txt\", delimiter=',')\n",
"\n",
"scaler = StandardScaler()\n",
"points = data\n",
"\n",
"m = len(points[:,0])\n",
"x = points[:, :3] # 10x3\n",
"y = points[:,3] # 1x10"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"原函数:\n",
"$$\n",
"\\vec{w} = {\\begin{bmatrix} w_1 & w_2 & w_3 & \\cdots & w_n \\end{bmatrix}}^T\n",
"$$\n",
"\n",
"$$\n",
"\\vec{x} = \\begin{bmatrix} x_1 & x_2 & x_3 & \\cdots & x_n \\end{bmatrix}\n",
"$$\n",
"\n",
"$$\n",
"f_{\\vec{w} \\cdot,b}(\\vec{x}) = \\vec{w} \\cdot \\vec{x} + b\n",
"$$\n",
"\n",
"损失函数: \n",
"\n",
"$$\n",
"\\text{MSE} = \\frac{1}{2m} \\sum_{i=1}^{m} \\left( y^{(i)} - \\hat{y}^{(i)} \\right)^2\n",
"$$\n",
"\n",
"梯度下降:\n",
"\n",
"分别对每个w和b求偏导数然后更新w和b\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"# 定义损失函数\n",
"def compute_loss(w, b):\n",
" return np.sum((y - (np.dot(w, x.T) + b)) ** 2) / (2 * m) # w 1x3 x.T 3x10 y 1x10 y-np.dot(w, x.T) 1x10 sum=number\n",
"\n",
"# 定义梯度下降\n",
"def gradient_descent(w, b, alpha, num_iter):\n",
" loss_history = []\n",
" for _ in range(num_iter):\n",
" error = y - np.dot(w, x.T) - b # 1x10\n",
" # 计算梯度\n",
" dw = -np.dot(x.T , error) / m # dw 1x3 \n",
" db = -np.sum(error) / m # db 1x1\n",
" # 更新w和b\n",
" w -= alpha * dw\n",
" b -= alpha * db\n",
" loss_history.append(compute_loss(w, b))\n",
" return w, b, loss_history"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"if __name__ == \"__main__\":\n",
" # 初始化w和b\n",
" w = np.zeros(x.shape[1])\n",
" b = 0.0\n",
" # 设置学习率\n",
" alpha = 0.01\n",
" # 设置迭代次数\n",
" num_iter = 10000\n",
" x = scaler.fit_transform(x) # 特征缩放\n",
" # 进行梯度下降\n",
" w, b, loss_history = gradient_descent(w, b, alpha, num_iter)\n",
" print(\"w:\", w)\n",
" print(\"b:\", b)\n",
" \n",
" # 计算损失\n",
" loss = compute_loss(w, b)\n",
" print(\"loss:\", loss)\n",
"\n",
" # 绘制\n",
" plt.figure(dpi=600)\n",
" plt.plot(range(num_iter), loss_history)\n",
" plt.xlabel('Iteration')\n",
" plt.ylabel('Loss')\n",
" plt.title('Loss History')\n",
" # 显示学习率\n",
" plt.text(num_iter * 0.6, max(loss_history) * 0.7, f'Learning Rate: {alpha}', fontsize=12, color='blue')\n",
"\n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 预测\n",
"def predict(x, w, b):\n",
" x_scaled = scaler.transform(x)\n",
" y = np.dot(w, x_scaled.T) + b\n",
" return y\n",
"\n",
"def original_predict(x):\n",
" w = np.array([1.35, 0.75, 2.1])\n",
" b = 2.89\n",
" return np.dot(w, x.T) + b\n",
"\n",
"x_new = np.array([\n",
" [2, 4, np.sqrt(2)],\n",
" [3, 9, np.sqrt(3)],\n",
" [4, 16, np.sqrt(4)]\n",
"])\n",
"y_pred = predict(x_new, w, b)\n",
"print(\"预测值:\", y_pred)\n",
"y_pred_original = original_predict(x_new)\n",
"print(\"原始值:\", y_pred_original)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 编码中遇到的错误\n",
"\n",
"梯度下降算法中把x.T和error相乘了正确应使用矩阵乘法。\n",
"\n",
"在特征缩放前学习率大之后会overflow导致模型不收敛。\n",
"\n",
"特征缩放后,由于代码写错,把结果也缩放了,导致后面预测时,结果不正确。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.linear_model import LinearRegression\n",
"from sklearn.pipeline import make_pipeline\n",
"from sklearn.metrics import mean_squared_error\n",
"\n",
"model = make_pipeline(LinearRegression())\n",
"# 拟合模型\n",
"model.fit(x, y)\n",
"\n",
"# 预测\n",
"y_pred_sklearn = model.predict(scaler.transform(x_new))\n",
"print(\"使用sklearn预测值:\", y_pred_sklearn)\n",
"y_pred_original = original_predict(x_new)\n",
"print(\"原始值:\", y_pred_original)\n",
"# 计算并打印训练数据的损失MSE\n",
"train_loss = mean_squared_error(y_pred_original, y_pred_sklearn)\n",
"print(\"训练数据的损失 (MSE):\", train_loss)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "pt",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,160 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from sklearn.preprocessing import PolynomialFeatures\n",
"from sklearn.linear_model import LinearRegression\n",
"from sklearn.linear_model import Ridge\n",
"from sklearn.pipeline import make_pipeline\n",
"from sklearn.metrics import mean_squared_error\n",
"from sklearn.preprocessing import StandardScaler"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"f_{w,b}(x) = 2x + 3x^2 + 4x^3 + 5\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def generateData():\n",
" # 生成数据集\n",
" x = np.linspace(-10, 10, 40)\n",
" # 使用噪声构建y\n",
" y = 2 * x + 3 * x**2 + 4 * x**3 + 5 + np.random.normal(scale=200, size=x.shape)\n",
"\n",
" data = np.column_stack((x, y))\n",
"\n",
" # 绘制数据集\n",
" plt.figure(dpi=600)\n",
" plt.scatter(x, y)\n",
" plt.show()\n",
" \n",
" return data\n",
"\n",
"data = generateData()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"# 保存数据\n",
"def save_data(filename, data):\n",
" np.savetxt(filename, data, delimiter=',')\n",
" print(f\"{filename} 已成功创建并写入数据。\")\n",
"\n",
"# save_data('data.csv', data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def polynomial_normal_regression(data, degree=3):\n",
" # 生成多项式特征并进行线性回归\n",
" model = make_pipeline(PolynomialFeatures(degree), LinearRegression())\n",
" model.fit(data[:, 0].reshape(-1, 1), data[:, 1])\n",
" y_pred = model.predict(data[:, 0].reshape(-1, 1))\n",
" \n",
" # 输出拟合后的多项式\n",
" coef = model.named_steps['linearregression'].coef_\n",
" intercept = model.named_steps['linearregression'].intercept_\n",
" poly_features = model.named_steps['polynomialfeatures']\n",
" feature_names = poly_features.get_feature_names_out(['x'])\n",
" \n",
" polynomial = \" + \".join(f\"{coef[i]:.2f}*{feature_names[i]}\" for i in range(len(coef)))\n",
" polynomial = f\"{intercept:.2f} + \" + polynomial\n",
" print(f\"拟合后的多项式: {polynomial}\")\n",
" \n",
" # 计算并输出损失\n",
" loss = mean_squared_error(data[:, 1], y_pred)\n",
" print(f\"损失: {loss:.2f}\")\n",
"\n",
" # 绘制拟合结果\n",
" plt.figure(dpi=600)\n",
" plt.scatter(data[:, 0], data[:, 1], label='original data')\n",
" plt.plot(data[:, 0], y_pred, label='fit curve', color='red')\n",
" plt.legend()\n",
" plt.show()\n",
"\n",
"polynomial_normal_regression(data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def polynomial_ridge_regression(data, degree=3):\n",
" # 生成多项式特征并进行线性回归\n",
" model = make_pipeline(PolynomialFeatures(degree), Ridge(alpha=0.5))\n",
" model.fit(data[:, 0].reshape(-1, 1), data[:, 1])\n",
" y_pred = model.predict(data[:, 0].reshape(-1, 1))\n",
" \n",
" # 输出拟合后的多项式\n",
" coef = model.named_steps['ridge'].coef_\n",
" intercept = model.named_steps['ridge'].intercept_\n",
" poly_features = model.named_steps['polynomialfeatures']\n",
" feature_names = poly_features.get_feature_names_out(['x'])\n",
" \n",
" polynomial = \" + \".join(f\"{coef[i]:.2f}*{feature_names[i]}\" for i in range(len(coef)))\n",
" polynomial = f\"{intercept:.2f} + \" + polynomial\n",
" print(f\"拟合后的多项式: {polynomial}\")\n",
" \n",
" # 计算并输出损失\n",
" loss = mean_squared_error(data[:, 1], y_pred)\n",
" print(f\"损失: {loss:.2f}\")\n",
"\n",
" # 绘制拟合结果\n",
" plt.figure(dpi=600)\n",
" plt.scatter(data[:, 0], data[:, 1], label='original data')\n",
" plt.plot(data[:, 0], y_pred, label='fit curve', color='red')\n",
" plt.legend()\n",
" plt.show()\n",
"\n",
"polynomial_ridge_regression(data)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "pt",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,198 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# 导入必要的库\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from sklearn.datasets import make_classification\n",
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.metrics import accuracy_score"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def generate_and_plot_dataset():\n",
" # 生成一个逻辑回归的数据集\n",
" x, y = make_classification(n_samples=100, n_features=2, \n",
" n_informative=2, n_redundant=0, \n",
" n_clusters_per_class=1, random_state=42)\n",
" # 可视化数据集\n",
" plt.scatter(x[:, 0], x[:, 1], c=y, cmap='viridis')\n",
" plt.xlabel('Feature 1')\n",
" plt.ylabel('Feature 2')\n",
" plt.title('Logistic Regression Dataset')\n",
" plt.show()\n",
" return x,y\n",
"x,y = generate_and_plot_dataset()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"def logistic_regression_analysis(x, y):\n",
" # 创建逻辑回归模型\n",
" model = LogisticRegression()\n",
"\n",
" # 拟合模型\n",
" model.fit(x, y)\n",
"\n",
" # 预测\n",
" y_pred = model.predict(x)\n",
"\n",
" # 计算准确率\n",
" accuracy = accuracy_score(y, y_pred)\n",
" print(f'模型准确率: {accuracy:.2f}')\n",
"\n",
" # 绘制决策边界\n",
" # 创建网格以绘制决策边界\n",
" xx, yy = np.meshgrid(np.arange(x[:, 0].min() - 1, x[:, 0].max() + 1, 0.01),\n",
" np.arange(x[:, 1].min() - 1, x[:, 1].max() + 1, 0.01))\n",
"\n",
" # 预测网格点的类别\n",
" Z = model.predict(np.c_[xx.ravel(), yy.ravel()])\n",
" Z = Z.reshape(xx.shape)\n",
"\n",
" # 绘制决策边界\n",
" plt.contourf(xx, yy, Z, alpha=0.8, cmap='viridis')\n",
" plt.scatter(x[:, 0], x[:, 1], c=y, edgecolors='k', marker='o', cmap='viridis')\n",
" plt.xlabel('Feature 1')\n",
" plt.ylabel('Feature 2')\n",
" plt.title('Logistic Regression Decision Boundary')\n",
" plt.show()\n",
"\n",
"# 调用函数\n",
"logistic_regression_analysis(x, y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 手动实现\n",
"$$\n",
"f_{\\vec{w},b}(x) = g(z) = \\frac{1}{1 + e^{-(\\vec{w} \\cdot \\vec{x} + b)}}\n",
"$$\n",
"\n",
"$$\n",
"J(\\vec{w},b) = -\\frac{1}{m} \\sum_{i=1}^{m} \\left( y^{(i)}\\ln(f_{\\vec{w},b}(x^{(i)})) + (1-y^{(i)})\\ln(1-f_{\\vec{w},b}(x^{(i)})) \\right)\n",
"$$\n",
"\n",
"$$\n",
"w_j = w_j - \\alpha \\frac{\\partial J(\\vec{w},b)}{\\partial w_j}\n",
"$$\n",
"\n",
"$$\n",
"b = b - \\alpha \\frac{\\partial J(\\vec{w},b)}{\\partial b}\n",
"$$\n",
"\n",
"$$\n",
"\\frac{\\partial J(\\vec{w},b)}{\\partial w_j} = \\frac{1}{m} \\sum_{i=1}^{m} (f_{\\vec{w},b}(x^{(i)}) - y^{(i)})x_j^{(i)}\n",
"$$\n",
"\n",
"$$\n",
"\\frac{\\partial J(\\vec{w},b)}{\\partial b} = \\frac{1}{m} \\sum_{i=1}^{m} (f_{\\vec{w},b}(x^{(i)}) - y^{(i)})\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def compute_cost_vectorized(w, b):\n",
" m = x.shape[0]\n",
" z = np.dot(x, w) + b\n",
" f_wb = sigmoid(z)\n",
" cost = (-1/m) * np.sum(y * np.log(f_wb) + (1 - y) * np.log(1 - f_wb))\n",
" return cost\n",
" \n",
"def sigmoid(z):\n",
" return 1/(1+np.exp(-z))\n",
" \n",
"def gradient_descent(w, b, alpha, num_iterations):\n",
" m = len(x)\n",
" for i in range(num_iterations):\n",
" z = np.dot(w, x.T) + b\n",
" f_wb = sigmoid(z)\n",
" w -= alpha * 1/m * np.dot(x.T, (f_wb-y))\n",
" b -= alpha * 1/m * np.sum(f_wb-y)\n",
" return w, b"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"if __name__ == \"__main__\":\n",
" w = np.zeros(x.shape[1])\n",
" b = 0\n",
" alpha = 0.04\n",
" num_iterations = 50000\n",
" w, b = gradient_descent(w, b, alpha, num_iterations)\n",
" print(w, b)\n",
" loss = compute_cost_vectorized(w, b)\n",
" print(loss)\n",
" \n",
" plt.figure(dpi=600)\n",
" # 绘制数据点\n",
" plt.scatter(x[:, 0], x[:, 1], c=y, cmap='viridis', edgecolors='k')\n",
"\n",
" # 计算决策边界\n",
" x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1\n",
" y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1\n",
" xx = np.linspace(x_min, x_max, 100)\n",
" # 计算对应的y值: w1*x + w2*y + b = 0 => y = -(w1*x + b)/w2\n",
" if w[1] != 0:\n",
" yy = -(w[0] * xx + b) / w[1]\n",
" plt.plot(xx, yy, color='red', label='Decision Boundary')\n",
" else:\n",
" # 当w2=0时决策边界为垂直线x = -b/w1\n",
" x_boundary = -b / w[0]\n",
" plt.axvline(x=x_boundary, color='red', label='Decision Boundary')\n",
"\n",
" plt.xlabel('Feature 1')\n",
" plt.ylabel('Feature 2')\n",
" plt.title('Logistic Regression Decision Boundary')\n",
" plt.legend()\n",
" plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "pt",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

426
lab/5_MLP-tf.ipynb Normal file

File diff suppressed because one or more lines are too long

123
lab/6_MLP-pt.ipynb Normal file
View File

@@ -0,0 +1,123 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2025-01-20T07:32:36.354335Z",
"start_time": "2025-01-20T07:32:35.224080Z"
}
},
"outputs": [],
"source": [
"import torch\n",
"import torch.nn as nn"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"# 设置使用gpu7 cuda\n",
"device = torch.device(\"cuda:7\" if torch.cuda.is_available() and torch.cuda.get_device_properties(0).total_memory >= 6*1024**3 else \"cpu\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2025-01-20T07:32:38.297401Z",
"start_time": "2025-01-20T07:32:38.261009Z"
}
},
"outputs": [],
"source": [
"# 设置使用mps mps设备当前未支持限制内存\n",
"device = torch.device(\"mps\" if torch.backends.mps.is_available() else \"cpu\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"ExecuteTime": {
"end_time": "2025-01-20T07:32:39.972353Z",
"start_time": "2025-01-20T07:32:39.958549Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MultiLayerPerceptron(\n",
" (hidden_layer1): Linear(in_features=10, out_features=20, bias=True)\n",
" (hidden_layer2): Linear(in_features=20, out_features=10, bias=True)\n",
" (output_layer): Linear(in_features=10, out_features=2, bias=True)\n",
" (activation1): ReLU()\n",
" (activation2): Sigmoid()\n",
")\n"
]
}
],
"source": [
"# 定义一个简单的神经元层\n",
"class MultiLayerPerceptron(nn.Module):\n",
" def __init__(self, input_size, hidden_size1, hidden_size2, output_size):\n",
" super(MultiLayerPerceptron, self).__init__()\n",
" self.hidden_layer1 = nn.Linear(input_size, hidden_size1)\n",
" self.hidden_layer2 = nn.Linear(hidden_size1, hidden_size2)\n",
" self.output_layer = nn.Linear(hidden_size2, output_size)\n",
" \n",
" # 定义不同的激活函数\n",
" self.activation1 = nn.ReLU() # 第一个隐藏层使用 ReLU\n",
" self.activation2 = nn.Sigmoid() # 第二个隐藏层使用 Sigmoid\n",
"\n",
" def forward(self, x):\n",
" # 第一个隐藏层及其激活函数\n",
" x = self.hidden_layer1(x)\n",
" x = self.activation1(x)\n",
" \n",
" # 第二个隐藏层及其激活函数\n",
" x = self.hidden_layer2(x)\n",
" x = self.activation2(x)\n",
" \n",
" # 输出层\n",
" x = self.output_layer(x)\n",
" return x\n",
"\n",
"# 创建一个MLP实例\n",
"mlp = MultiLayerPerceptron(input_size=10, hidden_size1=20, hidden_size2=10, output_size=2)\n",
"\n",
"# 打印模型结构\n",
"print(mlp)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ail",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

184
lab/7_Muticlass.ipynb Normal file
View File

@@ -0,0 +1,184 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 多分类问题 - 手写数字识别\n",
"\n",
"## 数据集\n",
"- minst数据集(手写数字数据集)\n",
"\n",
"## 激活函数\n",
"- softmax\n",
"\n",
"## 损失函数\n",
"- 交叉熵\n",
"\n",
"## 优化器\n",
"- 梯度下降\n",
"\n",
"## 模型\n",
"- 全连接层\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# 导库\n",
"import tensorflow as tf\n",
"from tensorflow.keras import Sequential\n",
"from tensorflow.keras.layers import Dense\n",
"from tensorflow.keras.losses import SparseCategoricalCrossentropy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# TEST\n",
"model = Sequential([Dense(units=25,activation='relu'),\n",
" Dense(units=15,activation='relu'),\n",
" Dense(units=10,activation='softmax')])\n",
"model.compile(loss=SparseCategoricalCrossentropy())\n",
"# 输出模型\n",
"print(model.summary())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 官方实例\n",
"\n",
"import tensorflow as tf\n",
"mnist = tf.keras.datasets.mnist\n",
"\n",
"(x_train, y_train),(x_test, y_test) = mnist.load_data()\n",
"x_train, x_test = x_train / 255.0, x_test / 255.0\n",
"\n",
"model = tf.keras.models.Sequential([\n",
" tf.keras.layers.Flatten(input_shape=(28, 28)),\n",
" tf.keras.layers.Dense(128, activation='relu'),\n",
" tf.keras.layers.Dropout(0.2),\n",
" tf.keras.layers.Dense(10, activation='softmax')\n",
"])\n",
"\n",
"model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n",
" loss=SparseCategoricalCrossentropy(),\n",
" metrics=['accuracy'])\n",
"\n",
"model.fit(x_train, y_train, epochs=5)\n",
"model.evaluate(x_test, y_test)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 用torch实现\n",
"\n",
"import torch\n",
"import torch.nn as nn\n",
"import torch.optim as optim\n",
"from torchvision import datasets, transforms\n",
"\n",
"# 数据预处理\n",
"transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])\n",
"\n",
"# 加载数据集\n",
"trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)\n",
"trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)\n",
"\n",
"testset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)\n",
"testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)\n",
"\n",
"# 定义模型\n",
"class SimpleNet(nn.Module):\n",
" def __init__(self):\n",
" super(SimpleNet, self).__init__()\n",
" self.flatten = nn.Flatten()\n",
" self.fc1 = nn.Linear(28 * 28, 128)\n",
" self.dropout = nn.Dropout(0.2)\n",
" self.fc2 = nn.Linear(128, 10)\n",
"\n",
" def forward(self, x):\n",
" x = self.flatten(x)\n",
" x = torch.relu(self.fc1(x))\n",
" x = self.dropout(x)\n",
" x = self.fc2(x)\n",
" return x\n",
"\n",
"model = SimpleNet()\n",
"\n",
"if torch.backends.mps.is_available():\n",
" device = torch.device(\"mps\")\n",
"else:\n",
" device = torch.device(\"cpu\")\n",
"\n",
"model.to(device)\n",
"\n",
"# 定义损失函数和优化器\n",
"criterion = nn.CrossEntropyLoss()\n",
"optimizer = optim.Adam(model.parameters(), lr=0.001)\n",
"\n",
"# 训练模型\n",
"epochs = 5\n",
"for epoch in range(epochs):\n",
" running_loss = 0\n",
" for images, labels in trainloader:\n",
" images, labels = images.to(device), labels.to(device) # 将数据移动到设备上\n",
" optimizer.zero_grad()\n",
" output = model(images)\n",
" loss = criterion(output, labels)\n",
" loss.backward()\n",
" optimizer.step()\n",
" running_loss += loss.item()\n",
" print(f\"Epoch {epoch+1}/{epochs} - Loss: {running_loss/len(trainloader)}\")\n",
"\n",
"# 测试模型\n",
"correct = 0\n",
"total = 0\n",
"with torch.no_grad():\n",
" for images, labels in testloader:\n",
" images, labels = images.to(device), labels.to(device) # 将数据移动到设备上\n",
" output = model(images)\n",
" _, predicted = torch.max(output, 1)\n",
" total += labels.size(0)\n",
" correct += (predicted == labels).sum().item()\n",
"\n",
"print(f\"Accuracy: {100 * correct / total}%\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ail",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.16"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

817
lab/8_FC-MNIST.ipynb Normal file

File diff suppressed because one or more lines are too long

602
lab/9_CNN-MNIST.ipynb Normal file

File diff suppressed because one or more lines are too long

BIN
lab/test/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lab/test/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
lab/test/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1,9 +0,0 @@
import numpy as np
w = np.array([1, 2, 3])
b = 4
x = np.array([10, 20, 30])
f = np.dot(w, x) + b
print(f)

View File

@@ -1,43 +0,0 @@
# No deep learning,just function mapping
$$
X = [v_1,v_2,.....,v_{784}]\\
X:[1,dx]
$$
$$
H_1 = XW_{1} + b_{1} \\
W_1:[d_1,dx] \\
b_1:[d_1]
$$
$$
H_2 = H_1W_2 + b_2 \\
W_1:[d_2,d_1] \\
b_1:[d_2]
$$
$$
H_3=H_2W_3 + b_3 \\
W_3:[10,d_2]\\
b_3:[10]
$$
## Loss
$$
H_3:[1,d_3] \\
Y:[0/1/2/.../9] \\
eg.:1\geq[0,1,0,0,0,0,0,0,0,0,0] \\
eg.:3\geq[0,0,0,1,0,0,0,0,0,0,0] \\
Euclidean\ Distance:H_3\ vs\ Y
$$
## In a nutshell
$$
pred = W_3 \times \{W_2\cdot[W_1X+b_1]+b_2\}+b_3
$$

View File

Before

Width:  |  Height:  |  Size: 493 KiB

After

Width:  |  Height:  |  Size: 493 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

54
plt/lenet-5.py Normal file
View File

@@ -0,0 +1,54 @@
from graphviz import Digraph
# 创建有向图
dot = Digraph(comment='LeNet-5', format='png',
graph_attr={'rankdir': 'LR', 'splines': 'line', 'nodesep': '0.5'})
# 定义节点样式
input_style = {'shape': 'box', 'style': 'filled', 'fillcolor': 'lightblue'}
conv_style = {'shape': 'box', 'style': 'filled', 'fillcolor': 'lightgreen'}
pool_style = {'shape': 'box', 'style': 'filled', 'fillcolor': 'lightcoral'}
fc_style = {'shape': 'box', 'style': 'filled', 'fillcolor': 'lightyellow'}
output_style = {'shape': 'box', 'style': 'filled', 'fillcolor': 'lightpink'}
# 添加节点,包含更多详细信息
dot.node('input', 'Input\n32x32x1\nGrayscale', **input_style)
dot.node('C1', 'Conv1\n5x5 kernel\n6 filters\nStride=1\n28x28x6', **conv_style)
dot.node('S2', 'Pool1\n2x2 kernel\nStride=2\n14x14x6', **pool_style)
dot.node('C3', 'Conv2\n5x5 kernel\n16 filters\nStride=1\n10x10x16', **conv_style)
dot.node('S4', 'Pool2\n2x2 kernel\nStride=2\n5x5x16', **pool_style)
dot.node('C5', 'FC1\n120 neurons', **fc_style)
dot.node('F6', 'FC2\n84 neurons', **fc_style)
dot.node('output', 'Output\n10 classes\n(Softmax)', **output_style)
# 添加边,带箭头
dot.edge('input', 'C1', label='Conv')
dot.edge('C1', 'S2', label='MaxPool')
dot.edge('S2', 'C3', label='Conv')
dot.edge('C3', 'S4', label='MaxPool')
dot.edge('S4', 'C5', label='Flatten\n+ FC')
dot.edge('C5', 'F6', label='FC')
dot.edge('F6', 'output', label='Softmax')
# 修改层数标注的显示方式
with dot.subgraph() as s:
s.attr(rank='same')
s.node('L1', 'Layer 1', shape='plaintext', pos='0,0!')
s.node('L2', 'Layer 2', shape='plaintext', pos='1,0!')
s.node('L3', 'Layer 3', shape='plaintext', pos='2,0!')
s.node('L4', 'Layer 4', shape='plaintext', pos='3,0!')
s.node('L5', 'Layer 5', shape='plaintext', pos='4,0!')
s.node('L6', 'Layer 6', shape='plaintext', pos='5,0!')
s.node('L7', 'Layer 7', shape='plaintext', pos='6,0!')
# 添加层数标注与模型结构的连接
dot.edge('L1', 'C1', style='invis')
dot.edge('L2', 'S2', style='invis')
dot.edge('L3', 'C3', style='invis')
dot.edge('L4', 'S4', style='invis')
dot.edge('L5', 'C5', style='invis')
dot.edge('L6', 'F6', style='invis')
dot.edge('L7', 'output', style='invis')
# 保存并渲染图像
dot.render('plt/lenet-5', view=False, cleanup=True)

40
plt/logistic.py Normal file
View File

@@ -0,0 +1,40 @@
import numpy as np
import matplotlib.pyplot as plt
def logistic_function(x, w, b):
return 1 / (1 + np.exp(-(w * x + b)))
def cost_function(f_wb, y):
if y == 1:
return -np.log(f_wb)
else:
return -np.log(1 - f_wb)
f_wb = np.linspace(-1, 2, 100) # 避免log(0)的情况
cost_y1 = cost_function(f_wb, 1)
cost_y0 = cost_function(f_wb, 0)
plt.figure(figsize=(12, 6),dpi=600)
plt.subplot(1, 2, 1)
plt.plot(f_wb, cost_y1, label='y=1')
plt.title('Cost Function when y=1')
plt.xlabel('f_wb')
plt.ylabel('Cost')
plt.axhline(0, color='black', linewidth=0.8) # 增加水平坐标轴
plt.axvline(0, color='black', linewidth=0.8) # 增加垂直坐标轴
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(f_wb, cost_y0, label='y=0')
plt.title('Cost Function when y=0')
plt.xlabel('f_wb')
plt.ylabel('Cost')
plt.axhline(0, color='black', linewidth=0.8) # 增加水平坐标轴
plt.axvline(0, color='black', linewidth=0.8) # 增加垂直坐标轴
plt.legend()
plt.tight_layout()
#plt.show()
plt.savefig('plt/logistic_cost_function.png')

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

View File

@@ -2,4 +2,9 @@ numpy
pandas
pillow
matplotlib
ipywidgets
ipywidgets
jupyter
scikit-learn
mnist
graphviz
tqdm

28
test/tf-cuda.py Normal file
View File

@@ -0,0 +1,28 @@
import tensorflow as tf
# 打印 TensorFlow 版本
print("TensorFlow 版本:", tf.__version__)
# 检查 CUDA 是否可用
cuda_available = tf.test.is_built_with_cuda()
print(f"CUDA 支持: {cuda_available}")
# 检查 GPU 是否可用
gpu_available = tf.config.list_physical_devices('GPU')
print(f"GPU 可用: {gpu_available}")
# 打印可用设备
print("\n可用设备:")
for device in tf.config.list_physical_devices():
print(device)
# 如果 GPU 可用,打印详细信息
gpus = tf.config.list_physical_devices('GPU')
if gpus:
print("\nGPU 详细信息:")
for gpu in gpus:
print(gpu)
print("设备名称:", gpu.name)
print("设备类型:", gpu.device_type)
else:
print("\n未检测到GPU设备")

20
test/torch-cuda.py Normal file
View File

@@ -0,0 +1,20 @@
import torch
# 打印 PyTorch 版本
print("PyTorch 版本:", torch.__version__)
# 检查 CUDA 是否可用
cuda_available = torch.cuda.is_available()
print(f"CUDA 可用: {cuda_available}")
# 如果 CUDA 可用,打印 GPU 信息
if cuda_available:
print("\nGPU 详细信息:")
print("GPU 数量:", torch.cuda.device_count())
print("当前 GPU:", torch.cuda.current_device())
print("GPU 名称:", torch.cuda.get_device_name(0))
print("GPU 内存:")
print(" 已分配:", torch.cuda.memory_allocated())
print(" 保留:", torch.cuda.memory_reserved())
else:
print("\n未检测到GPU设备")

3
tf/docker-run.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
# nvcr.io/nvidia/tensorflow:24.12-tf2-py3
docker run -itd --gpus all --name ail-tf -v /data/szh2/Project/AI-learning:/workspace/ail -p 58888:8888 nvcr.io/nvidia/tensorflow:24.12-tf2-py3 jupyter notebook --NotebookApp.token='12345678'

112
tf/gpu.ipynb Normal file
View File

@@ -0,0 +1,112 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2025-01-09 10:12:54.526706: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
"2025-01-09 10:12:54.541661: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:485] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
"2025-01-09 10:12:54.560110: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:8473] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
"2025-01-09 10:12:54.565525: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1471] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
"2025-01-09 10:12:54.578678: I tensorflow/core/platform/cpu_feature_guard.cc:211] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
"To enable the following instructions: SSE3 SSE4.1 SSE4.2 AVX, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"b'Hello, TensorFlow!'\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2025-01-09 10:12:58.748603: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 1143 MB memory: -> device: 0, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:35:00.0, compute capability: 8.0\n",
"2025-01-09 10:12:58.751140: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 78412 MB memory: -> device: 1, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:36:00.0, compute capability: 8.0\n",
"2025-01-09 10:12:58.752975: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:2 with 78412 MB memory: -> device: 2, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:39:00.0, compute capability: 8.0\n",
"2025-01-09 10:12:58.754821: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:3 with 78412 MB memory: -> device: 3, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:3d:00.0, compute capability: 8.0\n",
"2025-01-09 10:12:58.756707: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:4 with 78412 MB memory: -> device: 4, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:9c:00.0, compute capability: 8.0\n",
"2025-01-09 10:12:58.758405: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:5 with 78412 MB memory: -> device: 5, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:9d:00.0, compute capability: 8.0\n",
"2025-01-09 10:12:58.760115: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:6 with 78412 MB memory: -> device: 6, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:a0:00.0, compute capability: 8.0\n",
"2025-01-09 10:12:58.761971: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /job:localhost/replica:0/task:0/device:GPU:7 with 77296 MB memory: -> device: 7, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:a4:00.0, compute capability: 8.0\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"# 创建一个TensorFlow常量\n",
"hello = tf.constant('Hello, TensorFlow!')\n",
"# 将TensorFlow张量转换为NumPy数组\n",
"numpy_array = hello.numpy()\n",
"print(numpy_array) # 输出: b'Hello, TensorFlow!'"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /tmp/ipykernel_137363/2801978163.py:2: is_gpu_available (from tensorflow.python.framework.test_util) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use `tf.config.list_physical_devices('GPU')` instead.\n",
"True\n",
"[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:2', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:3', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:4', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:5', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:6', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:7', device_type='GPU')] [PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU')]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2025-01-09 10:13:03.154945: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:0 with 1143 MB memory: -> device: 0, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:35:00.0, compute capability: 8.0\n",
"2025-01-09 10:13:03.156613: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:1 with 78412 MB memory: -> device: 1, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:36:00.0, compute capability: 8.0\n",
"2025-01-09 10:13:03.158071: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:2 with 78412 MB memory: -> device: 2, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:39:00.0, compute capability: 8.0\n",
"2025-01-09 10:13:03.159472: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:3 with 78412 MB memory: -> device: 3, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:3d:00.0, compute capability: 8.0\n",
"2025-01-09 10:13:03.161049: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:4 with 78412 MB memory: -> device: 4, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:9c:00.0, compute capability: 8.0\n",
"2025-01-09 10:13:03.162507: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:5 with 78412 MB memory: -> device: 5, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:9d:00.0, compute capability: 8.0\n",
"2025-01-09 10:13:03.163784: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:6 with 78412 MB memory: -> device: 6, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:a0:00.0, compute capability: 8.0\n",
"2025-01-09 10:13:03.165104: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2021] Created device /device:GPU:7 with 77296 MB memory: -> device: 7, name: NVIDIA A800 80GB PCIe, pci bus id: 0000:a4:00.0, compute capability: 8.0\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"print(tf.test.is_gpu_available())\n",
"gpus = tf.config.experimental.list_physical_devices(device_type='GPU')\n",
"cpus = tf.config.experimental.list_physical_devices(device_type='CPU')\n",
"print(gpus, cpus)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

1
tf/requirements.txt Normal file
View File

@@ -0,0 +1 @@
matplotlib

View File

@@ -1,160 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Brief Introduction to Python and Jupyter Notebooks\n",
"Welcome to the first optional lab! \n",
"Optional labs are available to:\n",
"- provide information - like this notebook\n",
"- reinforce lecture material with hands-on examples\n",
"- provide working examples of routines used in the graded labs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goals\n",
"In this lab, you will:\n",
"- Get a brief introduction to Jupyter notebooks\n",
"- Take a tour of Jupyter notebooks\n",
"- Learn the difference between markdown cells and code cells\n",
"- Practice some basic python\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The easiest way to become familiar with Jupyter notebooks is to take the tour available above in the Help menu:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<figure>\n",
" <center> <img src=\"./images/C1W1L1_Tour.PNG\" alt='missing' width=\"400\" ><center/>\n",
"<figure/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jupyter notebooks have two types of cells that are used in this course. Cells such as this which contain documentation called `Markdown Cells`. The name is derived from the simple formatting language used in the cells. You will not be required to produce markdown cells. Its useful to understand the `cell pulldown` shown in graphic below. Occasionally, a cell will end up in the wrong mode and you may need to restore it to the right state:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<figure>\n",
" <img src=\"./images/C1W1L1_Markdown.PNG\" alt='missing' width=\"400\" >\n",
"<figure/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The other type of cell is the `code cell` where you will write your code:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is a code cell\n"
]
}
],
"source": [
"#This is a 'Code' Cell\n",
"print(\"This is a code cell\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Python\n",
"You can write your code in the code cells. \n",
"To run the code, select the cell and either\n",
"- hold the shift-key down and hit 'enter' or 'return'\n",
"- click the 'run' arrow above\n",
"<figure>\n",
" <img src=\"./images/C1W1L1_Run.PNG\" width=\"400\" >\n",
"<figure/>\n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Print statement\n",
"Print statements will generally use the python f-string style. \n",
"Try creating your own print in the following cell. \n",
"Try both methods of running the cell."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"f strings allow you to embed variables right in the strings! 23\n"
]
}
],
"source": [
"# print statements\n",
"variable = \"right in the strings!\"\n",
"var='23'\n",
"print(f\"f strings allow you to embed variables {variable} {var}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Congratulations!\n",
"You now know how to find your way around a Jupyter Notebook."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because one or more lines are too long

View File

@@ -1,352 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Cost Function \n",
"<figure>\n",
" <center> <img src=\"https://i.wolves.top/picgo/202408030514986.png\" style=\"width:1000px;height:200px;\" ></center>\n",
"</figure>\n",
"\n"
],
"id": "2eb3fe737905ed4d"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goals\n",
"In this lab you will:\n",
"- you will implement and explore the `cost` function for linear regression with one variable. \n"
],
"id": "1fcf9bd45e9feda9"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tools\n",
"In this lab we will make use of: \n",
"- NumPy, a popular library for scientific computing\n",
"- Matplotlib, a popular library for plotting data\n",
"- local plotting routines in the lab_utils_uni.py file in the local directory"
],
"id": "7d157dcf2c8adeb1"
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"%matplotlib widget\n",
"import matplotlib.pyplot as plt\n",
"from lab_utils_uni import plt_intuition, plt_stationary, plt_update_onclick, soup_bowl\n",
"plt.style.use('./deeplearning.mplstyle')"
],
"id": "520a04274f8b8984"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem Statement\n",
"\n",
"You would like a model which can predict housing prices given the size of the house. \n",
"Let's use the same two data points as before the previous lab- a house with 1000 square feet sold for \\\\$300,000 and a house with 2000 square feet sold for \\\\$500,000.\n",
"\n",
"\n",
"| Size (1000 sqft) | Price (1000s of dollars) |\n",
"| -------------------| ------------------------ |\n",
"| 1 | 300 |\n",
"| 2 | 500 |\n"
],
"id": "8a119e41544f0e89"
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"x_train = np.array([1.0, 2.0]) #(size in 1000 square feet)\n",
"y_train = np.array([300.0, 500.0]) #(price in 1000s of dollars)"
],
"id": "f2abb1684508d059"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Computing Cost\n",
"The term 'cost' in this assignment might be a little confusing since the data is housing cost. Here, cost is a measure how well our model is predicting the target price of the house. The term 'price' is used for housing data.\n",
"\n",
"The equation for cost with one variable is:\n",
" $$J(w,b) = \\frac{1}{2m} \\sum\\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})^2 \\tag{1}$$ \n",
" \n",
"where \n",
" $$f_{w,b}(x^{(i)}) = wx^{(i)} + b \\tag{2}$$\n",
" \n",
"- $f_{w,b}(x^{(i)})$ is our prediction for example $i$ using parameters $w,b$. \n",
"- $(f_{w,b}(x^{(i)}) -y^{(i)})^2$ is the squared difference between the target value and the prediction. \n",
"- These differences are summed over all the $m$ examples and divided by `2m` to produce the cost, $J(w,b)$. \n",
">Note, in lecture summation ranges are typically from 1 to m, while code will be from 0 to m-1.\n"
],
"id": "aa7329fc4c914325"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The code below calculates cost by looping over each example. In each loop:\n",
"- `f_wb`, a prediction is calculated\n",
"- the difference between the target and the prediction is calculated and squared.\n",
"- this is added to the total cost."
],
"id": "d3a36b72897daea3"
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"def compute_cost(x, y, w, b): \n",
" \"\"\"\n",
" Computes the cost function for linear regression.\n",
" \n",
" Args:\n",
" x (ndarray (m,)): Data, m examples \n",
" y (ndarray (m,)): target values\n",
" w,b (scalar) : model parameters \n",
" \n",
" Returns\n",
" total_cost (float): The cost of using w,b as the parameters for linear regression\n",
" to fit the data points in x and y\n",
" \"\"\"\n",
" # number of training examples\n",
" m = x.shape[0] \n",
" \n",
" cost_sum = 0 \n",
" for i in range(m): \n",
" f_wb = w * x[i] + b \n",
" cost = (f_wb - y[i]) ** 2 \n",
" cost_sum = cost_sum + cost \n",
" total_cost = (1 / (2 * m)) * cost_sum \n",
"\n",
" return total_cost"
],
"id": "2c1741a176659c0a"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cost Function Intuition"
],
"id": "949501e9bdaccf82"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img align=\"left\" src=\"https://i.wolves.top/picgo/202408030515720.png\" style=\" width:380px; padding: 10px; \" /> Your goal is to find a model $f_{w,b}(x) = wx + b$, with parameters $w,b$, which will accurately predict house values given an input $x$. The cost is a measure of how accurate the model is on the training data.\n",
"\n",
"The cost equation (1) above shows that if $w$ and $b$ can be selected such that the predictions $f_{w,b}(x)$ match the target data $y$, the $(f_{w,b}(x^{(i)}) - y^{(i)})^2 $ term will be zero and the cost minimized. In this simple two point example, you can achieve this!\n",
"\n",
"In the previous lab, you determined that $b=100$ provided an optimal solution so let's set $b$ to 100 and focus on $w$.\n",
"\n",
"<br/>\n",
"Below, use the slider control to select the value of $w$ that minimizes cost. It can take a few seconds for the plot to update."
],
"id": "44df7c59f9760dc9"
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7d57d1ccadbf42d6bc17488114bbf179",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt_intuition(x_train,y_train)"
],
"id": "22cd3ef9d4ec0ad6"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The plot contains a few points that are worth mentioning.\n",
"- cost is minimized when $w = 200$, which matches results from the previous lab\n",
"- Because the difference between the target and pediction is squared in the cost equation, the cost increases rapidly when $w$ is either too large or too small.\n",
"- Using the `w` and `b` selected by minimizing cost results in a line which is a perfect fit to the data."
],
"id": "375ff8495648a3fc"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cost Function Visualization- 3D\n",
"\n",
"You can see how cost varies with respect to *both* `w` and `b` by plotting in 3D or using a contour plot. \n",
"It is worth noting that some of the plotting in this course can become quite involved. The plotting routines are provided and while it can be instructive to read through the code to become familiar with the methods, it is not needed to complete the course successfully. The routines are in lab_utils_uni.py in the local directory."
],
"id": "11ced4ee637d0bc2"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Larger Data Set\n",
"It is instructive to view a scenario with a few more data points. This data set includes data points that do not fall on the same line. What does that mean for the cost equation? Can we find $w$, and $b$ that will give us a cost of 0? "
],
"id": "965277e5ec9d8183"
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"x_train = np.array([1.0, 1.7, 2.0, 2.5, 3.0, 3.2])\n",
"y_train = np.array([250, 300, 480, 430, 630, 730,])"
],
"id": "e7497ddb4e257caf"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the contour plot, click on a point to select `w` and `b` to achieve the lowest cost. Use the contours to guide your selections. Note, it can take a few seconds to update the graph. "
],
"id": "7d477a675cb9fca2"
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d5cceda8ce34448290f1c2cac01ee091",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.close('all') \n",
"fig, ax, dyn_items = plt_stationary(x_train, y_train)\n",
"updater = plt_update_onclick(fig, ax, x_train, y_train, dyn_items)"
],
"id": "d93ed50102bca74e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Above, note the dashed lines in the left plot. These represent the portion of the cost contributed by each example in your training set. In this case, values of approximately $w=209$ and $b=2.4$ provide low cost. Note that, because our training examples are not on a line, the minimum cost is not zero."
],
"id": "27a1d1e4a0575e15"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Convex Cost surface\n",
"The fact that the cost function squares the loss ensures that the 'error surface' is convex like a soup bowl. It will always have a minimum that can be reached by following the gradient in all dimensions. In the previous plot, because the $w$ and $b$ dimensions scale differently, this is not easy to recognize. The following plot, where $w$ and $b$ are symmetric, was shown in lecture:"
],
"id": "3e066cb5f7dfd29c"
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b9ea89764a324a98893ec2d8d2689e77",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"soup_bowl()"
],
"id": "f9545acc0a1322e0"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Congratulations!\n",
"You have learned the following:\n",
" - The cost equation provides a measure of how well your predictions match your training data.\n",
" - Minimizing the cost can provide optimal values of $w$, $b$."
],
"id": "653d254837760414"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [],
"id": "cc3b485e8def457"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
},
"toc-autonumbering": false
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because one or more lines are too long

View File

@@ -1,159 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Brief Introduction to Python and Jupyter Notebooks\n",
"Welcome to the first optional lab! \n",
"Optional labs are available to:\n",
"- provide information - like this notebook\n",
"- reinforce lecture material with hands-on examples\n",
"- provide working examples of routines used in the graded labs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goals\n",
"In this lab, you will:\n",
"- Get a brief introduction to Jupyter notebooks\n",
"- Take a tour of Jupyter notebooks\n",
"- Learn the difference between markdown cells and code cells\n",
"- Practice some basic python\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The easiest way to become familiar with Jupyter notebooks is to take the tour available above in the Help menu:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<figure>\n",
" <center> <img src=\"./images/C1W1L1_Tour.PNG\" alt='missing' width=\"400\" ><center/>\n",
"<figure/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jupyter notebooks have two types of cells that are used in this course. Cells such as this which contain documentation called `Markdown Cells`. The name is derived from the simple formatting language used in the cells. You will not be required to produce markdown cells. Its useful to understand the `cell pulldown` shown in graphic below. Occasionally, a cell will end up in the wrong mode and you may need to restore it to the right state:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<figure>\n",
" <img src=\"./images/C1W1L1_Markdown.PNG\" alt='missing' width=\"400\" >\n",
"<figure/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The other type of cell is the `code cell` where you will write your code:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is code cell\n"
]
}
],
"source": [
"#This is a 'Code' Cell\n",
"print(\"This is code cell\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Python\n",
"You can write your code in the code cells. \n",
"To run the code, select the cell and either\n",
"- hold the shift-key down and hit 'enter' or 'return'\n",
"- click the 'run' arrow above\n",
"<figure>\n",
" <img src=\"./images/C1W1L1_Run.PNG\" width=\"400\" >\n",
"<figure/>\n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Print statement\n",
"Print statements will generally use the python f-string style. \n",
"Try creating your own print in the following cell. \n",
"Try both methods of running the cell."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"f strings allow you to embed variables right in the strings!\n"
]
}
],
"source": [
"# print statements\n",
"variable = \"right in the strings!\"\n",
"print(f\"f strings allow you to embed variables {variable}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Congratulations!\n",
"You now know how to find your way around a Jupyter Notebook."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,33 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ungraded Lab - Examples of Material that will be covered in this course\n",
"Work in Progress"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,428 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Model Representation\n",
"\n",
"<figure>\n",
" <img src=\"./images/C1_W1_L3_S1_Lecture_b.png\" style=\"width:600px;height:200px;\">\n",
"</figure>"
],
"id": "7fae6127b91f846d"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goals\n",
"In this lab you will:\n",
"- Learn to implement the model $f_{w,b}$ for linear regression with one variable"
],
"id": "558caa26f894e501"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Notation\n",
"Here is a summary of some of the notation you will encounter. \n",
"\n",
"|General <img width=70/> <br /> Notation <img width=70/> | Description<img width=350/>| Python (if applicable) |\n",
"|: ------------|: ------------------------------------------------------------||\n",
"| $a$ | scalar, non bold ||\n",
"| $\\mathbf{a}$ | vector, bold ||\n",
"| **Regression** | | | |\n",
"| $\\mathbf{x}$ | Training Example feature values (in this lab - Size (1000 sqft)) | `x_train` | \n",
"| $\\mathbf{y}$ | Training Example targets (in this lab Price (1000s of dollars)).) | `y_train` \n",
"| $x^{(i)}$, $y^{(i)}$ | $i_{th}$Training Example | `x_i`, `y_i`|\n",
"| m | Number of training examples | `m`|\n",
"| $w$ | parameter: weight, | `w` |\n",
"| $b$ | parameter: bias | `b` | \n",
"| $f_{w,b}(x^{(i)})$ | The result of the model evaluation at $x^{(i)}$ parameterized by $w,b$: $f_{w,b}(x^{(i)}) = wx^{(i)}+b$ | `f_wb` | \n"
],
"id": "387f93949917f1d2"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tools\n",
"In this lab you will make use of: \n",
"- NumPy, a popular library for scientific computing\n",
"- Matplotlib, a popular library for plotting data"
],
"id": "26fe2d14cedb9a1a"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('./deeplearning.mplstyle')"
],
"id": "e7a25e396c4b3d2d"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Problem Statement\n",
"<img align=\"left\" src=\"./images/C1_W1_L3_S1_trainingdata.png\" style=\" width:380px; padding: 10px; \" /> \n",
"\n",
"As in the lecture, you will use the motivating example of housing price prediction. \n",
"This lab will use a simple data set with only two data points - a house with 1000 square feet(sqft) sold for \\\\$300,000 and a house with 2000 square feet sold for \\\\$500,000. These two points will constitute our *data or training set*. In this lab, the units of size are 1000 sqft and the units of price are $1000's of dollars.\n",
"\n",
"| Size (1000 sqft) | Price (1000s of dollars) |\n",
"| -------------------| ------------------------ |\n",
"| 1.0 | 300 |\n",
"| 2.0 | 500 |\n",
"\n",
"You would like to fit a linear regression model (shown above as the blue straight line) through these two points, so you can then predict price for other houses - say, a house with 1200 sqft.\n"
],
"id": "a9cebb19cb18409e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please run the following code cell to create your `x_train` and `y_train` variables. The data is stored in one-dimensional NumPy arrays."
],
"id": "514bee6257b3de45"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# x_train is the input variable (size in 1000 square feet)\n",
"# y_train in the target (price in 1000s of dollars)\n",
"x_train = np.array([1.0, 2.0])\n",
"y_train = np.array([300.0, 500.0])\n",
"print(f\"x_train = {x_train}\")\n",
"print(f\"y_train = {y_train}\")"
],
"id": "a2b5841f412550ba"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
">**Note**: The course will frequently utilize the python 'f-string' output formatting described [here](https://docs.python.org/3/tutorial/inputoutput.html) when printing. The content between the curly braces is evaluated when producing the output."
],
"id": "8845118d4044e7df"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Number of training examples `m`\n",
"You will use `m` to denote the number of training examples. Numpy arrays have a `.shape` parameter. `x_train.shape` returns a python tuple with an entry for each dimension. `x_train.shape[0]` is the length of the array and number of examples as shown below."
],
"id": "9435bc31d71a55a1"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# m is the number of training examples\n",
"print(f\"x_train.shape: {x_train.shape}\")\n",
"m = x_train.shape[0]\n",
"print(f\"Number of training examples is: {m}\")"
],
"id": "3042542073a8dee"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One can also use the Python `len()` function as shown below."
],
"id": "681e2c43a225a085"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# m is the number of training examples\n",
"m = len(x_train)\n",
"print(f\"Number of training examples is: {m}\")"
],
"id": "29b77e357217cb68"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Training example `x_i, y_i`\n",
"\n",
"You will use (x$^{(i)}$, y$^{(i)}$) to denote the $i^{th}$ training example. Since Python is zero indexed, (x$^{(0)}$, y$^{(0)}$) is (1.0, 300.0) and (x$^{(1)}$, y$^{(1)}$) is (2.0, 500.0). \n",
"\n",
"To access a value in a Numpy array, one indexes the array with the desired offset. For example the syntax to access location zero of `x_train` is `x_train[0]`.\n",
"Run the next code block below to get the $i^{th}$ training example."
],
"id": "a09b9410eb2bdb4f"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"i = 0 # Change this to 1 to see (x^1, y^1)\n",
"\n",
"x_i = x_train[i]\n",
"y_i = y_train[i]\n",
"print(f\"(x^({i}), y^({i})) = ({x_i}, {y_i})\")"
],
"id": "6c3c658d4f75db4"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Plotting the data"
],
"id": "a49af67439b97d82"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can plot these two points using the `scatter()` function in the `matplotlib` library, as shown in the cell below. \n",
"- The function arguments `marker` and `c` show the points as red crosses (the default is blue dots).\n",
"\n",
"You can also use other functions in the `matplotlib` library to display the title and labels for the axes."
],
"id": "b15cbcf6b0ca004c"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Plot the data points\n",
"plt.scatter(x_train, y_train, marker='x', c='r')\n",
"# Set the title\n",
"plt.title(\"Housing Prices\")\n",
"# Set the y-axis label\n",
"plt.ylabel('Price (in 1000s of dollars)')\n",
"# Set the x-axis label\n",
"plt.xlabel('Size (1000 sqft)')\n",
"plt.show()"
],
"id": "24298cc22c6eae4b"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model function\n",
"\n",
"<img align=\"left\" src=\"./images/C1_W1_L3_S1_model.png\" style=\" width:380px; padding: 10px; \" > As described in lecture, the model function for linear regression (which is a function that maps from `x` to `y`) is represented as \n",
"\n",
"$$ f_{w,b}(x^{(i)}) = wx^{(i)} + b \\tag{1}$$\n",
"\n",
"The formula above is how you can represent straight lines - different values of $w$ and $b$ give you different straight lines on the plot. <br/> <br/> <br/> <br/> <br/> \n",
"\n",
"Let's try to get a better intuition for this through the code blocks below. Let's start with $w = 100$ and $b = 100$. \n",
"\n",
"**Note: You can come back to this cell to adjust the model's w and b parameters**"
],
"id": "1650263e8dd4d997"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"w = 100\n",
"b = 100\n",
"print(f\"w: {w}\")\n",
"print(f\"b: {b}\")"
],
"id": "d14be934509bf334"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, let's compute the value of $f_{w,b}(x^{(i)})$ for your two data points. You can explicitly write this out for each data point as - \n",
"\n",
"for $x^{(0)}$, `f_wb = w * x[0] + b`\n",
"\n",
"for $x^{(1)}$, `f_wb = w * x[1] + b`\n",
"\n",
"For a large number of data points, this can get unwieldy and repetitive. So instead, you can calculate the function output in a `for` loop as shown in the `compute_model_output` function below.\n",
"> **Note**: The argument description `(ndarray (m,))` describes a Numpy n-dimensional array of shape (m,). `(scalar)` describes an argument without dimensions, just a magnitude. \n",
"> **Note**: `np.zero(n)` will return a one-dimensional numpy array with $n$ entries \n"
],
"id": "7d6df6dd84468603"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def compute_model_output(x, w, b):\n",
" \"\"\"\n",
" Computes the prediction of a linear model\n",
" Args:\n",
" x (ndarray (m,)): Data, m examples \n",
" w,b (scalar) : model parameters \n",
" Returns\n",
" y (ndarray (m,)): target values\n",
" \"\"\"\n",
" m = x.shape[0]\n",
" f_wb = np.zeros(m)\n",
" for i in range(m):\n",
" f_wb[i] = w * x[i] + b\n",
" \n",
" return f_wb"
],
"id": "1fcf5af9a7d85129"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's call the `compute_model_output` function and plot the output.."
],
"id": "47d041104e3c39d6"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tmp_f_wb = compute_model_output(x_train, w, b,)\n",
"\n",
"# Plot our model prediction\n",
"plt.plot(x_train, tmp_f_wb, c='b',label='Our Prediction')\n",
"\n",
"# Plot the data points\n",
"plt.scatter(x_train, y_train, marker='x', c='r',label='Actual Values')\n",
"\n",
"# Set the title\n",
"plt.title(\"Housing Prices\")\n",
"# Set the y-axis label\n",
"plt.ylabel('Price (in 1000s of dollars)')\n",
"# Set the x-axis label\n",
"plt.xlabel('Size (1000 sqft)')\n",
"plt.legend()\n",
"plt.show()"
],
"id": "736ec583c1cf5d67"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see, setting $w = 100$ and $b = 100$ does *not* result in a line that fits our data. \n",
"\n",
"### Challenge\n",
"Try experimenting with different values of $w$ and $b$. What should the values be for a line that fits our data?\n",
"\n",
"#### Tip:\n",
"You can use your mouse to click on the triangle to the left of the green \"Hints\" below to reveal some hints for choosing b and w."
],
"id": "7dec7d8a8efef44"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<details>\n",
"<summary>\n",
" <font size='3', color='darkgreen'><b>Hints</b></font>\n",
"</summary>\n",
" <p>\n",
" <ul>\n",
" <li>Try $w = 200$ and $b = 100$ </li>\n",
" </ul>\n",
" </p>"
],
"id": "5ba15f56d2568e04"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Prediction\n",
"Now that we have a model, we can use it to make our original prediction. Let's predict the price of a house with 1200 sqft. Since the units of $x$ are in 1000's of sqft, $x$ is 1.2.\n"
],
"id": "2ae9a0f157f44afb"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"w = 200 \n",
"b = 100 \n",
"x_i = 1.2\n",
"cost_1200sqft = w * x_i + b \n",
"\n",
"print(f\"${cost_1200sqft:.0f} thousand dollars\")"
],
"id": "7604756c838dc53a"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Congratulations!\n",
"In this lab you have learned:\n",
" - Linear regression builds a model which establishes a relationship between features and targets\n",
" - In the example above, the feature was house size and the target was house price\n",
" - for simple linear regression, the model has two parameters $w$ and $b$ whose values are 'fit' using *training data*.\n",
" - once a model's parameters have been determined, the model can be used to make predictions on novel data."
],
"id": "b9411842a79a5c"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [],
"id": "6854e2f089d03b0c"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
},
"toc-autonumbering": false
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,307 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Cost Function \n",
"<figure>\n",
" <center> <img src=\"./images/C1_W1_L3_S2_Lecture_b.png\" style=\"width:1000px;height:200px;\" ></center>\n",
"</figure>\n",
"\n"
],
"id": "7d3391ce25e5ba89"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goals\n",
"In this lab you will:\n",
"- you will implement and explore the `cost` function for linear regression with one variable. \n"
],
"id": "1e010f719c5d086f"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tools\n",
"In this lab we will make use of: \n",
"- NumPy, a popular library for scientific computing\n",
"- Matplotlib, a popular library for plotting data\n",
"- local plotting routines in the lab_utils_uni.py file in the local directory"
],
"id": "13698dcbd73ca0d9"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"%matplotlib widget\n",
"import matplotlib.pyplot as plt\n",
"from lab_utils_uni import plt_intuition, plt_stationary, plt_update_onclick, soup_bowl\n",
"plt.style.use('./deeplearning.mplstyle')"
],
"id": "32c06d217d8bb153"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem Statement\n",
"\n",
"You would like a model which can predict housing prices given the size of the house. \n",
"Let's use the same two data points as before the previous lab- a house with 1000 square feet sold for \\\\$300,000 and a house with 2000 square feet sold for \\\\$500,000.\n",
"\n",
"\n",
"| Size (1000 sqft) | Price (1000s of dollars) |\n",
"| -------------------| ------------------------ |\n",
"| 1 | 300 |\n",
"| 2 | 500 |\n"
],
"id": "68e608da30aff630"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x_train = np.array([1.0, 2.0]) #(size in 1000 square feet)\n",
"y_train = np.array([300.0, 500.0]) #(price in 1000s of dollars)"
],
"id": "8f289b3bf82b01f0"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Computing Cost\n",
"The term 'cost' in this assignment might be a little confusing since the data is housing cost. Here, cost is a measure how well our model is predicting the target price of the house. The term 'price' is used for housing data.\n",
"\n",
"The equation for cost with one variable is:\n",
" $$J(w,b) = \\frac{1}{2m} \\sum\\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})^2 \\tag{1}$$ \n",
" \n",
"where \n",
" $$f_{w,b}(x^{(i)}) = wx^{(i)} + b \\tag{2}$$\n",
" \n",
"- $f_{w,b}(x^{(i)})$ is our prediction for example $i$ using parameters $w,b$. \n",
"- $(f_{w,b}(x^{(i)}) -y^{(i)})^2$ is the squared difference between the target value and the prediction. \n",
"- These differences are summed over all the $m$ examples and divided by `2m` to produce the cost, $J(w,b)$. \n",
">Note, in lecture summation ranges are typically from 1 to m, while code will be from 0 to m-1.\n"
],
"id": "ab44dcb0c92cfdc"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The code below calculates cost by looping over each example. In each loop:\n",
"- `f_wb`, a prediction is calculated\n",
"- the difference between the target and the prediction is calculated and squared.\n",
"- this is added to the total cost."
],
"id": "a63a74f54bb59b2d"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def compute_cost(x, y, w, b): \n",
" \"\"\"\n",
" Computes the cost function for linear regression.\n",
" \n",
" Args:\n",
" x (ndarray (m,)): Data, m examples \n",
" y (ndarray (m,)): target values\n",
" w,b (scalar) : model parameters \n",
" \n",
" Returns\n",
" total_cost (float): The cost of using w,b as the parameters for linear regression\n",
" to fit the data points in x and y\n",
" \"\"\"\n",
" # number of training examples\n",
" m = x.shape[0] \n",
" \n",
" cost_sum = 0 \n",
" for i in range(m): \n",
" f_wb = w * x[i] + b \n",
" cost = (f_wb - y[i]) ** 2 \n",
" cost_sum = cost_sum + cost \n",
" total_cost = (1 / (2 * m)) * cost_sum \n",
"\n",
" return total_cost"
],
"id": "60ea841f910b8fb8"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cost Function Intuition"
],
"id": "b1c901ba1558365"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img align=\"left\" src=\"./images/C1_W1_Lab02_GoalOfRegression.PNG\" style=\" width:380px; padding: 10px; \" /> Your goal is to find a model $f_{w,b}(x) = wx + b$, with parameters $w,b$, which will accurately predict house values given an input $x$. The cost is a measure of how accurate the model is on the training data.\n",
"\n",
"The cost equation (1) above shows that if $w$ and $b$ can be selected such that the predictions $f_{w,b}(x)$ match the target data $y$, the $(f_{w,b}(x^{(i)}) - y^{(i)})^2 $ term will be zero and the cost minimized. In this simple two point example, you can achieve this!\n",
"\n",
"In the previous lab, you determined that $b=100$ provided an optimal solution so let's set $b$ to 100 and focus on $w$.\n",
"\n",
"<br/>\n",
"Below, use the slider control to select the value of $w$ that minimizes cost. It can take a few seconds for the plot to update."
],
"id": "954affed3a8238a1"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt_intuition(x_train,y_train)"
],
"id": "1b2e52672dee209"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The plot contains a few points that are worth mentioning.\n",
"- cost is minimized when $w = 200$, which matches results from the previous lab\n",
"- Because the difference between the target and pediction is squared in the cost equation, the cost increases rapidly when $w$ is either too large or too small.\n",
"- Using the `w` and `b` selected by minimizing cost results in a line which is a perfect fit to the data."
],
"id": "63966209b0e61188"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cost Function Visualization- 3D\n",
"\n",
"You can see how cost varies with respect to *both* `w` and `b` by plotting in 3D or using a contour plot. \n",
"It is worth noting that some of the plotting in this course can become quite involved. The plotting routines are provided and while it can be instructive to read through the code to become familiar with the methods, it is not needed to complete the course successfully. The routines are in lab_utils_uni.py in the local directory."
],
"id": "8e2feee1b673a863"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Larger Data Set\n",
"It's use instructive to view a scenario with a few more data points. This data set includes data points that do not fall on the same line. What does that mean for the cost equation? Can we find $w$, and $b$ that will give us a cost of 0? "
],
"id": "454fc752f58e3ee"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x_train = np.array([1.0, 1.7, 2.0, 2.5, 3.0, 3.2])\n",
"y_train = np.array([250, 300, 480, 430, 630, 730,])"
],
"id": "dc3d7ddc773fc308"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the contour plot, click on a point to select `w` and `b` to achieve the lowest cost. Use the contours to guide your selections. Note, it can take a few seconds to update the graph. "
],
"id": "7685a3371c85960d"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.close('all') \n",
"fig, ax, dyn_items = plt_stationary(x_train, y_train)\n",
"updater = plt_update_onclick(fig, ax, x_train, y_train, dyn_items)"
],
"id": "9132ad0f6d362e2f"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Above, note the dashed lines in the left plot. These represent the portion of the cost contributed by each example in your training set. In this case, values of approximately $w=209$ and $b=2.4$ provide low cost. Note that, because our training examples are not on a line, the minimum cost is not zero."
],
"id": "78bf73a9e76b7764"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Convex Cost surface\n",
"The fact that the cost function squares the loss ensures that the 'error surface' is convex like a soup bowl. It will always have a minimum that can be reached by following the gradient in all dimensions. In the previous plot, because the $w$ and $b$ dimensions scale differently, this is not easy to recognize. The following plot, where $w$ and $b$ are symmetric, was shown in lecture:"
],
"id": "136c6383bf6097f5"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"soup_bowl()"
],
"id": "2a02853e7204d759"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Congratulations!\n",
"You have learned the following:\n",
" - The cost equation provides a measure of how well your predictions match your training data.\n",
" - Minimizing the cost can provide optimal values of $w$, $b$."
],
"id": "1f57a3241189a2cc"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [],
"id": "9b162b4e8ebec360"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
},
"toc-autonumbering": false
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,558 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Gradient Descent for Linear Regression\n",
"\n",
"<figure>\n",
" <center> <img src=\"./images/C1_W1_L4_S1_Lecture_GD.png\" style=\"width:800px;height:200px;\" ></center>\n",
"</figure>"
],
"id": "5c7e9de1670dfc91"
},
{
"cell_type": "markdown",
"id": "da452e68",
"metadata": {},
"source": [
"## Goals\n",
"In this lab, you will:\n",
"- automate the process of optimizing $w$ and $b$ using gradient descent."
]
},
{
"cell_type": "markdown",
"id": "6f6d4021",
"metadata": {},
"source": [
"## Tools\n",
"In this lab, we will make use of: \n",
"- NumPy, a popular library for scientific computing\n",
"- Matplotlib, a popular library for plotting data\n",
"- plotting routines in the lab_utils.py file in the local directory"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef4d610a",
"metadata": {},
"outputs": [],
"source": [
"import math, copy\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('./deeplearning.mplstyle')\n",
"from lab_utils_uni import plt_house_x, plt_contour_wgrad, plt_divergence, plt_gradients"
]
},
{
"cell_type": "markdown",
"id": "c571a7b4",
"metadata": {},
"source": [
"<a name=\"toc_40291_2\"></a>\n",
"# Problem Statement\n",
"\n",
"Let's use the same two data points as before - a house with 1000 square feet sold for \\\\$300,000 and a house with 2000 square feet sold for \\\\$500,000.\n",
"\n",
"| Size (1000 sqft) | Price (1000s of dollars) |\n",
"| ----------------| ------------------------ |\n",
"| 1 | 300 |\n",
"| 2 | 500 |\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "26dd9666",
"metadata": {},
"outputs": [],
"source": [
"# Load our data set\n",
"x_train = np.array([1.0, 2.0]) #features\n",
"y_train = np.array([300.0, 500.0]) #target value"
]
},
{
"cell_type": "markdown",
"id": "2b7851bd",
"metadata": {},
"source": [
"<a name=\"toc_40291_2.0.1\"></a>\n",
"### Compute_Cost\n",
"This was developed in the last lab. We'll need it again here."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c6ffb7d",
"metadata": {},
"outputs": [],
"source": [
"#Function to calculate the cost\n",
"def compute_cost(x, y, w, b):\n",
" \n",
" m = x.shape[0] \n",
" cost = 0\n",
" \n",
" for i in range(m):\n",
" f_wb = w * x[i] + b\n",
" cost = cost + (f_wb - y[i])**2\n",
" total_cost = 1 / (2 * m) * cost\n",
"\n",
" return total_cost"
]
},
{
"cell_type": "markdown",
"id": "fd4be849",
"metadata": {},
"source": [
"<a name=\"toc_40291_2.1\"></a>\n",
"## Gradient descent summary\n",
"So far in this course, you have developed a linear model that predicts $f_{w,b}(x^{(i)})$:\n",
"$$f_{w,b}(x^{(i)}) = wx^{(i)} + b \\tag{1}$$\n",
"In linear regression, you utilize input training data to fit the parameters $w$,$b$ by minimizing a measure of the error between our predictions $f_{w,b}(x^{(i)})$ and the actual data $y^{(i)}$. The measure is called the $cost$, $J(w,b)$. In training you measure the cost over all of our training samples $x^{(i)},y^{(i)}$\n",
"$$J(w,b) = \\frac{1}{2m} \\sum\\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})^2\\tag{2}$$ "
]
},
{
"cell_type": "markdown",
"id": "6061233c",
"metadata": {},
"source": [
"\n",
"In lecture, *gradient descent* was described as:\n",
"\n",
"$$\\begin{align*} \\text{repeat}&\\text{ until convergence:} \\; \\lbrace \\newline\n",
"\\; w &= w - \\alpha \\frac{\\partial J(w,b)}{\\partial w} \\tag{3} \\; \\newline \n",
" b &= b - \\alpha \\frac{\\partial J(w,b)}{\\partial b} \\newline \\rbrace\n",
"\\end{align*}$$\n",
"where, parameters $w$, $b$ are updated simultaneously. \n",
"The gradient is defined as:\n",
"$$\n",
"\\begin{align}\n",
"\\frac{\\partial J(w,b)}{\\partial w} &= \\frac{1}{m} \\sum\\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})x^{(i)} \\tag{4}\\\\\n",
" \\frac{\\partial J(w,b)}{\\partial b} &= \\frac{1}{m} \\sum\\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)}) \\tag{5}\\\\\n",
"\\end{align}\n",
"$$\n",
"\n",
"Here *simultaniously* means that you calculate the partial derivatives for all the parameters before updating any of the parameters."
]
},
{
"cell_type": "markdown",
"id": "6cfb9401",
"metadata": {},
"source": [
"<a name=\"toc_40291_2.2\"></a>\n",
"## Implement Gradient Descent\n",
"You will implement batch gradient descent algorithm for one feature. You will need three functions. \n",
"- `compute_gradient` implementing equation (4) and (5) above\n",
"- `compute_cost` implementing equation (2) above (code from previous lab)\n",
"- `gradient_descent`, utilizing compute_gradient and compute_cost\n",
"\n",
"Conventions:\n",
"- The naming of python variables containing partial derivatives follows this pattern,$\\frac{\\partial J(w,b)}{\\partial b}$ will be `dj_db`.\n",
"- w.r.t is With Respect To, as in partial derivative of $J(wb)$ With Respect To $b$.\n"
]
},
{
"cell_type": "markdown",
"id": "f9b6ad38",
"metadata": {},
"source": [
"<a name=\"toc_40291_2.3\"></a>\n",
"### compute_gradient\n",
"<a name='ex-01'></a>\n",
"`compute_gradient` implements (4) and (5) above and returns $\\frac{\\partial J(w,b)}{\\partial w}$,$\\frac{\\partial J(w,b)}{\\partial b}$. The embedded comments describe the operations."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "857066af",
"metadata": {},
"outputs": [],
"source": [
"def compute_gradient(x, y, w, b): \n",
" \"\"\"\n",
" Computes the gradient for linear regression \n",
" Args:\n",
" x (ndarray (m,)): Data, m examples \n",
" y (ndarray (m,)): target values\n",
" w,b (scalar) : model parameters \n",
" Returns\n",
" dj_dw (scalar): The gradient of the cost w.r.t. the parameters w\n",
" dj_db (scalar): The gradient of the cost w.r.t. the parameter b \n",
" \"\"\"\n",
" \n",
" # Number of training examples\n",
" m = x.shape[0] \n",
" dj_dw = 0\n",
" dj_db = 0\n",
" \n",
" for i in range(m): \n",
" f_wb = w * x[i] + b \n",
" dj_dw_i = (f_wb - y[i]) * x[i] \n",
" dj_db_i = f_wb - y[i] \n",
" dj_db += dj_db_i\n",
" dj_dw += dj_dw_i \n",
" dj_dw = dj_dw / m \n",
" dj_db = dj_db / m \n",
" \n",
" return dj_dw, dj_db"
]
},
{
"cell_type": "markdown",
"id": "dccbb458",
"metadata": {},
"source": [
"<br/>"
]
},
{
"cell_type": "markdown",
"id": "42358679",
"metadata": {},
"source": [
"<img align=\"left\" src=\"./images/C1_W1_Lab03_lecture_slopes.PNG\" style=\"width:340px;\" > The lectures described how gradient descent utilizes the partial derivative of the cost with respect to a parameter at a point to update that parameter. \n",
"Let's use our `compute_gradient` function to find and plot some partial derivatives of our cost function relative to one of the parameters, $w_0$.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "01d52fb1",
"metadata": {},
"outputs": [],
"source": [
"plt_gradients(x_train,y_train, compute_cost, compute_gradient)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "20269810",
"metadata": {},
"source": [
"Above, the left plot shows $\\frac{\\partial J(w,b)}{\\partial w}$ or the slope of the cost curve relative to $w$ at three points. On the right side of the plot, the derivative is positive, while on the left it is negative. Due to the 'bowl shape', the derivatives will always lead gradient descent toward the bottom where the gradient is zero.\n",
" \n",
"The left plot has fixed $b=100$. Gradient descent will utilize both $\\frac{\\partial J(w,b)}{\\partial w}$ and $\\frac{\\partial J(w,b)}{\\partial b}$ to update parameters. The 'quiver plot' on the right provides a means of viewing the gradient of both parameters. The arrow sizes reflect the magnitude of the gradient at that point. The direction and slope of the arrow reflects the ratio of $\\frac{\\partial J(w,b)}{\\partial w}$ and $\\frac{\\partial J(w,b)}{\\partial b}$ at that point.\n",
"Note that the gradient points *away* from the minimum. Review equation (3) above. The scaled gradient is *subtracted* from the current value of $w$ or $b$. This moves the parameter in a direction that will reduce cost."
]
},
{
"cell_type": "markdown",
"id": "09cde02a",
"metadata": {},
"source": [
"<a name=\"toc_40291_2.5\"></a>\n",
"### Gradient Descent\n",
"Now that gradients can be computed, gradient descent, described in equation (3) above can be implemented. The details of the implementation are described in the comments. Below, you will utilize this function to find optimal values of $w$ and $b$ on the training data."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ca792dcb",
"metadata": {},
"outputs": [],
"source": [
"def gradient_descent(x, y, w_in, b_in, alpha, num_iters, cost_function, gradient_function): \n",
" \"\"\"\n",
" Performs batch gradient descent to fit w,b. Updates w,b by taking \n",
" num_iters gradient steps with learning rate alpha\n",
" \n",
" Args:\n",
" x (ndarray (m,)) : Data, m examples \n",
" y (ndarray (m,)) : target values\n",
" w_in,b_in (scalar): initial values of model parameters \n",
" alpha (float): Learning rate\n",
" num_iters (int): number of iterations to run gradient descent\n",
" cost_function: function to call to produce cost\n",
" gradient_function: function to call to produce gradient\n",
" \n",
" Returns:\n",
" w (scalar): Updated value of parameter after running gradient descent\n",
" b (scalar): Updated value of parameter after running gradient descent\n",
" J_history (List): History of cost values\n",
" p_history (list): History of parameters [w,b] \n",
" \"\"\"\n",
" \n",
" w = copy.deepcopy(w_in) # avoid modifying global w_in\n",
" # An array to store cost J and w's at each iteration primarily for graphing later\n",
" J_history = []\n",
" p_history = []\n",
" b = b_in\n",
" w = w_in\n",
" \n",
" for i in range(num_iters):\n",
" # Calculate the gradient and update the parameters using gradient_function\n",
" dj_dw, dj_db = gradient_function(x, y, w , b) \n",
"\n",
" # Update Parameters using equation (3) above\n",
" b = b - alpha * dj_db \n",
" w = w - alpha * dj_dw \n",
"\n",
" # Save cost J at each iteration\n",
" if i<100000: # prevent resource exhaustion \n",
" J_history.append( cost_function(x, y, w , b))\n",
" p_history.append([w,b])\n",
" # Print cost every at intervals 10 times or as many iterations if < 10\n",
" if i% math.ceil(num_iters/10) == 0:\n",
" print(f\"Iteration {i:4}: Cost {J_history[-1]:0.2e} \",\n",
" f\"dj_dw: {dj_dw: 0.3e}, dj_db: {dj_db: 0.3e} \",\n",
" f\"w: {w: 0.3e}, b:{b: 0.5e}\")\n",
" \n",
" return w, b, J_history, p_history #return w and J,w history for graphing"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "af449437",
"metadata": {},
"outputs": [],
"source": [
"# initialize parameters\n",
"w_init = 0\n",
"b_init = 0\n",
"# some gradient descent settings\n",
"iterations = 10000\n",
"tmp_alpha = 1.0e-2\n",
"# run gradient descent\n",
"w_final, b_final, J_hist, p_hist = gradient_descent(x_train ,y_train, w_init, b_init, tmp_alpha, \n",
" iterations, compute_cost, compute_gradient)\n",
"print(f\"(w,b) found by gradient descent: ({w_final:8.4f},{b_final:8.4f})\")"
]
},
{
"cell_type": "markdown",
"id": "f659147c",
"metadata": {},
"source": [
"<img align=\"left\" src=\"./images/C1_W1_Lab03_lecture_learningrate.PNG\" style=\"width:340px; padding: 15px; \" > \n",
"Take a moment and note some characteristics of the gradient descent process printed above. \n",
"\n",
"- The cost starts large and rapidly declines as described in the slide from the lecture.\n",
"- The partial derivatives, `dj_dw`, and `dj_db` also get smaller, rapidly at first and then more slowly. As shown in the diagram from the lecture, as the process nears the 'bottom of the bowl' progress is slower due to the smaller value of the derivative at that point.\n",
"- progress slows though the learning rate, alpha, remains fixed"
]
},
{
"cell_type": "markdown",
"id": "a2366fd8",
"metadata": {},
"source": [
"### Cost versus iterations of gradient descent \n",
"A plot of cost versus iterations is a useful measure of progress in gradient descent. Cost should always decrease in successful runs. The change in cost is so rapid initially, it is also helpful in this case to view a plot that does not include the initial iterations."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ceb161ee",
"metadata": {},
"outputs": [],
"source": [
"# plot cost versus iteration \n",
"fig, (ax1, ax2) = plt.subplots(1, 2, constrained_layout=True, figsize=(12,4))\n",
"ax1.plot(J_hist)\n",
"ax2.plot(1000 + np.arange(len(J_hist[1000:])), J_hist[1000:])\n",
"ax1.set_title(\"Cost vs. iteration\"); ax2.set_title(\"Cost vs. iteration (tail)\")\n",
"ax1.set_ylabel('Cost') ; ax2.set_ylabel('Cost') \n",
"ax1.set_xlabel('iteration step') ; ax2.set_xlabel('iteration step') \n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "205bd40f",
"metadata": {},
"source": [
"### Predictions\n",
"Now that you have discovered the optimal values for the parameters $w$ and $b$, you can now use the model to predict housing values based on our learned parameters. As expected, the predicted values are nearly the same as the training values for the same housing. Further, the value not in the prediction is in line with the expected value."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "54271146",
"metadata": {},
"outputs": [],
"source": [
"print(f\"1000 sqft house prediction {w_final*1.0 + b_final:0.1f} Thousand dollars\")\n",
"print(f\"1200 sqft house prediction {w_final*1.2 + b_final:0.1f} Thousand dollars\")\n",
"print(f\"2000 sqft house prediction {w_final*2.0 + b_final:0.1f} Thousand dollars\")"
]
},
{
"cell_type": "markdown",
"id": "b7081853",
"metadata": {},
"source": [
"<a name=\"toc_40291_2.6\"></a>\n",
"## Plotting\n",
"You can show the progress of gradient descent during its execution by plotting the cost over iterations on a contour plot of the cost(w,b). "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6c9e24f",
"metadata": {},
"outputs": [],
"source": [
"fig, ax = plt.subplots(1,1, figsize=(12, 6))\n",
"plt_contour_wgrad(x_train, y_train, p_hist, ax)"
]
},
{
"cell_type": "markdown",
"id": "1d3bda0a",
"metadata": {},
"source": [
"Above, the contour plot shows the $cost(w,b)$ over a range of $w$ and $b$. Cost levels are represented by the rings. Overlayed, using red arrows, is the path of gradient descent. Here are some things to note:\n",
"- The path makes steady (monotonic) progress toward its goal.\n",
"- initial steps are much larger than the steps near the goal."
]
},
{
"cell_type": "markdown",
"id": "9d2f0d6b",
"metadata": {},
"source": [
"**Zooming in**, we can see that final steps of gradient descent. Note the distance between steps shrinks as the gradient approaches zero."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5e58742e",
"metadata": {},
"outputs": [],
"source": [
"fig, ax = plt.subplots(1,1, figsize=(12, 4))\n",
"plt_contour_wgrad(x_train, y_train, p_hist, ax, w_range=[180, 220, 0.5], b_range=[80, 120, 0.5],\n",
" contours=[1,5,10,20],resolution=0.5)"
]
},
{
"cell_type": "markdown",
"id": "66a68a52",
"metadata": {},
"source": [
"<a name=\"toc_40291_2.7.1\"></a>\n",
"### Increased Learning Rate\n",
"\n",
"<figure>\n",
" <img align=\"left\", src=\"./images/C1_W1_Lab03_alpha_too_big.PNG\" style=\"width:340px;height:240px;\" >\n",
"</figure>\n",
"In the lecture, there was a discussion related to the proper value of the learning rate, $\\alpha$ in equation(3). The larger $\\alpha$ is, the faster gradient descent will converge to a solution. But, if it is too large, gradient descent will diverge. Above you have an example of a solution which converges nicely.\n",
"\n",
"Let's try increasing the value of $\\alpha$ and see what happens:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "01c2c046",
"metadata": {},
"outputs": [],
"source": [
"# initialize parameters\n",
"w_init = 0\n",
"b_init = 0\n",
"# set alpha to a large value\n",
"iterations = 10\n",
"tmp_alpha = 8.0e-1\n",
"# run gradient descent\n",
"w_final, b_final, J_hist, p_hist = gradient_descent(x_train ,y_train, w_init, b_init, tmp_alpha, \n",
" iterations, compute_cost, compute_gradient)"
]
},
{
"cell_type": "markdown",
"id": "84d9cb5e",
"metadata": {},
"source": [
"Above, $w$ and $b$ are bouncing back and forth between positive and negative with the absolute value increasing with each iteration. Further, each iteration $\\frac{\\partial J(w,b)}{\\partial w}$ changes sign and cost is increasing rather than decreasing. This is a clear sign that the *learning rate is too large* and the solution is diverging. \n",
"Let's visualize this with a plot."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cd87463e",
"metadata": {},
"outputs": [],
"source": [
"plt_divergence(p_hist, J_hist,x_train, y_train)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "1af14beb",
"metadata": {},
"source": [
"Above, the left graph shows $w$'s progression over the first few steps of gradient descent. $w$ oscillates from positive to negative and cost grows rapidly. Gradient Descent is operating on both $w$ and $b$ simultaneously, so one needs the 3-D plot on the right for the complete picture."
]
},
{
"cell_type": "markdown",
"id": "17283374",
"metadata": {},
"source": [
"\n",
"## Congratulations!\n",
"In this lab you:\n",
"- delved into the details of gradient descent for a single variable.\n",
"- developed a routine to compute the gradient\n",
"- visualized what the gradient is\n",
"- completed a gradient descent routine\n",
"- utilized gradient descent to find parameters\n",
"- examined the impact of sizing the learning rate"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "852c45c0",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"dl_toc_settings": {
"rndtag": "40291"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"toc-autonumbering": false
},
"nbformat": 4,
"nbformat_minor": 5
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -1,112 +0,0 @@
"""
lab_utils_common.py
functions common to all optional labs, Course 1, Week 2
"""
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('./deeplearning.mplstyle')
dlblue = '#0096ff'; dlorange = '#FF9300'; dldarkred='#C00000'; dlmagenta='#FF40FF'; dlpurple='#7030A0';
dlcolors = [dlblue, dlorange, dldarkred, dlmagenta, dlpurple]
dlc = dict(dlblue = '#0096ff', dlorange = '#FF9300', dldarkred='#C00000', dlmagenta='#FF40FF', dlpurple='#7030A0')
##########################################################
# Regression Routines
##########################################################
#Function to calculate the cost
def compute_cost_matrix(X, y, w, b, verbose=False):
"""
Computes the gradient for linear regression
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
verbose : (Boolean) If true, print out intermediate value f_wb
Returns
cost: (scalar)
"""
m = X.shape[0]
# calculate f_wb for all examples.
f_wb = X @ w + b
# calculate cost
total_cost = (1/(2*m)) * np.sum((f_wb-y)**2)
if verbose: print("f_wb:")
if verbose: print(f_wb)
return total_cost
def compute_gradient_matrix(X, y, w, b):
"""
Computes the gradient for linear regression
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
Returns
dj_dw (ndarray (n,1)): The gradient of the cost w.r.t. the parameters w.
dj_db (scalar): The gradient of the cost w.r.t. the parameter b.
"""
m,n = X.shape
f_wb = X @ w + b
e = f_wb - y
dj_dw = (1/m) * (X.T @ e)
dj_db = (1/m) * np.sum(e)
return dj_db,dj_dw
# Loop version of multi-variable compute_cost
def compute_cost(X, y, w, b):
"""
compute cost
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
Returns
cost (scalar) : cost
"""
m = X.shape[0]
cost = 0.0
for i in range(m):
f_wb_i = np.dot(X[i],w) + b #(n,)(n,)=scalar
cost = cost + (f_wb_i - y[i])**2
cost = cost/(2*m)
return cost
def compute_gradient(X, y, w, b):
"""
Computes the gradient for linear regression
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
Returns
dj_dw (ndarray Shape (n,)): The gradient of the cost w.r.t. the parameters w.
dj_db (scalar): The gradient of the cost w.r.t. the parameter b.
"""
m,n = X.shape #(number of examples, number of features)
dj_dw = np.zeros((n,))
dj_db = 0.
for i in range(m):
err = (np.dot(X[i], w) + b) - y[i]
for j in range(n):
dj_dw[j] = dj_dw[j] + err * X[i,j]
dj_db = dj_db + err
dj_dw = dj_dw/m
dj_db = dj_db/m
return dj_db,dj_dw

View File

@@ -1,398 +0,0 @@
"""
lab_utils_uni.py
routines used in Course 1, Week2, labs1-3 dealing with single variables (univariate)
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from matplotlib.gridspec import GridSpec
from matplotlib.colors import LinearSegmentedColormap
from ipywidgets import interact
from lab_utils_common import compute_cost
from lab_utils_common import dlblue, dlorange, dldarkred, dlmagenta, dlpurple, dlcolors
plt.style.use('./deeplearning.mplstyle')
n_bin = 5
dlcm = LinearSegmentedColormap.from_list(
'dl_map', dlcolors, N=n_bin)
##########################################################
# Plotting Routines
##########################################################
def plt_house_x(X, y,f_wb=None, ax=None):
''' plot house with aXis '''
if not ax:
fig, ax = plt.subplots(1,1)
ax.scatter(X, y, marker='x', c='r', label="Actual Value")
ax.set_title("Housing Prices")
ax.set_ylabel('Price (in 1000s of dollars)')
ax.set_xlabel(f'Size (1000 sqft)')
if f_wb is not None:
ax.plot(X, f_wb, c=dlblue, label="Our Prediction")
ax.legend()
def mk_cost_lines(x,y,w,b, ax):
''' makes vertical cost lines'''
cstr = "cost = (1/m)*("
ctot = 0
label = 'cost for point'
addedbreak = False
for p in zip(x,y):
f_wb_p = w*p[0]+b
c_p = ((f_wb_p - p[1])**2)/2
c_p_txt = c_p
ax.vlines(p[0], p[1],f_wb_p, lw=3, color=dlpurple, ls='dotted', label=label)
label='' #just one
cxy = [p[0], p[1] + (f_wb_p-p[1])/2]
ax.annotate(f'{c_p_txt:0.0f}', xy=cxy, xycoords='data',color=dlpurple,
xytext=(5, 0), textcoords='offset points')
cstr += f"{c_p_txt:0.0f} +"
if len(cstr) > 38 and addedbreak is False:
cstr += "\n"
addedbreak = True
ctot += c_p
ctot = ctot/(len(x))
cstr = cstr[:-1] + f") = {ctot:0.0f}"
ax.text(0.15,0.02,cstr, transform=ax.transAxes, color=dlpurple)
##########
# Cost lab
##########
def plt_intuition(x_train, y_train):
w_range = np.array([200-200,200+200])
tmp_b = 100
w_array = np.arange(*w_range, 5)
cost = np.zeros_like(w_array)
for i in range(len(w_array)):
tmp_w = w_array[i]
cost[i] = compute_cost(x_train, y_train, tmp_w, tmp_b)
@interact(w=(*w_range,10),continuous_update=False)
def func( w=150):
f_wb = np.dot(x_train, w) + tmp_b
fig, ax = plt.subplots(1, 2, constrained_layout=True, figsize=(8,4))
fig.canvas.toolbar_position = 'bottom'
mk_cost_lines(x_train, y_train, w, tmp_b, ax[0])
plt_house_x(x_train, y_train, f_wb=f_wb, ax=ax[0])
ax[1].plot(w_array, cost)
cur_cost = compute_cost(x_train, y_train, w, tmp_b)
ax[1].scatter(w,cur_cost, s=100, color=dldarkred, zorder= 10, label= f"cost at w={w}")
ax[1].hlines(cur_cost, ax[1].get_xlim()[0],w, lw=4, color=dlpurple, ls='dotted')
ax[1].vlines(w, ax[1].get_ylim()[0],cur_cost, lw=4, color=dlpurple, ls='dotted')
ax[1].set_title("Cost vs. w, (b fixed at 100)")
ax[1].set_ylabel('Cost')
ax[1].set_xlabel('w')
ax[1].legend(loc='upper center')
fig.suptitle(f"Minimize Cost: Current Cost = {cur_cost:0.0f}", fontsize=12)
plt.show()
# this is the 2D cost curve with interactive slider
def plt_stationary(x_train, y_train):
# setup figure
fig = plt.figure( figsize=(9,8))
#fig = plt.figure(constrained_layout=True, figsize=(12,10))
fig.set_facecolor('#ffffff') #white
fig.canvas.toolbar_position = 'top'
#gs = GridSpec(2, 2, figure=fig, wspace = 0.01)
gs = GridSpec(2, 2, figure=fig)
ax0 = fig.add_subplot(gs[0, 0])
ax1 = fig.add_subplot(gs[0, 1])
ax2 = fig.add_subplot(gs[1, :], projection='3d')
ax = np.array([ax0,ax1,ax2])
#setup useful ranges and common linspaces
w_range = np.array([200-300.,200+300])
b_range = np.array([50-300., 50+300])
b_space = np.linspace(*b_range, 100)
w_space = np.linspace(*w_range, 100)
# get cost for w,b ranges for contour and 3D
tmp_b,tmp_w = np.meshgrid(b_space,w_space)
z=np.zeros_like(tmp_b)
for i in range(tmp_w.shape[0]):
for j in range(tmp_w.shape[1]):
z[i,j] = compute_cost(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
if z[i,j] == 0: z[i,j] = 1e-6
w0=200;b=-100 #initial point
### plot model w cost ###
f_wb = np.dot(x_train,w0) + b
mk_cost_lines(x_train,y_train,w0,b,ax[0])
plt_house_x(x_train, y_train, f_wb=f_wb, ax=ax[0])
### plot contour ###
CS = ax[1].contour(tmp_w, tmp_b, np.log(z),levels=12, linewidths=2, alpha=0.7,colors=dlcolors)
ax[1].set_title('Cost(w,b)')
ax[1].set_xlabel('w', fontsize=10)
ax[1].set_ylabel('b', fontsize=10)
ax[1].set_xlim(w_range) ; ax[1].set_ylim(b_range)
cscat = ax[1].scatter(w0,b, s=100, color=dlblue, zorder= 10, label="cost with \ncurrent w,b")
chline = ax[1].hlines(b, ax[1].get_xlim()[0],w0, lw=4, color=dlpurple, ls='dotted')
cvline = ax[1].vlines(w0, ax[1].get_ylim()[0],b, lw=4, color=dlpurple, ls='dotted')
ax[1].text(0.5,0.95,"Click to choose w,b", bbox=dict(facecolor='white', ec = 'black'), fontsize = 10,
transform=ax[1].transAxes, verticalalignment = 'center', horizontalalignment= 'center')
#Surface plot of the cost function J(w,b)
ax[2].plot_surface(tmp_w, tmp_b, z, cmap = dlcm, alpha=0.3, antialiased=True)
ax[2].plot_wireframe(tmp_w, tmp_b, z, color='k', alpha=0.1)
plt.xlabel("$w$")
plt.ylabel("$b$")
ax[2].zaxis.set_rotate_label(False)
ax[2].xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax[2].yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax[2].zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax[2].set_zlabel("J(w, b)\n\n", rotation=90)
plt.title("Cost(w,b) \n [You can rotate this figure]", size=12)
ax[2].view_init(30, -120)
return fig,ax, [cscat, chline, cvline]
#https://matplotlib.org/stable/users/event_handling.html
class plt_update_onclick:
def __init__(self, fig, ax, x_train,y_train, dyn_items):
self.fig = fig
self.ax = ax
self.x_train = x_train
self.y_train = y_train
self.dyn_items = dyn_items
self.cid = fig.canvas.mpl_connect('button_press_event', self)
def __call__(self, event):
if event.inaxes == self.ax[1]:
ws = event.xdata
bs = event.ydata
cst = compute_cost(self.x_train, self.y_train, ws, bs)
# clear and redraw line plot
self.ax[0].clear()
f_wb = np.dot(self.x_train,ws) + bs
mk_cost_lines(self.x_train,self.y_train,ws,bs,self.ax[0])
plt_house_x(self.x_train, self.y_train, f_wb=f_wb, ax=self.ax[0])
# remove lines and re-add on countour plot and 3d plot
for artist in self.dyn_items:
artist.remove()
a = self.ax[1].scatter(ws,bs, s=100, color=dlblue, zorder= 10, label="cost with \ncurrent w,b")
b = self.ax[1].hlines(bs, self.ax[1].get_xlim()[0],ws, lw=4, color=dlpurple, ls='dotted')
c = self.ax[1].vlines(ws, self.ax[1].get_ylim()[0],bs, lw=4, color=dlpurple, ls='dotted')
d = self.ax[1].annotate(f"Cost: {cst:.0f}", xy= (ws, bs), xytext = (4,4), textcoords = 'offset points',
bbox=dict(facecolor='white'), size = 10)
#Add point in 3D surface plot
e = self.ax[2].scatter3D(ws, bs,cst , marker='X', s=100)
self.dyn_items = [a,b,c,d,e]
self.fig.canvas.draw()
def soup_bowl():
""" Create figure and plot with a 3D projection"""
fig = plt.figure(figsize=(8,8))
#Plot configuration
ax = fig.add_subplot(111, projection='3d')
ax.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.zaxis.set_rotate_label(False)
ax.view_init(45, -120)
#Useful linearspaces to give values to the parameters w and b
w = np.linspace(-20, 20, 100)
b = np.linspace(-20, 20, 100)
#Get the z value for a bowl-shaped cost function
z=np.zeros((len(w), len(b)))
j=0
for x in w:
i=0
for y in b:
z[i,j] = x**2 + y**2
i+=1
j+=1
#Meshgrid used for plotting 3D functions
W, B = np.meshgrid(w, b)
#Create the 3D surface plot of the bowl-shaped cost function
ax.plot_surface(W, B, z, cmap = "Spectral_r", alpha=0.7, antialiased=False)
ax.plot_wireframe(W, B, z, color='k', alpha=0.1)
ax.set_xlabel("$w$")
ax.set_ylabel("$b$")
ax.set_zlabel("$J(w,b)$", rotation=90)
ax.set_title("$J(w,b)$\n [You can rotate this figure]", size=15)
plt.show()
def inbounds(a,b,xlim,ylim):
xlow,xhigh = xlim
ylow,yhigh = ylim
ax, ay = a
bx, by = b
if (ax > xlow and ax < xhigh) and (bx > xlow and bx < xhigh) \
and (ay > ylow and ay < yhigh) and (by > ylow and by < yhigh):
return True
return False
def plt_contour_wgrad(x, y, hist, ax, w_range=[-100, 500, 5], b_range=[-500, 500, 5],
contours = [0.1,50,1000,5000,10000,25000,50000],
resolution=5, w_final=200, b_final=100,step=10 ):
b0,w0 = np.meshgrid(np.arange(*b_range),np.arange(*w_range))
z=np.zeros_like(b0)
for i in range(w0.shape[0]):
for j in range(w0.shape[1]):
z[i][j] = compute_cost(x, y, w0[i][j], b0[i][j] )
CS = ax.contour(w0, b0, z, contours, linewidths=2,
colors=[dlblue, dlorange, dldarkred, dlmagenta, dlpurple])
ax.clabel(CS, inline=1, fmt='%1.0f', fontsize=10)
ax.set_xlabel("w"); ax.set_ylabel("b")
ax.set_title('Contour plot of cost J(w,b), vs b,w with path of gradient descent')
w = w_final; b=b_final
ax.hlines(b, ax.get_xlim()[0],w, lw=2, color=dlpurple, ls='dotted')
ax.vlines(w, ax.get_ylim()[0],b, lw=2, color=dlpurple, ls='dotted')
base = hist[0]
for point in hist[0::step]:
edist = np.sqrt((base[0] - point[0])**2 + (base[1] - point[1])**2)
if(edist > resolution or point==hist[-1]):
if inbounds(point,base, ax.get_xlim(),ax.get_ylim()):
plt.annotate('', xy=point, xytext=base,xycoords='data',
arrowprops={'arrowstyle': '->', 'color': 'r', 'lw': 3},
va='center', ha='center')
base=point
return
def plt_divergence(p_hist, J_hist, x_train,y_train):
x=np.zeros(len(p_hist))
y=np.zeros(len(p_hist))
v=np.zeros(len(p_hist))
for i in range(len(p_hist)):
x[i] = p_hist[i][0]
y[i] = p_hist[i][1]
v[i] = J_hist[i]
fig = plt.figure(figsize=(12,5))
plt.subplots_adjust( wspace=0 )
gs = fig.add_gridspec(1, 5)
fig.suptitle(f"Cost escalates when learning rate is too large")
#===============
# First subplot
#===============
ax = fig.add_subplot(gs[:2], )
# Print w vs cost to see minimum
fix_b = 100
w_array = np.arange(-70000, 70000, 1000)
cost = np.zeros_like(w_array)
for i in range(len(w_array)):
tmp_w = w_array[i]
cost[i] = compute_cost(x_train, y_train, tmp_w, fix_b)
ax.plot(w_array, cost)
ax.plot(x,v, c=dlmagenta)
ax.set_title("Cost vs w, b set to 100")
ax.set_ylabel('Cost')
ax.set_xlabel('w')
ax.xaxis.set_major_locator(MaxNLocator(2))
#===============
# Second Subplot
#===============
tmp_b,tmp_w = np.meshgrid(np.arange(-35000, 35000, 500),np.arange(-70000, 70000, 500))
z=np.zeros_like(tmp_b)
for i in range(tmp_w.shape[0]):
for j in range(tmp_w.shape[1]):
z[i][j] = compute_cost(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
ax = fig.add_subplot(gs[2:], projection='3d')
ax.plot_surface(tmp_w, tmp_b, z, alpha=0.3, color=dlblue)
ax.xaxis.set_major_locator(MaxNLocator(2))
ax.yaxis.set_major_locator(MaxNLocator(2))
ax.set_xlabel('w', fontsize=16)
ax.set_ylabel('b', fontsize=16)
ax.set_zlabel('\ncost', fontsize=16)
plt.title('Cost vs (b, w)')
# Customize the view angle
ax.view_init(elev=20., azim=-65)
ax.plot(x, y, v,c=dlmagenta)
return
# draw derivative line
# y = m*(x - x1) + y1
def add_line(dj_dx, x1, y1, d, ax):
x = np.linspace(x1-d, x1+d,50)
y = dj_dx*(x - x1) + y1
ax.scatter(x1, y1, color=dlblue, s=50)
ax.plot(x, y, '--', c=dldarkred,zorder=10, linewidth = 1)
xoff = 30 if x1 == 200 else 10
ax.annotate(r"$\frac{\partial J}{\partial w}$ =%d" % dj_dx, fontsize=14,
xy=(x1, y1), xycoords='data',
xytext=(xoff, 10), textcoords='offset points',
arrowprops=dict(arrowstyle="->"),
horizontalalignment='left', verticalalignment='top')
def plt_gradients(x_train,y_train, f_compute_cost, f_compute_gradient):
#===============
# First subplot
#===============
fig,ax = plt.subplots(1,2,figsize=(12,4))
# Print w vs cost to see minimum
fix_b = 100
w_array = np.linspace(-100, 500, 50)
w_array = np.linspace(0, 400, 50)
cost = np.zeros_like(w_array)
for i in range(len(w_array)):
tmp_w = w_array[i]
cost[i] = f_compute_cost(x_train, y_train, tmp_w, fix_b)
ax[0].plot(w_array, cost,linewidth=1)
ax[0].set_title("Cost vs w, with gradient; b set to 100")
ax[0].set_ylabel('Cost')
ax[0].set_xlabel('w')
# plot lines for fixed b=100
for tmp_w in [100,200,300]:
fix_b = 100
dj_dw,dj_db = f_compute_gradient(x_train, y_train, tmp_w, fix_b )
j = f_compute_cost(x_train, y_train, tmp_w, fix_b)
add_line(dj_dw, tmp_w, j, 30, ax[0])
#===============
# Second Subplot
#===============
tmp_b,tmp_w = np.meshgrid(np.linspace(-200, 200, 10), np.linspace(-100, 600, 10))
U = np.zeros_like(tmp_w)
V = np.zeros_like(tmp_b)
for i in range(tmp_w.shape[0]):
for j in range(tmp_w.shape[1]):
U[i][j], V[i][j] = f_compute_gradient(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
X = tmp_w
Y = tmp_b
n=-2
color_array = np.sqrt(((V-n)/2)**2 + ((U-n)/2)**2)
ax[1].set_title('Gradient shown in quiver plot')
Q = ax[1].quiver(X, Y, U, V, color_array, units='width', )
ax[1].quiverkey(Q, 0.9, 0.9, 2, r'$2 \frac{m}{s}$', labelpos='E',coordinates='figure')
ax[1].set_xlabel("w"); ax[1].set_ylabel("b")

View File

@@ -1,47 +0,0 @@
2104,3,399900
1600,3,329900
2400,3,369000
1416,2,232000
3000,4,539900
1985,4,299900
1534,3,314900
1427,3,198999
1380,3,212000
1494,3,242500
1940,4,239999
2000,3,347000
1890,3,329999
4478,5,699900
1268,3,259900
2300,4,449900
1320,2,299900
1236,3,199900
2609,4,499998
3031,4,599000
1767,3,252900
1888,2,255000
1604,3,242900
1962,4,259900
3890,3,573900
1100,3,249900
1458,3,464500
2526,3,469000
2200,3,475000
2637,3,299900
1839,2,349900
1000,1,169900
2040,4,314900
3137,3,579900
1811,4,285900
1437,3,249900
1239,3,229900
2132,4,345000
4215,4,549000
2162,4,287000
1664,2,368500
2238,3,329900
2567,4,314000
1200,3,299000
852,2,179900
1852,4,299900
1203,3,239500

View File

@@ -1,124 +0,0 @@
# see https://matplotlib.org/stable/tutorials/introductory/customizing.html
lines.linewidth: 4
lines.solid_capstyle: butt
legend.fancybox: true
# Verdana" for non-math text,
# Cambria Math
#Blue (Crayon-Aqua) 0096FF
#Dark Red C00000
#Orange (Apple Orange) FF9300
#Black 000000
#Magenta FF40FF
#Purple 7030A0
axes.prop_cycle: cycler('color', ['0096FF', 'FF9300', 'FF40FF', '7030A0', 'C00000'])
#axes.facecolor: f0f0f0 # grey
axes.facecolor: ffffff # white
axes.labelsize: large
axes.axisbelow: true
axes.grid: False
axes.edgecolor: f0f0f0
axes.linewidth: 3.0
axes.titlesize: x-large
patch.edgecolor: f0f0f0
patch.linewidth: 0.5
svg.fonttype: path
grid.linestyle: -
grid.linewidth: 1.0
grid.color: cbcbcb
xtick.major.size: 0
xtick.minor.size: 0
ytick.major.size: 0
ytick.minor.size: 0
savefig.edgecolor: f0f0f0
savefig.facecolor: f0f0f0
#figure.subplot.left: 0.08
#figure.subplot.right: 0.95
#figure.subplot.bottom: 0.07
#figure.facecolor: f0f0f0 # grey
figure.facecolor: ffffff # white
## ***************************************************************************
## * FONT *
## ***************************************************************************
## The font properties used by `text.Text`.
## See https://matplotlib.org/api/font_manager_api.html for more information
## on font properties. The 6 font properties used for font matching are
## given below with their default values.
##
## The font.family property can take either a concrete font name (not supported
## when rendering text with usetex), or one of the following five generic
## values:
## - 'serif' (e.g., Times),
## - 'sans-serif' (e.g., Helvetica),
## - 'cursive' (e.g., Zapf-Chancery),
## - 'fantasy' (e.g., Western), and
## - 'monospace' (e.g., Courier).
## Each of these values has a corresponding default list of font names
## (font.serif, etc.); the first available font in the list is used. Note that
## for font.serif, font.sans-serif, and font.monospace, the first element of
## the list (a DejaVu font) will always be used because DejaVu is shipped with
## Matplotlib and is thus guaranteed to be available; the other entries are
## left as examples of other possible values.
##
## The font.style property has three values: normal (or roman), italic
## or oblique. The oblique style will be used for italic, if it is not
## present.
##
## The font.variant property has two values: normal or small-caps. For
## TrueType fonts, which are scalable fonts, small-caps is equivalent
## to using a font size of 'smaller', or about 83%% of the current font
## size.
##
## The font.weight property has effectively 13 values: normal, bold,
## bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as
## 400, and bold is 700. bolder and lighter are relative values with
## respect to the current weight.
##
## The font.stretch property has 11 values: ultra-condensed,
## extra-condensed, condensed, semi-condensed, normal, semi-expanded,
## expanded, extra-expanded, ultra-expanded, wider, and narrower. This
## property is not currently implemented.
##
## The font.size property is the default font size for text, given in points.
## 10 pt is the standard value.
##
## Note that font.size controls default text sizes. To configure
## special text sizes tick labels, axes, labels, title, etc., see the rc
## settings for axes and ticks. Special text sizes can be defined
## relative to font.size, using the following values: xx-small, x-small,
## small, medium, large, x-large, xx-large, larger, or smaller
font.family: sans-serif
font.style: normal
font.variant: normal
font.weight: normal
font.stretch: normal
font.size: 8.0
font.serif: DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
font.sans-serif: Verdana, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
font.cursive: Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, Comic Neue, Comic Sans MS, cursive
font.fantasy: Chicago, Charcoal, Impact, Western, Humor Sans, xkcd, fantasy
font.monospace: DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace
## ***************************************************************************
## * TEXT *
## ***************************************************************************
## The text properties used by `text.Text`.
## See https://matplotlib.org/api/artist_api.html#module-matplotlib.text
## for more information on text properties
#text.color: black

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -1,112 +0,0 @@
"""
lab_utils_common.py
functions common to all optional labs, Course 1, Week 2
"""
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('deeplearning.mplstyle')
dlblue = '#0096ff'; dlorange = '#FF9300'; dldarkred='#C00000'; dlmagenta='#FF40FF'; dlpurple='#7030A0';
dlcolors = [dlblue, dlorange, dldarkred, dlmagenta, dlpurple]
dlc = dict(dlblue = '#0096ff', dlorange = '#FF9300', dldarkred='#C00000', dlmagenta='#FF40FF', dlpurple='#7030A0')
##########################################################
# Regression Routines
##########################################################
#Function to calculate the cost
def compute_cost_matrix(X, y, w, b, verbose=False):
"""
Computes the gradient for linear regression
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
verbose : (Boolean) If true, print out intermediate value f_wb
Returns
cost: (scalar)
"""
m = X.shape[0]
# calculate f_wb for all examples.
f_wb = X @ w + b
# calculate cost
total_cost = (1/(2*m)) * np.sum((f_wb-y)**2)
if verbose: print("f_wb:")
if verbose: print(f_wb)
return total_cost
def compute_gradient_matrix(X, y, w, b):
"""
Computes the gradient for linear regression
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
Returns
dj_dw (ndarray (n,1)): The gradient of the cost w.r.t. the parameters w.
dj_db (scalar): The gradient of the cost w.r.t. the parameter b.
"""
m,n = X.shape
f_wb = X @ w + b
e = f_wb - y
dj_dw = (1/m) * (X.T @ e)
dj_db = (1/m) * np.sum(e)
return dj_db,dj_dw
# Loop version of multi-variable compute_cost
def compute_cost(X, y, w, b):
"""
compute cost
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
Returns
cost (scalar) : cost
"""
m = X.shape[0]
cost = 0.0
for i in range(m):
f_wb_i = np.dot(X[i],w) + b #(n,)(n,)=scalar
cost = cost + (f_wb_i - y[i])**2
cost = cost/(2*m)
return cost
def compute_gradient(X, y, w, b):
"""
Computes the gradient for linear regression
Args:
X (ndarray (m,n)): Data, m examples with n features
y (ndarray (m,)) : target values
w (ndarray (n,)) : model parameters
b (scalar) : model parameter
Returns
dj_dw (ndarray Shape (n,)): The gradient of the cost w.r.t. the parameters w.
dj_db (scalar): The gradient of the cost w.r.t. the parameter b.
"""
m,n = X.shape #(number of examples, number of features)
dj_dw = np.zeros((n,))
dj_db = 0.
for i in range(m):
err = (np.dot(X[i], w) + b) - y[i]
for j in range(n):
dj_dw[j] = dj_dw[j] + err * X[i,j]
dj_db = dj_db + err
dj_dw = dj_dw/m
dj_db = dj_db/m
return dj_db,dj_dw

View File

@@ -1,398 +0,0 @@
"""
lab_utils_uni.py
routines used in Course 1, Week2, labs1-3 dealing with single variables (univariate)
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from matplotlib.gridspec import GridSpec
from matplotlib.colors import LinearSegmentedColormap
from ipywidgets import interact
from lab_utils_common import compute_cost
from lab_utils_common import dlblue, dlorange, dldarkred, dlmagenta, dlpurple, dlcolors
plt.style.use('deeplearning.mplstyle')
n_bin = 5
dlcm = LinearSegmentedColormap.from_list(
'dl_map', dlcolors, N=n_bin)
##########################################################
# Plotting Routines
##########################################################
def plt_house_x(X, y,f_wb=None, ax=None):
''' plot house with aXis '''
if not ax:
fig, ax = plt.subplots(1,1)
ax.scatter(X, y, marker='x', c='r', label="Actual Value")
ax.set_title("Housing Prices")
ax.set_ylabel('Price (in 1000s of dollars)')
ax.set_xlabel(f'Size (1000 sqft)')
if f_wb is not None:
ax.plot(X, f_wb, c=dlblue, label="Our Prediction")
ax.legend()
def mk_cost_lines(x,y,w,b, ax):
''' makes vertical cost lines'''
cstr = "cost = (1/m)*("
ctot = 0
label = 'cost for point'
addedbreak = False
for p in zip(x,y):
f_wb_p = w*p[0]+b
c_p = ((f_wb_p - p[1])**2)/2
c_p_txt = c_p
ax.vlines(p[0], p[1],f_wb_p, lw=3, color=dlpurple, ls='dotted', label=label)
label='' #just one
cxy = [p[0], p[1] + (f_wb_p-p[1])/2]
ax.annotate(f'{c_p_txt:0.0f}', xy=cxy, xycoords='data',color=dlpurple,
xytext=(5, 0), textcoords='offset points')
cstr += f"{c_p_txt:0.0f} +"
if len(cstr) > 38 and addedbreak is False:
cstr += "\n"
addedbreak = True
ctot += c_p
ctot = ctot/(len(x))
cstr = cstr[:-1] + f") = {ctot:0.0f}"
ax.text(0.15,0.02,cstr, transform=ax.transAxes, color=dlpurple)
##########
# Cost lab
##########
def plt_intuition(x_train, y_train):
w_range = np.array([200-200,200+200])
tmp_b = 100
w_array = np.arange(*w_range, 5)
cost = np.zeros_like(w_array)
for i in range(len(w_array)):
tmp_w = w_array[i]
cost[i] = compute_cost(x_train, y_train, tmp_w, tmp_b)
@interact(w=(*w_range,10),continuous_update=False)
def func( w=150):
f_wb = np.dot(x_train, w) + tmp_b
fig, ax = plt.subplots(1, 2, constrained_layout=True, figsize=(8,4))
fig.canvas.toolbar_position = 'bottom'
mk_cost_lines(x_train, y_train, w, tmp_b, ax[0])
plt_house_x(x_train, y_train, f_wb=f_wb, ax=ax[0])
ax[1].plot(w_array, cost)
cur_cost = compute_cost(x_train, y_train, w, tmp_b)
ax[1].scatter(w,cur_cost, s=100, color=dldarkred, zorder= 10, label= f"cost at w={w}")
ax[1].hlines(cur_cost, ax[1].get_xlim()[0],w, lw=4, color=dlpurple, ls='dotted')
ax[1].vlines(w, ax[1].get_ylim()[0],cur_cost, lw=4, color=dlpurple, ls='dotted')
ax[1].set_title("Cost vs. w, (b fixed at 100)")
ax[1].set_ylabel('Cost')
ax[1].set_xlabel('w')
ax[1].legend(loc='upper center')
fig.suptitle(f"Minimize Cost: Current Cost = {cur_cost:0.0f}", fontsize=12)
plt.show()
# this is the 2D cost curve with interactive slider
def plt_stationary(x_train, y_train):
# setup figure
fig = plt.figure( figsize=(9,8))
#fig = plt.figure(constrained_layout=True, figsize=(12,10))
fig.set_facecolor('#ffffff') #white
fig.canvas.toolbar_position = 'top'
#gs = GridSpec(2, 2, figure=fig, wspace = 0.01)
gs = GridSpec(2, 2, figure=fig)
ax0 = fig.add_subplot(gs[0, 0])
ax1 = fig.add_subplot(gs[0, 1])
ax2 = fig.add_subplot(gs[1, :], projection='3d')
ax = np.array([ax0,ax1,ax2])
#setup useful ranges and common linspaces
w_range = np.array([200-300.,200+300])
b_range = np.array([50-300., 50+300])
b_space = np.linspace(*b_range, 100)
w_space = np.linspace(*w_range, 100)
# get cost for w,b ranges for contour and 3D
tmp_b,tmp_w = np.meshgrid(b_space,w_space)
z=np.zeros_like(tmp_b)
for i in range(tmp_w.shape[0]):
for j in range(tmp_w.shape[1]):
z[i,j] = compute_cost(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
if z[i,j] == 0: z[i,j] = 1e-6
w0=200;b=-100 #initial point
### plot model w cost ###
f_wb = np.dot(x_train,w0) + b
mk_cost_lines(x_train,y_train,w0,b,ax[0])
plt_house_x(x_train, y_train, f_wb=f_wb, ax=ax[0])
### plot contour ###
CS = ax[1].contour(tmp_w, tmp_b, np.log(z),levels=12, linewidths=2, alpha=0.7,colors=dlcolors)
ax[1].set_title('Cost(w,b)')
ax[1].set_xlabel('w', fontsize=10)
ax[1].set_ylabel('b', fontsize=10)
ax[1].set_xlim(w_range) ; ax[1].set_ylim(b_range)
cscat = ax[1].scatter(w0,b, s=100, color=dlblue, zorder= 10, label="cost with \ncurrent w,b")
chline = ax[1].hlines(b, ax[1].get_xlim()[0],w0, lw=4, color=dlpurple, ls='dotted')
cvline = ax[1].vlines(w0, ax[1].get_ylim()[0],b, lw=4, color=dlpurple, ls='dotted')
ax[1].text(0.5,0.95,"Click to choose w,b", bbox=dict(facecolor='white', ec = 'black'), fontsize = 10,
transform=ax[1].transAxes, verticalalignment = 'center', horizontalalignment= 'center')
#Surface plot of the cost function J(w,b)
ax[2].plot_surface(tmp_w, tmp_b, z, cmap = dlcm, alpha=0.3, antialiased=True)
ax[2].plot_wireframe(tmp_w, tmp_b, z, color='k', alpha=0.1)
plt.xlabel("$w$")
plt.ylabel("$b$")
ax[2].zaxis.set_rotate_label(False)
ax[2].xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax[2].yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax[2].zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax[2].set_zlabel("J(w, b)\n\n", rotation=90)
plt.title("Cost(w,b) \n [You can rotate this figure]", size=12)
ax[2].view_init(30, -120)
return fig,ax, [cscat, chline, cvline]
#https://matplotlib.org/stable/users/event_handling.html
class plt_update_onclick:
def __init__(self, fig, ax, x_train,y_train, dyn_items):
self.fig = fig
self.ax = ax
self.x_train = x_train
self.y_train = y_train
self.dyn_items = dyn_items
self.cid = fig.canvas.mpl_connect('button_press_event', self)
def __call__(self, event):
if event.inaxes == self.ax[1]:
ws = event.xdata
bs = event.ydata
cst = compute_cost(self.x_train, self.y_train, ws, bs)
# clear and redraw line plot
self.ax[0].clear()
f_wb = np.dot(self.x_train,ws) + bs
mk_cost_lines(self.x_train,self.y_train,ws,bs,self.ax[0])
plt_house_x(self.x_train, self.y_train, f_wb=f_wb, ax=self.ax[0])
# remove lines and re-add on countour plot and 3d plot
for artist in self.dyn_items:
artist.remove()
a = self.ax[1].scatter(ws,bs, s=100, color=dlblue, zorder= 10, label="cost with \ncurrent w,b")
b = self.ax[1].hlines(bs, self.ax[1].get_xlim()[0],ws, lw=4, color=dlpurple, ls='dotted')
c = self.ax[1].vlines(ws, self.ax[1].get_ylim()[0],bs, lw=4, color=dlpurple, ls='dotted')
d = self.ax[1].annotate(f"Cost: {cst:.0f}", xy= (ws, bs), xytext = (4,4), textcoords = 'offset points',
bbox=dict(facecolor='white'), size = 10)
#Add point in 3D surface plot
e = self.ax[2].scatter3D(ws, bs,cst , marker='X', s=100)
self.dyn_items = [a,b,c,d,e]
self.fig.canvas.draw()
def soup_bowl():
""" Create figure and plot with a 3D projection"""
fig = plt.figure(figsize=(8,8))
#Plot configuration
ax = fig.add_subplot(111, projection='3d')
ax.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
ax.zaxis.set_rotate_label(False)
ax.view_init(45, -120)
#Useful linearspaces to give values to the parameters w and b
w = np.linspace(-20, 20, 100)
b = np.linspace(-20, 20, 100)
#Get the z value for a bowl-shaped cost function
z=np.zeros((len(w), len(b)))
j=0
for x in w:
i=0
for y in b:
z[i,j] = x**2 + y**2
i+=1
j+=1
#Meshgrid used for plotting 3D functions
W, B = np.meshgrid(w, b)
#Create the 3D surface plot of the bowl-shaped cost function
ax.plot_surface(W, B, z, cmap = "Spectral_r", alpha=0.7, antialiased=False)
ax.plot_wireframe(W, B, z, color='k', alpha=0.1)
ax.set_xlabel("$w$")
ax.set_ylabel("$b$")
ax.set_zlabel("$J(w,b)$", rotation=90)
ax.set_title("$J(w,b)$\n [You can rotate this figure]", size=15)
plt.show()
def inbounds(a,b,xlim,ylim):
xlow,xhigh = xlim
ylow,yhigh = ylim
ax, ay = a
bx, by = b
if (ax > xlow and ax < xhigh) and (bx > xlow and bx < xhigh) \
and (ay > ylow and ay < yhigh) and (by > ylow and by < yhigh):
return True
return False
def plt_contour_wgrad(x, y, hist, ax, w_range=[-100, 500, 5], b_range=[-500, 500, 5],
contours = [0.1,50,1000,5000,10000,25000,50000],
resolution=5, w_final=200, b_final=100,step=10 ):
b0,w0 = np.meshgrid(np.arange(*b_range),np.arange(*w_range))
z=np.zeros_like(b0)
for i in range(w0.shape[0]):
for j in range(w0.shape[1]):
z[i][j] = compute_cost(x, y, w0[i][j], b0[i][j] )
CS = ax.contour(w0, b0, z, contours, linewidths=2,
colors=[dlblue, dlorange, dldarkred, dlmagenta, dlpurple])
ax.clabel(CS, inline=1, fmt='%1.0f', fontsize=10)
ax.set_xlabel("w"); ax.set_ylabel("b")
ax.set_title('Contour plot of cost J(w,b), vs b,w with path of gradient descent')
w = w_final; b=b_final
ax.hlines(b, ax.get_xlim()[0],w, lw=2, color=dlpurple, ls='dotted')
ax.vlines(w, ax.get_ylim()[0],b, lw=2, color=dlpurple, ls='dotted')
base = hist[0]
for point in hist[0::step]:
edist = np.sqrt((base[0] - point[0])**2 + (base[1] - point[1])**2)
if(edist > resolution or point==hist[-1]):
if inbounds(point,base, ax.get_xlim(),ax.get_ylim()):
plt.annotate('', xy=point, xytext=base,xycoords='data',
arrowprops={'arrowstyle': '->', 'color': 'r', 'lw': 3},
va='center', ha='center')
base=point
return
def plt_divergence(p_hist, J_hist, x_train,y_train):
x=np.zeros(len(p_hist))
y=np.zeros(len(p_hist))
v=np.zeros(len(p_hist))
for i in range(len(p_hist)):
x[i] = p_hist[i][0]
y[i] = p_hist[i][1]
v[i] = J_hist[i]
fig = plt.figure(figsize=(12,5))
plt.subplots_adjust( wspace=0 )
gs = fig.add_gridspec(1, 5)
fig.suptitle(f"Cost escalates when learning rate is too large")
#===============
# First subplot
#===============
ax = fig.add_subplot(gs[:2], )
# Print w vs cost to see minimum
fix_b = 100
w_array = np.arange(-70000, 70000, 1000)
cost = np.zeros_like(w_array)
for i in range(len(w_array)):
tmp_w = w_array[i]
cost[i] = compute_cost(x_train, y_train, tmp_w, fix_b)
ax.plot(w_array, cost)
ax.plot(x,v, c=dlmagenta)
ax.set_title("Cost vs w, b set to 100")
ax.set_ylabel('Cost')
ax.set_xlabel('w')
ax.xaxis.set_major_locator(MaxNLocator(2))
#===============
# Second Subplot
#===============
tmp_b,tmp_w = np.meshgrid(np.arange(-35000, 35000, 500),np.arange(-70000, 70000, 500))
z=np.zeros_like(tmp_b)
for i in range(tmp_w.shape[0]):
for j in range(tmp_w.shape[1]):
z[i][j] = compute_cost(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
ax = fig.add_subplot(gs[2:], projection='3d')
ax.plot_surface(tmp_w, tmp_b, z, alpha=0.3, color=dlblue)
ax.xaxis.set_major_locator(MaxNLocator(2))
ax.yaxis.set_major_locator(MaxNLocator(2))
ax.set_xlabel('w', fontsize=16)
ax.set_ylabel('b', fontsize=16)
ax.set_zlabel('\ncost', fontsize=16)
plt.title('Cost vs (b, w)')
# Customize the view angle
ax.view_init(elev=20., azim=-65)
ax.plot(x, y, v,c=dlmagenta)
return
# draw derivative line
# y = m*(x - x1) + y1
def add_line(dj_dx, x1, y1, d, ax):
x = np.linspace(x1-d, x1+d,50)
y = dj_dx*(x - x1) + y1
ax.scatter(x1, y1, color=dlblue, s=50)
ax.plot(x, y, '--', c=dldarkred,zorder=10, linewidth = 1)
xoff = 30 if x1 == 200 else 10
ax.annotate(r"$\frac{\partial J}{\partial w}$ =%d" % dj_dx, fontsize=14,
xy=(x1, y1), xycoords='data',
xytext=(xoff, 10), textcoords='offset points',
arrowprops=dict(arrowstyle="->"),
horizontalalignment='left', verticalalignment='top')
def plt_gradients(x_train,y_train, f_compute_cost, f_compute_gradient):
#===============
# First subplot
#===============
fig,ax = plt.subplots(1,2,figsize=(12,4))
# Print w vs cost to see minimum
fix_b = 100
w_array = np.linspace(-100, 500, 50)
w_array = np.linspace(0, 400, 50)
cost = np.zeros_like(w_array)
for i in range(len(w_array)):
tmp_w = w_array[i]
cost[i] = f_compute_cost(x_train, y_train, tmp_w, fix_b)
ax[0].plot(w_array, cost,linewidth=1)
ax[0].set_title("Cost vs w, with gradient; b set to 100")
ax[0].set_ylabel('Cost')
ax[0].set_xlabel('w')
# plot lines for fixed b=100
for tmp_w in [100,200,300]:
fix_b = 100
dj_dw,dj_db = f_compute_gradient(x_train, y_train, tmp_w, fix_b )
j = f_compute_cost(x_train, y_train, tmp_w, fix_b)
add_line(dj_dw, tmp_w, j, 30, ax[0])
#===============
# Second Subplot
#===============
tmp_b,tmp_w = np.meshgrid(np.linspace(-200, 200, 10), np.linspace(-100, 600, 10))
U = np.zeros_like(tmp_w)
V = np.zeros_like(tmp_b)
for i in range(tmp_w.shape[0]):
for j in range(tmp_w.shape[1]):
U[i][j], V[i][j] = f_compute_gradient(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
X = tmp_w
Y = tmp_b
n=-2
color_array = np.sqrt(((V-n)/2)**2 + ((U-n)/2)**2)
ax[1].set_title('Gradient shown in quiver plot')
Q = ax[1].quiver(X, Y, U, V, color_array, units='width', )
ax[1].quiverkey(Q, 0.9, 0.9, 2, r'$2 \frac{m}{s}$', labelpos='E',coordinates='figure')
ax[1].set_xlabel("w"); ax[1].set_ylabel("b")

View File

@@ -1,916 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Python, NumPy and Vectorization\n",
"A brief introduction to some of the scientific computing used in this course. In particular the NumPy scientific computing package and its use with python.\n",
"\n",
"# Outline\n",
"- [&nbsp;&nbsp;1.1 Goals](#toc_40015_1.1)\n",
"- [&nbsp;&nbsp;1.2 Useful References](#toc_40015_1.2)\n",
"- [2 Python and NumPy <a name='Python and NumPy'></a>](#toc_40015_2)\n",
"- [3 Vectors](#toc_40015_3)\n",
"- [&nbsp;&nbsp;3.1 Abstract](#toc_40015_3.1)\n",
"- [&nbsp;&nbsp;3.2 NumPy Arrays](#toc_40015_3.2)\n",
"- [&nbsp;&nbsp;3.3 Vector Creation](#toc_40015_3.3)\n",
"- [&nbsp;&nbsp;3.4 Operations on Vectors](#toc_40015_3.4)\n",
"- [4 Matrices](#toc_40015_4)\n",
"- [&nbsp;&nbsp;4.1 Abstract](#toc_40015_4.1)\n",
"- [&nbsp;&nbsp;4.2 NumPy Arrays](#toc_40015_4.2)\n",
"- [&nbsp;&nbsp;4.3 Matrix Creation](#toc_40015_4.3)\n",
"- [&nbsp;&nbsp;4.4 Operations on Matrices](#toc_40015_4.4)\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np # it is an unofficial standard to use np for numpy\n",
"import time"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_1.1\"></a>\n",
"## 1.1 Goals\n",
"In this lab, you will:\n",
"- Review the features of NumPy and Python that are used in Course 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_1.2\"></a>\n",
"## 1.2 Useful References\n",
"- NumPy Documentation including a basic introduction: [NumPy.org](https://NumPy.org/doc/stable/)\n",
"- A challenging feature topic: [NumPy Broadcasting](https://NumPy.org/doc/stable/user/basics.broadcasting.html)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_2\"></a>\n",
"# 2 Python and NumPy <a name='Python and NumPy'></a>\n",
"Python is the programming language we will be using in this course. It has a set of numeric data types and arithmetic operations. NumPy is a library that extends the base capabilities of python to add a richer data set including more numeric types, vectors, matrices, and many matrix functions. NumPy and python work together fairly seamlessly. Python arithmetic operators work on NumPy data types and many NumPy functions will accept python data types.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3\"></a>\n",
"# 3 Vectors\n",
"<a name=\"toc_40015_3.1\"></a>\n",
"## 3.1 Abstract\n",
"<img align=\"right\" src=\"./images/C1_W2_Lab04_Vectors.PNG\" style=\"width:340px;\" >Vectors, as you will use them in this course, are ordered arrays of numbers. In notation, vectors are denoted with lower case bold letters such as $\\mathbf{x}$. The elements of a vector are all the same type. A vector does not, for example, contain both characters and numbers. The number of elements in the array is often referred to as the *dimension* though mathematicians may prefer *rank*. The vector shown has a dimension of $n$. The elements of a vector can be referenced with an index. In math settings, indexes typically run from 1 to n. In computer science and these labs, indexing will typically run from 0 to n-1. In notation, elements of a vector, when referenced individually will indicate the index in a subscript, for example, the $0^{th}$ element, of the vector $\\mathbf{x}$ is $x_0$. Note, the x is not bold in this case. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.2\"></a>\n",
"## 3.2 NumPy Arrays\n",
"\n",
"NumPy's basic data structure is an indexable, n-dimensional *array* containing elements of the same type (`dtype`). Right away, you may notice we have overloaded the term 'dimension'. Above, it was the number of elements in the vector, here, dimension refers to the number of indexes of an array. A one-dimensional or 1-D array has one index. In Course 1, we will represent vectors as NumPy 1-D arrays. \n",
"\n",
" - 1-D array, shape (n,): n elements indexed [0] through [n-1]\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.3\"></a>\n",
"## 3.3 Vector Creation\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Data creation routines in NumPy will generally have a first parameter which is the shape of the object. This can either be a single value for a 1-D result or a tuple (n,m,...) specifying the shape of the result. Below are examples of creating vectors using these routines."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"np.zeros(4) : a = [0. 0. 0. 0.], a shape = (4,), a data type = float64\n",
"np.zeros(4,) : a = [0. 0. 0. 0.], a shape = (4,), a data type = float64\n",
"np.random.random_sample(4): a = [0.04076162 0.01386783 0.16757523 0.9833998 ], a shape = (4,), a data type = float64\n"
]
}
],
"source": [
"# NumPy routines which allocate memory and fill arrays with value\n",
"a = np.zeros(4); print(f\"np.zeros(4) : a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.zeros((4,)); print(f\"np.zeros(4,) : a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.random.random_sample(4); print(f\"np.random.random_sample(4): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some data creation routines do not take a shape tuple:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"np.arange(4.): a = [0. 1. 2. 3.], a shape = (4,), a data type = float64\n",
"np.random.rand(4): a = [0.37476357 0.06946621 0.79627083 0.96134986], a shape = (4,), a data type = float64\n"
]
}
],
"source": [
"# NumPy routines which allocate memory and fill arrays with value but do not accept shape as input argument\n",
"a = np.arange(4.); print(f\"np.arange(4.): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.random.rand(4); print(f\"np.random.rand(4): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"values can be specified manually as well. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"np.array([5,4,3,2]): a = [5 4 3 2], a shape = (4,), a data type = int64\n",
"np.array([5.,4,3,2]): a = [5. 4. 3. 2.], a shape = (4,), a data type = float64\n"
]
}
],
"source": [
"# NumPy routines which allocate memory and fill with user specified values\n",
"a = np.array([5,4,3,2]); print(f\"np.array([5,4,3,2]): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.array([5.,4,3,2]); print(f\"np.array([5.,4,3,2]): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These have all created a one-dimensional vector `a` with four elements. `a.shape` returns the dimensions. Here we see a.shape = `(4,)` indicating a 1-d array with 4 elements. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4\"></a>\n",
"## 3.4 Operations on Vectors\n",
"Let's explore some operations using vectors.\n",
"<a name=\"toc_40015_3.4.1\"></a>\n",
"### 3.4.1 Indexing\n",
"Elements of vectors can be accessed via indexing and slicing. NumPy provides a very complete set of indexing and slicing capabilities. We will explore only the basics needed for the course here. Reference [Slicing and Indexing](https://NumPy.org/doc/stable/reference/arrays.indexing.html) for more details. \n",
"**Indexing** means referring to *an element* of an array by its position within the array. \n",
"**Slicing** means getting a *subset* of elements from an array based on their indices. \n",
"NumPy starts indexing at zero so the 3rd element of an vector $\\mathbf{a}$ is `a[2]`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0 1 2 3 4 5 6 7 8 9]\n",
"a[2].shape: () a[2] = 2, Accessing an element returns a scalar\n",
"a[-1] = 9\n",
"The error message you'll see is:\n",
"index 10 is out of bounds for axis 0 with size 10\n"
]
}
],
"source": [
"#vector indexing operations on 1-D vectors\n",
"a = np.arange(10)\n",
"print(a)\n",
"\n",
"#access an element\n",
"print(f\"a[2].shape: {a[2].shape} a[2] = {a[2]}, Accessing an element returns a scalar\")\n",
"\n",
"# access the last element, negative indexes count from the end\n",
"print(f\"a[-1] = {a[-1]}\")\n",
"\n",
"#indexs must be within the range of the vector or they will produce and error\n",
"try:\n",
" c = a[10]\n",
"except Exception as e:\n",
" print(\"The error message you'll see is:\")\n",
" print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.2\"></a>\n",
"### 3.4.2 Slicing\n",
"Slicing creates an array of indices using a set of three values (`start:stop:step`). A subset of values is also valid. Its use is best explained by example:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a = [0 1 2 3 4 5 6 7 8 9]\n",
"a[2:7:1] = [2 3 4 5 6]\n",
"a[2:7:2] = [2 4 6]\n",
"a[3:] = [3 4 5 6 7 8 9]\n",
"a[:3] = [0 1 2]\n",
"a[:] = [0 1 2 3 4 5 6 7 8 9]\n"
]
}
],
"source": [
"#vector slicing operations\n",
"a = np.arange(10)\n",
"print(f\"a = {a}\")\n",
"\n",
"#access 5 consecutive elements (start:stop:step)\n",
"c = a[2:7:1]; print(\"a[2:7:1] = \", c)\n",
"\n",
"# access 3 elements separated by two \n",
"c = a[2:7:2]; print(\"a[2:7:2] = \", c)\n",
"\n",
"# access all elements index 3 and above\n",
"c = a[3:]; print(\"a[3:] = \", c)\n",
"\n",
"# access all elements below index 3\n",
"c = a[:3]; print(\"a[:3] = \", c)\n",
"\n",
"# access all elements\n",
"c = a[:]; print(\"a[:] = \", c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.3\"></a>\n",
"### 3.4.3 Single vector operations\n",
"There are a number of useful operations that involve operations on a single vector."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a : [1 2 3 4]\n",
"b = -a : [-1 -2 -3 -4]\n",
"b = np.sum(a) : 10\n",
"b = np.mean(a): 2.5\n",
"b = a**2 : [ 1 4 9 16]\n"
]
}
],
"source": [
"a = np.array([1,2,3,4])\n",
"print(f\"a : {a}\")\n",
"# negate elements of a\n",
"b = -a \n",
"print(f\"b = -a : {b}\")\n",
"\n",
"# sum all elements of a, returns a scalar\n",
"b = np.sum(a) \n",
"print(f\"b = np.sum(a) : {b}\")\n",
"\n",
"b = np.mean(a)\n",
"print(f\"b = np.mean(a): {b}\")\n",
"\n",
"b = a**2\n",
"print(f\"b = a**2 : {b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.4\"></a>\n",
"### 3.4.4 Vector Vector element-wise operations\n",
"Most of the NumPy arithmetic, logical and comparison operations apply to vectors as well. These operators work on an element-by-element basis. For example \n",
"$$ c_i = a_i + b_i $$"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Binary operators work element wise: [0 0 6 8]\n"
]
}
],
"source": [
"a = np.array([ 1, 2, 3, 4])\n",
"b = np.array([-1,-2, 3, 4])\n",
"print(f\"Binary operators work element wise: {a + b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Of course, for this to work correctly, the vectors must be of the same size:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The error message you'll see is:\n",
"operands could not be broadcast together with shapes (4,) (2,) \n"
]
}
],
"source": [
"#try a mismatched vector operation\n",
"c = np.array([1, 2])\n",
"try:\n",
" d = a + c\n",
"except Exception as e:\n",
" print(\"The error message you'll see is:\")\n",
" print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.5\"></a>\n",
"### 3.4.5 Scalar Vector operations\n",
"Vectors can be 'scaled' by scalar values. A scalar value is just a number. The scalar multiplies all the elements of the vector."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"b = 5 * a : [ 5 10 15 20]\n"
]
}
],
"source": [
"a = np.array([1, 2, 3, 4])\n",
"\n",
"# multiply a by a scalar\n",
"b = 5 * a \n",
"print(f\"b = 5 * a : {b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.6\"></a>\n",
"### 3.4.6 Vector Vector dot product\n",
"The dot product is a mainstay of Linear Algebra and NumPy. This is an operation used extensively in this course and should be well understood. The dot product is shown below."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"./images/C1_W2_Lab04_dot_notrans.gif\" width=800> "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The dot product multiplies the values in two vectors element-wise and then sums the result.\n",
"Vector dot product requires the dimensions of the two vectors to be the same. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's implement our own version of the dot product below:\n",
"\n",
"**Using a for loop**, implement a function which returns the dot product of two vectors. The function to return given inputs $a$ and $b$:\n",
"$$ x = \\sum_{i=0}^{n-1} a_i b_i $$\n",
"Assume both `a` and `b` are the same shape."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"def my_dot(a, b): \n",
" \"\"\"\n",
" Compute the dot product of two vectors\n",
" \n",
" Args:\n",
" a (ndarray (n,)): input vector \n",
" b (ndarray (n,)): input vector with same dimension as a\n",
" \n",
" Returns:\n",
" x (scalar): \n",
" \"\"\"\n",
" x=0\n",
" for i in range(a.shape[0]):\n",
" x = x + a[i] * b[i]\n",
" return x"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"my_dot(a, b) = 24\n"
]
}
],
"source": [
"# test 1-D\n",
"a = np.array([1, 2, 3, 4])\n",
"b = np.array([-1, 4, 3, 2])\n",
"print(f\"my_dot(a, b) = {my_dot(a, b)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note, the dot product is expected to return a scalar value. \n",
"\n",
"Let's try the same operations using `np.dot`. "
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"NumPy 1-D np.dot(a, b) = 24, np.dot(a, b).shape = () \n",
"NumPy 1-D np.dot(b, a) = 24, np.dot(a, b).shape = () \n"
]
}
],
"source": [
"# test 1-D\n",
"a = np.array([1, 2, 3, 4])\n",
"b = np.array([-1, 4, 3, 2])\n",
"c = np.dot(a, b)\n",
"print(f\"NumPy 1-D np.dot(a, b) = {c}, np.dot(a, b).shape = {c.shape} \") \n",
"c = np.dot(b, a)\n",
"print(f\"NumPy 1-D np.dot(b, a) = {c}, np.dot(a, b).shape = {c.shape} \")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Above, you will note that the results for 1-D matched our implementation."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.7\"></a>\n",
"### 3.4.7 The Need for Speed: vector vs for loop\n",
"We utilized the NumPy library because it improves speed memory efficiency. Let's demonstrate:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"np.dot(a, b) = 2501072.5817\n",
"Vectorized version duration: 197.7768 ms \n",
"my_dot(a, b) = 2501072.5817\n",
"loop version duration: 8699.8875 ms \n"
]
}
],
"source": [
"np.random.seed(1)\n",
"a = np.random.rand(10000000) # very large arrays\n",
"b = np.random.rand(10000000)\n",
"\n",
"tic = time.time() # capture start time\n",
"c = np.dot(a, b)\n",
"toc = time.time() # capture end time\n",
"\n",
"print(f\"np.dot(a, b) = {c:.4f}\")\n",
"print(f\"Vectorized version duration: {1000*(toc-tic):.4f} ms \")\n",
"\n",
"tic = time.time() # capture start time\n",
"c = my_dot(a,b)\n",
"toc = time.time() # capture end time\n",
"\n",
"print(f\"my_dot(a, b) = {c:.4f}\")\n",
"print(f\"loop version duration: {1000*(toc-tic):.4f} ms \")\n",
"\n",
"del(a);del(b) #remove these big arrays from memory"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So, vectorization provides a large speed up in this example. This is because NumPy makes better use of available data parallelism in the underlying hardware. GPU's and modern CPU's implement Single Instruction, Multiple Data (SIMD) pipelines allowing multiple operations to be issued in parallel. This is critical in Machine Learning where the data sets are often very large."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_12345_3.4.8\"></a>\n",
"### 3.4.8 Vector Vector operations in Course 1\n",
"Vector Vector operations will appear frequently in course 1. Here is why:\n",
"- Going forward, our examples will be stored in an array, `X_train` of dimension (m,n). This will be explained more in context, but here it is important to note it is a 2 Dimensional array or matrix (see next section on matrices).\n",
"- `w` will be a 1-dimensional vector of shape (n,).\n",
"- we will perform operations by looping through the examples, extracting each example to work on individually by indexing X. For example:`X[i]`\n",
"- `X[i]` returns a value of shape (n,), a 1-dimensional vector. Consequently, operations involving `X[i]` are often vector-vector. \n",
"\n",
"That is a somewhat lengthy explanation, but aligning and understanding the shapes of your operands is important when performing vector operations."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"X[1] has shape (1,)\n",
"w has shape (1,)\n",
"c has shape ()\n"
]
}
],
"source": [
"# show common Course 1 example\n",
"X = np.array([[1],[2],[3],[4]])\n",
"w = np.array([2])\n",
"c = np.dot(X[1], w)\n",
"\n",
"print(f\"X[1] has shape {X[1].shape}\")\n",
"print(f\"w has shape {w.shape}\")\n",
"print(f\"c has shape {c.shape}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4\"></a>\n",
"# 4 Matrices\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.1\"></a>\n",
"## 4.1 Abstract\n",
"Matrices, are two dimensional arrays. The elements of a matrix are all of the same type. In notation, matrices are denoted with capitol, bold letter such as $\\mathbf{X}$. In this and other labs, `m` is often the number of rows and `n` the number of columns. The elements of a matrix can be referenced with a two dimensional index. In math settings, numbers in the index typically run from 1 to n. In computer science and these labs, indexing will run from 0 to n-1. \n",
"<figure>\n",
" <center> <img src=\"./images/C1_W2_Lab04_Matrices.PNG\" alt='missing' width=900><center/>\n",
" <figcaption> Generic Matrix Notation, 1st index is row, 2nd is column </figcaption>\n",
"<figure/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.2\"></a>\n",
"## 4.2 NumPy Arrays\n",
"\n",
"NumPy's basic data structure is an indexable, n-dimensional *array* containing elements of the same type (`dtype`). These were described earlier. Matrices have a two-dimensional (2-D) index [m,n].\n",
"\n",
"In Course 1, 2-D matrices are used to hold training data. Training data is $m$ examples by $n$ features creating an (m,n) array. Course 1 does not do operations directly on matrices but typically extracts an example as a vector and operates on that. Below you will review: \n",
"- data creation\n",
"- slicing and indexing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.3\"></a>\n",
"## 4.3 Matrix Creation\n",
"The same functions that created 1-D vectors will create 2-D or n-D arrays. Here are some examples\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Below, the shape tuple is provided to achieve a 2-D result. Notice how NumPy uses brackets to denote each dimension. Notice further than NumPy, when printing, will print one row per line.\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a shape = (1, 5), a = [[0. 0. 0. 0. 0.]]\n",
"a shape = (2, 1), a = [[0.]\n",
" [0.]]\n",
"a shape = (1, 1), a = [[0.44236513]]\n"
]
}
],
"source": [
"a = np.zeros((1, 5)) \n",
"print(f\"a shape = {a.shape}, a = {a}\") \n",
"\n",
"a = np.zeros((2, 1)) \n",
"print(f\"a shape = {a.shape}, a = {a}\") \n",
"\n",
"a = np.random.random_sample((1, 1)) \n",
"print(f\"a shape = {a.shape}, a = {a}\") "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One can also manually specify data. Dimensions are specified with additional brackets matching the format in the printing above."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" a shape = (3, 1), np.array: a = [[5]\n",
" [4]\n",
" [3]]\n",
" a shape = (3, 1), np.array: a = [[5]\n",
" [4]\n",
" [3]]\n"
]
}
],
"source": [
"# NumPy routines which allocate memory and fill with user specified values\n",
"a = np.array([[5], [4], [3]]); print(f\" a shape = {a.shape}, np.array: a = {a}\")\n",
"a = np.array([[5], # One can also\n",
" [4], # separate values\n",
" [3]]); #into separate rows\n",
"print(f\" a shape = {a.shape}, np.array: a = {a}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.4\"></a>\n",
"## 4.4 Operations on Matrices\n",
"Let's explore some operations using matrices."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.4.1\"></a>\n",
"### 4.4.1 Indexing\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Matrices include a second index. The two indexes describe [row, column]. Access can either return an element or a row/column. See below:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a.shape: (3, 2), \n",
"a= [[0 1]\n",
" [2 3]\n",
" [4 5]]\n",
"\n",
"a[2,0].shape: (), a[2,0] = 4, type(a[2,0]) = <class 'numpy.int64'> Accessing an element returns a scalar\n",
"\n",
"a[2].shape: (2,), a[2] = [4 5], type(a[2]) = <class 'numpy.ndarray'>\n"
]
}
],
"source": [
"#vector indexing operations on matrices\n",
"a = np.arange(6).reshape(-1, 2) #reshape is a convenient way to create matrices\n",
"print(f\"a.shape: {a.shape}, \\na= {a}\")\n",
"\n",
"#access an element\n",
"print(f\"\\na[2,0].shape: {a[2, 0].shape}, a[2,0] = {a[2, 0]}, type(a[2,0]) = {type(a[2, 0])} Accessing an element returns a scalar\\n\")\n",
"\n",
"#access a row\n",
"print(f\"a[2].shape: {a[2].shape}, a[2] = {a[2]}, type(a[2]) = {type(a[2])}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is worth drawing attention to the last example. Accessing a matrix by just specifying the row will return a *1-D vector*."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Reshape** \n",
"The previous example used [reshape](https://numpy.org/doc/stable/reference/generated/numpy.reshape.html) to shape the array. \n",
"`a = np.arange(6).reshape(-1, 2) ` \n",
"This line of code first created a *1-D Vector* of six elements. It then reshaped that vector into a *2-D* array using the reshape command. This could have been written: \n",
"`a = np.arange(6).reshape(3, 2) ` \n",
"To arrive at the same 3 row, 2 column array.\n",
"The -1 argument tells the routine to compute the number of rows given the size of the array and the number of columns.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.4.2\"></a>\n",
"### 4.4.2 Slicing\n",
"Slicing creates an array of indices using a set of three values (`start:stop:step`). A subset of values is also valid. Its use is best explained by example:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a = \n",
"[[ 0 1 2 3 4 5 6 7 8 9]\n",
" [10 11 12 13 14 15 16 17 18 19]]\n",
"a[0, 2:7:1] = [2 3 4 5 6] , a[0, 2:7:1].shape = (5,) a 1-D array\n",
"a[:, 2:7:1] = \n",
" [[ 2 3 4 5 6]\n",
" [12 13 14 15 16]] , a[:, 2:7:1].shape = (2, 5) a 2-D array\n",
"a[:,:] = \n",
" [[ 0 1 2 3 4 5 6 7 8 9]\n",
" [10 11 12 13 14 15 16 17 18 19]] , a[:,:].shape = (2, 10)\n",
"a[1,:] = [10 11 12 13 14 15 16 17 18 19] , a[1,:].shape = (10,) a 1-D array\n",
"a[1] = [10 11 12 13 14 15 16 17 18 19] , a[1].shape = (10,) a 1-D array\n"
]
}
],
"source": [
"#vector 2-D slicing operations\n",
"a = np.arange(20).reshape(-1, 10)\n",
"print(f\"a = \\n{a}\")\n",
"\n",
"#access 5 consecutive elements (start:stop:step)\n",
"print(\"a[0, 2:7:1] = \", a[0, 2:7:1], \", a[0, 2:7:1].shape =\", a[0, 2:7:1].shape, \"a 1-D array\")\n",
"\n",
"#access 5 consecutive elements (start:stop:step) in two rows\n",
"print(\"a[:, 2:7:1] = \\n\", a[:, 2:7:1], \", a[:, 2:7:1].shape =\", a[:, 2:7:1].shape, \"a 2-D array\")\n",
"\n",
"# access all elements\n",
"print(\"a[:,:] = \\n\", a[:,:], \", a[:,:].shape =\", a[:,:].shape)\n",
"\n",
"# access all elements in one row (very common usage)\n",
"print(\"a[1,:] = \", a[1,:], \", a[1,:].shape =\", a[1,:].shape, \"a 1-D array\")\n",
"# same as\n",
"print(\"a[1] = \", a[1], \", a[1].shape =\", a[1].shape, \"a 1-D array\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_5.0\"></a>\n",
"## Congratulations!\n",
"In this lab you mastered the features of Python and NumPy that are needed for Course 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"dl_toc_settings": {
"rndtag": "40015"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
},
"toc-autonumbering": false
},
"nbformat": 4,
"nbformat_minor": 4
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,241 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Linear Regression using Scikit-Learn"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There is an open-source, commercially usable machine learning toolkit called [scikit-learn](https://scikit-learn.org/stable/index.html). This toolkit contains implementations of many of the algorithms that you will work with in this course.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goals\n",
"In this lab you will:\n",
"- Utilize scikit-learn to implement linear regression using a close form solution based on the normal equation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tools\n",
"You will utilize functions from scikit-learn as well as matplotlib and NumPy. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from sklearn.linear_model import LinearRegression\n",
"from lab_utils_multi import load_house_data\n",
"plt.style.use('./deeplearning.mplstyle')\n",
"np.set_printoptions(precision=2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40291_2\"></a>\n",
"# Linear Regression, closed-form solution\n",
"Scikit-learn has the [linear regression model](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression) which implements a closed-form linear regression.\n",
"\n",
"Let's use the data from the early labs - a house with 1000 square feet sold for \\\\$300,000 and a house with 2000 square feet sold for \\\\$500,000.\n",
"\n",
"| Size (1000 sqft) | Price (1000s of dollars) |\n",
"| ----------------| ------------------------ |\n",
"| 1 | 300 |\n",
"| 2 | 500 |\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Load the data set"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"X_train = np.array([1.0, 2.0]) #features\n",
"y_train = np.array([300, 500]) #target value"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create and fit the model\n",
"The code below performs regression using scikit-learn. \n",
"The first step creates a regression object. \n",
"The second step utilizes one of the methods associated with the object, `fit`. This performs regression, fitting the parameters to the input data. The toolkit expects a two-dimensional X matrix."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"linear_model = LinearRegression()\n",
"#X must be a 2-D Matrix\n",
"linear_model.fit(X_train.reshape(-1, 1), y_train) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### View Parameters \n",
"The $\\mathbf{w}$ and $\\mathbf{b}$ parameters are referred to as 'coefficients' and 'intercept' in scikit-learn."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b = linear_model.intercept_\n",
"w = linear_model.coef_\n",
"print(f\"w = {w:}, b = {b:0.2f}\")\n",
"print(f\"'manual' prediction: f_wb = wx+b : {1200*w + b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Make Predictions\n",
"\n",
"Calling the `predict` function generates predictions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y_pred = linear_model.predict(X_train.reshape(-1, 1))\n",
"\n",
"print(\"Prediction on training set:\", y_pred)\n",
"\n",
"X_test = np.array([[1200]])\n",
"print(f\"Prediction for 1200 sqft house: ${linear_model.predict(X_test)[0]:0.2f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Second Example\n",
"The second example is from an earlier lab with multiple features. The final parameter values and predictions are very close to the results from the un-normalized 'long-run' from that lab. That un-normalized run took hours to produce results, while this is nearly instantaneous. The closed-form solution work well on smaller data sets such as these but can be computationally demanding on larger data sets. \n",
">The closed-form solution does not require normalization."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# load the dataset\n",
"X_train, y_train = load_house_data()\n",
"X_features = ['size(sqft)','bedrooms','floors','age']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"linear_model = LinearRegression()\n",
"linear_model.fit(X_train, y_train) "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b = linear_model.intercept_\n",
"w = linear_model.coef_\n",
"print(f\"w = {w:}, b = {b:0.2f}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(f\"Prediction on training set:\\n {linear_model.predict(X_train)[:4]}\" )\n",
"print(f\"prediction using w,b:\\n {(X_train @ w + b)[:4]}\")\n",
"print(f\"Target values \\n {y_train[:4]}\")\n",
"\n",
"x_house = np.array([1200, 3,1, 40]).reshape(-1,4)\n",
"x_house_predict = linear_model.predict(x_house)[0]\n",
"print(f\" predicted price of a house with 1200 sqft, 3 bedrooms, 1 floor, 40 years old = ${x_house_predict*1000:0.2f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Congratulations!\n",
"In this lab you:\n",
"- utilized an open-source machine learning toolkit, scikit-learn\n",
"- implemented linear regression using a close-form solution from that toolkit"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,730 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optional Lab: Python, NumPy and Vectorization\n",
"A brief introduction to some of the scientific computing used in this course. In particular the NumPy scientific computing package and its use with python.\n",
"\n",
"# Outline\n",
"- [&nbsp;&nbsp;1.1 Goals](#toc_40015_1.1)\n",
"- [&nbsp;&nbsp;1.2 Useful References](#toc_40015_1.2)\n",
"- [2 Python and NumPy <a name='Python and NumPy'></a>](#toc_40015_2)\n",
"- [3 Vectors](#toc_40015_3)\n",
"- [&nbsp;&nbsp;3.1 Abstract](#toc_40015_3.1)\n",
"- [&nbsp;&nbsp;3.2 NumPy Arrays](#toc_40015_3.2)\n",
"- [&nbsp;&nbsp;3.3 Vector Creation](#toc_40015_3.3)\n",
"- [&nbsp;&nbsp;3.4 Operations on Vectors](#toc_40015_3.4)\n",
"- [4 Matrices](#toc_40015_4)\n",
"- [&nbsp;&nbsp;4.1 Abstract](#toc_40015_4.1)\n",
"- [&nbsp;&nbsp;4.2 NumPy Arrays](#toc_40015_4.2)\n",
"- [&nbsp;&nbsp;4.3 Matrix Creation](#toc_40015_4.3)\n",
"- [&nbsp;&nbsp;4.4 Operations on Matrices](#toc_40015_4.4)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np # it is an unofficial standard to use np for numpy\n",
"import time"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_1.1\"></a>\n",
"## 1.1 Goals\n",
"In this lab, you will:\n",
"- Review the features of NumPy and Python that are used in Course 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_1.2\"></a>\n",
"## 1.2 Useful References\n",
"- NumPy Documentation including a basic introduction: [NumPy.org](https://NumPy.org/doc/stable/)\n",
"- A challenging feature topic: [NumPy Broadcasting](https://NumPy.org/doc/stable/user/basics.broadcasting.html)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_2\"></a>\n",
"# 2 Python and NumPy <a name='Python and NumPy'></a>\n",
"Python is the programming language we will be using in this course. It has a set of numeric data types and arithmetic operations. NumPy is a library that extends the base capabilities of python to add a richer data set including more numeric types, vectors, matrices, and many matrix functions. NumPy and python work together fairly seamlessly. Python arithmetic operators work on NumPy data types and many NumPy functions will accept python data types.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3\"></a>\n",
"# 3 Vectors\n",
"<a name=\"toc_40015_3.1\"></a>\n",
"## 3.1 Abstract\n",
"<img align=\"right\" src=\"./images/C1_W2_Lab04_Vectors.PNG\" style=\"width:340px;\" >Vectors, as you will use them in this course, are ordered arrays of numbers. In notation, vectors are denoted with lower case bold letters such as $\\mathbf{x}$. The elements of a vector are all the same type. A vector does not, for example, contain both characters and numbers. The number of elements in the array is often referred to as the *dimension* though mathematicians may prefer *rank*. The vector shown has a dimension of $n$. The elements of a vector can be referenced with an index. In math settings, indexes typically run from 1 to n. In computer science and these labs, indexing will typically run from 0 to n-1. In notation, elements of a vector, when referenced individually will indicate the index in a subscript, for example, the $0^{th}$ element, of the vector $\\mathbf{x}$ is $x_0$. Note, the x is not bold in this case. \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.2\"></a>\n",
"## 3.2 NumPy Arrays\n",
"\n",
"NumPy's basic data structure is an indexable, n-dimensional *array* containing elements of the same type (`dtype`). Right away, you may notice we have overloaded the term 'dimension'. Above, it was the number of elements in the vector, here, dimension refers to the number of indexes of an array. A one-dimensional or 1-D array has one index. In Course 1, we will represent vectors as NumPy 1-D arrays. \n",
"\n",
" - 1-D array, shape (n,): n elements indexed [0] through [n-1]\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.3\"></a>\n",
"## 3.3 Vector Creation\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Data creation routines in NumPy will generally have a first parameter which is the shape of the object. This can either be a single value for a 1-D result or a tuple (n,m,...) specifying the shape of the result. Below are examples of creating vectors using these routines."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# NumPy routines which allocate memory and fill arrays with value\n",
"a = np.zeros(4); print(f\"np.zeros(4) : a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.zeros((4,)); print(f\"np.zeros(4,) : a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.random.random_sample(4); print(f\"np.random.random_sample(4): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some data creation routines do not take a shape tuple:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# NumPy routines which allocate memory and fill arrays with value but do not accept shape as input argument\n",
"a = np.arange(4.); print(f\"np.arange(4.): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.random.rand(4); print(f\"np.random.rand(4): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"values can be specified manually as well. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# NumPy routines which allocate memory and fill with user specified values\n",
"a = np.array([5,4,3,2]); print(f\"np.array([5,4,3,2]): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")\n",
"a = np.array([5.,4,3,2]); print(f\"np.array([5.,4,3,2]): a = {a}, a shape = {a.shape}, a data type = {a.dtype}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These have all created a one-dimensional vector `a` with four elements. `a.shape` returns the dimensions. Here we see a.shape = `(4,)` indicating a 1-d array with 4 elements. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4\"></a>\n",
"## 3.4 Operations on Vectors\n",
"Let's explore some operations using vectors.\n",
"<a name=\"toc_40015_3.4.1\"></a>\n",
"### 3.4.1 Indexing\n",
"Elements of vectors can be accessed via indexing and slicing. NumPy provides a very complete set of indexing and slicing capabilities. We will explore only the basics needed for the course here. Reference [Slicing and Indexing](https://NumPy.org/doc/stable/reference/arrays.indexing.html) for more details. \n",
"**Indexing** means referring to *an element* of an array by its position within the array. \n",
"**Slicing** means getting a *subset* of elements from an array based on their indices. \n",
"NumPy starts indexing at zero so the 3rd element of an vector $\\mathbf{a}$ is `a[2]`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#vector indexing operations on 1-D vectors\n",
"a = np.arange(10)\n",
"print(a)\n",
"\n",
"#access an element\n",
"print(f\"a[2].shape: {a[2].shape} a[2] = {a[2]}, Accessing an element returns a scalar\")\n",
"\n",
"# access the last element, negative indexes count from the end\n",
"print(f\"a[-1] = {a[-1]}\")\n",
"\n",
"#indexs must be within the range of the vector or they will produce and error\n",
"try:\n",
" c = a[10]\n",
"except Exception as e:\n",
" print(\"The error message you'll see is:\")\n",
" print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.2\"></a>\n",
"### 3.4.2 Slicing\n",
"Slicing creates an array of indices using a set of three values (`start:stop:step`). A subset of values is also valid. Its use is best explained by example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#vector slicing operations\n",
"a = np.arange(10)\n",
"print(f\"a = {a}\")\n",
"\n",
"#access 5 consecutive elements (start:stop:step)\n",
"c = a[2:7:1]; print(\"a[2:7:1] = \", c)\n",
"\n",
"# access 3 elements separated by two \n",
"c = a[2:7:2]; print(\"a[2:7:2] = \", c)\n",
"\n",
"# access all elements index 3 and above\n",
"c = a[3:]; print(\"a[3:] = \", c)\n",
"\n",
"# access all elements below index 3\n",
"c = a[:3]; print(\"a[:3] = \", c)\n",
"\n",
"# access all elements\n",
"c = a[:]; print(\"a[:] = \", c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.3\"></a>\n",
"### 3.4.3 Single vector operations\n",
"There are a number of useful operations that involve operations on a single vector."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3,4])\n",
"print(f\"a : {a}\")\n",
"# negate elements of a\n",
"b = -a \n",
"print(f\"b = -a : {b}\")\n",
"\n",
"# sum all elements of a, returns a scalar\n",
"b = np.sum(a) \n",
"print(f\"b = np.sum(a) : {b}\")\n",
"\n",
"b = np.mean(a)\n",
"print(f\"b = np.mean(a): {b}\")\n",
"\n",
"b = a**2\n",
"print(f\"b = a**2 : {b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.4\"></a>\n",
"### 3.4.4 Vector Vector element-wise operations\n",
"Most of the NumPy arithmetic, logical and comparison operations apply to vectors as well. These operators work on an element-by-element basis. For example \n",
"$$ \\mathbf{a} + \\mathbf{b} = \\sum_{i=0}^{n-1} a_i + b_i $$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([ 1, 2, 3, 4])\n",
"b = np.array([-1,-2, 3, 4])\n",
"print(f\"Binary operators work element wise: {a + b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Of course, for this to work correctly, the vectors must be of the same size:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#try a mismatched vector operation\n",
"c = np.array([1, 2])\n",
"try:\n",
" d = a + c\n",
"except Exception as e:\n",
" print(\"The error message you'll see is:\")\n",
" print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.5\"></a>\n",
"### 3.4.5 Scalar Vector operations\n",
"Vectors can be 'scaled' by scalar values. A scalar value is just a number. The scalar multiplies all the elements of the vector."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1, 2, 3, 4])\n",
"\n",
"# multiply a by a scalar\n",
"b = 5 * a \n",
"print(f\"b = 5 * a : {b}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.6\"></a>\n",
"### 3.4.6 Vector Vector dot product\n",
"The dot product is a mainstay of Linear Algebra and NumPy. This is an operation used extensively in this course and should be well understood. The dot product is shown below."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"./images/C1_W2_Lab04_dot_notrans.gif\" width=800> "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The dot product multiplies the values in two vectors element-wise and then sums the result.\n",
"Vector dot product requires the dimensions of the two vectors to be the same. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's implement our own version of the dot product below:\n",
"\n",
"**Using a for loop**, implement a function which returns the dot product of two vectors. The function to return given inputs $a$ and $b$:\n",
"$$ x = \\sum_{i=0}^{n-1} a_i b_i $$\n",
"Assume both `a` and `b` are the same shape."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def my_dot(a, b): \n",
" \"\"\"\n",
" Compute the dot product of two vectors\n",
" \n",
" Args:\n",
" a (ndarray (n,)): input vector \n",
" b (ndarray (n,)): input vector with same dimension as a\n",
" \n",
" Returns:\n",
" x (scalar): \n",
" \"\"\"\n",
" x=0\n",
" for i in range(a.shape[0]):\n",
" x = x + a[i] * b[i]\n",
" return x"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# test 1-D\n",
"a = np.array([1, 2, 3, 4])\n",
"b = np.array([-1, 4, 3, 2])\n",
"print(f\"my_dot(a, b) = {my_dot(a, b)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note, the dot product is expected to return a scalar value. \n",
"\n",
"Let's try the same operations using `np.dot`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# test 1-D\n",
"a = np.array([1, 2, 3, 4])\n",
"b = np.array([-1, 4, 3, 2])\n",
"c = np.dot(a, b)\n",
"print(f\"NumPy 1-D np.dot(a, b) = {c}, np.dot(a, b).shape = {c.shape} \") \n",
"c = np.dot(b, a)\n",
"print(f\"NumPy 1-D np.dot(b, a) = {c}, np.dot(a, b).shape = {c.shape} \")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Above, you will note that the results for 1-D matched our implementation."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_3.4.7\"></a>\n",
"### 3.4.7 The Need for Speed: vector vs for loop\n",
"We utilized the NumPy library because it improves speed memory efficiency. Let's demonstrate:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.random.seed(1)\n",
"a = np.random.rand(10000000) # very large arrays\n",
"b = np.random.rand(10000000)\n",
"\n",
"tic = time.time() # capture start time\n",
"c = np.dot(a, b)\n",
"toc = time.time() # capture end time\n",
"\n",
"print(f\"np.dot(a, b) = {c:.4f}\")\n",
"print(f\"Vectorized version duration: {1000*(toc-tic):.4f} ms \")\n",
"\n",
"tic = time.time() # capture start time\n",
"c = my_dot(a,b)\n",
"toc = time.time() # capture end time\n",
"\n",
"print(f\"my_dot(a, b) = {c:.4f}\")\n",
"print(f\"loop version duration: {1000*(toc-tic):.4f} ms \")\n",
"\n",
"del(a);del(b) #remove these big arrays from memory"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So, vectorization provides a large speed up in this example. This is because NumPy makes better use of available data parallelism in the underlying hardware. GPU's and modern CPU's implement Single Instruction, Multiple Data (SIMD) pipelines allowing multiple operations to be issued in parallel. This is critical in Machine Learning where the data sets are often very large."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_12345_3.4.8\"></a>\n",
"### 3.4.8 Vector Vector operations in Course 1\n",
"Vector Vector operations will appear frequently in course 1. Here is why:\n",
"- Going forward, our examples will be stored in an array, `X_train` of dimension (m,n). This will be explained more in context, but here it is important to note it is a 2 Dimensional array or matrix (see next section on matrices).\n",
"- `w` will be a 1-dimensional vector of shape (n,).\n",
"- we will perform operations by looping through the examples, extracting each example to work on individually by indexing X. For example:`X[i]`\n",
"- `X[i]` returns a value of shape (n,), a 1-dimensional vector. Consequently, operations involving `X[i]` are often vector-vector. \n",
"\n",
"That is a somewhat lengthy explanation, but aligning and understanding the shapes of your operands is important when performing vector operations."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# show common Course 1 example\n",
"X = np.array([[1],[2],[3],[4]])\n",
"w = np.array([2])\n",
"c = np.dot(X[1], w)\n",
"\n",
"print(f\"X[1] has shape {X[1].shape}\")\n",
"print(f\"w has shape {w.shape}\")\n",
"print(f\"c has shape {c.shape}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4\"></a>\n",
"# 4 Matrices\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.1\"></a>\n",
"## 4.1 Abstract\n",
"Matrices, are two dimensional arrays. The elements of a matrix are all of the same type. In notation, matrices are denoted with capitol, bold letter such as $\\mathbf{X}$. In this and other labs, `m` is often the number of rows and `n` the number of columns. The elements of a matrix can be referenced with a two dimensional index. In math settings, numbers in the index typically run from 1 to n. In computer science and these labs, indexing will run from 0 to n-1. \n",
"<figure>\n",
" <center> <img src=\"./images/C1_W2_Lab04_Matrices.PNG\" alt='missing' width=900><center/>\n",
" <figcaption> Generic Matrix Notation, 1st index is row, 2nd is column </figcaption>\n",
"<figure/>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.2\"></a>\n",
"## 4.2 NumPy Arrays\n",
"\n",
"NumPy's basic data structure is an indexable, n-dimensional *array* containing elements of the same type (`dtype`). These were described earlier. Matrices have a two-dimensional (2-D) index [m,n].\n",
"\n",
"In Course 1, 2-D matrices are used to hold training data. Training data is $m$ examples by $n$ features creating an (m,n) array. Course 1 does not do operations directly on matrices but typically extracts an example as a vector and operates on that. Below you will review: \n",
"- data creation\n",
"- slicing and indexing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.3\"></a>\n",
"## 4.3 Matrix Creation\n",
"The same functions that created 1-D vectors will create 2-D or n-D arrays. Here are some examples\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Below, the shape tuple is provided to achieve a 2-D result. Notice how NumPy uses brackets to denote each dimension. Notice further than NumPy, when printing, will print one row per line.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.zeros((1, 5)) \n",
"print(f\"a shape = {a.shape}, a = {a}\") \n",
"\n",
"a = np.zeros((2, 1)) \n",
"print(f\"a shape = {a.shape}, a = {a}\") \n",
"\n",
"a = np.random.random_sample((1, 1)) \n",
"print(f\"a shape = {a.shape}, a = {a}\") "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One can also manually specify data. Dimensions are specified with additional brackets matching the format in the printing above."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# NumPy routines which allocate memory and fill with user specified values\n",
"a = np.array([[5], [4], [3]]); print(f\" a shape = {a.shape}, np.array: a = {a}\")\n",
"a = np.array([[5], # One can also\n",
" [4], # separate values\n",
" [3]]); #into separate rows\n",
"print(f\" a shape = {a.shape}, np.array: a = {a}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.4\"></a>\n",
"## 4.4 Operations on Matrices\n",
"Let's explore some operations using matrices."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.4.1\"></a>\n",
"### 4.4.1 Indexing\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Matrices include a second index. The two indexes describe [row, column]. Access can either return an element or a row/column. See below:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#vector indexing operations on matrices\n",
"a = np.arange(6).reshape(-1, 2) #reshape is a convenient way to create matrices\n",
"print(f\"a.shape: {a.shape}, \\na= {a}\")\n",
"\n",
"#access an element\n",
"print(f\"\\na[2,0].shape: {a[2, 0].shape}, a[2,0] = {a[2, 0]}, type(a[2,0]) = {type(a[2, 0])} Accessing an element returns a scalar\\n\")\n",
"\n",
"#access a row\n",
"print(f\"a[2].shape: {a[2].shape}, a[2] = {a[2]}, type(a[2]) = {type(a[2])}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is worth drawing attention to the last example. Accessing a matrix by just specifying the row will return a *1-D vector*."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Reshape** \n",
"The previous example used [reshape](https://numpy.org/doc/stable/reference/generated/numpy.reshape.html) to shape the array. \n",
"`a = np.arange(6).reshape(-1, 2) ` \n",
"This line of code first created a *1-D Vector* of six elements. It then reshaped that vector into a *2-D* array using the reshape command. This could have been written: \n",
"`a = np.arange(6).reshape(3, 2) ` \n",
"To arrive at the same 3 row, 2 column array.\n",
"The -1 argument tells the routine to compute the number of rows given the size of the array and the number of columns.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_4.4.2\"></a>\n",
"### 4.4.2 Slicing\n",
"Slicing creates an array of indices using a set of three values (`start:stop:step`). A subset of values is also valid. Its use is best explained by example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#vector 2-D slicing operations\n",
"a = np.arange(20).reshape(-1, 10)\n",
"print(f\"a = \\n{a}\")\n",
"\n",
"#access 5 consecutive elements (start:stop:step)\n",
"print(\"a[0, 2:7:1] = \", a[0, 2:7:1], \", a[0, 2:7:1].shape =\", a[0, 2:7:1].shape, \"a 1-D array\")\n",
"\n",
"#access 5 consecutive elements (start:stop:step) in two rows\n",
"print(\"a[:, 2:7:1] = \\n\", a[:, 2:7:1], \", a[:, 2:7:1].shape =\", a[:, 2:7:1].shape, \"a 2-D array\")\n",
"\n",
"# access all elements\n",
"print(\"a[:,:] = \\n\", a[:,:], \", a[:,:].shape =\", a[:,:].shape)\n",
"\n",
"# access all elements in one row (very common usage)\n",
"print(\"a[1,:] = \", a[1,:], \", a[1,:].shape =\", a[1,:].shape, \"a 1-D array\")\n",
"# same as\n",
"print(\"a[1] = \", a[1], \", a[1].shape =\", a[1].shape, \"a 1-D array\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"toc_40015_5.0\"></a>\n",
"## Congratulations!\n",
"In this lab you mastered the features of Python and NumPy that are needed for Course 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"dl_toc_settings": {
"rndtag": "40015"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.10"
},
"toc-autonumbering": false
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,100 +0,0 @@
9.520000000000000000e+02,2.000000000000000000e+00,1.000000000000000000e+00,6.500000000000000000e+01,2.715000000000000000e+02
1.244000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,6.400000000000000000e+01,3.000000000000000000e+02
1.947000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.700000000000000000e+01,5.098000000000000114e+02
1.725000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,4.200000000000000000e+01,3.940000000000000000e+02
1.959000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.500000000000000000e+01,5.400000000000000000e+02
1.314000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.400000000000000000e+01,4.150000000000000000e+02
8.640000000000000000e+02,2.000000000000000000e+00,1.000000000000000000e+00,6.600000000000000000e+01,2.300000000000000000e+02
1.836000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.700000000000000000e+01,5.600000000000000000e+02
1.026000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,4.300000000000000000e+01,2.940000000000000000e+02
3.194000000000000000e+03,4.000000000000000000e+00,2.000000000000000000e+00,8.700000000000000000e+01,7.182000000000000455e+02
7.880000000000000000e+02,2.000000000000000000e+00,1.000000000000000000e+00,8.000000000000000000e+01,2.000000000000000000e+02
1.200000000000000000e+03,2.000000000000000000e+00,2.000000000000000000e+00,1.700000000000000000e+01,3.020000000000000000e+02
1.557000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.800000000000000000e+01,4.680000000000000000e+02
1.430000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,2.000000000000000000e+01,3.741999999999999886e+02
1.220000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.500000000000000000e+01,3.880000000000000000e+02
1.092000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,6.400000000000000000e+01,2.820000000000000000e+02
8.480000000000000000e+02,1.000000000000000000e+00,1.000000000000000000e+00,1.700000000000000000e+01,3.118000000000000114e+02
1.682000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.300000000000000000e+01,4.010000000000000000e+02
1.768000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.800000000000000000e+01,4.498000000000000114e+02
1.040000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,4.400000000000000000e+01,3.010000000000000000e+02
1.652000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,2.100000000000000000e+01,5.020000000000000000e+02
1.088000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,3.500000000000000000e+01,3.400000000000000000e+02
1.316000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.400000000000000000e+01,4.002819999999999823e+02
1.593000000000000000e+03,0.000000000000000000e+00,1.000000000000000000e+00,2.000000000000000000e+01,5.720000000000000000e+02
9.720000000000000000e+02,2.000000000000000000e+00,1.000000000000000000e+00,7.300000000000000000e+01,2.640000000000000000e+02
1.097000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,3.700000000000000000e+01,3.040000000000000000e+02
1.004000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,5.100000000000000000e+01,2.980000000000000000e+02
9.040000000000000000e+02,3.000000000000000000e+00,1.000000000000000000e+00,5.500000000000000000e+01,2.198000000000000114e+02
1.694000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.300000000000000000e+01,4.906999999999999886e+02
1.073000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.000000000000000000e+02,2.169600000000000080e+02
1.419000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.900000000000000000e+01,3.681999999999999886e+02
1.164000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,5.200000000000000000e+01,2.800000000000000000e+02
1.935000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.200000000000000000e+01,5.268700000000000045e+02
1.216000000000000000e+03,2.000000000000000000e+00,2.000000000000000000e+00,7.400000000000000000e+01,2.370000000000000000e+02
2.482000000000000000e+03,4.000000000000000000e+00,2.000000000000000000e+00,1.600000000000000000e+01,5.624260000000000446e+02
1.200000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.800000000000000000e+01,3.698000000000000114e+02
1.840000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.000000000000000000e+01,4.600000000000000000e+02
1.851000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,5.700000000000000000e+01,3.740000000000000000e+02
1.660000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.900000000000000000e+01,3.900000000000000000e+02
1.096000000000000000e+03,2.000000000000000000e+00,2.000000000000000000e+00,9.700000000000000000e+01,1.580000000000000000e+02
1.775000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.800000000000000000e+01,4.260000000000000000e+02
2.030000000000000000e+03,4.000000000000000000e+00,2.000000000000000000e+00,4.500000000000000000e+01,3.900000000000000000e+02
1.784000000000000000e+03,4.000000000000000000e+00,2.000000000000000000e+00,1.070000000000000000e+02,2.777740000000000009e+02
1.073000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.000000000000000000e+02,2.169600000000000080e+02
1.552000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.600000000000000000e+01,4.258000000000000114e+02
1.953000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.600000000000000000e+01,5.040000000000000000e+02
1.224000000000000000e+03,2.000000000000000000e+00,2.000000000000000000e+00,1.200000000000000000e+01,3.290000000000000000e+02
1.616000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.600000000000000000e+01,4.640000000000000000e+02
8.160000000000000000e+02,2.000000000000000000e+00,1.000000000000000000e+00,5.800000000000000000e+01,2.200000000000000000e+02
1.349000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,2.100000000000000000e+01,3.580000000000000000e+02
1.571000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.400000000000000000e+01,4.780000000000000000e+02
1.486000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,5.700000000000000000e+01,3.340000000000000000e+02
1.506000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.600000000000000000e+01,4.269800000000000182e+02
1.097000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,2.700000000000000000e+01,2.900000000000000000e+02
1.764000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.400000000000000000e+01,4.630000000000000000e+02
1.208000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.400000000000000000e+01,3.908000000000000114e+02
1.470000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.400000000000000000e+01,3.540000000000000000e+02
1.768000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,8.400000000000000000e+01,3.500000000000000000e+02
1.654000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.900000000000000000e+01,4.600000000000000000e+02
1.029000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,6.000000000000000000e+01,2.370000000000000000e+02
1.120000000000000000e+03,2.000000000000000000e+00,2.000000000000000000e+00,1.600000000000000000e+01,2.883039999999999736e+02
1.150000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,6.200000000000000000e+01,2.820000000000000000e+02
8.160000000000000000e+02,2.000000000000000000e+00,1.000000000000000000e+00,3.900000000000000000e+01,2.490000000000000000e+02
1.040000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,2.500000000000000000e+01,3.040000000000000000e+02
1.392000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,6.400000000000000000e+01,3.320000000000000000e+02
1.603000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.900000000000000000e+01,3.518000000000000114e+02
1.215000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,6.300000000000000000e+01,3.100000000000000000e+02
1.073000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.000000000000000000e+02,2.169600000000000080e+02
2.599000000000000000e+03,4.000000000000000000e+00,2.000000000000000000e+00,2.200000000000000000e+01,6.663360000000000127e+02
1.431000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,5.900000000000000000e+01,3.300000000000000000e+02
2.090000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.600000000000000000e+01,4.800000000000000000e+02
1.790000000000000000e+03,4.000000000000000000e+00,2.000000000000000000e+00,4.900000000000000000e+01,3.303000000000000114e+02
1.484000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.600000000000000000e+01,3.480000000000000000e+02
1.040000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,2.500000000000000000e+01,3.040000000000000000e+02
1.431000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,2.200000000000000000e+01,3.840000000000000000e+02
1.159000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,5.300000000000000000e+01,3.160000000000000000e+02
1.547000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.200000000000000000e+01,4.303999999999999773e+02
1.983000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.200000000000000000e+01,4.500000000000000000e+02
1.056000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,5.300000000000000000e+01,2.840000000000000000e+02
1.180000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,9.900000000000000000e+01,2.750000000000000000e+02
1.358000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.700000000000000000e+01,4.140000000000000000e+02
9.600000000000000000e+02,3.000000000000000000e+00,1.000000000000000000e+00,5.100000000000000000e+01,2.580000000000000000e+02
1.456000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.600000000000000000e+01,3.780000000000000000e+02
1.446000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.500000000000000000e+01,3.500000000000000000e+02
1.208000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,1.500000000000000000e+01,4.120000000000000000e+02
1.553000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.600000000000000000e+01,3.730000000000000000e+02
8.820000000000000000e+02,3.000000000000000000e+00,1.000000000000000000e+00,4.900000000000000000e+01,2.250000000000000000e+02
2.030000000000000000e+03,4.000000000000000000e+00,2.000000000000000000e+00,4.500000000000000000e+01,3.900000000000000000e+02
1.040000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,6.200000000000000000e+01,2.673999999999999773e+02
1.616000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.600000000000000000e+01,4.640000000000000000e+02
8.030000000000000000e+02,2.000000000000000000e+00,1.000000000000000000e+00,8.000000000000000000e+01,1.740000000000000000e+02
1.430000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,2.100000000000000000e+01,3.400000000000000000e+02
1.656000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,6.100000000000000000e+01,4.300000000000000000e+02
1.541000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,1.600000000000000000e+01,4.400000000000000000e+02
9.480000000000000000e+02,3.000000000000000000e+00,1.000000000000000000e+00,5.300000000000000000e+01,2.160000000000000000e+02
1.224000000000000000e+03,2.000000000000000000e+00,2.000000000000000000e+00,1.200000000000000000e+01,3.290000000000000000e+02
1.432000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,4.300000000000000000e+01,3.880000000000000000e+02
1.660000000000000000e+03,3.000000000000000000e+00,2.000000000000000000e+00,1.900000000000000000e+01,3.900000000000000000e+02
1.212000000000000000e+03,3.000000000000000000e+00,1.000000000000000000e+00,2.000000000000000000e+01,3.560000000000000000e+02
1.050000000000000000e+03,2.000000000000000000e+00,1.000000000000000000e+00,6.500000000000000000e+01,2.578000000000000114e+02

View File

@@ -1,124 +0,0 @@
# see https://matplotlib.org/stable/tutorials/introductory/customizing.html
lines.linewidth: 4
lines.solid_capstyle: butt
legend.fancybox: true
# Verdana" for non-math text,
# Cambria Math
#Blue (Crayon-Aqua) 0096FF
#Dark Red C00000
#Orange (Apple Orange) FF9300
#Black 000000
#Magenta FF40FF
#Purple 7030A0
axes.prop_cycle: cycler('color', ['0096FF', 'FF9300', 'FF40FF', '7030A0', 'C00000'])
#axes.facecolor: f0f0f0 # grey
axes.facecolor: ffffff # white
axes.labelsize: large
axes.axisbelow: true
axes.grid: False
axes.edgecolor: f0f0f0
axes.linewidth: 3.0
axes.titlesize: x-large
patch.edgecolor: f0f0f0
patch.linewidth: 0.5
svg.fonttype: path
grid.linestyle: -
grid.linewidth: 1.0
grid.color: cbcbcb
xtick.major.size: 0
xtick.minor.size: 0
ytick.major.size: 0
ytick.minor.size: 0
savefig.edgecolor: f0f0f0
savefig.facecolor: f0f0f0
#figure.subplot.left: 0.08
#figure.subplot.right: 0.95
#figure.subplot.bottom: 0.07
#figure.facecolor: f0f0f0 # grey
figure.facecolor: ffffff # white
## ***************************************************************************
## * FONT *
## ***************************************************************************
## The font properties used by `text.Text`.
## See https://matplotlib.org/api/font_manager_api.html for more information
## on font properties. The 6 font properties used for font matching are
## given below with their default values.
##
## The font.family property can take either a concrete font name (not supported
## when rendering text with usetex), or one of the following five generic
## values:
## - 'serif' (e.g., Times),
## - 'sans-serif' (e.g., Helvetica),
## - 'cursive' (e.g., Zapf-Chancery),
## - 'fantasy' (e.g., Western), and
## - 'monospace' (e.g., Courier).
## Each of these values has a corresponding default list of font names
## (font.serif, etc.); the first available font in the list is used. Note that
## for font.serif, font.sans-serif, and font.monospace, the first element of
## the list (a DejaVu font) will always be used because DejaVu is shipped with
## Matplotlib and is thus guaranteed to be available; the other entries are
## left as examples of other possible values.
##
## The font.style property has three values: normal (or roman), italic
## or oblique. The oblique style will be used for italic, if it is not
## present.
##
## The font.variant property has two values: normal or small-caps. For
## TrueType fonts, which are scalable fonts, small-caps is equivalent
## to using a font size of 'smaller', or about 83%% of the current font
## size.
##
## The font.weight property has effectively 13 values: normal, bold,
## bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as
## 400, and bold is 700. bolder and lighter are relative values with
## respect to the current weight.
##
## The font.stretch property has 11 values: ultra-condensed,
## extra-condensed, condensed, semi-condensed, normal, semi-expanded,
## expanded, extra-expanded, ultra-expanded, wider, and narrower. This
## property is not currently implemented.
##
## The font.size property is the default font size for text, given in points.
## 10 pt is the standard value.
##
## Note that font.size controls default text sizes. To configure
## special text sizes tick labels, axes, labels, title, etc., see the rc
## settings for axes and ticks. Special text sizes can be defined
## relative to font.size, using the following values: xx-small, x-small,
## small, medium, large, x-large, xx-large, larger, or smaller
font.family: sans-serif
font.style: normal
font.variant: normal
font.weight: normal
font.stretch: normal
font.size: 12.0
font.serif: DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
font.sans-serif: Verdana, DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
font.cursive: Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, Comic Neue, Comic Sans MS, cursive
font.fantasy: Chicago, Charcoal, Impact, Western, Humor Sans, xkcd, fantasy
font.monospace: DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace
## ***************************************************************************
## * TEXT *
## ***************************************************************************
## The text properties used by `text.Text`.
## See https://matplotlib.org/api/artist_api.html#module-matplotlib.text
## for more information on text properties
#text.color: black

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Some files were not shown because too many files have changed in this diff Show More