机器学习实战

基础知识

防止过拟合通常1增加数据集2正则化(比较温和)3.降维(把一些冗余特征删除)

线性回归

函数说明
np.zeros((3, 4))创建 3x4 的零矩阵
np.ones((2, 2))创建 2x2 的全1矩阵
np.eye(3)创建 3x3 的单位矩阵
np.arange(0, 10, 2)[0, 2, 4, 6, 8] 类似 range
np.linspace(0, 1, 5)线性等分:[0. , 0.25, 0.5 , 0.75, 1.]

 总代码:

import numpy as np
import matplotlib.pyplot as plt

# 数据:面积(x1)、房间数(x2)、房价(y)
X = np.array([
    [50, 2],
    [60, 3],
    [80, 3],
    [100, 4],
    [120, 4],
    [140, 5],
    [160, 5],
    [180, 6],
    [200, 6],
    [220, 7]
], dtype=np.float64)#精度64位浮点数

y = np.array([120, 150, 180, 210, 250, 280, 310, 340, 370, 400], dtype=np.float64)

# 特征归一化(提升收敛速度),提升梯度下降速度
X_mean = np.mean(X, axis=0)
X_std = np.std(X, axis=0)
X = (X - X_mean) / X_std

# 添加一列全为1的偏置项(即x0 = 1)
X = np.hstack((np.ones((X.shape[0], 1)), X))  # X.shape = (10, 3)
'''创建X.shape[0]行1列的全一矩阵#np.ones((X.shape[0], 1))
np.hstack((..., X))hstack 表示“水平拼接”,沿着列的方向,把两个矩阵拼在一起:
左边是全 1 的列(偏置);右边是原始特征 X。
'''


# 初始化参数 theta(包括 bias)
theta = np.zeros(X.shape[1])  # theta.shape = (3,)

# 设置学习率和迭代次数
alpha = 0.1
epochs = 1000
losses = []

# 梯度下降
for epoch in range(epochs):
    y_pred = X @ theta               # 预测值(矩阵乘法)
    error = y_pred - y               # 预测误差
    loss = (1 / (2 * len(y))) * np.sum(error ** 2)
    losses.append(loss)

    grad = (1 / len(y)) * (X.T @ error)  # 梯度计算
    theta -= alpha * grad               # 参数更新

    if epoch % 100 == 0:
        print(f"Epoch {epoch}, Loss: {loss:.4f}")

print("\n训练完成后的参数:", theta)

# 画出损失下降过程
plt.plot(losses)
plt.title("Loss Curve")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.grid()
plt.show()

np库的array用法:切片和索引左闭右开,但是冒号表示到最后

a = np.array([[10, 20, 30],
              [40, 50, 60]])

print(a[0, 1])   # 取第一行第二列:20
print(a[1])      # 取第二行:[40 50 60]
print(a[:, 0])   # 所有行的第一列:[10 40]
print(a[0:2, 1:]) # 子矩阵:从前两行取后两列

矩阵乘法 

x = np.array([[1, 2], [3, 4]])   # 2x2 矩阵
w = np.array([[2], [1]])         # 2x1 矩阵

# 矩阵乘法用 @ 或 np.dot
y = x @ w
print(y)
# [[ 4]
#  [10]]

shape的用法

import numpy as np

a = np.array([[1, 2, 3],
              [4, 5, 6]])

print(a.shape)      # 输出:(2, 3)
print(type(a.shape))  # <class 'tuple'>

 np.mean和np.std求均值和标准差

b = np.array([[1, 2],
              [3, 4]])

print(np.std(b))            # 所有元素的标准差
print(np.std(b, axis=0))    # 每列的标准差
print(np.std(b, axis=1))    # 每行的标准差

标准化举例,(原数据-均值)/标准差

标准化(Z-score Normalization)
x′=x−μσx′=σx−μ​
使数据均值为0,方差为1,适用于大部分深度学习模型(如DNN、CNN)。

学习率固定,如果有的特征相较于其他特征特别大就容易震荡。

import numpy as np

X = np.array([[1, 2],
              [3, 4],
              [5, 6]], dtype=np.float64)

X_mean = np.mean(X, axis=0)  # 每列平均值 → [3. 4.]
X_std = np.std(X, axis=0)    # 每列标准差 → [1.6329 1.6329]

X_standardized = (X - X_mean) / X_std

对数几率回归

