头文件

1
2
3
4
import matplotlib.pyplot as plt
import numpy as np
import math
import torch

plt 画图(matplotlib.pyplot)

1
2
3
4
5
6
7
8
9
10
plt.figure(figsize=(8, 6))  # 设置绘图窗口大小
plt.plot(x, y, label="函数曲线", color="blue") # 绘制函数曲线,设置标签和颜色
plt.plot(x, tangent_line, '--', label="切线", color="red") # 绘制切线,虚线样式
plt.scatter(i, y0, color="black", label="切点") # 标出切点位置
plt.title("函数及其切线") # 设置图表标题
plt.xlabel("x") # x轴标签
plt.ylabel("y") # y轴标签
plt.legend() # 显示图例
plt.grid(True) # 显示网格
plt.show() # 展示图形

高斯概率密度函数(numpy + math)

$$
f(x) = \frac{1}{\sqrt{2 \pi \sigma^2}} e^{-\frac{(x - \mu)^2}{2 \sigma^2}}
$$
1
2
3
4
5
6
7
def normal(x, mu=0.0, sigma=1.0):
x = np.asarray(x, dtype=np.float64) # 转换后保证为标准的 NumPy 数组
if sigma <= 0:
raise ValueError("sigma must be positive")
coeff = 1.0 / (np.sqrt(2 * np.pi) * sigma) #归一化系数
exponent = -0.5 * ((x - mu) / sigma) ** 2 #指数
return coeff * np.exp(exponent)

线性回归

线性回归手动构造数据集(torch)

噪声是目标变量 y 的随机误差,根据噪声服从正态分布假设,不参与偏置和权重加权求和。

个人看法:看下来噪声就是不知道没考虑的因素影响随便加减点数值假装考虑了现实随机影响,因为已知数据为主不能加太过,但加少了就一点不考虑了太理想。

y 本是一维向量(n),但需要将其转换为二维矩阵(nx1)。因为模型的预测输出是二维张量,标签必须与之形状一致才能匹配,否则计算损失时会报错。二维矩阵表示每个样本对应一个标签,决定了它是否可以广播(broadcast)、是否能被线性层接受、是否可以与其他张量拼接或乘法。
y.reshape((-1, 1))中-1 是自动推断维度的意思,自计算样本数。

1
2
3
4
5
def synthetic_data(w, b, num_examples):
X = torch.normal(0, 1, (num_examples, len(w))) #num_examples为样本数,len(w)为特征数
y = torch.matmul(X, w) + b # 偏置加权求和,计算每个样本的预测值(标签)
y += torch.normal(0, 0.01, y.shape) # 添加随机扰动(噪声)
return X, y.reshape((-1, 1)) #保持模型输出和标签结构完全一致

读取数据集

1
2
3
4
5
6
7
8
9
def data_iter(batch_size, features, labels):
num_examples = len(features)
indices = list(range(num_examples))
# 这些样本是随机读取的,没有特定的顺序
random.shuffle(indices)
for i in range(0, num_examples, batch_size):
batch_indices = torch.tensor(
indices[i: min(i + batch_size, num_examples)])
yield features[batch_indices], labels[batch_indices]
1
2



定义模型

$$
f(\mathbf{X}) = \mathbf{X} \mathbf{w} + b
$$
1
2
def linreg(X, w, b):
return torch.matmul(X, w) + b

定义损失函数

1
2
3
def squared_loss(y_hat, y):  #@save
"""均方损失"""
return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2

定义优化算法

$$
L(\hat{y}, y) = \frac{1}{2} (\hat{y} - y)^2
$$
1
2
3
4
with torch.no_grad():  #禁用梯度追踪,保证参数更新不被记录
for param in params:
param -= lr * param.grad / batch_size #原地更新参数
param.grad.zero_()

1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2



1
2