实用的的机器学习
Practical Machine Learning — Practical Machine Learning (d2l.ai)
课程介绍
机器学习在工业中的应用
- 制造业:检修设备加入传感器、替代人
- 零售业:推荐商品、预测产品的销量
- 健康领域:穿戴式的传感器
- 金融领域:诈骗的检测
- 汽车领域:预测车胎气压、无人驾驶
机器学习的工作流程
- 把我们遇到的问题变成机器学习的问题
- 收集数据(关于人的的数据集比较关注隐私)
- 训练模型(选择简单的模型测试数据的好坏)
- 部署模型(部署需要考率模型的大小、模型需要不断的监控和更新)
- 关注模型的性能
数据获取
数据发现
常用数据集
- MINIST:手写数字数据集
- ImageNet:图片收索引擎
- Audio Set:youTube
- KITTI:无人驾驶
- Amazon Review:收集用户的评论
- SQuAD
- LibriSpeech
网上爬
数据采集
数据集网站
Find Open Datasets and Machine Learning Projects | Kaggle
The latest in Machine Learning | Papers With Code
https://aws.amazon.com/cn/free/database/
数据集之间的比较
学术数据集:
优点:数据集比较干净,适合机器学习,难度适中
缺点:数据集比较单一,不适合做应用
竞赛的数据集:
优点:数据集更加接近应用
缺点:数据集计较干净,数据集比较单一
原始数据集:
优点:灵活
缺点:要做大量的预处理
注意:要考虑法律风险,和隐私风险
数据融合
inner join
找不到数据集怎么办
GAN来生成数据集
AI生成数据集stable diffusion
总结
找数据是非常有挑战的问题
工业界一般使用原始数据、学术界一般使用的数据是处理好的
数据融合
数据增强
AI生成数据集
网页抓取数据集
网页抓取使用工具
“curl”:是一个用于在命令行界面中进行网络数据传输的工具和库。它支持各种协议,如HTTP、HTTPS、FTP、SCP、SFTP、SMTP、LDAP、等等,并能够通过命令行参数进行各种网络操作。
headless:没有头的浏览器
# 导入Selenium库中的webdriver模块
from selenium import webdriver
# 创建一个ChromeOptions对象,用于配置Chrome浏览器选项
chrome_options = webdriver.ChromeOptions()
# 设置Chrome浏览器以无头模式运行
chrome_options.headless = True
# 创建一个Chrome浏览器实例,使用配置好的选项
chrome = webdriver.Chrome(chrome_options=chrome_options)
# 打开指定的URL,加载网页并等待页面加载完成
# 请在url变量中替换为实际的网页URL
page = chrome.get(url)
# 导入BeautifulSoup库
from bs4 import BeautifulSoup
# 打开指定的HTML文件(在这里假设文件路径为html_path)
with open(html_path, 'r') as file:
# 使用BeautifulSoup解析HTML内容
page = BeautifulSoup(file, 'html.parser')
# 查找所有带有 'a' 标签和类名 'list-card-link' 的元素,并提取它们的 'href' 属性
links = [a['href'] for a in page.find_all('a', class_='list-card-link')]
# 遍历链接列表并提取每个链接的一部分信息
ids = [link.split('/')[-2].split('')[0] for link in links]
成本
crawl images
考虑法律问题
总结:
- 网页的数据抓取是收集数据集一个很有用的方法
- 使用云端可以节省成本
- 合理的使用
- 网页是一个html的文档通过工具去定位要抓取的东西
数据的标注
半监督学习
- 连续性的假设
- 聚类的假设
- 流型假设:通过降维
自学习:
- 小部分标注好的数据来训练一个模型
- 对没有标好的数据用这个训练好的模型进行预测
- 得到预测和标注的数据集进行融合再去训练一个新的模型
- 最后不断迭代使得模型变的更好
建议:标数据可以用比较深的模型,可以不考虑成本
挑战
- 将标注任务做的简单
- 标注成本
- 质量控制
主动学习
- 不确性的采样
弱监督学习
数据编程
总结
- 自训练
- 众包
探索性数据分析
- 了解列的数据类型、值和分布。
- 了解列之间的相互作用。
用不同的画图方式来挖掘你数据之间的关系
数据清理
数据的错误类型:离群值,规则违反、模式违反
存在多种工具可以帮助数据清理
图形界面用于交互式清理
自动检测和修复
数据变型
归一化
- 最小最大归一化
- Z-分数归一化
- 十进制缩进
- 对数缩放
图片
存储数据是一个问题
裁剪:减少存储、机器学习擅长低分辨率的图片
中等(80%-90%)的jpeg压缩可能会导致imageNet的准确率下降
注意有损压缩
视频
视频一般只裁剪有用的片段大约10s
理想情况下每一个片段是一个连贯的事件
语义分割非常困难
预处理要权衡存储,质量和加载速度
一般用GPU进行采样
文本
词干提取和词性还原
Tkenization:将一段文本呢分割成更小的部分
总结
- 表格数据:对实值特征进行归一化处理
- 图像数据:进行裁剪、降采样和白化处理
- 视频数据:进行剪辑和帧采样
- 文本数据:进行词干提取、词形还原和分词
特征工程
表格数据
- 特征组合:两个特征组的笛卡尔积,例如[cat, dog] x [male, female] -> [(cat, male), (cat, female), (dog, male), (dog, female)]。这种方法可以创建更复杂的特征,以捕捉数据中的更多信息
图片和视频
现在用预训练好的深度神经网络来抽取特征
总结
特征是原始数据的表示,这些表示与目标任务有关
数据总结
挑战:
数据的数量和质量要做权衡
考虑数据的多样性
考虑数据的平衡性
大数据的管理、处理、版本控制、安全
机器学习模型
监督学习:在标签数据上进行训练
自监督学习:在标签数据集和无标签数据集训练,使用模型为无标签数据预测标签
无监督学习:在无标签的数据集上训练
强化学习:与环境交互,最大化奖励(和人类的学习比较像)
监督学习
- 模型:决策树、线性方法、核方法、神经网络
- 损失:用于衡量模型的好坏
- 优化目标:优化 模型参数以达到目标
- 优化算法:最小化损失
决策树
优点:
- 可以解释
- 可以数值类和类别类的特征
缺点:
- 不稳定
- 容易过拟合
- 不容易被并行
随机森林
多决策树
并行训练
投票决策
随机性来源:自主采样、随机特征选择
梯度Boosting
总结
- 解释性强
- 易于训练和调整
- 对数据敏感
线性模型
独热编码
Mini-batch Stochastic gradient descent (SGD)
深度学习常用
# `features` shape is (n, p), `labels` shape is (n, 1)
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]
# 初始化模型参数
w = torch.normal(0, 0.01, size=(p, 1), requires_grad=True) # 权重参数
b = torch.zeros(1, requires_grad=True) # 偏置参数
# 模型训练
for epoch in range(num_epochs):
for X, y in data_iter(batch_size, features, labels):
y_hat = X @ w + b # 模型预测
loss = ((y_hat - y)**2 / 2).mean() # 计算损失
loss.backward() # 反向传播计算梯度
for param in [w, b]:
param -= learning_rate * param.grad # 使用随机梯度下降法更新参数
param.grad.zero_() # 梯度清零,准备处理下一个batch的数据
总结:
线性模型就是把我们的输出进行线性加权来得到我们的预测
线性回归用均方误差来作为损失函数
在softmax回归里用Coss Entropy做为损失
小批量随机梯度可以求解
神经网络
深度学习是自己用神经网络提取特征
需要大量的数据集,和计算量
三类抽取特征的方法
- 多层感知机
import torch
import torch.nn as nn
# 定义ReLU激活函数
def relu(X):
return torch.max(X, 0)
# 定义模型参数
W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens) * 0.01) # 输入层到隐藏层的权重参数
b1 = nn.Parameter(torch.zeros(num_hiddens)) # 隐藏层的偏置参数
W2 = nn.Parameter(torch.randn(num_hiddens, num_outputs) * 0.01) # 隐藏层到输出层的权重参数
b2 = nn.Parameter(torch.zeros(num_outputs)) # 输出层的偏置参数
# 前向传播
H = relu(X @ W1 + b1) # 隐藏层的输出,使用ReLU激活函数
Y = H @ W2 + b2 # 模型的输出
# 注释:
# - X是输入数据
# - @ 表示矩阵相乘
# - W1、b1、W2、b2 是模型参数,通过nn.Parameter包装,使其能够被优化
# - 隐藏层的输出经过ReLU激活函数处理
# - Y 是模型的最终输出
- 卷积神经网络:平移不变性、本地性(只跟你的窗口有关系),得到多通道得输出
# 获取卷积核的高度和宽度
h, w = K.shape
# 初始化输出矩阵 Y,其形状为 (X.shape[0] - h + 1, X.shape[1] - w + 1)
Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
# 对输出矩阵 Y 进行遍历计算
# 使用嵌套的循环,i 和 j 分别表示 Y 的行和列的索引
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
# 通过切片获取与卷积核大小相同的输入区域,并与卷积核逐元素相乘,然后求和
Y[i, j] = (X[i : i + h, j : j + w] * K).sum()
# 注释:
# - Y 是卷积操作的输出
# - X 是输入矩阵
# - K 是卷积核
# - 卷积核在输入矩阵上以步长为1进行滑动,对应位置相乘并求和得到输出矩阵的一个元素
主流得CNN神经网络
- 循环神经网络
- Transform
评估指标
只跟模型的数据和超参数有关
Model Metrics
常见做分类的指标:精度、具体类的精度、召回率
AUC是曲线下面的面积
0不是坏事情,只是把两件事情搞反了
总结:
- 对一个模型来说会考虑多个评价指标
- 论文评价指标&商业评价指标
过拟合和欠拟合
训练误差:所谓的训练误差就是说你这个模型在我的训练数据上你能才看到的一些错误率
泛化误差:就表示说我这个模型在新的没有见过的数据上会怎么样
数据简单选择简单的模型
数据复杂选择复杂的模型
数据复杂度:
样本越多数据越复杂
时间和空间的特殊结构
多样性
增加数据往往不会使得模型变的更坏
数据的复杂度和模型的复杂度是一个相互匹配的过程
总结
泛化能力更值得关注
模型复杂度
数据复杂度
模型选择:结合数据来选择
模型的验证
验证数据集:验证数据集可以使用多次
测试数据集:只能生成一次
用验证的精度做模型的选择
随机数据要符合独立同分布
K-fold Cross Validation
K-fold 交叉验证是一种通过将数据集划分为K个子集,循环使用其中K-1个子集进行训练,1个子集进行验证,最终取平均性能指标的方法,以更充分地评估机器学习模型性能。
模型的结果特别好很多时候是由于bug造成的
验证集被污染:验证集有训练集的样本
数据融合
信息的泄露
构造验证集要特别小心
总结:
通常用验证集来看模型的泛化误差
验证集和测试集要尽量的相似