正负样本,正样本是符合分类预期的,比如垃圾邮件检测中的垃圾邮件。

损失函数是衡量单个样本的,

交叉损失熵 

 

import numpy as np

# 模拟数据(两个特征,二分类)
X = np.array([
    [2, 3],
    [1, 5],
    [2, 8],
    [5, 2],
    [6, 1],
    [7, 3]
], dtype=np.float64)

y = np.array([0, 0, 0, 1, 1, 1], dtype=np.float64)

# 数据归一化(可选但推荐)
X_mean = np.mean(X, axis=0)
X_std = np.std(X, axis=0)
X = (X - X_mean) / X_std

# 添加偏置项
X = np.hstack((np.ones((X.shape[0], 1)), X))  # shape: (6, 3)

# Sigmoid 函数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 损失函数(交叉熵)
def compute_loss(y_pred, y_true):
    epsilon = 1e-8  # 避免 log(0)
    return -np.mean(y_true * np.log(y_pred + epsilon) + (1 - y_true) * np.log(1 - y_pred + epsilon))

# 初始化参数
theta = np.zeros(X.shape[1])  # shape: (3,)

# 超参数
lr = 0.1
num_iters = 1000

# 梯度下降训练过程
for i in range(num_iters):
    z = X @ theta                 # 线性部分
    y_pred = sigmoid(z)          # 预测概率
    error = y_pred - y           # 残差
    grad = (1 / len(y)) * (X.T @ error)  # 梯度
    theta -= lr * grad           # 参数更新

    if i % 100 == 0:
        loss = compute_loss(y_pred, y)
        print(f"Iteration {i}, Loss: {loss:.4f}")

# 最终参数
print("Final theta:", theta)

# 预测函数
def predict(x_new):
    x_new = (x_new - X_mean) / X_std           # 特征归一化
    x_new = np.insert(x_new, 0, 1.0)           # 加偏置项
    prob = sigmoid(np.dot(x_new, theta))       # 概率
    return 1 if prob >= 0.5 else 0, prob

# 测试预测
x_test = np.array([4, 3])  # 一个新样本
cls, prob = predict(x_test)
print(f"Test sample {x_test} → Predict: class={cls}, prob={prob:.4f}")

小知识点

layer_1 = Dense(units=3, activation='sigmoid')
layer_1(x)
  • units=3
    表示该层有 3 个神经元,即输出一个 3 维向量(形状为 (batch_size, 3))。

  • activation='sigmoid'
    表示该层的激活函数是 Sigmoid

假设输入是一个向量 xx(形状为 (batch_size, input_dim)),则该层的计算步骤如下:

  1. 线性变换(加权和 + 偏置):

    z=xW+b
    • WW 是权重矩阵,形状为 (input_dim, 3)

    • bb 是偏置向量,形状为 (3,)

  2. 非线性激活(Sigmoid):

    a=σ(z)

    输出的 aa 是 3 维向量,每个元素在 (0, 1) 之间。

Dense类的代码(简单示意版) 

import torch
import torch.nn as nn
import torch.nn.functional as F
import math

class Dense(nn.Module):
    def __init__(self, units, activation=None):
        super(Dense, self).__init__()
        self.units = units
        self.activation = activation
        
        # 权重和偏置会在第一次前向传播时初始化(知道输入维度后)
        self.weight = None
        self.bias = None
        self.input_dim = None

    def forward(self, x):
        # 如果是第一次运行,初始化权重和偏置
        if self.weight is None:
            self.input_dim = x.shape[-1]  # 输入的特征维度
            # 初始化权重 (input_dim, units)
            self.weight = nn.Parameter(
                torch.Tensor(self.input_dim, self.units)
            )
            # 初始化偏置 (units,)
            self.bias = nn.Parameter(torch.Tensor(self.units))
            # 使用 Xavier/Glorot 初始化
            nn.init.xavier_uniform_(self.weight)
            nn.init.zeros_(self.bias)

        # 计算线性变换: x @ W + b
        output = torch.matmul(x, self.weight) + self.bias
        
        # 应用激活函数
        if self.activation == 'sigmoid':
            output = torch.sigmoid(output)
        elif self.activation == 'relu':
            output = F.relu(output)
        # 其他激活函数...
        
        return output

layer_1被实例化为Dense的对象,forword方法被__call__重写,帮助其可以被像函数一样调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值