Merge pull request #192 from m0n-k1y/master

docs: Delete fun-rec & Rearrange Index
This commit is contained in:
camera-2018
2024-02-22 22:41:04 +08:00
committed by GitHub
67 changed files with 10 additions and 4130 deletions

View File

@@ -312,250 +312,14 @@ export function chapter4() {
]
},
{ text: '4.4FAQ:常见问题', link: '/4.人工智能/4.4FAQ:常见问题' },
{
text: '4.6深度学习',
collapsed: true,
items: [
{ text: '4.6深度学习', link: '/4.人工智能/4.6深度学习' },
{ text: '4.6.1工欲善其事,必先利其器', link: '/4.人工智能/4.6.1工欲善其事,必先利其器' },
{ text: '4.6.2你可能会需要的术语介绍', link: '/4.人工智能/4.6.2你可能会需要的术语介绍' },
{ text: '4.6.3深度学习快速入门', link: '/4.人工智能/4.6.3深度学习快速入门' },
{ text: '4.6.4Pytorch安装', link: '/4.人工智能/4.6.4Pytorch安装' },
{
text: '4.6.5计算机视觉CV',
collapsed: true,
items: [
{ text: '4.6.5计算机视觉CV', link: '/4.人工智能/4.6.5计算机视觉CV' },
{ text: '4.6.5.1CV领域任务(研究目标)', link: '/4.人工智能/4.6.5.1CV领域任务(研究目标)' },
{
text: '4.6.5.2CV中的数据预处理torchvision',
collapsed: true,
items: [
{ text: '4.6.5.2CV中的数据预处理torchvision', link: '/4.人工智能/4.6.5.2CV中的数据预处理torchvision' },
{ text: '4.6.5.2.1数据读取', link: '/4.人工智能/4.6.5.2.1数据读取' },
{ text: '4.6.5.2.2数据增强', link: '/4.人工智能/4.6.5.2.2数据增强' },
]
},
{
text: '4.6.5.3CV中的经典网络',
collapsed: true,
items: [
{ text: '4.6.5.3CV中的经典网络', link: '/4.人工智能/4.6.5.3CV中的经典网络' },
{ text: '4.6.5.3.1AlexNet', link: '/4.人工智能/4.6.5.3.1AlexNet' },
{ text: '4.6.5.3.2FCN', link: '/4.人工智能/4.6.5.3.2FCN' },
{ text: '4.6.5.3.3ResNet', link: '/4.人工智能/4.6.5.3.3ResNet' },
{ text: '4.6.5.3.4UNet', link: '/4.人工智能/4.6.5.3.4UNet' },
{ text: '4.6.5.3.5GAN', link: '/4.人工智能/4.6.5.3.5GAN' },
{ text: '4.6.5.3.6思考题参考', link: '/4.人工智能/4.6.5.3.6思考题参考' },
{ text: '4.6.5.3.7还要学更多?', link: '/4.人工智能/4.6.5.3.7还要学更多?' },
]
},
{
text: '4.6.5.4神经辐射场(NeRF)',
collapsed: true,
items: [
{ text: '4.6.5.4神经辐射场(NeRF)', link: '/4.人工智能/4.6.5.4神经辐射场(NeRF)' },
{ text: '4.6.5.4.1NeRF', link: '/4.人工智能/4.6.5.4.1NeRF' },
{ text: '4.6.5.4.2NeRF的改进方向', link: '/4.人工智能/4.6.5.4.2NeRF的改进方向' },
{ text: '4.6.5.4.3自制数据集的工具COLMAP', link: '/4.人工智能/4.6.5.4.3自制数据集的工具COLMAP' },
]
},
{
text: '4.6.5.5行人重识别(ReID)',
collapsed: true,
items: [
{ text: '4.6.5.5行人重识别(ReID)', link: '/4.人工智能/4.6.5.5行人重识别(ReID)' },
]
},
]
},
{
text: '4.6.6自然语言处理NLP',
collapsed: true,
items: [
{ text: '4.6.6自然语言处理NLP', link: '/4.人工智能/4.6.6自然语言处理NLP' },
{ text: '4.6.6.1NLP领域任务(研究目标)', link: '/4.人工智能/4.6.6.1NLP领域任务(研究目标)' },
{
text: '4.6.6.2推荐系统',
collapsed: true,
items: [
{ text: '4.6.6.2推荐系统', link: '/4.人工智能/4.6.6.2推荐系统' },
{ text: '4.6.6.2.1推荐系统经典模型综述', link: '/4.人工智能/4.6.6.2.1推荐系统经典模型综述' },
{
text: '4.6.6.2.2基于数据的角度,看待推荐系统的构造',
collapsed: true,
items: [
{ text: '4.6.6.2.2基于数据的角度,看待推荐系统的构造', link: '/4.人工智能/4.6.6.2.2基于数据的角度,看待推荐系统的构造' },
{ text: '4.6.6.2.2.1《推荐系统实践》读后的一些想法', link: '/4.人工智能/4.6.6.2.2.1《推荐系统实践》读后的一些想法' },
{ text: '4.6.6.2.2.2推荐系统概念解释 and 一个好的推荐系统', link: '/4.人工智能/4.6.6.2.2.2推荐系统概念解释 and 一个好的推荐系统' },
{ text: '4.6.6.2.2.3推荐系统实例', link: '/4.人工智能/4.6.6.2.2.3推荐系统实例' },
{ text: '4.6.6.2.2.4利用用户行为数据', link: '/4.人工智能/4.6.6.2.2.4利用用户行为数据' },
{ text: '4.6.6.2.2.5推荐系统冷启动', link: '/4.人工智能/4.6.6.2.2.5推荐系统冷启动' },
{ text: '4.6.6.2.2.6利用标签信息', link: '/4.人工智能/4.6.6.2.2.6利用标签信息' },
{ text: '4.6.6.2.2.7利用上下文信息', link: '/4.人工智能/4.6.6.2.2.7利用上下文信息' },
]
},
{ text: '4.6.6.2.3序列化推荐', link: '/4.人工智能/4.6.6.2.3序列化推荐' },
]
},
{ text: '4.6.6.3知识图谱', link: '/4.人工智能/4.6.6.3知识图谱' },
]
},
{
text: '4.6.7Transformer',
collapsed: true,
items: [
{ text: '4.6.7Transformer', link: '/4.人工智能/4.6.7Transformer' },
{ text: '4.6.7.1VIT', link: '/4.人工智能/4.6.7.1VIT' },
{ text: '4.6.7.2BERT', link: '/4.人工智能/4.6.7.2BERT' },
{ text: '4.6.7.3MAE', link: '/4.人工智能/4.6.7.3MAE' },
]
},
{
text: '4.6.8对比学习',
collapsed: true,
items: [
{ text: '4.6.8对比学习', link: '/4.人工智能/4.6.8对比学习' },
{ text: '4.6.8.1前言', link: '/4.人工智能/4.6.8.1前言' },
{ text: '4.6.8.2Inst Disc', link: '/4.人工智能/4.6.8.2Inst Disc' },
{ text: '4.6.8.3定义正负样本的方式', link: '/4.人工智能/4.6.8.3定义正负样本的方式' },
{ text: '4.6.8.4MoCo', link: '/4.人工智能/4.6.8.4MoCo' },
{ text: '4.6.8.5SimCLR', link: '/4.人工智能/4.6.8.5SimCLR' },
{ text: '4.6.8.6SwAV', link: '/4.人工智能/4.6.8.6SwAV' },
{ text: '4.6.8.7BYOL', link: '/4.人工智能/4.6.8.7BYOL' },
{ text: '4.6.8.8SimSiam', link: '/4.人工智能/4.6.8.8SimSiam' },
{ text: '4.6.8.9MoCo v3', link: '/4.人工智能/4.6.8.9MoCo v3' },
{ text: '4.6.8.10总结', link: '/4.人工智能/4.6.8.10总结' },
]
},
{
text: '4.6.9深度强化学习',
collapsed: true,
items: [
{ text: '4.6.9深度强化学习', link: '/4.人工智能/4.6.9深度强化学习' },
{ text: '4.6.9.1前言', link: '/4.人工智能/4.6.9.1前言' },
{ text: '4.6.9.2基础资料推荐', link: '/4.人工智能/4.6.9.2基础资料推荐' },
{ text: '4.6.9.3基本概念介绍', link: '/4.人工智能/4.6.9.3基本概念介绍' },
]
}
]
},
{ text: '4.7图网络略述intro&GCN', link: '/4.人工智能/4.7图网络略述intro&GCN' },
{ text: '4.8数据分析', link: '/4.人工智能/4.8数据分析' },
{ text: '4.9如何做研究', link: '/4.人工智能/4.9如何做研究' },
{ text: '4.10科研论文写作', link: '/4.人工智能/4.10科研论文写作' },
{ text: '4.11从 AI 到 智能系统 —— 从 LLMs 到 Agents', link: '/4.人工智能/4.11从 AI 到 智能系统 —— 从 LLMs 到 Agents' },
{ text: '4.12LLM Agent之结构化输出', link: '/4.人工智能/4.12LLMAgent之结构化输出' },
{ text: '4.13本章节内容的局限性', link: '/4.人工智能/4.13本章节内容的局限性' },
{ text: 'SRT社团介绍', link: '/4.人工智能/SRT' },
{
text: 'FunRec',
collapsed: true,
items: [
{ text: 'FunRec概述', link: '/4.人工智能/FunRec概述' },
{
text: '推荐系统概述',
collapsed: true,
items: [
{ text: '推荐系统的意义', link: '/4.人工智能/ch01/ch1.1.md' },
{ text: '推荐系统架构', link: '/4.人工智能/ch01/ch1.2.md' },
{ text: '推荐系统技术栈', link: '/4.人工智能/ch01/ch1.3.md' },
]
},
{
text: '推荐系统算法基础',
collapsed: true,
items: [
{
text: '经典召回模型',
collapsed: true,
items: [
{
text: '基于协同过滤的召回', collapsed: true, items: [
{ text: 'UserCF', link: '/4.人工智能/ch02/ch2.1/ch2.1.1/usercf.md' },
{ text: 'ItemCF', link: '/4.人工智能/ch02/ch2.1/ch2.1.1/itemcf.md' },
{ text: 'Swing', link: '/4.人工智能/ch02/ch2.1/ch2.1.1/Swing.md' },
{ text: '矩阵分解', link: '/4.人工智能/ch02/ch2.1/ch2.1.1/mf.md' },
]
},
{ text: 'FM召回', link: '/4.人工智能/ch02/ch2.1/ch2.1.2/FM.md' },
{
text: 'item2vec召回系列', collapsed: true, items: [
{ text: 'word2vec原理', link: '/4.人工智能/ch02/ch2.1/ch2.1.2/word2vec.md' },
{ text: 'item2vec召回', link: '/4.人工智能/ch02/ch2.1/ch2.1.2/item2vec.md' },
{ text: 'Airbnb召回', link: '/4.人工智能/ch02/ch2.1/ch2.1.2/Airbnb.md' },
]
},
{ text: 'YoutubeDNN召回', link: '/4.人工智能/ch02/ch2.1/ch2.1.2/YoutubeDNN.md' },
{
text: '双塔召回', collapsed: true, items: [
{ text: '经典双塔', link: '/4.人工智能/ch02/ch2.1/ch2.1.2/DSSM.md' },
{ text: 'Youtube双塔', link: '/4.人工智能/ch02/ch2.1/ch2.1.2/YoutubeTwoTower.md' },
]
},
{
text: '图召回', collapsed: true, items: [
{ text: 'EGES', link: '/4.人工智能/ch02/ch2.1/ch2.1.3/EGES.md' },
{ text: 'PinSAGE', link: '/4.人工智能/ch02/ch2.1/ch2.1.3/PinSage.md' },
]
},
{
text: '序列召回', collapsed: true, items: [
{ text: 'MIND', link: '/4.人工智能/ch02/ch2.1/ch2.1.4/MIND.md' },
{ text: 'SDM', link: '/4.人工智能/ch02/ch2.1/ch2.1.4/SDM.md' },
]
},
{
text: '树模型召回', collapsed: true, items: [
{ text: 'TDM', link: '/4.人工智能/ch02/ch2.1/ch2.1.5/TDM.md' },
]
}
]
},
{
text: '经典排序模型',
collapsed: true,
items: [
{ text: 'GBDT+LR', link: '/4.人工智能/ch02/ch2.2/ch2.2.1.md' },
{
text: '特征交叉', collapsed: true, items: [
{ text: 'FM', link: '/4.人工智能/ch02/ch2.2/ch2.2.2/FM.md' },
{ text: 'PNN', link: '/4.人工智能/ch02/ch2.2/ch2.2.2/PNN.md' },
{ text: 'DCN', link: '/4.人工智能/ch02/ch2.2/ch2.2.2/DCN.md' },
{ text: 'AutoInt', link: '/4.人工智能/ch02/ch2.2/ch2.2.2/AutoInt.md' },
{ text: 'FiBiNET', link: '/4.人工智能/ch02/ch2.2/ch2.2.2/FiBiNet.md' },
]
},
{
text: 'WideNDeep系列', collapsed: true, items: [
{ text: 'Wide&Deep', link: '/4.人工智能/ch02/ch2.2/ch2.2.3/WideNDeep.md' },
{ text: 'NFM', link: '/4.人工智能/ch02/ch2.2/ch2.2.3/NFM.md' },
{ text: 'AFM', link: '/4.人工智能/ch02/ch2.2/ch2.2.3/AFM.md' },
{ text: 'DeepFM', link: '/4.人工智能/ch02/ch2.2/ch2.2.3/DeepFM.md' },
{ text: 'xDeepFM', link: '/4.人工智能/ch02/ch2.2/ch2.2.3/xDeepFM.md' },
]
},
{
text: '序列模型', collapsed: true, items: [
{ text: 'DIN', link: '/4.人工智能/ch02/ch2.2/ch2.2.4/DIN.md' },
{ text: 'DIEN', link: '/4.人工智能/ch02/ch2.2/ch2.2.4/DIEN.md' },
{ text: 'DSIN', link: '/4.人工智能/ch02/ch2.2/ch2.2.4/DSIN.md' },
]
},
{
text: '多任务学习', collapsed: true, items: [
{ text: '多任务学习概述', link: '/4.人工智能/ch02/ch2.2/ch2.2.5/2.2.5.0.md' },
{ text: 'ESMM', link: '/4.人工智能/ch02/ch2.2/ch2.2.5/ESMM.md' },
{ text: 'MMOE', link: '/4.人工智能/ch02/ch2.2/ch2.2.5/MMOE.md' },
{ text: 'PLE', link: '/4.人工智能/ch02/ch2.2/ch2.2.5/PLE.md' },
]
}
]
}
]
}
]
}
{ text: '4.5图网络略述intro&GCN', link: '/4.人工智能/4.5图网络略述intro&GCN' },
{ text: '4.6数据分析', link: '/4.人工智能/4.6数据分析' },
{ text: '4.7如何做研究', link: '/4.人工智能/4.7如何做研究' },
{ text: '4.8科研论文写作', link: '/4.人工智能/4.8科研论文写作' },
{ text: '4.9从 AI 到 智能系统 —— 从 LLMs 到 Agents', link: '/4.人工智能/4.9从 AI 到 智能系统 —— 从 LLMs 到 Agents' },
{ text: '4.10LLM Agent之结构化输出', link: '/4.人工智能/4.10LLMAgent之结构化输出' },
{ text: '4.11本章节内容的局限性', link: '/4.人工智能/4.11本章节内容的局限性' },
]
},
]

View File

@@ -64,7 +64,7 @@
### 对比学习
因为传统 AI 训练一般都需要数据集标注,比如说图片分割数据集需要人工在数万张图片上抠出具体位置,才能进行训练,这样的人力成本是巨大的,而且难以得到更多数据。因此,对比学习应运而生,这是一种不需要进行标注或者只需要少量标注的训练方式,具体可见[4.6.8 对比学习](4.6.8%E5%AF%B9%E6%AF%94%E5%AD%A6%E4%B9%A0.md) 。
因为传统 AI 训练一般都需要数据集标注,比如说图片分割数据集需要人工在数万张图片上抠出具体位置,才能进行训练,这样的人力成本是巨大的,而且难以得到更多数据。因此,对比学习应运而生,这是一种不需要进行标注或者只需要少量标注的训练方式
### 强化学习
@@ -96,4 +96,4 @@
非常荣幸能在本章中得到 IIPL 智能信息处理实验室 [http://iipl.net.cn](http://iipl.net.cn) 的宝贵贡献,衷心感谢他们的无私支持与帮助!
希望加入 IIPL欢迎移步[SRT 社团介绍](SRT.md)
<!-- 希望加入 IIPL欢迎移步[SRT 社团介绍](SRT.md) -->

View File

@@ -1,240 +0,0 @@
# 工欲善其事,必先利其器
> 有一个英语词汇叫做 Handy讲的是便利的易使用的当你有一个良好的环境配置时候编程将变得 handy随手打开即可编程一点都不复杂所以配置好的环境是未来学习快速进步的必要保障。
首先来了解一下深度学习框架
## 深度学习框架
![](https://cdn.xyxsw.site/boxcnWLzi1LIWLCncrXcTcjAKne.png)
### 1、深度学习框架是什么
在深度学习初始阶段,每个深度学习研究者都需要写大量的重复代码。
为了提高工作效率,他们就将这些代码写成了框架放到网上让所有研究者一起使用。
作一个简单的比喻,一套深度学习框架就是一套积木,各个组件就是某个模型或算法的一部分,你可
以自己设计如何使用积木去堆砌符合你数据集的积木。
#### 思考题
自行了解张量和基于张量的各种操作。
### 2、为什么需要深度学习框架
显然是为了降低使用门槛。 深度学习对硬件环境的依赖很高,对于开发者有较高的门槛,深度学习计
算框架的出现,屏蔽了大量硬件环境层面的开发代价,使研究者和开发人员可以专注于算法的实现,
快速迭代。
## TensorFlow 和 pytorch
这么多的框架,我们应该如何选择呢(好吧直接就 TensorFlow 和 pytorch 了)
### 1. TensorFlow
#### 开发语言
基于 python 编写,通过 C/C++ 引擎加速,是 Google 开源的第二代深度学习框架。
#### 编程语言
Python 是处理 TensorFlow 的最方便的客户端语言。不过JavaScript、C++、Java、Go、C#和 Julia 也提供了实验性的交互界面。
#### 优点
(不讲人话的版本)
处理循环神经网 RNN 非常友好。其用途不止于深度学习,还可以支持增强学习和其他算法。
内部实现使用了向量运算的符号图方法,使用图 graph 来表示计算任务使新网络的指定变得相当容易支持快速开发。TF 使用静态计算图进行操作。也就是说我们首先定义图然后运行计算如果需要对架构进行更改我们将重新训练模型。TF 选择这种方法是为了提高效率但是许多现代神经网络工具能够在不显著降低学习速度的情况下同时兼顾到在学习过程中进行改进。在这方面TensorFlow 的主要竞争对手是 Pythorch。
(讲人话啊喂!!)
- 谷歌爸爸一撑腰,研究代码两丰收
- 新版 TensorFlow APISTFW) 较简洁
- 天生和谷歌云兼容
- 有良好的推断支持
- 功能十分强大!
#### 缺点
(不讲人话的版本)
目前 TensorFlow 还不支持“内联inline”矩阵运算必须要复制矩阵才能对其进行运算复制庞大的矩阵会导致系统运行效率降低并占用部分内存。
TensorFlow 不提供商业支持,仅为研究者提供的一种新工具,因此公司如果要商业化需要考虑开源协议问题。
(讲人话!!)
- API 不稳定
- 学习成本高
- 开发成本高
- 会出现前面版本存在的功能后面版本直接没了
### 2.pytorch
#### 开发语言
Facebook 用 Lua 编写的开源计算框架支持机器学习算法。Tensorflow 之后深入学习的主要软件工具是 PyTorch。
Facebook 于 2017 年 1 月开放了 Torch 的 Python API ― PyTorch 源代码。
#### 编程语言
PyTorch 完全基于 Python。
(直接说人话吧)
#### 优点
- 上手容易
- 代码简洁
- 有较好的灵活性和速度
- 发展快速,现在已经支持 TPU
- API 相对稳定
- 里面附带许多开源模型代码可以直接调用
- 非常建议使用 pytorchtensorflow 版本更迭会导致很多代码失效,前期不建议使用。
#### 缺点
-
没有 Keras API 那么简洁
- 一些功能难以实现
## 安装
### Pytorch
官网如下
![](https://cdn.xyxsw.site/boxcnaF9UWNcr5pt99Zu5Wr0PTg.png)
![](https://cdn.xyxsw.site/boxcnqHCP5KiSF4Vmc6M1cjEXKg.png)
选择 Conda 或者 Pip 安装皆可
有独立显卡请下载 CUDA没有的话请下载 CPU
最后选择 CUDA 版本或者 CPU 版本运行指令就好了
### Tipconda 换源
如果你使用 conda 安装 pytorch 太慢或者失败,不妨换个下载源试试
在 cmd 命令行中,输入添加以下命令:
```bash
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
```
### TensorFlow
![](https://cdn.xyxsw.site/boxcn5u9u9M6DPRh83ufoSwfuof.png)
#### 教程
[在 Windows 上配置 pytorchCPU 和 GPU 版)](https://www.bilibili.com/video/BV1YY4y1B7cA)
<Bilibili bvid='BV1YY4y1B7cA'/>
[Windows 下 PyTorch 入门深度学习环境安装与配置 CPU GPU 版](https://www.bilibili.com/video/BV1S5411X7FY)
<Bilibili bvid='BV1S5411X7FY'/>
[最新 TensorFlow 2.8 极简安装教程](https://www.bilibili.com/video/BV1i34y1r7dv)
<Bilibili bvid='BV1i34y1r7dv'/>
#### 思考题:为什么需要 CUDA 版本???
cuda 版本需要额外配置,我们将这个任务留给聪明的你!!!
### TipsWindows 和 Linux 如何查看显卡信息
#### windows
同时按下键盘的 win+r 键,打开 cmd键入 `dxdiag` 然后回车
系统、显卡、声卡以及其他输入设备的信息都在这里了。(给出我的界面)
![](https://cdn.xyxsw.site/boxcnXHceTuUl0XzCNJv9RqHN9c.png)
cuda 版本查看
桌面空白位置摁下右键
![](https://cdn.xyxsw.site/boxcnbxhAei6H4OWjaN0Hp0YICg.png)
![](https://cdn.xyxsw.site/boxcnp9i1SagOxXd17W9BiP3RNe.png)
![](https://cdn.xyxsw.site/boxcngaZNZB3XLSJia0rk0DgGbe.png)
#### linux
打开 bash 键入
```bash
nvidia-smi
```
## 很多人会混淆的东西(非常重要)
### cuda driver version / cuda runtime version
通常大家所指的 cuda 是位于/usr/local 下的 cuda
![](https://cdn.xyxsw.site/boxcntFGELTpdcVoigy5ldCorAb.png)
当然可以看到 cuda 是 cuda-11.6 所指向的软链接(类似 windows 的快捷方式),所以我们如果要切换 cuda 版本只需要改变软链接的指向即可。
![](https://cdn.xyxsw.site/boxcnTB39MtPKBr9CgufCpSIYuf.png)
cuda driver version 是 cuda 的驱动版本。
cuda runtimer version 是我们实际很多时候我们实际调用的版本。
二者的版本是可以不一致的。如下图所示:
![](https://cdn.xyxsw.site/boxcnATNfI2spkNsXbqtIuwwY6c.png)
![](https://cdn.xyxsw.site/boxcnz03UebyZ42JNOXpdUfjMBg.png)
一般来讲 cuda driver 是向下兼容的。所以 cuda driver version >= cuda runtime version 就不会太大问题。
如果我们用 C++ 写 CUDA具体的说就是编写以.cu 为后缀的文件。就是用 nvcccuda 编译器去编译的nvcc 是 cuda runtime api 的一部分。cuda runtime 只知道自身构建时的版本,并不知道是否 GPU driver 的版本,甚至不知道是否安装了 GPU driver。
### Pytorch/tensorflow 使用的 cuda 版本
以 pytorch 为例,可以看到在安装过程中我们选择的 cuda 版本是 10.2
![](https://cdn.xyxsw.site/boxcns8yMCuacj0A2BbMU6ZB08b.png)
那么这个 cudatookit10.2 和 nvidia-smi 的 11.7 以及 nvcc -V 的 11.4 三者有什么区别呢?
pytorch 实际只需要 cuda 的链接文件,即.so 文件,这些链接文件就都包含的 cudatookkit 里面。并不需要 cuda 的头文件等其他东西,如下所示
![](https://cdn.xyxsw.site/boxcnXWjMnlXjMg2lA1ApjoUhnh.png)
所以我们如果想让使用 pytorch-cuda 版本,我们实际上不需要/usr/local/cuda。只需要在安装驱动的前提下在 python 里面安装 cudatookit 即可。
但是有一种情况例外,就是你要用 C++ CUDA 编写核函数给 pytorch 当做插件。这种情况下就需要/usr/local/cuda 以及 nvcccudatookit而且后面两个版本很多时候需要保持严格一致。
### Cudnn
Cudnn 是一些链接文件,你可以理解成是为了给 cuda 计算加速的东西。同样的我们也可以用以下命令查看/usr/local/cuda 的 cudnn
![](https://cdn.xyxsw.site/boxcnPD5DbA3NPimtV0kVoDJGmh.png)
以及 pytorch 的 cuda 环境的 cudnn
![](https://cdn.xyxsw.site/boxcnZQ2Mc52Us6ku543l7WPEZd.png)

View File

@@ -1,47 +0,0 @@
# 你可能会需要的术语介绍
众所周知一个领域的黑话对新人来说是比较不友好的为此我从知乎上找了一篇黑话大赏bushi做了点改良放在这里。如果遇到看不懂的词了可以来这找找。**在系统学习之前可以先无视这篇文章,遇到问题再来找找**<u>。</u>
> 作者Young<br/>链接:[https://www.zhihu.com/question/469612040/answer/2008770105](https://www.zhihu.com/question/469612040/answer/2008770105)<br/>来源:知乎
- feature一个向量
- representation还是一个向量
- embedding把输入映射成向量有时作为名词=feature
- 提高泛化性:在各种东西上预测更准了
- 过拟合:训练过头了
- attention加权提取特征越重要的 feature 权重越高
- adaptive还是加权
- few-shot learning看了几个样本就学会了
- zero-shot learning一个没看就开始用自带的知识瞎蒙
- self-supervised自学自监督
- semi-supervised教一点自学一点半监督
- unsupervised没人教了跟谁学无监督
- end-to-end一套操作行云流水搞到底输入是图像输出也是图像就算
- multi-stage发现不行还得一步一步来
- domain我圈起来一堆样本就管他叫一个<u>domain</u>
- transfer我非得在这一堆样本上训练用在另一堆样本上就是不直接训练就是玩
- adversarial我加了一部分就是让 loss 增大
- robust很稳我不会让 loss 变大的(但也不容易变小了)
- state of the artsota吹 nb第一
- outperform我虽然没第一但是我比 baseline 强
- baseline(故意)选出来的方法,让我能够看起来比它强
- empirically我做实验了但不知道为啥 work
- theoretically我以为我知道为啥 work但没做实验或者只做了个 toy model
- multi 开头词组
- multi-task把几个不同任务的 loss 加一起,完事
- multi-domain把几堆儿样本混一块训练完事
- multi-modality把视频语音文字图像 graph 点云 xxx 混一块训练,完事
- multi-domain multi-modal multi-media modelmuamuamuamua……
- 消融实验:删掉某模块做对比实验
- 长尾数据:出现频率低的类别很多
- ... Is all you need骗你的就是把你骗进来。除了...你还要一堆 trick
- 体素:我把世界变成 MC 了,世界是一堆方块,他们在不同视角下有各自的颜色和透明度
- 点云:我每采样一次得到一个点,由这些点去表示我要的物体,不太直观,来张图
这是我用照片重建的独角兽**稀疏**点云,红色的不用管,是照相机视角(图不够多,巨糊)
![](https://cdn.xyxsw.site/boxcnWx8hYfT6kFug4A1iA3uftg.png)
![](https://cdn.xyxsw.site/boxcnbWfXyklyZwpjwy8uz2XnLh.jpg)
先这些,后续想起来了可能会补充。

View File

@@ -1,114 +0,0 @@
# 深度学习快速入门
## **刘二大人(Pytorch)**
## 速成课:人工智能
[【速成课人工智能】Ai - [21 集全/中英双语] - Artificial Intelligence_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1P7411r7Dw)
<Bilibili bvid='BV1P7411r7Dw'/>
Crash course 的课程可以基本了解pytorch的内容但是当然有很多内容已经有些过时
# 这是啥?
这是一个快速入门深度学习的途径。
# 课程大概讲了啥?
刘二大人的深度学习是用来给小白快速上手用的。其中介绍了大概的深度学习框架,基本的几种损失函数,激活函数,网络。
课程中用到了 3 个数据集:糖尿病数据集,泰坦尼克号数据集,和最经典的 MINIST 数据集。其中我们只需要用到 MINIST 数据集,其他两个如果有兴趣可以去尝试。我们最快可以在 1 个星期内训练出我们的第一个模型用来识别手写数字,初窥人工智能的门槛。
这个课程最主要的是着重讲解了大致的框架,深度学习的代码就像搭积木一样,当大致的框架有了,剩下的就只剩下往里面塞东西就好了。当我们学习了刘二大人的课程之后,一些基本的任务都可以用这些基本的网络简单解决。
# 学习这系列视频需要哪些前置条件?
## python
基本的一些 python 知识,你可以在本讲义中的 [3.6python 模块](../3.%E7%BC%96%E7%A8%8B%E6%80%9D%E7%BB%B4%E4%BD%93%E7%B3%BB%E6%9E%84%E5%BB%BA/3.6Python%EF%BC%88%E7%81%B5%E5%B7%A7%E7%9A%84%E8%83%B6%E6%B0%B4%EF%BC%89.md)中进行简单的学习。解决其中的题目大致就可以了,之后遇到不会的只要去 Google 一下,或者去问问 ChatGPT问问 New Bing。
## pycharm,pytorch,anaconda 等环境配置
你可以在本讲义中的 [Pytorch 安装](../4.%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/4.6.4Pytorch%E5%AE%89%E8%A3%85.md)中找到怎么配置 pytorch你可以在这里安装 [Pycharm](https://www.jetbrains.com/zh-cn/pycharm/)。
你可以在本讲义中的 [python 安装](../3.%E7%BC%96%E7%A8%8B%E6%80%9D%E7%BB%B4%E4%BD%93%E7%B3%BB%E6%9E%84%E5%BB%BA/3.6.3%E5%AE%89%E8%A3%85python.md)中找到 Pycharm 和 anaconda 的安装教学视频
## 一个找乐子的心
如果觉得它好玩的话,就去学吧。
## 前置知识?
要啥前置知识,这就是给你入门用的。如果你不打无准备的仗,你可以简单看看[机器学习快速入门](4.2%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%EF%BC%88AI%EF%BC%89%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8%EF%BC%88quick%20start%EF%BC%89.md)。
# 学完课程之后可能出现的问题
通过这个课程虽然我们可以进行快速入门,但经过我个人的入门实践表明,视频中没有告诉你完整的数学推导,也懒得进行公式推导,所以在观看这门教程之后虽然已经会基本的 coding 能力了但是基础并不扎实。
我们不知道每一个给你封装好的函数具体在干什么不知道经过这个线性层经过这个卷积操作出来的特征大致对应着什么它们对我们来说确实变成了一个黑盒。我们只知道我就这么一写in_feature 和 out_feature 写对了,程序成功运行了,正确率有 80% 多欸,我已经会深度学习了。
所以在这门课程结束之后建议手写其中的一些封装好的函数,比如一些基础的线性层。尝试画个图,像课程中刘二讲给我们的那样,看看大致的流程,每一层出来的特征大致代表着什么。
# 你还有疑惑?
你可以通过以下方式解决你对于此课程的疑惑:
## 基础知识的疑惑
如果你对于课程中的一些基本知识比如说梯度下降算法等感到疑惑,你可以移步[机器学习快速入门](4.2%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%EF%BC%88AI%EF%BC%89%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8%EF%BC%88quick%20start%EF%BC%89.md)
当然,在这里我会简单的为你讲解一下最基础最关键的算法:梯度下降算法。和怎么快速理解计算机为什么能识别手写数字。
## torch 我还不会呢!
学会一个**庞大并且高度封装**的包并不是一蹴而就的,我们建议从实践开始,比如说自己搭建一个神经网络来实现 MNIST 的分类。在使用这些函数和类的过程中你能更快地掌握它们的方法。
# 关于梯度下降算法:
### 损失
![](https://cdn.xyxsw.site/boxcnRbeabbEppeHlM39UwqJSJc.png)
首先我们需要有一个损失函数$Fxx=true-predict$
这样通过一个函数我们就得到了一个具体的数值,这个数值的意义是:现在的输入数据经过一个拟合函数处理后得到的结果和真实结果的差距,梯度下降算法就是根据这个为基础进行对拟合函数中参数的优化。
### 梯度下降
![](https://cdn.xyxsw.site/boxcnMuwaG2okodvywzbxX138Re.png)
假设损失函数为$y=x^2$,梯度下降的目的是快速找到导数为 0 的位置(附近)
![](https://cdn.xyxsw.site/boxcn83M9AW6xDm5pBIqmZEC6Kf.png)
![](https://cdn.xyxsw.site/boxcneVFa131Lb9xDMCsIMI9fcc.png)
以此类推,我们最后的 w 在 0 的附近反复横跳,最后最接近目标函数的权重 w 就是 0。
### 简单理解
你可以简单这样理解:游戏中你在靶场练狙击枪,你用 4-8 倍镜瞄了 400 米的靶子,真实值就是靶心。你开了一枪后发现落在靶心上方,于是你根据距离靶心的远近,你的大脑开始计算优化下次瞄的位置,如果你往上面偏了很多,你就会将瞄点往下移动很多,如果往上偏了一点点,你就会将瞄点往下移动一点点。
移动的途中可能出现移动的过多的情况,从上偏变成下偏了,这就是如果学习率过大会出现的问题。
总而言之,你打狙击枪脑子怎么分析的,梯度下降算法就是怎么算的。当然由于它是电脑没有灵活的机动性,他的权重只能逐渐改变。
# 关于 MINIST
![](https://cdn.xyxsw.site/boxcnxdyWA6Sj82kNxMlQ1b9hDg.png)
这个数据集可以说是最最经典的数据集了,里面有 0-9 这 10 个数字的手写图片和标注,正确率最高已经到了 99.7%.
# 接下来干什么?
- **我想学 CV !!!!!!**
你可以在 CV 模块中找到[4.6.5.3CV中的经典网络](4.6.5.3CV%E4%B8%AD%E7%9A%84%E7%BB%8F%E5%85%B8%E7%BD%91%E7%BB%9C.md) ,这里是一些最最经典的论文,我们推荐你阅读它们的原文并且复现它们的代码,这可以同时锻炼你的**coding 能力和论文阅读能力**,在阅读前,请参见[如何读论文](../1.%E6%9D%AD%E7%94%B5%E7%94%9F%E5%AD%98%E6%8C%87%E5%8D%97/1.10%E5%A6%82%E4%BD%95%E8%AF%BB%E8%AE%BA%E6%96%87.md) 。本模块的撰写者**SRT 社团**主要从事 CV 方向的研究,遇到问题欢迎与我们交流。(你都完成这些了不至于找不到我们的联系方式吧~**如果你读完了经典网络模块,你可以在它的最后找到接下来的学习路线~**
- **我想做****NLP**** !!!!!!**
NLP 研究方向庞大且复杂,若直接从 GPT 系列开始不免有些过于困难。我们建议你从了解 NLP 的任务开始,在有足够的基础后开始学习 RNNLSTM 基准方法后向 [4.6.7Transformer](4.6.7Transformer.md) 进发 ,这个方法广泛运用在几乎所有深度学习领域,尤其是 NLP 的前沿研究已经无法离开 Transformer 了 hhhh。这个模块中我们也加入了一些 Transformer 的改进工作,包括 NLPCV和多模态
- **如果你想做多模态,对比学习等**,请同时了解 CV 和 NLP 模块。这将是你后续知识的基础。多模态我们没有完善的讲义推出,对比学习可以参见[4.6.8对比学习](4.6.8%E5%AF%B9%E6%AF%94%E5%AD%A6%E4%B9%A0.md) 。这是撰写者之一的论文阅读笔记,不保证准确性与理解是否准确,可以作为论文阅读路线图来参考~

View File

@@ -1,63 +0,0 @@
# Pytorch 安装
官网如下:
进入官网后选择 Install在下面表格中按照你的配置进行选择
![](https://cdn.xyxsw.site/boxcnxltvaT52E6mu6JIYaKvM1X.png)
其中 Package 部分选择安装的途径,这里主要介绍 Pip 和 Conda 两种途径。
# 通过 Pip 安装
Pip 在通过 python 官网下载 python 并安装时可以选择同时安装 pip不需要额外安装 Anaconda比较方便。
1. 根据你的系统、CUDA 版本等配置在表中选择,最后复制表格最下面生成的指令。
2. Win+R 唤出 cmd 命令行窗口,将指令粘贴并运行,然后会生成下载计划并在最后附上[y/n],输入 y 并等待下载完成即可。完整的环境大概有 2.9G 且从官网下载,如果没有挂梯子需要等待较长时间。也可以配置镜像源,方法按照接下来的步骤。
3. 对于 Windows 用户,在 C:\Users\xx\pip 目录下(没有 pip 目录就新建)创建一个 pip.ini 文件,并将下面代码块中内容复制进去:
4. 对于 Linux 用户,同样在~/.pip/pip.conf 进行配置。如果没有.pip 目录就新建,然后将下面代码块中内容复制进去:
```bash
[global]
index-url = http://pypi.douban.com/simple
extra-index-url = https://pypi.mirrors.ustc.edu.cn/simple/
https://mirrors.aliyun.com/pypi/simple/
https://pypi.tuna.tsinghua.edu.cn/simple/
https://pypi.org/simple/
trusted-host = pypi.mirrors.ustc.edu.cn
mirrors.aliyun.com
pypi.tuna.tsinghua.edu.cn
pypi.org
pypi.douban.com
```
# 通过 Conda 安装
因为 Conda 可以配置并切换虚拟环境,较为方便的下载各种库,这里更推荐使用 Conda 配环境。
1. 以管理员身份打开 Anaconda Prompt。这是一个操作 conda 的命令行窗口。不给管理员权限最后可能下载完成后无法安装。
2. 按照你的配置在官网选择,记得把 Package 改为 conda复制命令到 Anaconda Prompt 运行。
3. 接下来 conda 会开始 solving environment这个过程需要较长时间并且 conda 会自动尝试多次,笔者在重配环境时平均每次 solving environment 需要 15min 左右,这一过程结束后才开始获取并生成下载计划,最后显示[y/n]询问是否开始下载。输入 y 回车开始下载。过程中请保证网络稳定!!!否则会下载失败终止进程,需要重新输入命令开始下载并等待再次 solving environment相当折磨。
4. 如果需要加快下载速度,可以在 Anaconda 中添加新的 channel 来换源加快下载速度,方法主要有两种:一是通过 Anaconda Navigaiton在左边选择 Environments在上方选择 ChannelsAdd最后记得 Update Channels 即可(某些 channel 通过这种方式添加好像会显示 invalid,但是通过下一种方法却可以成功添加,原理未知);或者在 Anaconda Prompt 执行以下指令:
```bash
conda config --set show_channel_urls yes
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --show channels
```
# Tips关于如何查看自己设备信息
## Windows
同时按下 Win+R,运行 cmd,输入 `dxdiag` 并回车。系统、显卡、声卡以及其他设备信息都会显示。
![](https://cdn.xyxsw.site/boxcnepK0nkI8pWAJaO89zQoRgh.png)
cuda 版本查看
![](https://cdn.xyxsw.site/boxcnRoZEZsUdVduFRR9DjegeNh.png)

View File

@@ -1,61 +0,0 @@
# CV 领域任务(研究目标)
### CV 领域的大任务
![](https://cdn.xyxsw.site/boxcnTUlm8EI0byGJJQ78IqGWGx.png)
#### aImage classification **图像分类**
- 识别这个图片整体所属的类别,解决的是"what"问题,给这个图片打上相应的标签,在 a 图内标签是 `bottlecupcube`,其他类型的图片也都有它们自己的标签,然后把这些打上标签的图片带进网络结构里作为训练集训练。
#### bObject localization **目标检测**(对象定位)
- 识别图片中各个物体所在的位置,解决的是"where"问题,此处还细分两个问题:
- 定位:检测出图片中的物体位置,一般只需要进行画框。
- 检测:不仅想要知道这些物体所属的类别,还想知道他们所在的具体位置,比如这张图片有 `bottlecupcube`,我们不仅要检测出这些物体所在的位置,还要检测处在这个位置的物体所属的类别,这就是目标检测。
- 再看一个目标检测的例子(此处为 [Roboflow-数据集标注工具](https://roboflow.com/)的示例)
- 这张图我们需要标注两个类别 `head、helmet头盔`
![](https://cdn.xyxsw.site/boxcnoyxKL4bOeYOOjrh6it0BHd.gif)
#### cSemantic segmentation **语义分割**
- 语义分割需要进一步判断图像中哪些像素属于哪个目标(进阶目标检测)。
- 看图右下角两个 `cube` 是连在一块的 并没有分出哪一部分是哪一个的 `cube`
#### dInstance segmentation **实例分割**
- 实例分割需要区分出哪些像素属于第一个物体、哪些像素属于第二个物体,即目标检测 + 语义分割。
- 看图右下角两个 `cube` 是分开的
#### eKey Point 人体关键点检测
![](https://cdn.xyxsw.site/boxcnT2udZtMmV2kLQsXoPuElNd.png)
通过人体关键节点的组合和追踪来识别人的运动和行为,对于描述人体姿态,预测人体行为至关重要。
#### fScene Text RecognitionSTR场景文字识别
![](https://cdn.xyxsw.site/boxcnB8ZB4bSaHhIhPFHHrxkakb.png)
很多照片中都有一些文字信息,这对理解图像有重要的作用。
场景文字识别是在图像背景复杂、分辨率低下、字体多样、分布随意等情况下,将图像信息转化为文字序列的过程。
#### gPattern Generation 图像生成
利用两张图片或者其他信息生成一张新的图片
![](https://cdn.xyxsw.site/boxcnOdmG0c1kkivVdTn5RUMCIc.png)
利用左边两张小图生成右边的图片
#### hSuper Resolution 超分辨率
将输入图片分辨率增加
![](https://cdn.xyxsw.site/boxcnDJ5aNv49ySjw96uCCF0dW8.png)
当然还有一些新兴领域我们没有写入~

View File

@@ -1,194 +0,0 @@
# 数据读取
Torchvision 中默认使用的图像加载器是 PIL因此为了确保 Torchvision 正常运行,我们还需要安装一个 Python 的第三方图像处理库——Pillow 库。Pillow 提供了广泛的文件格式支持,强大的图像处理能力,主要包括图像储存、图像显示、格式转换以及基本的图像处理操作等。
我们先介绍 Torchvision 的常用数据集及其读取方法。
PyTorch 为我们提供了一种十分方便的数据读取机制,即使用 Dataset 类与 DataLoader 类的组合,来得到数据迭代器。在训练或预测时,数据迭代器能够输出每一批次所需的数据,并且对数据进行相应的预处理与数据增强操作。
下面我们分别来看下 Dataset 类与 DataLoader 类。
# Dataset 类
PyTorch 中的 Dataset 类是一个抽象类,它可以用来表示数据集。我们通过继承 Dataset 类来自定义数据集的格式、大小和其它属性,后面就可以供 DataLoader 类直接使用。
其实这就表示,无论使用自定义的数据集,还是官方为我们封装好的数据集,其本质都是继承了 Dataset 类。而在继承 Dataset 类时,至少需要重写以下几个方法:
- __init__():构造函数,可自定义数据读取方法以及进行数据预处理;
- __len__():返回数据集大小;
- __getitem__():索引数据集中的某一个数据。
下面我们来编写一个简单的例子,看下如何使用 Dataset 类定义一个 Tensor 类型的数据集。
```python
import torch
from torch.utils.data import Dataset
class MyDataset(Dataset):
# 构造函数
def __init__(self, data_tensor, target_tensor):
self.data_tensor = data_tensor
self.target_tensor = target_tensor
# 返回数据集大小
def __len__(self):
return self.data_tensor.size(0)
# 返回索引的数据与标签
def __getitem__(self, index):
return self.data_tensor[index], self.target_tensor[index]
'''
我们定义了一个名字为 MyDataset 的数据集,在构造函数中,传入 Tensor 类型的数据与标签;
在 __len__ 函数中,直接返回 Tensor 的大小;在 __getitem__ 函数中返回索引的数据与标签。
'''
```
然后我们来看一下如何调用刚才定义的数据集。首先随机生成一个 10*3 维的数据 Tensor然后生成 10 维的标签 Tensor与数据 Tensor 相对应。利用这两个 Tensor生成一个 MyDataset 的对象。查看数据集的大小可以直接用 len() 函数,索引调用数据可以直接使用下标。
```python
# 生成数据
data_tensor = torch.randn(10, 3)
target_tensor = torch.randint(2, (10,)) # 标签是0或1
# 生成10个随机数随机数的范围只能是0或者1
# 将数据封装成Dataset
my_dataset = MyDataset(data_tensor, target_tensor)
# 查看数据集大小
print('Dataset size:', len(my_dataset))
# 使用索引调用数据
print('tensor_data[0]: ', my_dataset[0])
```
# DataLoader 类
在实际项目中如果数据量很大考虑到内存有限、I/O 速度等问题,在训练过程中不可能一次性的将所有数据全部加载到内存中,也不能只用一个进程去加载,所以就需要多进程、迭代加载,而 DataLoader 就是基于这些需要被设计出来的。
DataLoader 是一个迭代器,最基本的使用方法就是传入一个 Dataset 对象,它会根据参数 batch_size 的值生成一个 batch 的数据,节省内存的同时,它还可以实现多进程、数据打乱等处理。
DataLoader 类的调用方式如下:
```python
from torch.utils.data import DataLoader
tensor_dataloader = DataLoader(dataset=my_dataset, # 传入的数据集, 必须参数
batch_size=2, # 输出的batch大小
shuffle=True, # 数据是否打乱
num_workers=0) # 进程数, 0表示只有主进程
# 以循环形式输出
for data, target in tensor_dataloader:
print(data, target)
'''
输出:
tensor([[-0.1781, -1.1019, -0.1507],
[-0.6170, 0.2366, 0.1006]]) tensor([0, 0])
tensor([[ 0.9451, -0.4923, -1.8178],
[-0.4046, -0.5436, -1.7911]]) tensor([0, 0])
tensor([[-0.4561, -1.2480, -0.3051],
[-0.9738, 0.9465, 0.4812]]) tensor([1, 0])
tensor([[ 0.0260, 1.5276, 0.1687],
[ 1.3692, -0.0170, -1.6831]]) tensor([1, 0])
tensor([[ 0.0515, -0.8892, -0.1699],
[ 0.4931, -0.0697, 0.4171]]) tensor([1, 0])
'''
# 输出一个batch(用iter()强制类型转换成迭代器的对象next()是输出迭代器下一个元素)
print('One batch tensor data: ', iter(tensor_dataloader).next())
'''
输出:
One batch tensor data: [tensor([[ 0.9451, -0.4923, -1.8178],
[-0.4046, -0.5436, -1.7911]]), tensor([0, 0])]
'''
```
结合代码,我们梳理一下 DataLoader 中的几个参数,它们分别表示:
- datasetDataset 类型,输入的数据集,必须参数;
- batch_sizeint 类型,每个 batch 有多少个样本;
- shufflebool 类型,在每个 epoch 开始的时候,是否对数据进行重新打乱;
- num_workersint 类型加载数据的进程数0 意味着所有的数据都会被加载进主进程,默认为 0。
**思考题**
按照上述代码One batch tensor data 的输出是否正确,若不正确,为什么?
# 利用 Torchvision 读取数据
Torchvision 库中的 torchvision.datasets 包中提供了丰富的图像数据集的接口。常用的图像数据集,例如 MNIST、COCO 等,这个模块都为我们做了相应的封装。
下表中列出了 torchvision.datasets 包所有支持的数据集。各个数据集的说明与接口,详见链接 [https://pytorch.org/vision/stable/datasets.html](https://pytorch.org/vision/stable/datasets.html)。
![](https://cdn.xyxsw.site/boxcnxvqC7FKt1qeCZoI2kVf9yg.png)
注意torchvision.datasets 这个包本身并不包含数据集的文件本身,它的工作方式是先从网络上把数据集下载到用户指定目录,然后再用它的加载器把数据集加载到内存中。最后,把这个加载后的数据集作为对象返回给用户。
为了让你进一步加深对知识的理解,我们以 MNIST 数据集为例,来说明一下这个模块具体的使用方法。
# MNIST 数据集简介
MNIST 数据集是一个著名的手写数字数据集,因为上手简单,在深度学习领域,手写数字识别是一个很经典的学习入门样例。
MNIST 数据集是 NIST 数据集的一个子集MNIST 数据集你可以通过[这里](http://yann.lecun.com/exdb/mnist/)下载。它包含了四个部分。
![](https://cdn.xyxsw.site/boxcnCP2Sp932nPy8Il5Z5d4Aih.png)
MNIST 数据集是 ubyte 格式存储,我们先将“训练集图片”解析成图片格式,来直观地看一看数据集具体是什么样子的。具体怎么解析,我们在后面数据预览再展开。
![](https://cdn.xyxsw.site/boxcnjsG31hhjqdxOnoCGFGR6sh.png)
接下来,我们看一下如何使用 Torchvision 来读取 MNIST 数据集。
对于 torchvision.datasets 所支持的所有数据集,它都内置了相应的数据集接口。例如刚才介绍的 MNIST 数据集torchvision.datasets 就有一个 MNIST 的接口,接口内封装了从下载、解压缩、读取数据、解析数据等全部过程。
这些接口的工作方式差不多,都是先从网络上把数据集下载到指定目录,然后再用加载器把数据集加载到内存中,最后将加载后的数据集作为对象返回给用户。
以 MNIST 为例,我们可以用如下方式调用:
```python
# 以MNIST为例
import torchvision
mnist_dataset = torchvision.datasets.MNIST(root='./data',
train=True,
transform=None,
target_transform=None,
download=True)
```
torchvision.datasets.MNIST 是一个类,对它进行实例化,即可返回一个 MNIST 数据集对象。构造函数包括包含 5 个参数:
- root是一个字符串用于指定你想要保存 MNIST 数据集的位置。如果 download 是 Flase则会从目标位置读取数据集
- download布尔类型表示是否下载数据集。如果为 True则会自动从网上下载这个数据集存储到 root 指定的位置。如果指定位置已经存在数据集文件,则不会重复下载;
- train布尔类型表示是否加载训练集数据。如果为 True则只加载训练数据。如果为 False则只加载测试数据集。这里需要注意并不是所有的数据集都做了训练集和测试集的划分这个参数并不一定是有效参数具体需要参考官方接口说明文档
- transform用于对图像进行预处理操作例如数据增强、归一化、旋转或缩放等。这些操作我们会在下节课展开讲解
- target_transform用于对图像标签进行预处理操作。
运行上述的代码后,程序会首先去指定的网址下载了 MNIST 数据集,然后进行了解压缩等操作。如果你再次运行相同的代码,则不会再有下载的过程。
如果你用 type 函数查看一下 mnist_dataset 的类型,就可以得到 torchvision.datasets.mnist.MNIST ,而这个类是之前我们介绍过的 Dataset 类的派生类。相当于 torchvision.datasets ,它已经帮我们写好了对 Dataset 类的继承,完成了对数据集的封装,我们直接使用即可。
这里我们主要以 MNIST 为例进行了说明。其它的数据集使用方法类似调用的时候你只要需要将类名“MNIST”换成其它数据集名字即可。
# 数据预览
完成了数据读取工作,我们得到的是对应的 mnist_dataset刚才已经讲过了这是一个封装了的数据集。
如果想要查看 mnist_dataset 中的具体内容,我们需要把它转化为列表。(如果 IOPub data rate 超限,可以只加载测试集数据,令 train=False
```python
mnist_dataset_list = list(mnist_dataset)
print(mnist_dataset_list)
```
转换后的数据集对象变成了一个元组列表,每个元组有两个元素,第一个元素是图像数据,第二个元素是图像的标签。
这里图像数据是 PIL.Image.Image 类型的,这种类型可以直接在 Jupyter 中显示出来。显示一条数据的代码如下。
```python
display(mnist_dataset_list[0][0])
print("Image label is:", mnist_dataset_list[0][1])
```
上面介绍了两种读取数据的方法,也就是自定义和读取常用图像数据集。最通用的数据读取方法,就是自己定义一个 Dataset 的派生类。而读取常用的图像数据集,就可以利用 PyTorch 提供的视觉包 Torchvision。
极客时间版权所有: [https://time.geekbang.org/column/article/429826](https://time.geekbang.org/column/article/429826)
(有删改)

View File

@@ -1,340 +0,0 @@
# 数据增强
仅仅将数据集中的图片读取出来是不够的,在训练的过程中,神经网络模型接收的数据类型是 Tensor而不是 PIL 对象,因此我们还需要对数据进行预处理操作,比如图像格式的转换。
我们对一张数据进行裁剪,很明显裁剪前后我们都可以辨认图片中的物体,但是我们的神经网络却没有这个能力。所以我们在训练前可能还需要对图像数据进行一系列图像变换与增强操作,例如裁切边框、调整图像比例和大小、标准化等,对同一张图片进行多种处理并送入神经网络进行训练,以便模型能够更好地学习到数据的特征。而这些操作都可以使用 torchvision.transforms 工具完成。
# Torchvision.transforms
Torchvision 库中的 torchvision.transforms 包中提供了常用的图像操作,包括对 Tensor 及 PIL Image 对象的操作,例如随机切割、旋转、数据类型转换等等。
按照 torchvision.transforms 的功能,大致分为以下几类:数据类型转换、对 PIL.Image 和 Tensor 进行变化和变换的组合。
## 数据类型转换
读取数据集中的图片,读取到的数据是 PIL.Image 的对象。而在模型训练阶段,需要传入 Tensor 类型的数据,神经网络才能进行运算。
那么如何将 PIL.Image 或 Numpy.ndarray 格式的数据转化为 Tensor 格式呢?这需要用到 transforms.ToTensor() 类。
而反之,将 Tensor 或 Numpy.ndarray 格式的数据转化为 PIL.Image 格式,则使用 transforms.ToPILImage(mode=None) 类。它则是 ToTensor 的一个逆操作,它能把 Tensor 或 Numpy 的数组转换成 PIL.Image 对象。
其中,参数 mode 代表 PIL.Image 的模式,如果 mode 为 None默认值则根据输入数据的维度进行推断
- 输入为 3 通道mode 为RGB
- 输入为 4 通道mode 为RGBA
- 输入为 2 通道mode 为LA;
- 输入为单通道mode 根据输入数据的类型确定具体模式。
我们来看一个具体的例子加深理解。将图片进行一下数据类型的相互转换。具体代码如下:
```python
from PIL import Image
from torchvision import transforms
img = Image.open('tupian.jpg')
display(img)
print(type(img)) # PIL.Image.Image是PIL.JpegImagePlugin.JpegImageFile的基类
'''
输出:
<class 'PIL.JpegImagePlugin.JpegImageFile'>
'''
# PIL.Image转换为Tensor
img1 = transforms.ToTensor()(img)
print(type(img1))
'''
输出:
<class 'torch.Tensor'>
'''
# Tensor转换为PIL.Image
img2 = transforms.ToPILImage()(img1) #PIL.Image.Image
print(type(img2))
'''
输出:
<class 'PIL.Image.Image'>
'''
```
首先用读取图片,查看一下图片的类型为 PIL.JpegImagePlugin.JpegImageFile这里需要注意**PIL.JpegImagePlugin.JpegImageFile 类是 PIL.Image.Image 类的子类**。然后,用 transforms.ToTensor() 将 PIL.Image 转换为 Tensor。最后再将 Tensor 转换回 PIL.Image。
## 对 PIL.Image 和 Tensor 进行变换
torchvision.transforms 提供了丰富的图像变换方法,例如:改变尺寸、剪裁、翻转等。并且这些图像变换操作可以接收多种数据格式,不仅可以直接对 PIL 格式的图像进行变换,也可以对 Tensor 进行变换,无需我们再去做额外的数据类型转换。
### Resize
将输入的 PIL Image 或 Tensor 尺寸调整为给定的尺寸,具体定义为:
```python
torchvision.transforms.Resize(size, interpolation=2)
```
- size期望输出的尺寸。如果 size 是一个像 (h, w) 这样的元组,则图像输出尺寸将与之匹配。如果 size 是一个 int 类型的整数,图像较小的边将被匹配到该整数,另一条边按比例缩放。
- interpolation插值算法我们在这里使其接收一个 int 类型 2表示 PIL.Image.BILINEAR(双线性插值,感兴趣可以自己单独了解,这个算法的应用比较广泛),但是需要注意的是当该参数接受 int 类型时会出现 warning这个无需担心也可以正常使用。
有关 Size 中是 tuple 还是 int 这一点请你一定要注意。
让我说明一下,在我们训练时,通常要把图片 resize 到一定的大小,比如说 128x128256x256 这样的。如果直接给定 resize 后的高与宽,是没有问题的。但如果设定的是一个 int 型,较长的边就会按比例缩放。
在 resize 之后呢,一般会接一个 crop 操作crop 到指定的大小。对于高与宽接近的图片来说,这么做问题不大,但是高与宽的差距较大时,就会 crop 掉很多有用的信息。关于这一点,我们在后续的图像分类部分还会遇到,到时我在详细展开。
```python
from PIL import Image
from torchvision import transforms
# 定义一个Resize操作
resize_img_oper = transforms.Resize((200,200), interpolation=2)
# 原图
orig_img = Image.open('tupian.jpg')
display(orig_img)
# Resize操作后的图
img = resize_img_oper(orig_img)
display(img)
```
首先定义一个 Resize 操作,设置好变换后的尺寸为 (200, 200),然后对图片进行 Resize 变换。
### 裁剪
torchvision.transforms 提供了多种剪裁方法,例如中心剪裁、随机剪裁、四角和中心剪裁等。我们依次来看下它们的定义。
先说中心剪裁,在中心裁剪指定的 PIL Image 或 Tensor其定义如下
```python
torchvision.transforms.CenterCrop(size)
```
其中size 表示期望输出的剪裁尺寸。如果 size 是一个像 (h, w) 这样的元组,则剪裁后的图像尺寸将与之匹配。如果 size 是 int 类型的整数,剪裁出来的图像是 (size, size) 的正方形。
然后是随机剪裁,在一个随机位置剪裁指定的 PIL Image 或 Tensor定义如下
```python
torchvision.transforms.RandomCrop(size, padding=None)
```
其中size 代表期望输出的剪裁尺寸,用法同上。而 padding 表示图像的每个边框上的可选填充。默认值是 None即没有填充。通常来说不会用 padding 这个参数,至少对于我来说至今没用过。
最后要说的是 FiveCrop我们将给定的 PIL Image 或 Tensor ,分别从四角和中心进行剪裁,共剪裁成五块,定义如下:
```python
torchvision.transforms.FiveCrop(size)
```
size 可以是 int 或 tuple用法同上。掌握了各种剪裁的定义和参数用法以后我们来看一下这些剪裁操作具体如何调用代码如下
```python
from PIL import Image
from torchvision import transforms
# 定义剪裁操作
center_crop_oper = transforms.CenterCrop((60,70))
random_crop_oper = transforms.RandomCrop((80,80))
five_crop_oper = transforms.FiveCrop((60,70))
# 原图
orig_img = Image.open('tupian.jpg')
display(orig_img)
# 中心剪裁
img1 = center_crop_oper(orig_img)
display(img1)
# 随机剪裁
img2 = random_crop_oper(orig_img)
display(img2)
# 四角和中心剪裁
imgs = five_crop_oper(orig_img)
for img in imgs:
display(img)
```
### 翻转
接下来我们来看一看翻转操作。torchvision.transforms 提供了两种翻转操作,分别是:以某一概率随机水平翻转图像和以某一概率随机垂直翻转图像。我们分别来看它们的定义。
以概率 p 随机水平翻转图像,定义如下:
```python
torchvision.transforms.RandomHorizontalFlip(p=0.5)
```
以概率 p 随机垂直翻转图像,定义如下:
```python
torchvision.transforms.RandomVerticalFlip(p=0.5)
```
其中p 表示随机翻转的概率值,默认为 0.5
这里的随机翻转,是为数据增强提供方便。如果想要必须执行翻转操作的话,将 p 设置为 1 即可。图片翻转代码如下:
```python
from PIL import Image
from torchvision import transforms
# 定义翻转操作
h_flip_oper = transforms.RandomHorizontalFlip(p=1)
v_flip_oper = transforms.RandomVerticalFlip(p=1)
# 原图
orig_img = Image.open('tupian.jpg')
display(orig_img)
# 水平翻转
img1 = h_flip_oper(orig_img)
display(img1)
# 垂直翻转
img2 = v_flip_oper(orig_img)
display(img2)
```
### 只对 Tensor 进行变换
目前版本的 Torchvisionv0.10.0)对各种图像变换操作已经基本同时支持 PIL Image 和 Tensor 类型了,因此只针对 Tensor 的变换操作很少,只有 4 个,分别是 LinearTransformation线性变换、Normalize标准化、RandomErasing随机擦除、ConvertImageDtype格式转换
这里我们重点来看最常用的一个操作:标准化,其他 3 个你可以查阅官方文档。
### 标准化
标准化是指每一个数据点减去所在通道的平均值再除以所在通道的标准差数学的计算公式output=(inputmean)/std
而对图像进行标准化,就是对图像的每个通道利用均值和标准差进行正则化。这样做的目的,是**为了保证数据集中所有的图像分布都相似,这样在训练的时候更容易收敛,既加快了训练速度,也提高了训练效果**。
让我来解释一下:首先,标准化是一个常规做法,可以理解为无脑进行标准化后再训练的效果,大概率要好于不进行标准化。
如果我们把一张图片上的每个像素点都减去某一数值得到一张新的图片,但在我们眼里他们还是内容一样的两张图片,只是颜色有一些不同。但卷积神经网络是通过图像的像素进行提取特征的,两张图片像素的数值都一样,如何让神经网络认为是一张图片?
而标准化后的数据就会避免这一问题,标准化后会将数据映射到同一区间中,一个类别的图片虽说有的像素值可能有差异,但是它们分布都是类似的分布。
torchvision.transforms 提供了对 Tensor 进行标准化的函数,定义如下:
```python
torchvision.transforms.Normalize(mean, std, inplace=False)
```
其中,每个参数的含义如下所示:
- mean表示各通道的均值
- std表示各通道的标准差
- inplace表示是否原地操作默认为否。
我们来看看以 (R, G, B) 均值和标准差均为 (0.5, 0.5, 0.5) 来标准化图片后,是什么效果:
```python
from PIL import Image
from torchvision import transforms
# 定义标准化操作
norm_oper = transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
# 原图
orig_img = Image.open('tupian.jpg')
display(orig_img)
# 图像转化为Tensor
img_tensor = transforms.ToTensor()(orig_img)
# 标准化
tensor_norm = norm_oper(img_tensor)
# Tensor转化为图像
img_norm = transforms.ToPILImage()(tensor_norm)
display(img_norm)
```
我们首先定义了均值和标准差均为 (0.5, 0.5, 0.5) 的标准化操作,然后将原图转化为 Tensor接着对 Tensor 进行标准化,最后再将 Tensor 转化为图像输出。
### 变换的组合
其实前面介绍过的所有操作都可以用 Compose 类组合起来,进行连续操作。
Compose 类是将多个变换组合到一起,它的定义如下:
```python
torchvision.transforms.Compose(transforms)
```
其中transforms 是一个 Transform 对象的列表,表示要组合的变换列表。
我们还是结合例子动手试试,如果我们想要将图片变为 200*200 像素大小,并且随机裁切成 80 像素的正方形。那么我们可以组合 Resize 和 RandomCrop 变换,具体代码如下所示:
```python
from PIL import Image
from IPython.display import display
from torchvision import transforms
# 原图
orig_img = Image.open('tupian.jpg')
display(orig_img)
# 定义组合操作
composed = transforms.Compose([transforms.Resize((200, 200)),
transforms.RandomCrop(80)])
# 组合操作后的图
img = composed(orig_img)
display(img)
```
### 结合 datasets 使用
Compose 类是未来我们在实际项目中经常要使用到的类,结合 torchvision.datasets 包,就可以在读取数据集的时候做图像变换与数据增强操作。
在利用 torchvision.datasets 读取 MNIST 数据集时有一个参数“transform”它就是用于对图像进行预处理操作的例如数据增强、归一化、旋转或缩放等。这里的“transform”就可以接收一个 torchvision.transforms 操作或者由 Compose 类所定义的操作组合。
我们在读取 MNIST 数据集时,直接读取出来的图像数据是 PIL.Image.Image 类型的。但是遇到要训练手写数字识别模型这类的情况,模型接收的数据类型是 Tensor而不是 PIL 对象。这时候我们就可以利用“transform”参数使数据在读取的同时做类型转换这样读取出的数据直接就可以是 Tensor 类型了。
不只是数据类型的转换,我们还可以增加归一化等数据增强的操作,只需要使用上面介绍过的 Compose 类进行组合即可。这样,在读取数据的同时,我们也就完成了数据预处理、数据增强等一系列操作。
我们还是以读取 MNIST 数据集为例,看下如何在读取数据的同时,完成数据预处理等操作。具体代码如下:
```python
from torchvision import transforms
from torchvision import datasets
# 定义一个transform
my_transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5), (0.5))
])
# 读取MNIST数据集 同时做数据变换
mnist_dataset = datasets.MNIST(root='./data',
train=False,
transform=my_transform,
target_transform=None,
download=True)
# 查看变换后的数据类型
item = mnist_dataset.__getitem__(0)
print(type(item[0]))
'''
输出:
<class 'torch.Tensor'>
'''
```
当然MNIST 数据集非常简单,根本不进行任何处理直接读入的话,效果也非常好,但是它确实适合学习来使用,你可以在利用它进行各种尝试。
我们下面先来看看,在图像分类实战中使用的 transform可以感受一下实际使用的 transforms 是什么样子:
```python
transform = transforms.Compose([
transforms.RandomResizedCrop(dest_image_size),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
```
常用的图像处理操作包括数据类型转换、图像尺寸变化、剪裁、翻转、标准化等等。Compose 类还可以将多个变换操作组合成一个 Transform 对象的列表。
torchvision.transforms 与 torchvision.datasets 结合使用,可以在数据加载的同时进行一系列图像变换与数据增强操作,不仅能够直接将数据送入模型训练,还可以加快模型收敛速度,让模型更好地学习到数据特征。
当然,我们在实际的项目中会有自己的数据,而不会使用 torchvision.datasets 中提供的公开数据集,我们今天讲的 torchvision.transforms 同样可以在我们自定义的数据集中使用,这里不再详细讲述。
极客时间版权所有: [https://time.geekbang.org/column/article/429826](https://time.geekbang.org/column/article/429826)
(有删改)

View File

@@ -1,17 +0,0 @@
# 数据预处理torchvision
不管我们的网络设计的有多复杂,选择什么样的优化器和损失函数,我们在训练模型时首先需要面对的是如何处理我们的数据。最简单的一个问题,我们需要怎么把数据拿过来送进我们的网络中呢(数据读取)。还有,我们把数据送进去之前还需要对其进行一些什么操作呢。
PyTorch 为我们提供了丰富的 API 以供我们方便的进行学习。
torchvision 是 pytorch 的一个图形库,其中还提供一些常用的数据集和几个已经搭建好的经典网络模型,以及一些图像数据处理方面的工具,主要供数据预处理阶段使用。它服务于 PyTorch 深度学习框架,主要用来构建计算机视觉模型。以下是 torchvision 的构成:
torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
torchvision.models: 包含常用的模型结构(含预训练模型),例如 AlexNet、VGG、ResNet 等;
torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;
torchvision.utils: 其他的一些有用的方法。
这部分是讲解如何读取数据集和处理数据集,如果你不是想真正上手写深度学习的代码,可以无视这块。

View File

@@ -1,61 +0,0 @@
# AlexNet
所谓“深度”学习的开山之作。
AlexNet 有 6 千万个参数和 650,000 个神经元。
虽然一些理念和方式已经略有过时,但仍然是入门非常有必要读的一篇论文
[知乎](https://zhuanlan.zhihu.com/p/42914388)
[论文](http://www.cs.toronto.edu/~fritz/absps/imagenet.pdf)
### **网络框架图**
![](https://cdn.xyxsw.site/boxcng0jB2dmDD18EwU8nAIFPIc.png)
### **使用 ReLU 激活函数代替 tanh**
在当时,标准的神经元激活函数是 tanh()函数,这种饱和的非线性函数在梯度下降的时候要比非饱和的非线性函数慢得多,因此,在 AlexNet 中使用 ReLU 函数作为激活函数。
![](https://cdn.xyxsw.site/boxcnFlENdpKXUR7l4MhUXFKzfg.png)
### **采用 Dropout 防止过拟合**
dropout 方法会遍历网络的每一层,并设置消除神经网络中节点的概率。假设网络中的每一层,每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是 0.5,设置完节点概率,我们会消除一些节点,然后删除掉从该节点进出的连线,最后得到一个节点更少,规模更小的网络(如下图所示),然后再用反向传播方法进行训练。
![](https://cdn.xyxsw.site/boxcnNXzBUtJWXbUtEZzxugBr6W.png)
![](https://cdn.xyxsw.site/boxcn7kG0PcXNumIdTFuEdaHl0e.png)
###
###
### **视频讲解**
# 思考
### 思考 1
AlexNet 中有着卷积和 MLP 两种不同的网络结构,那两者之间有着何种区别和联系呢?(可以从两者的权值矩阵去思考)
### **思考 2**
卷积中有一个叫感受野的概念,是什么意思呢?不同的感受野对网络有什么影响?
### 思考 3
CNN 的平移不变性是什么意思?
### 思考 4
分成两块来训练是一个历史遗留问题,后面接线性层也是历史问题,可以思考一下为什么并且你会在下一章中得到一定的答案。
### 思考 5
这里面提出了 relu 激活函数,你在这章知道 relu 是怎么样的函数,那么它是怎么样实现线性与非线性的转化呢
### 思考 6
前面学习中你已经掌握了卷积,那卷积是怎样实现特征提取的呢。

View File

@@ -1,51 +0,0 @@
# FCN
图像分割领域的开山之作。
首次将**End-to-End**的思想应用在了 CV 领域。
[知乎](https://zhuanlan.zhihu.com/p/30195134)
[论文](https://arxiv.org/pdf/1411.4038.pdf)
### 框架图
![](https://cdn.xyxsw.site/boxcndYCXYj7rNfhXoSaEPZxpyc.png)
### 同 CNN 的对比
通常 CNN 网络在卷积层之后会接上若干个全连接层, 将卷积层产生的特征图(feature map)映射成一个固定长度的特征向量。以 AlexNet 为代表的经典 CNN 结构适合于图像级的分类和回归任务,因为它们最后都期望得到整个输入图像的一个数值描述,比如 AlexNet 的 ImageNet 模型输出一个 1000 维的向量表示输入图像属于每一类的概率。
FCN 对图像进行像素级的分类,从而解决了语义级别的图像分割问题。与经典的 CNN 在卷积层之后使用全连接层得到固定长度的特征向量进行分类不同FCN 可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的 feature map 进行上采样, 使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测, 同时保留了原始输入图像中的空间信息, 最后在上采样的特征图上进行逐像素分类。
**简单的来说FCN 与 CNN 的区域在把于 CNN 最后的全连接层换成卷积层,输出的是一张已经 Label 好的图片。**
### 反卷积
这里提到的反卷积FCN 作者称为 backwards convolution有人称 Deconvolution layer is a very unfortunate name and should rather be called a transposed convolutional layer. 我们可以知道,在 CNN 中有 con layer 与 pool layercon layer 进行对图像卷积提取特征pool layer 对图像缩小一半筛选重要特征,对于经典的图像识别 CNN 网络,如 IMAGENET最后输出结果是 1X1X10001000 是类别种类1x1 得到的是。FCN 作者,或者后来对 end to end 研究的人员,就是对最终 1x1 的结果使用反卷积(事实上 FCN 作者最后的输出不是 1X1是图片大小的 32 分之一,但不影响反卷积的使用)。
这里图像的反卷积使用了这一种反卷积手段使得图像可以变大FCN 作者使用的方法是这里所说反卷积的一种变体,这样就可以获得相应的像素值,图像可以实现 end to end。
![](https://cdn.xyxsw.site/boxcngqgiogbvy4OYpIzIo6eSXd.png)
### 视频
# 思考
## 思考 1
什么是端到端End-to-End
端到端的网络有什么优点?
## 思考 2
关于反卷积,你理解了吗?
## 思考 3
FCN 的任务和上一篇论文 AlexNet 有什么区别,从对图像的最终预测延伸到数学上是哪两种模型?
## 思考 4
在该文中提到的语义分割是什么意思呢?语义又代表什么?

View File

@@ -1,211 +0,0 @@
# ResNet
::: warning 🕶
残差神经网络(ResNet)是由微软研究院的何恺明大神团队提出的一个经典网络模型,一经现世就成为了沿用至今的超级 Backbone。
:::
[知乎](https://zhuanlan.zhihu.com/p/101332297)
[论文](https://arxiv.org/pdf/1512.03385.pdf)
## WHY residual?
::: warning 🎨
在 ResNet 提出之前,所有的神经网络都是通过卷积层和池化层的叠加组成的。
人们认为卷积层和池化层的层数越多,获取到的图片特征信息越全,学习效果也就越好。但是在实际的试验中发现,随着卷积层和池化层的叠加,不但没有出现学习效果越来越好的情况,反而出现两种问题:
- 梯度消失和梯度爆炸
梯度消失:若每一层的梯度误差小于 1反向传播时网络越深梯度越趋近于 0
梯度爆炸:若每一层的梯度误差大于 1反向传播时网络越深梯度越趋近于无穷大
- 退化现象
如图所示,随着层数越来越深,预测的效果反而越来越差(error 越大)
:::
![](https://cdn.xyxsw.site/boxcnBDfBnOPmS0btwNseKvsN6f.png)
## 网络模型
![](https://cdn.xyxsw.site/boxcnn8a16DYyEPEVuHxvvw7eAf.png)
::: warning 😺
我们可以看到ResNet 的网络依旧非常深,这是因为研究团队不仅发现了退化现象,还采用出一个可以将网络继续加深的 trickshortcut亦即我们所说的 residual。
- 为了解决梯度消失或梯度爆炸问题ResNet 论文提出通过数据的预处理以及在网络中使用 BNBatch Normalization层来解决。
- 为了解决深层网络中的退化问题,可以人为地让神经网络某些层跳过下一层神经元的连接,隔层相连,弱化每层之间的强联系。这种神经网络被称为 残差网络 (ResNets)。ResNet 论文提出了 residual 结构(残差结构)来减轻退化问题。
:::
### residual 结构
![](https://cdn.xyxsw.site/boxcnhgVaLChu3O2omGJKzFU7uB.png)
## 网络代码
```python
import torch.nn as nn
import torch
# ResNet18/34的残差结构用的是2个3x3的卷积
class BasicBlock(nn.Module):
expansion = 1 # 残差结构中主分支的卷积核个数是否发生变化不变则为1
def __init__(self, in_channel, out_channel, stride=1, downsample=None): # downsample对应虚线残差结构
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,
kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channel)
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel,
kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(out_channel)
self.downsample = downsample
def forward(self, x):
identity = x
if self.downsample is not None: # 虚线残差结构,需要下采样
identity = self.downsample(x) # 捷径分支 short cut
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out += identity
out = self.relu(out)
return out
# ResNet50/101/152的残差结构用的是1x1+3x3+1x1的卷积
class Bottleneck(nn.Module):
expansion = 4 # 残差结构中第三层卷积核个数是第一/二层卷积核个数的4倍
def __init__(self, in_channel, out_channel, stride=1, downsample=None):
super(Bottleneck, self).__init__()
self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,
kernel_size=1, stride=1, bias=False) # squeeze channels
self.bn1 = nn.BatchNorm2d(out_channel)
# -----------------------------------------
self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel,
kernel_size=3, stride=stride, bias=False, padding=1)
self.bn2 = nn.BatchNorm2d(out_channel)
# -----------------------------------------
self.conv3 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel * self.expansion,
kernel_size=1, stride=1, bias=False) # unsqueeze channels
self.bn3 = nn.BatchNorm2d(out_channel * self.expansion)
self.relu = nn.ReLU(inplace=True)
self.downsample = downsample
def forward(self, x):
identity = x
if self.downsample is not None:
identity = self.downsample(x) # 捷径分支 short cut
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
out += identity
out = self.relu(out)
return out
class ResNet(nn.Module):
# block = BasicBlock or Bottleneck
# block_num为残差结构中conv2_x~conv5_x中残差块个数是一个列表
def __init__(self, block, blocks_num, num_classes=1000, include_top=True):
super(ResNet, self).__init__()
self.include_top = include_top
self.in_channel = 64
self.conv1 = nn.Conv2d(3, self.in_channel, kernel_size=7, stride=2,
padding=3, bias=False)
self.bn1 = nn.BatchNorm2d(self.in_channel)
self.relu = nn.ReLU(inplace=True)
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
self.layer1 = self._make_layer(block, 64, blocks_num[0]) # conv2_x
self.layer2 = self._make_layer(block, 128, blocks_num[1], stride=2) # conv3_x
self.layer3 = self._make_layer(block, 256, blocks_num[2], stride=2) # conv4_x
self.layer4 = self._make_layer(block, 512, blocks_num[3], stride=2) # conv5_x
if self.include_top:
self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) # output size = (1, 1)
self.fc = nn.Linear(512 * block.expansion, num_classes)
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
# channel为残差结构中第一层卷积核个数
def _make_layer(self, block, channel, block_num, stride=1):
downsample = None
# ResNet50/101/152的残差结构block.expansion=4
if stride != 1 or self.in_channel != channel * block.expansion:
downsample = nn.Sequential(
nn.Conv2d(self.in_channel, channel * block.expansion, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(channel * block.expansion))
layers = []
layers.append(block(self.in_channel, channel, downsample=downsample, stride=stride))
self.in_channel = channel * block.expansion
for _ in range(1, block_num):
layers.append(block(self.in_channel, channel))
return nn.Sequential(*layers)
def forward(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
if self.include_top:
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.fc(x)
return x
def resnet34(num_classes=1000, include_top=True):
return ResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)
def resnet101(num_classes=1000, include_top=True):
return ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes, include_top=include_top)
'''
我们希望你能够去将论文下载下来以后跟一些讲解视频尝试将论文与代码结合起来理解
看论文的源码是我们必须要做的一个中重要的工作
'''
```
## 视频
<Bilibili bvid='BV1P3411y7nn'/>
## 思考
### 思考 1
::: warning 🤔
请你自行了解网络结构中的 BNBatch Normalization这是很重要的一个 normalization 操作,如果感兴趣还可以继续了解 LN (Layer Normalization)
:::
### 思考 2
::: warning 🤔
你觉得论文中提出用 residual 这一解决方法来解决网络的退化现象的依据是什么,如果可以,请你进一步尝试用数学角度思考这一问题
:::

View File

@@ -1,64 +0,0 @@
# UNet
[论文](https://arxiv.org/pdf/1505.04597.pdf)
[博客](https://blog.csdn.net/Formlsl/article/details/80373200)
[博客 2](https://blog.csdn.net/BreakingDawn0/article/details/103435768?spm=1001.2101.3001.6650.16&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-16-103435768-blog-87979765.t5_layer_targeting_s&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-16-103435768-blog-87979765.t5_layer_targeting_s&utm_relevant_index=19)
## 网络框架
![](https://cdn.xyxsw.site/boxcnoo4bKuLo5qQdQmRP2H75Sb.png)
::: warning 😺
2015 年OlafRonneberger 等人提出了 U-net 网络结构U-net 网络是基于 FCN 的一种语义分割网络,适用于做医学图像的分割
U-net 网络结构与 FCN 网络结构相似,也是分为下采样阶段和上采样阶段,网络结构中只有卷积层和池化层,没有全连接层,网络中较浅的高分辨率层用来解决像素定位的问题,较深的层用来解决像素分类的问题,从而可以实现图像语义级别的分割,与 FCN 网络不同的是U-net 的上采样阶段与下采样阶段采用了相同数量层次的卷积操作,且使用 skip connection 结构将下采样层与上采样层相连,使得下采样层提取道的特征可以直接传递到上采样层,这使得 U-net 网络的像素定位更加准确分割精度更高。此外在训练过程中U-net 只需要一次训练FCN 为达到较精确的 FCN-8s 结构需要三次训练,故 U-net 网络的训练效率也高于 FCN 网络。
U-net 网络的结构如图所示蓝色箭头代表卷积和激活函数灰色箭头代表复制剪切操作红色箭头代表下采样绿色箭头代表反卷积conv1X1 代表卷积核为 1X1 的卷积操作。U-net 网络没有全连接层只有卷积和下采样。U-net 可以对像素进行端到端的分割,即输入是一幅图像,输出也是一幅图像。
:::
### 下采样(编码)
::: warning 😽
编码层由 N 个结构相同的卷积层 L(i)级联组成L(i)包含两个 3x3 卷积层和一个 2x2 最大池化层,经过 L(i)后图像通道数加倍。
其中卷积和池化的 padding 都是valid不补 0即只对图像的有效部分进行窄卷积得到图像的有效特征因此得到的输出图像会比输入图像小。解决这个问题的方法是根据输出图像的大小应该等于原图像大小out_size=img_size沿着网络逆向计算出输入图像的大小 in_size对原图像沿着四条边进行镜像扩大作为输入图像。图中输出分割图像的黄框与输入图像的黄框对应输入图像中蓝框的边缘部分由于窄卷积丢失最后的到输出图像中的黄框因此输出的分割图像对应输入图像中原图 img 的位置。
:::
### 上采样(解码)
::: warning 😻
解码层由 N 个结构相同的反卷积层 L(i)级联组成L(i)包含一个 2x2 反卷积层和两个 3x3 卷积层,经过 L(i)后图像通道减半。
每层解码层会将反卷积恢复的特征与同层编码层提取的特征连接concatenate再进行卷积实现了编码层和解码层的特征融合有助于特征恢复过程中保留图像的更多细节使得到的分割图像轮廓更清晰。如图在训练左心室内外膜分割的 UNet 网络时c 得到的特征比 b 更接近标签。
最后,解码层连接一个 1x1 全卷积网络,逐像素二分类,得到 2 个通道的输出图像。
:::
## 视频
<Bilibili bvid='BV1Vq4y127fB'/>
## 思考 1
::: warning 🤔
UNet 的跳连接结构好在哪?跟 Resnet 相比有什么异同?
:::
## 思考 2
::: warning 🐒
有很多的论文是基于 Unet 的改进,包括但不限于
Unet++
U2net
甚至其结构也被视为 EN-DE 结构的一个经典案例,你能否通过这些论文感受一下神经网络整体的发展脉络。
:::

View File

@@ -1,24 +0,0 @@
# GAN
这篇论文画风都和前面的几篇完全不一样,因为他的任务是生成,本篇文章将作为可选的拓展阅读。
比如说生成一些虚拟的 vtuber 他也是完全办得到的,首先留下经典的文章
[Generative Adversarial Networks](https://arxiv.org/abs/1406.2661)
GAN 的基本原理其实非常简单这里以生成图片为例进行说明。假设我们有两个网络GGenerator和 DDiscriminator。正如它的名字所暗示的那样它们的功能分别是
- G 是一个生成图片的网络,它接收一个随机的噪声 z通过这个噪声生成图片记做 G(z)。
- D 是一个判别网络,判别一张图片是不是“真实的”。它的输入参数是 xx 代表一张图片,输出 Dx代表 x 为真实图片的概率,如果为 1就代表 100% 是真实的图片,而输出为 0就代表不可能是真实的图片。
在训练过程中,生成网络 G 的目标就是尽量生成真实的图片去欺骗判别网络 D。而 D 的目标就是尽量把 G 生成的图片和真实的图片分别开来。这样G 和 D 构成了一个动态的“博弈过程”。
最后博弈的结果是什么在最理想的状态下G 可以生成足以“以假乱真”的图片 G(z)。对于 D 来说,它难以判定 G 生成的图片究竟是不是真实的,因此 D(G(z)) = 0.5。
其实就是一个骗一个验证。
提到他我就想提到另一个算法叫 VAE你可以对比一下两者的相同点和不同点
同时,数学推导要从极大似然估计考虑起!
[https://zhuanlan.zhihu.com/p/266677860](https://zhuanlan.zhihu.com/p/266677860)

View File

@@ -1,53 +0,0 @@
# 思考题参考
思考并无绝对的对错,此处仅供参考,希望大家能在自己的思考的基础上再来这里解决思考的疑惑。
##
## 思考 1
### 1.1
[CNN 与 MLP 之间的关系,优缺点](https://www.editcode.net/archive/detail/89781)
### 1.2
[深度理解感受野](https://blog.csdn.net/weixin_40756000/article/details/117264194)
### 1.3
[卷积神经网络中的平移不变性](https://zhuanlan.zhihu.com/p/382926269)
### 1.5
[你真的看懂 Relu 了吗?大家都说是非线性,为什么我怎么看都是线性啊?](https://zhuanlan.zhihu.com/p/405068757)
### 1.6
[什么是深度学习中的卷积?](https://zhuanlan.zhihu.com/p/140550547)
## 思考 2
### 2.1
[深度学习端到端的理解](https://blog.csdn.net/Bulldozer_GD/article/details/95071826)
### 2.2
[反卷积详解](https://blog.csdn.net/bestrivern/article/details/89553513)
### 2.3
### 2.4
[语义分割概念及应用介绍](https://zhuanlan.zhihu.com/p/46200875)
## 思考 3
### 3.1
[Batch NormalizationBN 层)详解](https://www.jianshu.com/p/b05282e9ca57)
### 3.2
[ResNet 残差、退化等细节解读](https://blog.csdn.net/a8039974/article/details/122380735)

View File

@@ -1,19 +0,0 @@
# 还要学更多?
# Try it yourself
你已经基本了解现代 CV 的理论架构了,你可以尝试写一些自己的网络来锻炼你的 coding 能力并且切身体会这些技术的效果
- 你可以先行尝试一下怎么把在 MNIST 上训练的网络真正投入应用,比如识别一张你自己用黑笔写的数字~
![](https://cdn.xyxsw.site/boxcn2juA3J3ycnHoN5SmYAfEfd.jpg)
- 比如你可以尝试训练一个网络来实现人体五官分割(笔者之前就玩过这个)数据集采用 [helen 数据集](https://pages.cs.wisc.edu/~lizhang/projects/face-parsing/),关于数据集的架构你可以搜一搜,自己设计一个 Dataloader 和 YourModle 来实现前言中的五官分割效果(真的很有乐子 hhh
![](https://cdn.xyxsw.site/boxcnJJlzanhvtE55Q7d0IR1vph.png)
- 当然你也可以尝试一些自己感兴趣的小任务来锻炼工程能力~
# Reading more
阅读更多的经典论文!当然如果你有更为具体的方向,你可以从该论文的开山之作慢慢学习

View File

@@ -1,5 +0,0 @@
# 经典网络
这篇文章罗列了对领域造成较大影响的一些经典的论文,要么他们开辟了一个先河,要么他们的方法广为流传。
通过熟悉与掌握这些网络,可以帮助你真的

View File

@@ -1,95 +0,0 @@
# NeRF
最原始的 NeRF 在 2020 年被提出这还是一个比较新的领域。NeRF 的主要目标是在密集采样的图片中对这个图片中的物体进行三维重建。
NeRF 想做这样一件事,不需要中间三维重建的过程,仅根据位姿内参和图像,直接合成新视角下的图像。
在生成建模前,我们需要对被建模物体进行密集的采样,如下图是一个示例的训练集,它含有 100 张图片以及保存了每一张图片相机参数(表示拍摄位置,拍摄角度,焦距的矩阵)的 json 文件。
![](https://cdn.xyxsw.site/boxcn6jg09V944MU1sBsstmdaib.png)
你可以看到,这 100 张图片是对一个乐高推土机的多角度拍摄结果。我们需要的是一个可**以获取这个推土机在任意角度下拍摄的图片**的模型。如图所示:
![](https://cdn.xyxsw.site/boxcnLEEyuUWOwiJOePhmmsAakd.gif)
现在来看 NeRF 网络:
在 NeRF 中,我们把空间**认为是一个个的小方块叠成的空间**(可以理解为 MC)每一个方块有以下属性:
- 3 个位置坐标(x,y,z)
- 透明度$\sigma$
- 注意:因为每个角度观察的颜色并不相同(光线原因),颜色属于一个会根据观察角度变化的隐藏属性。
# 用 NeRF 如何建模?(思路部分)
## 得到模型
我们需要的是每个视角下的图片,可以理解为从一个视角发射**光线**<u>一根光线对应一个像素点</u>。这些光线穿透路径上的所有方块,把这些方块上的属性信息以某种方式累计,就能得到这个像素的颜色。这是 一个已有的公式,只要我们获得每个小方块的颜色信息和不透明度,我们就能知道这个角度下的视图。(这个我们后面介绍)
现在的难点在于:我们不知道**每个小方块的颜色信息**(因为颜色会随着观察角度变化)。众所周知,算法解决不了的问题就扔给神经网络试试啦~
**为了获取根据角度变化而变化的颜色信息,我们选择了神经网络。**
**这个网络的输入是:**
- 小方块的位置坐标(x,y,z)
- 观察角度(以二维坐标表示两个偏转角)
**这个网络的输出是:**
- 对应的小方块的 RGB 信息
- 不透明度
![](https://cdn.xyxsw.site/boxcni4q9Cp8G7H9HjKMrfImcZe.jpg)
在这里,作者选择了最简单的 MLP因此**这是一个输入为 5 维,输出为 4 维向量**($R,G,B,\sigma$)的简单网络,值得注意的是,不透明度与观察角度无关,这里在网络中进行了特殊处理,让这个值与后两维无关。
**现在我们能够输入坐标和视角信息得到小方块的颜色和不透明度,我们就可以对光线穿过的小方块进行计算了。**
## 进行渲染
(渲染就是得到三维建模的某视角下图片)
得到每条光线上的方块信息后,我们对其进行计算(这里开始介绍上面略过的公式)
这个公式对光线上的所有小方块的颜色进行加权求和,权重是关于不透明度$\sigma$的一个函数$T(\sigma)$,不透明度在[0,1]之间,越不透明这个值越大。也就是越不透明,占的颜色比重越高,比如空气的$\sigma$就接近于 0乐高本身就接近 1。而求和的结果就是这个光线对应像素的颜色。
这里展开说一下$T(\sigma)$,我们把不透明度理解为光线在这个小方块被阻止的概率,越不透明,越容易阻挡光线,而光线一旦被阻挡,就不用计算后面的小方块颜色了。因此,我们的$T(\sigma)$就表示**光线能够行进到这个小方块的概率**,也就是这点之前所有小方块的$(1-\sigma)$的乘积。
这段要仔细看和推导,第一遍不容易直接懂。顺带一提,我们的**小方块**学名叫**体素**<del>为了显得我们更专业一点以后就叫它体素罢</del>
![](https://cdn.xyxsw.site/boxcnnwHy3Hlhbu2bOsi6r2BYJe.png)
上面所说的公式具体如下t 是我们的$\sigma$$t_f,t_n$分别是离发射点最远的体素和最近的体素。这个公式求得是像素的颜色。
![](https://cdn.xyxsw.site/boxcnDWBUOJucS2YdT7MlKBAq8g.png)
思路总体如上,这里放一张找来的渲染过程示意图(<del>不知道为什么有点包浆</del>
![](https://cdn.xyxsw.site/boxcnfH30VDvbSdzahs5lRuirUd.gif)
# 算法细节部分
上述只是 NeRF 的思路,也是后续改进工作的核心,具体实现使用了很多 trick下面进行列举介绍
## 采样方法
因为上述计算使用了积分,而计算机只能处理非连续的信息,因此我们先把光线分为数个小段,在每个小段中使用蒙特卡罗采样(就是随机抽),得到积分的近似值。
我们也可以配合另一种更巧妙的方法实现采样,就在下面啦。
## 粗网络和精细网络
如上述采样方法所说,因为是均匀采样,我们对空气和实体的体素关注度都是差不多的,但是这并无必要,空气上采样点少了也不会怎么样,而实体上如果采样点增多,图片就会更加清晰,因此我们设计了以下算法来进行优化。
我们使用了两个网络:粗网络和精细网络。
粗网络就是上述采样方法用的普通网络,而**粗网络输出的不透明度值会被作为一个概率分布函数**,精细网络根据这个概率分布在光线上进行采样,不透明度越大的点,它的邻域被采样的概率越大,也就实现了我们要求的在实体上多采样,空气中少采样。最后精细网络输出作为结果,因此粗网络可以只求不透明度,无视颜色信息。
![](https://cdn.xyxsw.site/boxcnwl72wntQgYMFvRPTWY5fPf.png)
## 位置编码
学过 cv 的大家想必对这个东西耳熟能详了吧~,这里的位置编码是对输入的两个位置和一个方向进行的(体素位置,相机位置和方向),使用的是类似 transformer 的三角函数类编码如下。位置编码存在的意义是放大原本的 5 维输入对网络的影响程度,把原本的 5D 输入变为 90 维向量;并且加入了与其他体素的相对位置信息。
![](https://cdn.xyxsw.site/boxcnliAj5mb0Afz0TOMwrwytmh.png)

View File

@@ -1,172 +0,0 @@
# NeRF 的改进方向
这里只列出论文的名字或者模型简称,以及一些概括,没看的先留白,这里写的会很随意,当作备忘录了。
适合作为学习索引或者备忘录,忘了就来这里找找。(更新中)
# 1.泛化性
## 1)减少输入图像类
### 1.Pixel-nerf
**Pixel-nerf**** **对输入图像使用卷积进行特征提取再执行 nerf若有多个输入对每个视角都执行 CNN在计算光线时取每一个已有视角下该坐标的特征经过 mlp 后算平均。可以在少量视角下重建视图,需要进行预训练才能使用,有一定自动补全能力(有限)
![](https://cdn.xyxsw.site/boxcnEiUODOd4FOBxYIZmmihyef.png)
### 2.IBRnet
**IBRnet**** **是 pixel-nerf 的改进版,取消了 CNN并且在 mlp 后接入了 transformer 结构处理体密度(不透明度),对这条光线上所有的采样点进行一个 transformer。同时在获取某个体素的颜色和密度时作者用了本视角相邻的两个视角获取对应体素在这两张图片中的像素以图片像素颜色视角图片特征作为 mlp 的输入。
![](https://cdn.xyxsw.site/boxcnwH75jIO9NiVwQaBqDrbe8e.png)
### 3.MVSnerf
**MVSnerf**** **它用 MVS 的方法构建代价体然后在后面接了一个 nerfMVS 是使用**多视角立体匹配**构建一个代价体,用 3D 卷积网络进行优化,这里对代价体进行 nerf 采样,可以得到可泛化网络。它需要 15min 的微调才能在新数据上使用。**多视角立体匹配是一种传统算法,通过光线,几何等信息计算图像中小块的相似度,得出两个相机视角之间的位置关系。这个算法也被广泛使用在得到我们自己采样的数据的相机变换矩阵上(我就是这么干的)**
![](https://cdn.xyxsw.site/boxcnbd2YxumunZR9LZG3ANrPrb.png)
此处涉及较多图形学,使用了平面扫描算法,其中有单应性变换这个角度变换算法,推导与讲解如下:
[MVSNet 单应性变换推导_朽一的博客-CSDN 博客_可微单应性变换](https://blog.csdn.net/qq_43027065/article/details/116946686)
简单来说就是把 A 视角下的图像转换到 B 视角
平面扫描就是把 A 视角中的某一像素点(如图中红色区域)的相邻的几个像素提取出来,用单应性变换转换到 B 视角中,这时候用的深度是假设的深度,遍历所有假设的深度,计算通过每一个假设深度经过单应性变换得到的像素小块和 B 视角中对应位置的差值loss取最小的 loss 处的深度作为该像素的深度。
![](https://cdn.xyxsw.site/boxcn5JmWUh1Gu283biqHq3Op0r.png)
构建代价体:
构建三维代价体的主要步骤:
1)假设离散的深度平面。
2)将每个视图提取的特征图变换到假设平面上,构造特征体;
3)将不同视角的特征体融合在一起,形成三维代价体。
## 2)可以 zero-shot 或者 fine-tune 类
**MVSnerf****,上面已经说了。**
# 2.速度提升
### 1.instan-ngp
使用了**哈希表**结构的**instant-ngp**,渲染完美只需要几分钟(采样正常的情况下)这块的速度已经到极致了。
展开说说其实这也是神经网络发展的一个方向以前的深层网络倾向于把所有东西用网络参数表示这样推理速度就会慢这里使用哈希表的快速查找能力存储一些数据信息instant-ngp 就是把要表达的模型数据特征按照不同的精细度存在哈希表中,使用时通过哈希表调用或插值调用。
![](https://cdn.xyxsw.site/boxcnXSUge0BqBCecdDJLQr4cRc.png)
# 3.可编辑(指比如人体运动等做修改工作的)
### 1.Human-nerf
**Human-nerf**** **生成可编辑的人体运动视频建模,输入是一段人随便动动的视频。输出的动作可以编辑修改,并且对衣物折叠等有一定优化。使用的模型并非全隐式的,并且对头发和衣物单独使用变换模型。使用了逆线性蒙皮模型提取人物骨骼(可学习的模型),上面那个蓝色的就是姿态矫正模块,这个模块赋予骨骼之间运动关系的权重(因为使用的是插值处理同一运动时不同骨骼的平移旋转矩阵,一块骨骼动会牵动其他骨骼)图中的 Ω 就是权重的集合,它通过 mlp 学习得到。然后得到显式表达的人物骨骼以及传入视频中得到的对应骨骼的 meshskeletal motion 就是做游戏人物动作用的编辑器这种,后面残差链接了一个 non-rigid-motion非刚性动作这个是专门处理衣物和毛发的主要通过学习得到然后粗暴的加起来就能得到模型再经过传统的 nerf 渲染出图像。
![](https://cdn.xyxsw.site/boxcnHRnNXHvwVXrRmM8wnl53p9.png)
### 2.Neural Body
**Neural Body** 通过下面这种**单视角视频**或稀**疏视角照片**来生成人体建模。
因为生成的是人体建模,作者使用了他们以前的工作 EasyMocap 得到**SMPL 模型(就是人体的结构)然后在 SMPL 表面生成一些 latent code包含颜色不透明度和位置也就是下左中的那些点。**
[EasyMocap 的代码](https://github.com/zju3dv/EasyMocap)
EasyMocap 是通过多视角视频生成骨架以及 SMPL 模型的一个工作,演示视频右下。
![](https://cdn.xyxsw.site/boxcnYmy1MnyWSPNEWvFWj9mzCf.png)
这是 EasyMocap 的演示。
这里作者对 nerf 进行了修改,让 nerf 通过 latent code 渲染图片。流程是先用 latent code 构建三维网格,在这个网络中用空间插值得到具体某个点的值。这一步通过 3D 卷积实现,把原先存在空间中的离散的点整合到一个 latent code volume 中,在这个空间中进行 nerf 的渲染。省掉了 mlp把整个建模储存在 3D 网格中而非 MLP 中,加快计算速度。
作者把每一帧提取到的骨架用 latent codes 进行蒙皮,使得人体变成对应的姿势,就可以进行逐帧渲染。
个人感觉这个模型不能很好处理光影效果,还有待改进。
是个预训练模型,**训练的模块就是这个 3D 卷积神经网络**。
![](https://cdn.xyxsw.site/boxcnbclBwg3BsubGOrt8vZf0qb.png)
### 3.wild-nerf
**wild-nerf** 思路很简单,就是加入了新的输入参数来调整白天黑夜等等一些简单的变化,并且把行人车辆之类的在采样过程中**不固定的物品**作为**随机项**,在渲染时按照概率加入。
### 4.D-nerf
**D-nerf** 是一种动态编辑的 nerf输入为x,y,z,相机位置,相机角度,**时间 t。**
把整个网络分为两块,一块是正常的 nerf 渲染,另一块是下面这个,输入时间与现在的位置坐标,输出**这个位置坐标中的物体现在的位置**与 t=0 时的**位置的差**。再用 t=0 时物体的点信息进行渲染。
在此网络的单个输出上貌似是不监督的,因为没办法进行人为标注。这点我不是很确定,以后如果发现了会来修改的。
![](https://cdn.xyxsw.site/boxcnYeaiioqtFzQlztsTwiEpzg.png)
渲染经过形变的物体时,光线其实是在 t=0 时刻进行渲染的,因为推土机的铲子放下去了,所以**光线是弯曲的**。
![](https://cdn.xyxsw.site/boxcng7xDooDmmpbCJRyLJBucwe.png)
# 4.用于辅助传统图像处理
还没涉猎,待补全
# 5.与对比学习结合
### 1.clip-nerf
**clip-nerf**** 太贵了玩不起,没仔细研究,应该是文本跟 3D 建模关联,跟 clip 一样。**
# 6.生成类(指加入新物体或者额外生成新场景)
### 1.GRAF
**GRAF**** **把 GAN 与 nerf 结合,增加了两个输入,分别是**外观/形状编码 z**和**2D 采样编码 v**z 用来改变渲染出来东西的特征比如把生成的车变色或者变牌子suv 变老爷车之类的。v(s,u)用来改变下图 2 中训练时选择光线的标准。这里训练时不是拿 G 生成的整张图扔进 D 网络,而是根据 v 的参数选择一些光线组成的 batch 扔进 D 进行辨别
![](https://cdn.xyxsw.site/boxcnVyFqHIoA2MGGc4JJo9tObh.png)
![](https://cdn.xyxsw.site/boxcnvBzqwCn9i8GGBIkMFEs3ne.png)
### 2.GIRAFFE
**GIRAFFE** 是 GRAF 的改进工作,可以把图片中的物品,背景一个个解耦出来单独进行改变或者移动和旋转,也可以增加新的物品或者减少物品,下图中蓝色是不可训练的模块,橙色可训练。以我的理解好像要设置你要解耦多少个(N)物品再训练,网络根据类似 k 近邻法的方法在特征空间上对物品进行分割解耦,然后分为 N 个渲染 mlp 进行训练,训练前加入外观/形状编码 z。最后还是要扔进 D 训练。
![](https://cdn.xyxsw.site/boxcnB04hwHA1o64WBvYSyVTDod.png)
![](https://cdn.xyxsw.site/boxcnC2bKVHOANjGOePLHk7jfZe.png)
### 3.OSF
**OSF**Object-Centric Neural Scene Rendering可以给移动的物体生成合理的阴影和光照效果。加入了新的坐标信息光源位置与相机坐标等一起输入。对每个小物件构建一个单独的小 nerf计算这个小 nerf 的体素时要先经过光源照射处理(训练出来的)然后在每个小物件之间也要计算反射这样的光线影响,最后进行正常的渲染。<del>这篇文章没人写 review有点冷门这些都是我自己读完感觉的不一定对。</del>
![](https://cdn.xyxsw.site/boxcnV7YcKIq5y8TkOGEGzrPc5g.png)
### 4.Hyper-nerf-gan
使用了超网络与 nerf-gan 结合,这篇比较新没有 review是我自己理解的可能有出入。
作者用了几个我比较陌生的技术,比如超网络 hypernet还有超网络与 gan 结合的 INR-Gan。
**hypernet**:把随机初始化和直接梯度回传更新的网络参数用另一个神经网络来更新,就是我们要同时训练两个网络,一个是本体,一个是调整参数用的超网络。
**INR-Gan**:把超网络技术与 Gan 结合,并且用了 INR 技术,这个技术类似 nerf不过是处理图片用到的是构建一个坐标(x,y)->RGB 的网络,可以让图片达到更高分辨率,也就是把离散的像素变成连续的。
左边是常规卷积网络生成图像,右边是用 INR 生成图像。
![](https://cdn.xyxsw.site/boxcnGCCZ8qXD1Hhc531NxfLzLd.png)
这种方法存在两个问题:
1.因为 INR 其实是一种超网络,也就是说我们要训练两个网络,但是只存在一个监督。使得网络训练更难。
2.因为使用神经网路去表示图片,占用内存更大。
因此,作者设计了**FMM**去应对这两个问题,这也是 Hyper-nerf-gan 借鉴的主要部分。
FMM 主要是把要学习的矩阵转化为两个低秩矩阵,去先生成他们俩再相乘,减少网络计算量。
![](https://cdn.xyxsw.site/boxcn0oHY54dgL2bxmryxjqxC6f.png)
现在开始讲 Hyper-nerf-gan 本身,它看上去其实就是 nerf 接在 gan 上。不过有一些变化,比如输入不再包含视角信息,我**很怀疑它不能很好表达反光效果**。而且抛弃了粗网络细网络的设计,只使用粗网络减少计算量。这里的 generator 完全就是 INR-Gan 的形状,生成权重,然后再经过 nerf 的 mlp 层生成,没啥别的了,就这样吧。
![](https://cdn.xyxsw.site/boxcnc9bZ1nqt3Lighlrj9zSrdd.png)

View File

@@ -1,64 +0,0 @@
# 自制数据集的工具 COLMAP <Badge type="danger">由于作者换方向了所以如下关于NERF的内容待完善</Badge>
如何使用和怎么下载就不讲了,直接搜就有,它可以把多个拍摄同一物体的图片转换为它们对应视角的相机矩阵和拍摄角度,可以实现自制数据集做 nerf。它的流程SFM 算法)可以概括如下:
![](https://cdn.xyxsw.site/boxcnXzgaIhmUQ7HQtEn52ksWIf.png)
这里主要是记录一下它的原理:
首先是一个经典关键点匹配技术:**SIFT**
# SIFT 特征点匹配
## DOG 金字塔
![](https://cdn.xyxsw.site/boxcneERqw4amGHf6f2SX7gcdny.png)
![](https://cdn.xyxsw.site/boxcnv4dRbGDg9eemcyQFREYs0b.png)
下面是原理方法:
首先是**高斯金字塔**,它是把原图先放大两倍,然后使用高斯滤波(高斯卷积)对图像进行模糊化数次,取出倒数第三层缩小一半继续进行这个过程,也就是说它是由一组一组的小金字塔组成的。
![](https://cdn.xyxsw.site/boxcnKJWrCUc5cPOuZg01HqNCsc.png)
![](https://cdn.xyxsw.site/boxcnd25i5LQ7WjGJEe2xgU3qce.jpg)
然后是基于高斯金字塔的 DOG 金字塔,也叫差分金字塔,它是把相邻的高斯金字塔层做减法得到的,因为经过高斯模糊,物体的轮廓(或者说不变特征)被模糊化,也就是被改变。通过相减可以得到这些被改变的点。
![](https://cdn.xyxsw.site/boxcncKZlnG7F4oEpcrQYqth8kh.jpg)
![](https://cdn.xyxsw.site/boxcnAEQSDhsLdDsNOQVxqcic5d.jpg)
## 空间极值点检测
为了找到变化的最大的几个点来作为特征点,我们需要找到变化的极值点,因此需要进行比较,这里是在整个金字塔中进行对比,我们提取某个点周边 3*3*3 的像素点进行比较,找到最大或最小的局部极值点。
![](https://cdn.xyxsw.site/boxcnl48ovxbqSeTljgF3rp16ue.png)
同时我们也对关键点分配方向,也就是这个点在图片空间中的梯度方向
梯度为:
![](https://cdn.xyxsw.site/boxcnbQx8TntyX8iETPixOnKjef.png)
梯度方向为:
![](https://cdn.xyxsw.site/boxcnfw5FrBxPaD4bNFT4GFyXmd.png)
我们计算以关键点为中心的邻域内所有点的梯度方向,然后把这些 360 度范围内的方向分配到 36 个每个 10 度的方向中,并构建方向直方图,这里的示例使用了 8 个方向,几个随你其实:
![](https://cdn.xyxsw.site/boxcnyuV5HCumJMhyW7Cb3HSxcg.jpg)
取其中最大的为主方向,若有一个方向超过主方向的 80%,那么把它作为辅方向。
操作可以优化为下图,先把关键点周围的像素分成 4 块,每块求一次上面的操作,以这个 4 个梯度直方图作为关键点的方向描述。也就是一个 2*2*8(方向数量)的矩阵作为这个点的方向特征。
![](https://cdn.xyxsw.site/boxcnEvWRhUKcWKAoYKWbN1kAuc.png)
实验表明,使用 4*4*8=122 的描述更加可靠。
![](https://cdn.xyxsw.site/boxcniVb6FvrZziID1B1JFmgVzx.jpg)
特征点的匹配是通过计算两组特征点的 128 维的关键点的欧式距离实现的。欧式距离越小,则相似度越高,当欧式距离小于设定的阈值时,可以判定为匹配成功。
以上是 colmap 的第一步SIFT

View File

@@ -1,11 +0,0 @@
# 神经辐射场(NeRF)
> Author康可均
NeRF 是一项用于三维重建的技术,使用深度学习对图片中的物体进行重建。
严格来讲,它属于计算机视觉的分支。
因为网络上能够找到的教程较少且不连贯,本文不会像 CV 和 NLP 那样简单介绍,而是像对比学习的介绍方式一样,介绍发展历程以及改进工作。
不建议直接通过 nerf 了解深度学习,学习之前希望你已有 CV 的基础。

View File

@@ -1,17 +0,0 @@
# 行人重识别ReID
> Author陈维文
行人重识别ReID是一项纯粹的计算机视觉(CV)任务,其主要目标是在不同的监控摄像头中识别出不同的人物或车辆,并确定它们是否是同一个人或车辆。
监控视频通常难以捕捉高质量的人脸并且经常会遇到刻意回避或遮盖的情况。为了解决这些问题ReID技术应运而生。它可以通过对身体外貌特征和行为模式的分析对监控视频中的个体进行识别和跟踪。
该任务目前在学术上是检索出不同摄像头下的相同行人图片,同时数据集中只有人的全身照,如下图所示。
![](https://cdn.xyxsw.site/ReID1.png)
但是实际上在实际应用中的时候会和检测结合,简单来说先框出目标后分类,如下图所示。
![](https://cdn.xyxsw.site/ReID2.png)
这个方向做的比较的奇怪,该模块只做整体性介绍,同时希望学习该模块的你对经典网络有所了解。

View File

@@ -1 +0,0 @@
# 计算机视觉CV

View File

@@ -1,29 +0,0 @@
# NLP 领域任务(研究目标)
下面给出了 NLP 的四大常见的应用。由于预训练的模型是在连续的文本序列上训练的,所以需要进行一些修改才能将其应用于不同的这些 NLP 任务。
**分类 (text classification)** 给一句话或者一段文本,判断一个标签。
![](https://cdn.xyxsw.site/PxE3b05ApofzZ1x8u49cirdUnye.png)
图 2分类 (text classification)
**蕴含 (textual entailment)** 给一段话,和一个假设,看看前面这段话有没有蕴含后面的假设。
![](https://cdn.xyxsw.site/OuhabfzABoqxQxxS1n1cPLTinKb.png)
图 3蕴含 (textual entailment)
**相似 (Similarity)** 判断两段文字是否相似。
![](https://cdn.xyxsw.site/ByeFbxTfToxFlgxh6xmcIKeRnzd.png)
图 4相似 (Similarity)
**多选题 (Multiple Choice)** 给个问题,从 N 个答案中选出正确答案。
![](https://cdn.xyxsw.site/ZYgybsj5dol1Ifx96Koc6SRpnmc.jpeg)
图 5多选题 (Multiple Choice)
可以看出,随着任务类型的变化,就需要构造不同的输入形式,把不同的子任务统一成相同的输入形式。但是,不变的是 Transformer 模型的结构。所有转换都包括添加随机初始化的开始 (Start) 和结束 (Extract) tokens有的包括分隔符 Delimiter tokens (Delim)。

View File

@@ -1,180 +0,0 @@
# 推荐系统经典模型综述
Author: 周东霖
# 概论
## 1.1 摘要
推荐系统技术最早起源于上世纪末和本世纪初最早是数据挖掘领域最为经典的应用之一。2012 年至 2015 年,机器学习技术进入推荐系统领域,使得这项古老的应用再次发光发热。 2016 年以来,随着深度学习的发展,大规模算力、大数据的应用的逐渐普及,基于深度学习的推荐系统研究再次成为行业热点,在工业界和学术界都占据极其重要之地。
本文旨在回顾经典的推荐系统经典模型和研究思路,但并不提供具体的推导方案,并讨论它们各自的优缺点。希望能够为后来入坑者提供一些思路。由于是个人观点陈述,未免存在遗漏和评价不当之嫌,望请见谅。
## 1.2 关键术语:
Recommender Systems(RS) : 推荐系统
Information overlaod: 信息过载
user:用户
item:物品
feedback:用户反馈
explicit feedback:显式反馈,例如用户评分
implicit feedback:隐式反馈,浏览、点击、购买等行为
## 1.3 主要任务
推荐系统的主要任务包括两方面:
评分预测(rating prediction)
物品推荐(item recommendation)
## 1.4 评价方式和评价指标
学术界通常采用离线方式进行评估,一般进行 N 折交叉验证。
优点:依赖数据集、容易验证和评估;
缺点:无法直接反映商业需求。
工业界常采用在线测试,比如 A/B test。
优点:和商业需求紧密挂钩。
缺点:成本高、风险大。
对于评分预测任务,常用评价指标包括:
Root Mean Squared Error (RMSE)
Mean Absolute Error (MAE)
对于物品推荐任务,常用评价指标包括:
Precision、Recall、F-measure、Hit Ratio(HR)
Average Precision (AP)、Mean Average Precision(MAP)
Area Under the ROC Curve (AUC)、Mean Reciprocal Rank (MRR)
Normalized Discounted Cumulative Gain (NDCG)
通常情况下,常用 @N 表示推荐前 N 个物品的性能,即 Top-N 推荐。近几年的论文常常采用 HR、NDCG 作为评价指标。
# 经典 SOTA
## 2.1 协同过滤collaborative filtering, CF
协同过滤是最早的一种推荐系统技术最早用于电影推荐系统。最早开启这项研究的是明尼苏达大学的研究小组GroupLens随后亚马逊研发了基于物品的协同过滤算法并开始将 RS 部署上线,正式推向工业界。
协同过滤的方法主要包括两大类:
- User-based CF:基于用户的协同过滤[1]
- Item-based CF:基于物品的协同过滤[2,3]
## 2.2 分解模型Factorization model
最早的推荐系统采用的是邻域模型neighborhood本质上是计算物品和用户的相似度进行推荐。但是这种方法存在两个致命缺点
- 稀疏性sparsity:实际应用(例如大型电商平台)中,数据非常稀疏,两个用户购买物品存在交集的情况非常少。
- 维度灾难:用户向量维度高、物品向量维度高,导致计算成本高,且无法保证准确度。
由此分解模型横空出世。最为经典的分解模型就是矩阵分解Matirx Factorization, MF[4]。它的理论基础来源于奇异值分解 SVD(Singular Value Decomposition)。 基于 SVD 理论,评分矩阵可被分解成用户和物品的潜在因子,潜在因子的维度 k 远小于用户数量 m 和物品数量 n由此可以大大降低计算量。(可以看作是后来的 embedding 技术的一个简化版)
Koren 等人提出 MF 以后,开始在最基础的矩阵分解模型上加入各种辅助信息,并衍生出分解模型的高阶版本,比如 SVD++TimeSVD++WRMFBPRSLIM 等等。
其中,特别推荐几个经典模型,它们的一些思想直到今天仍然未过时,也是学习分解模型的必备。
- SVD++[4]:加入了邻域信息之后的矩阵分解
- BPR[5]:采用贝叶斯概率思想,引入隐式反馈优化
## 2.3 高阶分解模型(high order factorization model)
矩阵分解模型包括用户和物品两类因子,在处理额外信息比如时间、标签时存在局限。处理额外信息的另一种直接做法是使用张量分解,主要的经典模型包括基于马尔可夫的分解模型 FPMC(Factorizing Personalized Markov Chains)。但是高阶张量分解开销十分巨大,各阶的交互方式不灵活。
提到高阶分解模型不得不提推荐系统领域的元老级人物——Rendle。他提出的因子分解机模型——Factorization machines几乎杀遍所有数据挖掘竞赛霸榜 SOTA 数年,引领数年风骚[6]。FM——因子分解机可以将多种信息进行高阶交互二阶、三阶等等但是一般到二阶以后训练将变得异常困难计算量也急剧增加。
当然,高阶分解的另一个相似模型,就是学术界明星-华人陈天奇在上海交大读研时提出的 SVDFeature 模型[7]。在原始论文中FM 模型称 SVDFeature 模型仅仅是高阶 FM 的一个泛化。
后来陈天奇赴美留学,将梯度树的性能提升到极致,也就是经典 XGBoost 模型[8],也霸榜 SOTA 数年一时风光无两。SVDFeature 库是上海交大实验室采用 C++ 编写XGBoost 开源版本很多,建议可以阅读前人开源代码,增加代码能力。同时,在机器学习时代,原版论文涉及很多数学推导和梯度计算,阅读这些论文,也是增进个人内功的很好法门。
## 2.4 深度模型(deep-learning models)
深度模型进入推荐系统领域大概是 16 年左右,最早将深度模型应用于推荐领域的应用主要是在评论文本挖掘领域。
评论信息中包含用户偏好、评价等反馈信息。研究者将 CNN 引入推荐系统领域,将文本映射成 word vector并采用卷积网络训练将 CNN 和传统的矩阵分解结合,并套上一个概率的外壳进行解释。这方面的工作主要包括 ConvMF[9]、DeepCoNN[10]。
基于 CNN 的模型主要是应用于评论文本挖掘和可解释性推荐方面,但是这种方法的计算量非常大,并且准确率不高,难以训练。个人认为这种方法仅仅是新奇,并不具备特别大的商业价值。对于推荐这种时效性非常强的应用,训练一个几百亿数量级的文本挖掘模型,却非用于自然语言领域,产生的价值和消耗的资源不成正比。
何向南在 2017 年提出 NCF将神经网络结合协同过滤——深度协同过滤霸榜 SOTA[11]。从此,推荐系统几乎被深度学习攻陷,各种方法层出不穷。他在中科大的团队同时开发了 NeuRec 开源框架——一个基于 Tensorflow 的推荐框架,适合新手入门。
在工业界方面,最早将深度学习应用于推荐系统领域的是 YouTobe它的大规模推荐系统分成两步——排序和召回。排序阶段是初排将百万级别数量级的物品进行排序选出几百个候选物品召回阶段是精排根据物品特征和用户偏好对几百个物品进行细粒度排序。
## 2.5 序列推荐(sequential recommender)
前面介绍了机器学习时代的几种经典模型接下来介绍深度序列推荐。Session based SRs 是会话推荐Sequential recommender 是序列推荐。前者是指一个用户在一个 session 当中的点击序列,而后者更关注于物品序列顺序本身,而与用户无关。但是两者之间有着非常相似而密切的联系。
最早开始将深度引入会话推荐的模型是 GRU4Rec[12],它直接将 RNNs 用于会话推荐系统,并采用 zero-padding 补齐序列长度不一致的问题。实际上Padding 是常见的序列补齐技术,但是值得注意的是,有些开源代码采用的是左补齐(在序列的左边补齐,如 RecBole有些采用的是右补齐如 GRU4RecSASRec
2018 年的 ICDM 顶会上,加州大学圣地亚哥分校的 McAuley 团队(推荐系统领域的又一个大牛)提出的 SASRec[13],直接将注意力机制用于序列推荐,完成 SOTA。原论文的实验部分设置十分精彩值得论文初写者模仿和借鉴。
从此以后,基于 attention-based 的模型开始百花齐放,比如加入物品序列和物品特征序列的双路注意力 FDSA[14]、使用双向注意力机制的 BERT4Rec[15]等等。
20 年以来由于图神经的方法渐渐成为研究热点。基于图网络的推荐系统也引起了学术界的兴趣。SR-GNN[16]是最近将 GNN 的方法用于会话推荐系统。随后,各种图方法开始爆发,目前主流的图神经网络方法包括清华大学和快手联合推出的 SURGE[17]。
# 主要会议和期刊
- ACM Conference on Recommender System (RecSys) 推荐系统顶会
- ACM SIGKDD International Conference on Knowledge Discovery and Data Mining. KDD 竞赛,数据挖掘顶会
- IEEE International Conference on Data Mining : ICDM数据挖掘顶会
- International Joint Conference on Artificial Intelligence: IJCAI
- **ACM the Web Conference**: 3W
- **ACM International Conference on Web Search and Data Mining**:WSDM
- **ACM International Conference on Informaiton and Knowledge Management**:CIKM
# 国内外大牛 Follow
- Koren: 矩阵分解模型提出者2009 年 Netflix prize 获得者
- Steffen Rendle: FM 系列提出者,工业界推荐系统大牛
- 何向南中科大教授NUS 博士,百万青橙奖得主,国内学术界推荐大牛,开源 NeuRec
- McAuley加州大学圣地亚哥分校教授北美推荐系统领域大牛SASRec 模型
- 赵鑫:中国人民大学教授,联合开发 Recbole 开源库
# 参考文献
[1]Breese et al. 1998. Empirical analysis of predictive algorithms for collaborative filtering. In Proceedings of the Fourteenth conference on Uncertainty in artificial intelligence (UAI'98), 4352.
[2]G. Linden J. Jacobi and E. Benson, Collaborative Recommendations Using Item-to Item Similarity Mappings, US Patent 6,266,649 (to Amazon.com), Patent and Trademark Office, Washington, D.C., 2001
[3]Sarwar et al., Item-based collaborative filtering recommendation algorithms, Proceedings of the 10th international conference on World Wide Web, p.285-295,
May 01-05, 2001, Hong Kong
[4] Koren, Y. 2008. Factorization meets the neighborhood: A multifaceted collaborative filtering model [C]. Proceedings of the 14th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining. KDD 08. Las Vegas, Nevada, USA: ACM, 426434
[5] Rendle, S., Freudenthaler, C., Gantner, Z., and Schmidt-Thieme, L. 2009b. Bpr: Bayesian personalized ranking from implicit feedback [C]. Proceedings of the Twenty-Fifth Conference on Uncertainty in Artificial Intelligence. UAI 09. Montreal, Quebec, Canada, 452461.
[6] Rendle, S. 2013. Scaling factorization machines to relational data [C]. Proceedings of the 39th International Conference on Very Large Data Bases. volume 6 of Proc. VLDB Endow. Riva del Garda, Trento, Italy: VLDB Endowment, 337348.
[7] Chen, T., Zhang, W., Lu, Q., Chen, K., Zheng, Z., and Yu, Y. 2012c. Svdfeature: a toolkit for feature-based collaborative filtering [J]. The Journal of Machine Learning Research, 13(1):35853588
[8] Chen, Tianqi, and Carlos Guestrin. "Xgboost: A scalable tree boosting system." Proceedings of the 22nd acm sigkdd international conference on knowledge discovery and data mining. 2016.
[9]Kim, Donghyun, et al. "Convolutional matrix factorization for document context-aware recommendation." Proceedings of the 10th ACM conference on recommender systems. 2016.
[10]Zheng, Lei, Vahid Noroozi, and Philip S. Yu. "Joint deep modeling of users and items using reviews for recommendation." Proceedings of the tenth ACM international conference on web search and data mining. 2017.
[11]He, Xiangnan, et al. "Neural collaborative filtering." Proceedings of the 26th international conference on world wide web. 2017.
[12] Hidasi, Balázs, et al. "Session-based recommendations with recurrent neural networks." arXiv preprint arXiv:1511.06939 (2015)
[13] Kang, Wang-Cheng, and Julian McAuley. "Self-attentive sequential recommendation." 2018 IEEE International Conference on Data Mining (ICDM). IEEE, 2018.
[14] Tingting Zhang, Pengpeng Zhao et al. Feature-level Deeper Self-Attention Network for Sequential Recommendation.2019.
[15]Fei Sun, Jun Liu et al. BERT4Rec: Sequential Recommendation with Bidirectional Encoder Representations from Transformer.2019.
[16]Shu Wu, Yuyuan Tang, Yanqiao Zhu, Liang Wang, Xing Xie, Tieniu Tan. Session-based Recommendation with Graph Neural Networks. 2019.
[17]Jianxin et al., Sequential Recommendation with Graph Neural Networks. SIGIR 2021.

View File

@@ -1,9 +0,0 @@
# 《推荐系统实践》读后的一些想法
- 说在前头的话:
在对这本书进行阅读之前,我对于大模块知识的学习方式一无所知,所以就想借由学习推荐系统的知识,来构建属于自己的大模块知识学习方式。我把这个方向上的学习,更倾向于一种对于学习本身的探索,而不强求自己真正能掌握多少知识。出于以上的原因,我将要记录的东西更偏向于一种阅读完之后的自己的理解,相当于把别人的东西吃进去,嚼两口再吐出来。其中所产生的信息缺失或信息差错,还望读者体谅,对于一些存疑的地方,翻阅原著是最佳的方式,若是有自己的思考,敬请斧正。
- 所以说,如果想对这方面有所了解的话,那我推荐您阅读原著,然后把文档中内容当成是复习或者是对照学习的资料,文档中的内容缺少了原文中生动形象的例子,对于刚接触者来说可能难以理解
- 小人不才,在专业知识匮乏和自身水平较低的情况下,擅自对这书的内容下一个定义。全书所围绕的主题重点在于从数据的角度出发,进行推荐系统的构造,重点着墨于包括:基于用户的行为数据,基于标签数据,基于上下文信息,给予社交网络数据,这些一早就写在目录中的数据。
- 书中的讲述深入浅出,如果愿意用心阅读作者的描述的话,很多的晦涩概念都被作者准确的描述了出来,再辅以一些实际例子,让整本书的阅读难度甚至降低到了兴趣者能读懂的程度。足以见到作者高超的笔力和深厚的理解。
- 当然书中并没有一个完整推荐系统的代码,这方面的空缺建议辅佐另一本《深度学习推荐系统》和 fun-rec 开源社区中的代码进行学习。
- 对于有想法了解推荐系统的人来说,这本书可以是一本合适的入门作品,书中对于推荐系统的定义和描述,足以让有想法的人对于这个领域有一个大概的了解。

View File

@@ -1,63 +0,0 @@
# 推荐系统概念解释 and 一个好的推荐系统
- **用户满意度**
- 用户满意度是推荐系统测评的重要指标,但是实际上,用户满意度数据获得的方式十分有限,因为这是一种用户的主观情感。
- 设计合适的方式对于用户的满意度进行回收分析,是改进推荐系统的一个很好的方式。这样的的方式包括但不限于,设计合适的调查问卷,在物品的购买结束后附上一份满意度调查。
- 满意度在一些程度上可以细分为更加具体的信息。例如点击率,用户停留时间,转化率,完播率,或者是哔站视频点赞,三连的比例。
- **预测准确度**
- **召回率(Recall)**
$$
Recall =\frac{\sum_{u\in U}{\vert R(u)\cap T(u) \vert}}{\sum_{u\in U \vert T(u)\vert}}
$$
- 其中 $R(u)$ 是根据用户在训练集上的行为给用户做出的推荐列表, $T(u)$ 是用户在测试集上的行为列表。
- 召回率的意义?可以参考机器学习中留下的定义进行理解
- **精确率**
$$
Precision =\frac{\sum_{u\in U}{\vert R(u)\cap T(u)\vert}}{\sum_{u\in U}{\vert R(u) \vert}}
$$
- 其中 $R(u)$ 是根据用户在训练集上的行为给用户做出的推荐列表, $T(u)$ 是用户在测试集上的行为列表。
- 精确率的意义?
- **覆盖率**
- 描述了一个系统对于物品长尾的发掘能力。
- 覆盖率的一个定义可以是:
$$
Coverage = \frac{\vert \bigcup_{u\in U}{R(u)}\vert}{\vert I \vert}
$$
- 其中,用户集合为 $U$ ,系统为每位用户推荐一个长度为 $N$ 的物品列表 $R(u)$
- 覆盖率的意义:覆盖率越高,以为这系统中被推荐给用户的物品,占所有物品的比例越大,对于一个好的推荐系统,不仅需要有较高的用户满意度,还需要有较高的覆盖率。
- 当然对于覆盖率的定义,不止以上的这一种,甚至说,在实际使用上,上述简单的覆盖率不足以支撑大规模复杂系统的覆盖率计算,所以如何对于覆盖率进行修正和更新?信息熵与基尼系数!
- 推荐了解,马太效应,一个强者更强,弱者更弱的效应,在推荐系统中也同样存在。
- **多样性**
- 假设,$s(i,j)$ 定义了物品 i 和 j 之间的相似度,给用户 $u$ 的推荐列表 $R(u)$的多样性定义:
$$
Diversity = 1- \frac{\sum_{i,j\in R(u),i\ne j}{s(i,j)}}{\frac{1}{2}\vert R(u)\vert (\vert R(u)-1\vert)}
$$
- 推荐系统整体的多样性可以定义为,用户推荐列表多样性的平均值:
$$
Diversity = \frac{1}{\vert U\vert}\sum_{u\in U}{Diversity(R(u))}
$$
- **信任度**
- 用户对于该系统的信任程度
- **实时性**
- 系统对于数据更新的时效性
- **健壮性**
- 系统对于外来攻击的防护性

View File

@@ -1,80 +0,0 @@
# 推荐系统的外围架构
![推荐系统外围架构图](https://cdn.xyxsw.site/推荐系统外围架构图.png)
<center>推荐系统外围架构图</center>
在外围结构中,我们有以下部分:
- **UI界面**:负责与用户进行交互,并收集用户的各种行为数据记录至日志系统。
- **日志系统**:通过日志系统,将用户的行为数据存储至用户日志存储系统。
- **用户日志存储系统**:可能存储在内存缓存中,数据库中或者文件系统中。
- **推荐系统**分析行为数据生成推荐列表展示至UI界面供用户选择。
# 推荐系统的架构
推荐系统的任务集中于:根据提供的数据,生成用户的推荐列表。这个任务可以抽象为一个从用户通过各种各样的特征最终走到不同物品的过程。而这个过程又可以拆解成两个部分:一是如何生成用户的特征,二是如何根据特征找到物品。
而基于之前学习的各种知识,我们可以对于这两个部分找到对应的方法。生成特征可以看成是在庞大的数据集中找到一个适合的分类规则,例如:通过基于上下文信息分类,通过标签信息,利用行为信息等,而根据特征找到物品可以看成是基于不同特征下的计算用户对于物品的兴趣度。(待斟酌)
若是将推荐系统的任务细分,可以结合现实实际情况:将最新加入的物品推荐给用户;商业上需要宣传的物品推荐给用户;为用户推荐不同种类的物品。
**复杂的特征和情况不同的任务**会让推荐系统变得非常复杂所以推荐系统的架构为了方便考虑采用多个不同的推荐引擎组成每个推荐引擎专门负责某一类特征和一种任务而推荐系统再将推荐引擎的结果按照一定的优先级合并排序并返回给UI系统。
![推荐系统的架构图](https://cdn.xyxsw.site/推荐系统的架构图.png)
<center>推荐系统的架构</center>
如上图所示。
这样做能够灵活的更换推荐引擎,以适应不同用户或不同场景下的推荐需求。
# 推荐引擎的架构
推荐引擎的架构主要包括三个部分:
- 特征向量生成部分(特征向量输出部分)
- 初始推荐物品列表生成部分
- 推荐列表筛选、过滤、重排列部分
![推荐引擎的架构](https://cdn.xyxsw.site/推荐引擎的架构.png)
以上为推荐引擎的架构图。
## 特征向量生成部分
特征向量生成时,若用户的人口统计学特征等信息直接缓存在内存中,则推荐是直接拿到用户的特征数据进行特征向量生成。
而另一种情况中,系统缺少人口统计学特征或是无法直接调用,则需要从用户的行为信息中生成特征向量。此时,就需要将用户行为的一些特征素纳入考虑,并将这些特征赋予适合的权重进行计算。
## 初始推荐物品列表生成
由得到的特征向量,进行特征-物品迁移,从而生成初始的推荐物品列表
## 推荐列表筛选、过滤、重排列
**筛选过滤模块**
得到了初始化的推荐列表之后,此时是不能直接将其展示给用户的,因为在这个列表中仍然存在包括:**用户已产生过行为**、**候选物品外的物品**、**某些质量很差的物品**,等不符合推荐原则的物品,所以需要进行第一步筛选过滤。
**排名模块**
再经历了筛选过滤之后的推荐列表,已经具有只是给用户的能力了,但若是能将排名进一步更新则会提高用户的满意度。对于排名进行更新有以下几种思路:
**新颖性排名**
为了提高列表的新颖性,可以对列表中的热门物品进行适当的降权处理
**多样性排名**
思路有:按照物品的内容分类后,从分类中选择排名最高的物品组合推荐;控制不同推荐理由出现的次数。
**时间多样性**
为了避免用户每次使用系统时得到的推荐列表没有任何变化
**用户反馈**
对于用户反馈的信息在排名加权计算中进行反馈,从而生成对应的推荐列表

View File

@@ -1,230 +0,0 @@
# 利用用户行为数据
## 用户行为数据介绍
### 什么是用户行为数据?
顾名思义,用户行为数据是指一些能表示用户行为的数据,最简单的存在形式就是网站上的日志,包括用户在网站上的点击被记录至点击日志,完成一次网站相应被记录至会话日志等。
### 用户行为数据分类
- 显性反馈数据:显形反馈包括用户明确表示对物品喜好的行为,例如对于一个视频的顶或者踩,更进一步是对于这个视频写下的评价、打上的标签等。
- 隐形反馈数据:隐形反馈包括用户的页面浏览行为等不能明确反映用户兴趣的行为,包括一个视频的完播率,页面的停留时间等数据。
若是按照反馈的划分,数据又可以被分为正反馈和负反馈,正反馈指用户的行为倾向于用户喜欢该物品,而负反馈则相反。
## 用户行为数据分析
### 用户活跃度和物品流行度的关系
**长尾分布** 互联网中很多数据都遵循长尾分布:$f(x)=\alpha x^k$ ,用户行为数据同样蕴含长尾分布的规律。
令 $f_{u}(k)$ 为对 $k$ 个物品产生过行为的用户数,$f_i(k)$ 为对 $k$ 个用户产生过行为的物品数。那么有以下的规律存在
$f_i(k)=\alpha_ik^{\beta_i}f_u(k)=\alpha_uk^{\beta_u}$
## 协同过滤算法
仅对用户行为数据所设计的推荐系统算法被称为协同过滤算法。协同过滤算法中包含多种算法:基于邻域的方法、隐语义模型、基于图的随机游走算法。
### 基于邻域的算法
推荐系统中最基本的算法,可以分为基于用户的协同过滤盒基于物品的协同过滤。
#### 基于用户的协同过滤
算法简介:当你想要出去玩时,你会询问身边和自己游玩兴趣相似的朋友的意见,并从他们的推荐中选择你自己的出行方案,而且一般你制定的出行方案中大部分是自己为听说过或去玩过的景点,这就是一种生活中的基于用户的协同过滤。
特点分析:可以从上面的例子看出,此类协同过滤主要包含两个步骤:
**(1)找到和目标用户相似的用户集合** ,我们称这个被找到的用户为,被寻用户以方便下文讲解
**(2)从被寻用户的兴趣集合中,找到目标用户喜欢的且目标用户未听说过的物品**
以上就是,基于用户的协同过滤最基本的思想,让我们分步对这个算法进行分析。
#### 如何找到和目标用户相似的被寻用户?
关键就是计算用户与用户之间的相似度,计算相似度有两种不同的方法,我们给定用户 $u$ 和用户 $v$ $N(u)$ 为用户 $u$ 有过正反馈的物品集合,$N(v)$ 为用户 $v$ 有过正反馈的物品集合。
**Jaccard 相似度** 公式为:$w_{uv} = \frac{\vert N(u)\cap N(v)\vert}{\vert N(u)\cup N(v)\vert}$
**余弦相似度** 公式为:$w_{uv} = \frac{\vert N(u)\cap N(v)\vert}{\sqrt{\vert N(u)\vert \vert N(v)\vert}}$
这就是一种计算相似度的方法,但是不可避免的,这样的相似度计算方法需要遍历整个用户信息表,时间开销极大,而且存在很多无效查询,所以考虑进行改进。**倒排表改法?**
用户相似度在遭遇热门物品时,会导致严重的误差,例如:如果两人同时购买了《新华字典》,可能并不是因为两人都对它有兴趣,而是因为它是一本基本工具书,所以不能通过这个过热门物品确定二人的兴趣相似。**改进公式惩罚热门物品?**
#### 如何为目标用户推荐物品?
关键是计算出目标用户对于各个物品的兴趣,设 $S(u,K)$ 包含和用户 $u$ 最接近的 $K$ 个用户,$N(i)$ 是对物品 $i$ 有过行为的物品集合,$w_{uv}$ 表示用户 $u 和 v$ 的兴趣相似度,$r_{vi}$ 表示用户 $u对i$ 的兴趣这个变量的值仅有01取值。
所以用户$u对于物品i的相似度$ 可表示为:$p(u,i)=\sum_{v\in S(u,K)\cap N(i)}{w_{uv}r_{vi}}$
其中会对这个推荐结果产生较大影响的外部变量,$K$。如何确定一个合适的K值是
#### 基于物品的协同过滤算法
算法简介:例如你以前购买过《算法导论》,而系统判断《算法导论》与《数据结构》具有较高的相似度,那么系统就会将《数据结构》推荐给你,需要注意的是,系统对于物品之间相似度的判定,来源与用户对于物品的行为信息,而不是根据物品与物品之间内容的相关性。
特点分析:**较高的解释性**,系统在进行推荐时,可以利用用户的历史行为给推荐结果提供解释;**较低的时间复杂度**,相较于基于用户协同过滤的和用户数量成平方的时间复杂度,基于物品协同过滤的时间复杂度较低。
该算法与用户协同过滤类似,分成两步:
**计算物品之间的相似度**,定义$N(i)$ 是喜欢物品 i 的用户数, $N(i)\cap N(j)$ 为喜欢物品 i 和 j 的用户数,因此物品相似度可定义为如下公式
<center>
$w_{ij}=\frac{\vert N(i)\cap N(j)\vert}{\vert N(i) \vert}$
</center>
同样的,该公式也存在热门物品造成误差的问题,因为如果多数人都喜欢 j ,那么 $w_{ij}$ 就会无限趋近于1导致系统中任何物品对于物品j都具有很大的物品相似度影响了推荐系统的覆盖率所以考虑对于公式进行修正为
<center>
$w_{ij}=\frac{\vert N(i)\cap N(j) \vert}{\vert N(i)\vert \vert N(j)\vert}$
</center>
**用户活跃度对于相似度的影响?** 如果一个批发商大肆购买物品,那么他对于这大量物品的相似度的实际贡献,是不如一个只购买了十几本书的兴趣爱好者的。那么,**如何对这种行为进行惩罚?**
更进一步,**归一化?**,将相似度矩阵按最大值归一化,可以有效提升推荐系统的性能。
#### 得到用户对于物品i的兴趣
同样通过相似度对于兴趣进行推测,$N(u)$ 表示用户喜欢的物品集合,$S(j,K)$ 是和物品 j 最相似的 K 个物品集合,$w_{ij}$ 是物品 i 和物品 j 的相似度,$r_{ui}$ 是用户 u 对于物品 i 的兴趣根据隐反馈数据集若用户对于物品有过行为则值为1所以公式为
<center>
$P_{uj}=\sum_{i\in N(u)\cap S(j,K)}{w_{ji}r_{ui}}$
</center>
## 隐语义模型
隐语义模型的基本思想是,通过隐含特征联系用户兴趣和物品,进行进一步解释即为:以物品的内容进行分类,根据用户的行为对用户进行兴趣判断,从对应符合用户兴趣的物品类别中推荐物品。
基于上述理解,需要解决的问题分别有:
(1)如何对于物品进行分类;
(2)如何确定用户的兴趣方向,以及用户对于不同兴趣方向的感兴趣程度;
(3)对于一个兴趣方向,如何挑选给定分类中的物品给用户,如何确定该物品在分类中的权重。
为了解决上述问题,以及上述问题牵扯出的一系列问题(思考这一系列问题中有哪些?是个很好的锻炼思维方式)。考虑采用隐含语义分析技术,因为**隐含语义分析技术**采取基于用户行为统计的自动聚类,具有对于以上问题较好的适应性。
类似于itemCF的思想若两件物品同时被很多用户标记则这两件物品可能属于统一分类
隐语义能够指定最终的分类数量,从而控制分类的粒度,当分类数量较大时,粒度则较小,分类数量较小时,粒度较大
隐语义会计算出单个物品不同内容的所占权重,所以不会出现一个物品只在一个分类中
隐语义所给出的分类是基于用户共同兴趣的,所以给出的分类有更大可能会给予不同维度
隐语义通过统计用户的行为来确定物品在当前分类的权重
#### LFM模型
###### 建立数据集
用户所产生的行为分为正反馈与负反馈LFM模型在显性反馈数据集上解决评分预测问题有很好的精度但是若是在隐性反馈数据集上样本只存在正样本而没有负样本如何解决这个问题**生成令人满意的负样本?**
生成负样本有如下的几种思路
定义用户未有过行为的物品、定义未有过行为中随机采样出的物品、定义未有过行为中随机采样出的物品,且这些物品数量与正样本数量相当、定义未有过行为的物品,且着重挑选一些不热门的物品。
在实际实验的过程中上述四种思路各有胜负最终通过一场2011年的推荐算法比赛得出了负样本采样应遵循的原则
- 负样本采样应保证正负样本平衡
- 采取负样本时,应遵循冷门物品有限的原则
#### 通过随机梯度下降法优化参数
通过建立的数据集 $K=\{(u,i)\}$ ,其中如果 $(u,i)$ 是正样本,则有 $r_{ui}=1$ 否则为0。然后通过优化如下的损失函数来找到合适的参数 $p,q$
$$C=sum_{(u,i)\in K}{(r_{ui}\hat r_{ui})^2}=\sum_{(u,i)\in K}{(r_{ui}\sum^K_{k=1}{p_{u,k} q_{i,k} })^2}+\lambda\Vert p_u\Vert^2+\lambda\Vert q_i\Vert^2$$
其中,$\lambda\Vert p_u\Vert^2+\lambda\Vert q_i\Vert^2$ 是用来防止过拟合的正则项,$\lambda$ 可通过实验获得。
使用随机梯度下降法优化以上的损失函数,递推公式如下:
$p_{uk}=p_{uk}+\alpha(q_{ik}\lambda p_{uk})$
$q_{ik}=q_{ik}+\alpha(p_{uk}\lambda q_{ik})$
重要参数共四个:
- 隐特征数量F
- 学习速率$\alpha$
- 正则化参数$\lambda$
- 负样本与正样本的比例ratio
将得到的参数代入Preference公式中
LFM定义了 $p_{u,k}$ 和 $q_{i,k}$ 作为模型的参数,其中,$p_{u,k}$ 度量了用户 u 的兴趣和第 k 个隐类的关系,而$q_{i,k}$ 度量了第 k 个隐类和物品 i 之间的关系,所以可以有公式计算兴趣度
<center>
$$Preference(u,i)=r_{ui}=p^T_uq_i=\sum^F_{f=1}{p_{u,k}q_{i,k}}$$
</center>
得到用户对于物品的兴趣度之后,就能进行排名再生成推荐列表。
#### LFM局限性
对于参数的训练的要再数据集上进行多次迭代,在一般的实际应用中每天只能训练一次并且得出结果,所以很难满足根据用户的实时行为对用户进行推荐,即实时性较弱。
## 基于图的模型
可以想到用户与物品之间的相互关系可以由二分图进行表示,所以在推荐算法中引入图模型
### 用户数据的二分图表示
在研究图模型之前,需要用已有的数据生成一个图,设二元组 $(u,i)$ 表示用u对于物品 i 产生过行为。令 $G(V,E)$ 表示用户物品二分图,其中$V=V_U\cup V_I$ 由用户顶点集合和物品顶点集合组成,$E$ 是边的集合。对于数据集中的二元组 $(u,i)$ 图中都会有对应的边 $e(v_u,v_i)\in E$ 如下图所示。
![用户物品二分图模型](https://cdn.xyxsw.site/用户物品二分图模型.png)
### 基于图的推荐算法
将数据集转换为图模型之后原来的给用户u推荐物品的任务就可以等效于计算与用户u没有边直接相连的物品集合中计算用户与物品的相关性相关性越高则它在推荐列表中的权限就越高。
#### 相关性计算
相关性的计算主要依赖于一下三个因素
1. 两个顶点间的路径数
2. 两个顶点之间的路径距离
3. 两个顶点之间的路径经过的顶点
相关性高的两个顶点,通常具有以下的特征
1. 两个顶点之间有很多路径相连
2. 连接两个顶点间的路径很短(相似度高)
3. 连接两个顶点之间的路径不会出现出度过大的顶点(热门物品少)
**PersonalRank算法**
基于上述相关性计算的因素有多种多样不同侧重的图算法下面将介绍一种基于随机游走的PersonalRank算法
PersonalRank算法的基本思想是假设要给用户u进行个性化推荐可以从用户节点 $v_u$ 开始在用户物品二分图上开始随机游走。当游走到一个节点是,首先按照概率$\alpha$ 决定是继续游走,还是停止游走并直接返回 $v_u$ 重新开始游走。如果决定继续游走,那么就从当前节点所指向的节点按照均匀分布随机选取一个节点作为下次游走的目标。这样,经过多轮游走之后,每个物品节点被访问到的概率会收敛到一个数。最终推荐列表的权重就是这个点的访问概率。
可表示为公式
$$
PR(v)=\begin{cases}\alpha \sum_{v'\in in(v)}\frac{PR(v')}{\vert out(v')\vert},&v\ne v_u\\(1\alpha)+\alpha \sum_{v'\in in(v)}\frac{PR(v')}{\vert out(v')\vert},&v=v_u\end{cases}
$$
与上面几种算法一样PersonalRank算法需要在全图迭代所耗费的时间是难以接受的如何改进算法
1. **减少迭代次数**
2. **通过矩阵论重新设计算法**
## 总结
在本节内容中,我们主要立足于用户的行为数据,介绍用户行为数据是什么?用户行为数据有哪些分类?用户行为数据的特点。并且通过用户对于物品产生行为数据这一活动,我们设计了一系列算法包括,基于邻域算法、隐特征模型、基于图的模型。
但是用户对于物品产生数据这一行为,在当今互联网上算是最为简单的一种交互,无法满足用户日益刁钻的推荐需求。反过来思考,一旦当系统是一个新上线的系统,还没有大量的数据信息进行训练参数时,如何进行推荐。这就是后面我们主要解决的两个问题
如何解决冷启动问题?
如何增加推荐因素以满足用户增长的推荐需求?

View File

@@ -1 +0,0 @@
# 推荐系统冷启动 <badge type="warning">待补充 bybuwyi</badge>

View File

@@ -1 +0,0 @@
# 利用标签信息 <badge type="warning">待补充 bybuwyi</badge>

View File

@@ -1,253 +0,0 @@
# 利用上下文信息
## 概述
- 在对用户进行推荐时,用户所处的空间与时间会对用户的喜好产生影响。例如,最经典的例子,如果当前季节是冬天,推荐系统不应该给用户推荐短袖。这就是一个很经典的时间上下文。同样能被成为上下文信息的包括但不限于,心情,地点等能描述用户当前状态的信息。利用这些上下文信息,我们能将推荐系统的推荐更加精确。
- 将重点讨论基于时间上下文信息的推荐系统
## 时间上下文
### 时间信息效应
- 时间信息对于用户的的影响可以主要分为以下几项:
- **用户的兴趣是变化的**
对于一个用户,其幼年时期和青年时期喜欢的动画片是不一样的;晴天和雨天想要的物品是不一样的;一个人开始工作前和开始工作后的需求也是不同的。
所以应该关注用户的近期行为,确定他的兴趣,最后给予用户推荐。
- **物品具有生命周期**
流行物品会随着热度持续火爆一段时间,但最终会无人问津;生活必需品无论在什么时候都有稳定的需求量。
- **季节效应**
正如概述中列出的冬衣与夏衣的区别,应该在合适的季节给用户推荐合适的物品。
### 系统时间特性分析
- 当系统由之前的静态系统变成随时间变化的时变系统后,需要关注特性也会发生变化,则需要重新观测一些数据,以推断系统的关于时间变化的特性。
下面是一些可以用来观测的数据:
- **确定系统的用户增长数**,以判断系统的增长情况或是衰退情况。
- **物品的平均在线天数**,即将满足用户物品互动次数的物品标记为在线,测算物品的平均在线天数以标量物品的生命周期。
- 系统的时效性,判断**相隔一段时间的物品流行度向量的相似度**,若是相隔一段时间的相似度仍然较大,说明经过一段时间后,该物品还是被大众喜欢,则说明这件物品具有持久流行性。而对于系统来说,若是系统中大量物品的相似度变化都不大,则说明这个系统是一个推荐热度较持久物品的系统,说明系统的时效性较弱。
- 系统对于用户的黏着性,统计**用户的平均活跃天数**,或者计算**相隔一段时间的用户活跃度**,以此判断系统对于用户的留存力或者说黏着性。
### 推荐系统的实时性
- 当引入了时间上下文信息后,推荐系统就可以进行实时性推荐,就类似于观看完一个视频后,立马弹出一系列的相关推荐列表“猜你想看”,存在这样特性的推荐系统有如下的特征:
- 实时推荐系统能根据用户的行为,实时计算推荐列表,而不是像之前所说的离线计算推荐列表。
- 推荐系统需要平衡用户短期行为和长期行为,用户的推荐列表需要体现其短期的兴趣变化,但是推荐列表的又不能完全受用户近期行为影响,需要保证推荐列表预测的延续性。
### 推荐算法的时间多样性
- 想象这样一种情况,现在有 ABC 三个系统A 系统为您推荐您最感兴趣的十样物品但是不会更新。B 系统为您推荐一百样物品中的十样物品推荐间隔一周一周之后的榜单有七件不会是这周的物品。C 系统随机为您推荐一百样物品中的十样物品。
用推荐系统的思想分析上述三个系统A 系统缺乏了随时间变化的推荐多样性所以用户对于其满意度会随着时间推移而下降B 系统兼顾了时间变化和推荐精度会得到用户较高的好评C 系统则是过于随机导致推荐精度下降。
综上,时间多样性会提高用户的满意度,所以如何在确保精度的条件下提高系统的时间多样性呢?
- **需要用户在有新行为时,更新推荐列表**
传统的离线更新的推荐系统无法满足需求,所以需要使用实时推荐系统。
- **需要用户在没有新行为的时候,经常变化推荐列表**
通常采取以下三种方法:
- 生成推荐列表时加入一定的随机性。
- 记录用户每天得到的推荐列表,在一段时间后,降低列表中用户未出现过行为的物品的权重。
- 每次给用户使用不同的推荐算法。
当然,对于推荐系统来说,推荐准度的重要性要大于时间多样性,所以应该在尽量保证准度的基础上强化实践多样性,而这个强化的程度,则需要对推荐系统进行多次实验得到。
### 时间上下文推荐算法
- **最近最热门**
一种最朴素的思想, 在系统引入了时间信息之后,最简单的非个性化推荐算法就是给用户推荐最近最热门的物品。
给定时间 T物品 i 在最近的流行度可定义为:
$$
n_i(T)= \sum_{(u,i,t) \in Train ,t<T} \frac{1}{1+\alpha(T-t)}
$$
- **时间上下文相关的 itemCF 算法**
itemCF 算法所依赖的核心部分,在引入时间信息后可以进行进一步更新
- **物品相似度** 利用用户行为,计算物品间的相似度,用户在相隔很短的时间内喜欢的物品通常具有更高的相似度,所以可以在相似度计算公式中引入时间信息,使得相似度计算更加准确。
原本的相似度公式为:
$$
sim(i,j)=\frac{\sum_{u\in N(i) \cap N(i)}{1}}{\sqrt{\vert N(i)\vert \vert N(j) \vert}}
$$
引入时间信息后,可更新为:
$$
sim(i,j)=\frac{\sum_{u\in N(i) \cap N(i)}{f(\vert t_{ui} - t_{uj}\vert)}}{\sqrt{\vert N(i)\vert \vert N(j) \vert}}$$
其中$f(\vert t_{ui}-t_{uj} \vert)$ 为时间衰减项,其中$t_{ui}$为用户u对物品i产生行为的时间$f()$ 函数的作用是用户对i与j的作用时间相距越远对应函数值越小相当于对输入因子$\vert t_{ui}-t_{uj} \vert$ 进行一个反比操作。可以找到在数学中许多的衰减函数,例如:
$$f(\vert t_{ui}-t_{uj} \vert)=\frac{1}{1+\alpha(\vert t_{ui}-t_{uj}\vert)}$$
其中$\alpha$ 是时间衰减参数,它的取值与系统的对于自身定义有关系。收到用户兴趣变化的额外影响。
- **在线推荐** 用户近期行为相比用户很久之前的行为,更能体现用户目前的兴趣,所以在进行预测时,应当加重用户近期行为的权重,但不应该偏离用户长期行为的行为基调。
原本的用户u对于物品i的兴趣$p(u,i)$ 可通过如下公式计算:
$$p(u,i)=\sum_{j\in N(u)}{sim(i,j)}$$
引入时间信息可更新为:
$$
p(u,i)=\sum_{j\in N(u)\cap S(i,k)}{sim(i,j)\frac{1}{1+\beta \vert t_0-t_{uj}\vert}}
$$
在上面的更新后公式中,$t_0$ 表示当前时间,该公式表明,当 $t_{uj}$ 与 $t_0$ 越靠近和物品j相似的物品就会在用户u的推荐列表中获得更高的排名。其中的$\beta$和上文的 $\alpha$ 是一样的,需要根据系统的情况选择合适的值。
- **时间上下文相关的userCF算法**
与itemCF算法类似userCF在引入时间信息后也可以进行更新
- **用户兴趣相似度** 用户相似度在引入时间信息后会将用户相同的逆时序选择相似度降低。简单来说就是A一月BF1长时间在线二月BF5长时间在线而B一月BF5长时间在线二月BF1长时间在线C行为信息与A相同。如果不引入时间信息那么AB的相似度与AC的相似度是一样的而实际上AC的相似度会大于AB的相似度。
userCF的用户uv间相似度的基本公式为
$$
w_{uv}=\frac{\vert N(u)\cap N(v)\vert}{\sqrt{\vert N(u)\cap N(v)\vert}}
$$
其中,$N(u)$ 是用户u喜欢的物品的合集$N(v)$ 是用户v喜欢的物品的合集。
引入时间信息后,公式可更新为:
$$
w_{uv}=\frac{\sum_{i \in N(u)\cap N(i)}{\frac{1}{1+\alpha \vert t_{ui}-t_{vi}\vert}}}{\sqrt{\vert N(u)\cap N(v)\vert}}
$$
同样增加了一个时间衰减因子用户uv对于i的作用时间差距越大那么两人的相似度会相应降低。
- **相似兴趣用户的最近行为** 对于用户u来说存在最近行为与用户u相似的用户v那么用户v的最近行为将会比用户u很久之前的行为更具有参考价值。
userCF中用户u对于物品i兴趣的基础公式为
$$
p(u,i)=\sum_{v\in S(u,k)}{w_{ui}r_{vi}}
$$
其中,$S(u,k)$ 包含了与用户 u 相似度最高的 k 名用户。而对应的$r_{ui}$ 若用户产生过对i的行为则其值为1 否则为0 。
引入时间信息更新公式:
$$
p(u,i)=\sum_{v\in S(u,k)}{w_{ui}r_{vi}} \frac{1}{1+\alpha(\vert t_0-t_{vi}\vert)}
$$
- **时间段图模型**
同样是一个基于图的推荐系统模型,引入时间信息,建立一个二分图时间段图模型:
$$
(U,S_U,I,S_I,,E,w,\sigma)
$$
其中,$U$ 是用户节点集合,$S_U$ 表示用户时间段节点集合,一个用户时间段节点$v_{ut}\in S_U$ 会和用户 $u$ 在时刻 $t$ 喜欢的的物品通过边相连。$I$ 是物品集合,$S_I$ 是物品时间段节点集合,一个物品时间段节点 $v_{it}\in S_I$ 会和所有在时间$t$ 喜欢物品 $i$ 的用户节点相连。
$E$ 是边集合,包含两大类边
第一种:若用户 $u$ 对于物品 $i$ 有行为,则会存在边 $e(u,i)\in E$ ;第二种,若用户 $u$ 对于物品 $i$ 在时间 $t$ 有行为,那么将存在对应的两条边,$e(v_{ut},v_i),e(v_u,v_{it})\in E$ 。
而 $w(e)$ 定义了边的权重,$\sigma(e)$ 定义了顶点的权重。具体示例:
在构建了引入时间信息的图结构后最简单的思想就是利用PersonalRank算法给用进行个性化推荐。但由于其复杂度较高所以引入路径融合算法。
一般来说,图上两个点的相关度强有以下的特征:
- **两个顶点间有很多路径**
- **两个顶点间路径比较短**
- **两点间不经过出度大的点** ,即不经过与很多其他点相连的节点,在推荐系统思维中等效于不与过热门物品关系紧密。
#### 路径融合算法
- 首先提取两个节点之间,长度小于一个给定值的所有路径。然后根据每条路径经过的不同节点,给予路径不同的权重。最后将所有路径的权重之和,作为两点的相关度。
设 $P=\lbrace v_1,v_2,...,v_n\rbrace$ 是链接顶点 $v_1$ 到 $v_n$ 的一条路径,这条路径的权重 $\Gamma(P)$ 取决于这条路径所经过的所有顶点和边。
$$
\Gamma(P)=\sigma(v_n)\prod_{i=1}^{n-1}{\frac{\sigma(v_i)\cdot w(v_i,v_{i+1})}{\vert out(v_i)\vert ^{\rho}}}
$$
其中,$out(v)$ 是顶点 $v$ 指向的顶点的集合,$\vert out(v) \vert$ 是顶点 $v$ 的出度,$\sigma(v_i)\in(0,1]$ 定义了顶点的权重,$w(v_i,v_{i+1})\in (0,1]$ 定义了边 $e(v_i,v_{i+1})$ 的权重。
定义了一条边的权重之后,就可以定义顶点之间的相关度。
对于顶点$v_1,v_n$ ,令$p(v_1,v_n,K)$ 为这两个顶点间距离小于K的所有路径那么这两个顶点的相关度就可以表示为
$$d(v_1,v_n)=\sum_{P\in P(v_1,v_n,K)}{\Gamma(P)}$$
而关于路径融合算法的算法实现,可以使用基于图上的广度优先搜索算法实现。
## 地点上下文
### 地点信息效应
- **基于用户当前位置的推荐**:对于用户当前位置,为其推荐距离更近的餐馆,娱乐场所或消费场所。
- **基于用户活跃位置的推荐**:对于用户长期活跃的区域,降低该区域内物品的权重,提高范围外物品的权重,以提高系统的新鲜度。
### 基于位置的推荐算法
- 明尼苏达大学的LARS推荐系统Location Aware Recommender System,位置感知推荐系统)。
- **对于数据的预处理**
将物品分为两类:(1)有空间属性的物品,餐馆,商店,旅游景点。(2)没有空间属性的物品,图书电影等。
将用户分为两类:(1)有空间属性的用户,(2)另一类用户没有空间属性。
基于上述的分类,将数据集整理成三个部分:
(用户,用户位置,物品,评分):记录了某一地点的用户,对于一个物品的评分。
(用户,物品,物品位置,评分):记录了用户对于某一地点的物品的评分。
(用户,用户位置,物品,物品位置,评分):记录了某个位置的用户,对于某个地点的物品的评分。
- **研究前两组数据**:发现两种特征:(1)兴趣本地化,不同位置的用户存在较大的兴趣差异,不同国家和不同地区的差异。(2)活动本地化,一个用户往往在附近的地区活动。
- **对于不同数据的处理**
- 第一种数据LARS的基本思想是采用树状结构来进行数据集划分。
(1)例如:将所有用户作为根节点,将国家作为第一级子节点,省作为第二级,依次往下。
(2)对于某一个具有位置信息的用户,我们就可以将他分配到一个子节点下,而该子节点包含了与当前用户具有相同位置信息的全体用户的行为数据。
(3)LARS通过该节点的行为数据利用基本推荐算法进行为用户进行推荐。
但是,对于上述过程,若是树的深度较大,则划分到每个节点的用户数据将较少,难以训练出一个令人满意的模型。所以有改进方法如下:
从根节点出发,利用每个中间节点的数据训练出一个模型,而最终的推荐结果,是这一些列推荐模型所产出的推荐结果的加权结果。这个模型也被称为“**金字塔模型**”,其中**深度**是影响这个模型性能的重要参数,选取合适的深度对于该算法十分重要。
- 第二种数据对于物品i在用户u推荐列表中的权重公式进行修正
(1)首先忽略物品的位置信息利用itemCF算法计算用户u对物品i的兴趣。
(2)计算物品i对于用户u的代价 $TravelPenalty(u,i)$ 对于物品i与用户u之前评分的所有物品的位置距离计算平均值度量方式通常采用交通网络数据。
(3) 利用公式
$$RecScore(u,i)=P(u,i)-TravelPenalty(u,i)$$
计算最终的权重。
- 第三种数据LARS的处理方法相当于在第二种数据中引入了用户当前位置的信息。

View File

@@ -1,9 +0,0 @@
# 基于数据的角度,看待推荐系统的构造 <badge type="warning">待补充 bybuwyi</badge>
推荐系统诞生的二十年以来,各种各样的推荐算法层出不穷。若是将他们进行一个粗略的分类,可以按照数据的形式和算法的形式分类。
按照数据的分类中:协同过滤,内容过滤,社会化过滤等
按照算法的分类中:基于领域的算法、基于图的算法、基于矩阵分解的算法等
接下来的这部分内容,主要遵循项亮老师在《推荐系统实践》中的思路,进行基于数据的角度的推荐系统构建介绍。

View File

@@ -1,14 +0,0 @@
# 序列化推荐
# 什么是序列化推荐?
在现实世界中,用户的前后行为都存在强烈的关联性与因果性,将用户过去的这一系列交互行为视作用户行为序列 u={$i_1$,$i_2$,……,$i_n$}并通过构建模型对其建模,来预测下一时刻用户最感兴趣的内容$i_{n+1}$这就是序列化推荐Sequential Recommendation的核心思想。目前序列化推荐的常用模型包括RNN、CNN、GNN以及Transformer。
> 传统的推荐系统,例如基于内容和协同过滤的推荐系统,以一种静态的方式建模用户和商品的交互并且只可以捕获用户广义的喜好。
<br/><br/>
而SRSs则是将用户和商品的交互建模为一个动态的序列并且利用序列的依赖性来活捉当前和最近用户的喜好。
![](https://cdn.xyxsw.site/boxcnolggxKhDZDBzIFPIaDFfhc.png)

View File

@@ -1,17 +0,0 @@
# 推荐系统
许多人把推荐系统视为一种神秘的存在,推荐系统似乎知道我们的想法是什么。
如下图是阿里巴巴著名的“千人千面”推荐系统
![](https://cdn.xyxsw.site/boxcn3bdrD08wpaYhL59ezDukuc.jpg)
还有短视频应用用户数量的急剧增长,这背后,视频推荐引擎发挥着不可替代的作用
个性化资讯应用更是以摧枯拉朽之势击败了传统的门户网站和新闻类应用
可以说,推荐系统几乎成了驱动互联网所有应用领域的核心技术系统,成为当今助推互联网增长的强劲引擎。
> 对于信息消费者,需要从大量信息中找到自己感兴趣的信息,而在信息过载时代,用户难以从大量信息中获取自己感兴趣、或者对自己有价值的信息。<br/>对于信息生产者,需要让自己生产的信息脱颖而出,受到广大用户的关注。从物品的角度出发,推荐系统可以更好的发掘物品的长尾。
请大家自行了解什么是长尾效应。

View File

@@ -1,44 +0,0 @@
# 知识图谱
## 谷歌的新概念
2012 年谷歌工程师阿米特·辛格尔Amit Singhal在自己的 official blog 发表了一篇名叫《Introduce the Knowledge Graph》的文章初次提出了知识图谱的概念并将知识图谱运用于 Google 搜索中,文中介绍到,结合了知识图谱的 Google 搜索有了更强的能力:
- Find the right thing :如果碰到要找的事物有同名时,你可以在相关推荐中看到
- Get the best Summary你能得到相关领域的一个很好概述
- Go deeper and broader除了你要找的知识外你可能可以意外获得新领域的事物
原文:
- https://www.blog.google/products/search/introducing-knowledge-graph-things-not/
## 发展脉络
不过知识图谱并非是一种新的技术和研究方向,更准确来说是一个新壶装老酒的概念包装,它的核心已有非常悠久的发展历史,甚至最早可以追溯到二十世纪五六年代,人工智能刚作为一个学科成立的时候,其中三大学派之一——符号主义。
具体其发展历程参考:
- [https://mp.weixin.qq.com/s/Mcikp99bsVgxAaykctmcAw](https://mp.weixin.qq.com/s/Mcikp99bsVgxAaykctmcAw) 知识图谱的前世今生
在大致了解知识图谱的历史发展脉络后,我们或许对它有了一个初步的认知——一个由抽象符号构成的知识库,目的是为了让计算机理解人类的语义信息,打个不太恰当的比方,就是个计算机理解人类世界的大脑。
从中我们可以也窥探到当年符号主义学派学者们的野心,不过很显然,这条道路发展并不顺利,如今知识图谱还无法完全担任“大脑”这种重要的角色,绝大多时候,都是作为一个辅助位的角色,不过这个方向的潜力无疑是巨大的,并且它所能勾连的方向是非常宽广繁多的(不仅仅局限于 NLP 里),这导致了其复杂程度很高,但也衬托出其上限也可以很高。
不过这些都是题外话,继续深入,我们可能会从这个认知上延申出两个问题,一是如何存储这个知识库,而是形成这个知识库后又如何让计算机理解,毕竟计算机只懂 01。这两个问题也是知识图谱的发展方向。
## 构建
在了解了抽象的概念后,我们将视角移到具体实现上,如何来存储这个知识库?于是,现在就需要寻找一种较为简单方便的,并且能够表达语义关系的数据结构,然后图(Graph)就被拉来了。了解过图的都知道,图由节点和边构成。所以如果当我们将节点看作实体,即一个个具体的事物或概念(例如小明,小红,人),再由边代表实体之间的关系(朋友关系,种族),虽然可能存在一定程度上语义表达的不完备性,但面对生活中的大多数事物,这种简单的三元组(RDF)关系都可以进行表示,不够就多来几组。
于是这种由 head(头实体)relation(关系)tail(尾实体)所构成的有向图的数据结构,就变成了如今知识图谱的大致构成方式。不过它的整个构建流程是有一套更加详细且具体的流程的,从知识抽取到实体消歧到知识推理。
更具体的可参考:
- [https://www.woshipm.com/pmd/5328539.html](https://www.woshipm.com/pmd/5328539.html) 产品视角下的知识图谱构建
## 让计算机理解
在成功搭建起知识图谱这个数据库后,接下来就是最重要的一步了,让计算机理解——表示学习。目前这个方向,最重要的就是向量化,将节点和关系全部向量化,一方面有向量的平移不变性的好处,另一方面也方便计算,在从中穿插点图论的相关知识,例如将知识图谱看成特大号异构图进行处理。不过这方面方向太多,难以一一列举。
- [https://www.cnblogs.com/fengwenying/default.html?page=5](https://www.cnblogs.com/fengwenying/default.html?page=5) 胡萝不青菜的博客
- [up主 骰子 AI](https://space.bilibili.com/497998686?spm_id_from=333.337.0.0) up 主 骰子 AI知识图谱在推荐系统上的利用

View File

@@ -1,7 +0,0 @@
# 自然语言处理NLP
Natural Language ProcessingNLP
当你看到这篇文章时,这一个领域已经被 GPT 等大语言模型干爆了。
[https://github.com/HarderThenHarder/transformers_tasks](https://github.com/HarderThenHarder/transformers_tasks)

View File

@@ -1,73 +0,0 @@
# VIT
## 前言
VIT前Transformer模型被大量应用在NLP自然语言处理当中而在CV领域Transformer的注意力机制attention也被广泛应用比如Se模块CBAM模块等等注意力模块这些注意力模块能够帮助提升网络性能。
而**VIT的工作展示了不需要依赖CNN的结构也可以在图像分类任务上达到很好的效果**。
同时VIT也影响了近2年的CV领域改变了自2012年AlexNet提出以来卷积神经网络在CV领域的绝对统治地位。
在本节内容中我们会带你了解这一框架。
## 论文
[知乎](https://zhuanlan.zhihu.com/p/356155277)
[论文](https://arxiv.org/abs/2010.11929)
## 模型详解
![](https://cdn.xyxsw.site/boxcn1wqKtwBc6MCJDm7ehvhXac.png)
### 模型主题结构
结构上VIT 采取的是原始 Transformer 模型,方便开箱即用,即在 encoder-decoder 结构上与 NLP 的 Transform 模型并无差别。
主要做出的贡献在于**数据处理和分类头**
### Patch embedding
#### 从 Word embedding 到 Patch embedding
##### Word embedding
简单来说就是用特殊的向量来表示一个句子中的某个词
即例如
> 今天天气不错,我要去看电影
其中**我**则编码为[0.50.60.6]
而具体来说 Word embedding 分为以下两步
1. 对 context 进行分词操作。
2. 对分好的词进行 one-hot 编码,根据学习相应的权重对 one-hot 编码进行 Nembedded_dim维空间的映射.
##### Patch embedding
简单来说 用一个特殊的向量来表示一张图片中某块图
例如
![](https://cdn.xyxsw.site/boxcn1szLG4Y4s0UkY3kkW18Xoc.png)
![](https://cdn.xyxsw.site/boxcnv2inISAGi2xOauc3pxKpCb.png)
其中该张图片的编码为[0.50.60.3....]
具体来说
1. 先对图片作分块
1. 假设原始输入的图片数据是 H * W * C,
2. 假设每个块的长宽为(P, P),那么分块的数目为 N=H W / (P P)
3. 其中 vit 的分块是定下每一块的大小然后块的数量为计算结果
2. 然后对每个图片块展平成一维向量
1. 每个向量大小为 P * P * C
3. 接着对每个向量都做一个线性变换(即全连接层),得到 patch embedding
## 视频
<Bilibili bvid='BV15P4y137jb'/>

View File

@@ -1,81 +0,0 @@
# BERT
如果你想深入了解自然语言处理相关知识,本文只能让你在基础上了解 BERT 的架构和理念,细节就不能保证了。
但如果你看 BERT 的目的是了解 BERT 的创新点以了解把 BERT 拓展到 cv 领域的工作(如 MAE),本文可以让你快速理解 BERT 的理念。
# 前言
BERT 是一种基于 transformer 架构的自然语言处理模型,它把在 cv 领域广为应用的**预训练(pre-trainning)**和**微调(fine-tune)**的结构成功引入了 NLP 领域。
简单来说BERT 就是一种**认识几乎所有词的****训练好**的网络,当你要做一些下游任务时,可以在 BERT 预训练模型的基础上进行一些微调,以进行你的任务。也就是 backbone 模型,输出的是文本特征。
举个例子,我要做一个文本情感分析任务,也就是把文本对情感进行分类,那我只需要在 BERT 的基础上加一个 mlp 作为分类头,在我的小规模数据上进行继续训练即可(也就是微调)。
mlp 的重点和创新并非它的模型结构,而是它的训练方式,前面没看懂的话可以先看看训练方式。
# 模型简单讲解
## 输入与输出
因为 BERT 是一个“backbone”模型所以它的任务是从文本中抽取特征(feature,embedding...叫法很多,其实就是个向量)因此,它的输入是文本,输出是向量。
### 文本输入前的处理
在文本被输入模型之前,我们要对它进行一些处理:
1. **词向量**(wordpiece embedding):单词本身的向量表示。每个词(或者进行时过去时后缀之类的)会被记录为一个向量。它们被储存在一个字典里,这一步其实就是在字典中查找这个词对应的向量。
2. **位置向量**(position embedding):将单词的位置信息编码成特征向量。构建 position embedding 有两种方法BERT 是初始化一个 position embedding**然后通过训练将其学出来**;而 Transformer 是通过**制定规则**来构建一个 position embedding。
3. **句子向量**(segment embedding):用于区分两个句子的向量表示。这个在问答等非对称句子中是用于区别的。(这个主要是因为可能会用到对句子的分析中)
BERT 模型的输入就是上面三者的和,如图所示:
![](https://cdn.xyxsw.site/boxcngc1a7cWapQA9rSLXYqUvkf.png)
## 模型结构
简单来说BERT 是 transformer**编码器**的叠加,**也就是下图左边部分**。这算一个 block。
![](https://cdn.xyxsw.site/boxcnPg8594YzCdnX6KZxpEYYod.png)
说白了就是一个 多头自注意力=>layer-norm=> 接 feed forward(其实就是 mlp)=>layer-norm没有什么创新点在这里。因为是一个 backbone 模型,它没有具体的分类头之类的东西。输出就是最后一层 block 的输出。
# 训练方式
BERT 训练方式跟 cv 里的很多 backbone 模型一样,是先用几个具体任务训练模型,最后把分类头之类的去掉即可。
它用了以下两种具体任务进行训练:
## 随机掩码(完形填空 MLM
跟以往的 nlp 模型不同BERT 的掩码并非 transformer 那样,给前面不给后面,而是在句子中随机把单词替换为 mask让模型去猜也就是完形填空。下面给个例子
**划掉的单词是被 mask 的**
正常的掩码I am a <del>little cat</del>
BERT 的随机掩码I <del>am</del> a little <del>cat</del>
#### 一些技术细节:
mask 方法是先抽取 15% 的单词,这些单词中 10% 不做变化10% 替换为随机单词(让模型适应错别字用的),剩下 80% 替换为 mask。
## 前后句判别(NSP)
这个很简单,从一篇文章中抽出两句,让模型判断它们是否是相邻的两个句子。
## 意义
BERT 的训练方式完全是无监督或者说自监督的。无论是 MLM 还是 NSP 都不需要进行人工标注,只要它是一个通顺的句子,就可以拿来进行训练,这大大降低了训练成本并且加大了数据使用量,这也是 BERT 最大的贡献点所在。
### 局限
BERT 因为是以完型填空训练的,因此不能用于文本生成任务,但是在分类等任务上效果显著并且广为适用。
# 相关资料:
李沐的【BERT 论文逐段精读【论文精读】】https://www.bilibili.com/video/BV1PL411M7eQ
<Bilibili bvid='BV1PL411M7eQ'/>
原论文:[https://arxiv.org/pdf/1810.04805v2](https://arxiv.org/pdf/1810.04805v2)

View File

@@ -1,51 +0,0 @@
# MAE
看本文前,请确保你已了解 BERT 的相关知识
# 前言
MAE 是一个把 BERT 的随机掩码结构拓展应用到 cv 领域的模型
目的是通过自监督训练一个通用的 cv 的 backbone 模型
## MAE 想解决的问题
cv 领域,其实预训练模型早已推广,一般是在 imagenet 上进行预训练,但是 imagenet 的图片是有局限性的,比如物体一般是在图片中间等等。并且指标也越来越难刷上去。于是作者想通过像 BERT 一样进行无监督学习来引入更多数据并降低训练成本。
那么问题来了,既然我们要学习 BERT 的随机掩码,那么我们应该对什么做 mask 呢?
因为图片不像文本,有单词这一基础单位。图片的基础单位像素在被单独拿出来的时候包含的语义信息是完全不如单词的。因为像素的语义信息与**上下左右的连续关系**很密切。于是作者采用了像 VIT 那样把图片分成好几个 patch对 patch 做随机掩码。
# 模型结构与训练方式
看了上面的解释,相信你也有些思路了,其实这个模型很简单,只要拿随便一个抽取特征用的 backbone 模型,比如 VIT,CNN 之类的做编码器,再接一个生成图像的解码器就 ok 啦。下面讲一下作者用的模型结构:
## 具体模型结构
为了方便比较起见,作者用了 VIT-large 做编码器,多层堆叠的 transformer 做解码器,其他貌似也没什么特殊的了。
## 模型输入
在这里,作者为了加大任务的难度,扩大了被 mask 掉的比例,避免模型只学到双线性插值去修补缺的图像。作者把 75% 的 patch 进行 mask然后放入模型训练。从下图可以看出被 mask 的块是不进行编码的,这样也可以降低计算量,减少成本。
![](https://cdn.xyxsw.site/boxcnd7HTEFOiJxVQ3jtOpzK4ie.png)
在被保留的块通过编码器后,我们再在原先位置插入只包含位置信息的 mask 块,一起放入解码器。
## 训练方式
在通过 VIT 编码抽取特征和多层 transformer 生成图片后,我们对生成的图片做简单的 MSE 损失(就是平方损失),在训练完成后,去掉多层 transformer留下训练好的 VIT 做 backbone进行微调就可以处理下游任务了。这个在 BERT 里讲了,这里不再赘述。
下面是原论文给的训练结果,可以看到效果是很惊人的。(有些图我脑补都补不出来)
![](https://cdn.xyxsw.site/boxcnPWO0VWbPvCE537tf6MWu4e.png)
# 相关资料
更具体的比如模型性能对比最好还是去看原论文或者李沐老师的讲解
李沐【MAE 论文逐段精读【论文精读】】 https://www.bilibili.com/video/BV1sq4y1q77t
<Bilibili bvid='BV1sq4y1q77t'/>
原论文:[https://arxiv.org/pdf/2111.06377v2.pdf](https://arxiv.org/pdf/2111.06377v2.pdf)

View File

@@ -1,61 +0,0 @@
# Transformer
# 简介
看到这个,不知道你是否会感到奇怪,为什么要单独把一个奇怪的英文单词提出来单独放到一章内容里面来?或者说这个词可以翻译成变形金刚,变形金刚和深度学习有什么联系吗?
这一切要从 2017 年一篇命名都很清奇的文章说起:[Attention Is All You Need](https://arxiv.org/abs/1706.03762?context=cs)
他本来是用于机器翻译的文章,属于 NLP 领域,但是他所提出的框架 transformer 一时声名鹊起,首先是在 NLP 领域Bert 及其无数改进席卷了整个领域,大规模的预训练模型广泛地被应用于各个任务内。
随后在 CV 领域中VIT 的横空出世标志着 transformer 几乎一统了深度学习的多数领域,直到现在,一篇文章十有八九会用但 transformer 的相关内容。
并且,不少人也尝试去验证他的可解释性,目前为止给我印象最深的就是新加坡的一位教授发的文章,他把其中一个重要模块换成了 POOLING 层,依然有还不错的效果。
在本章节中我会尝试带你走进这个神奇的算法框架,但是在这之前,有几点是需要声明的:
1. 鉴于我们视野的局限性,我无法很好的阐述清楚 NLP 领域的知识,但是有些内容是必要的,因此我会留下一下重要的教程供你参考。如果有机会我会进行补充
2. 并不是你接触 NLP 或者了解一些任务,你就必须得把 RNNLSTM 这些经典网络弄得烂熟于心,完全没必要,你可以让你对他们保持一个大体上的理解,希望这可以帮助你节约更多的时间。
3. 该算法耗费的算力资源非常大,有时候想跑起来一个模型可能需要更大的显存
# 必要知识
## Sequence to Sequence
序列到序列学习,一个有趣的概念
[A ten-minute introduction to sequence-to-sequence learning in Keras](https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html)
你可以实操一下,它是调包 LSTM 的。你也可以借此了解一下他的概念,不用太精通。
## 注意力机制
大家不需要觉得它非常神秘,因为他其实本身就是矩阵运算的一种操作罢了,取了个好听的名字,我在很早的目标检测文章上看到过类似的机制,不过那时候没有这个名字罢了。
他很重要的一点在于处理序列数据上的优越性,在这里附上一个视频帮助大家学习
但是在 transformer 内,他使用的是名为 self attention 的东西,这点需要你额外进行学习
论文的优秀讲解
[Transformer 中 Self-Attention 以及 Multi-Head Attention 详解_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV15v411W78M)
<Bilibili bvid='BV15v411W78M'/>
除此之外就是相关代码,不要求你可以完全自己复现,但是要保证非常重要的知识都懂
再贴上一个难度稍高的教程
[Vision Transformer 超详细解读 (原理分析 + 代码解读) (一)](https://zhuanlan.zhihu.com/p/340149804)
# 思考题
我在这里留下一些思考题希望对你有启发
在 Multi-head Self-attention 中所谓 Q,K,V 到底指代的是什么?他们怎么产生的?
位置编码有没有更好的形式产生?
为什么用的是 LN 层?为什么不用 BN 层?
你能不能阅读一下 transformer 的代码并且能明确说出哪些维度变换所对应的操作呢?

View File

@@ -1,30 +0,0 @@
# 总结
对比学习综述讲到这里也就基本结束了
来回顾一下对比学习的发展历程和一些要点吧!
# 发展历程
| 论文名称 | 贡献 | 网络类型 | 用的代理任务 | 延续了哪篇工作 |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------- | ------------------------------------- | -------------- |
| Inst Disc | 奠基作,引入 Memory Bank 大字典的概念,提出个体判别任务。 | 判别式网络 | 个体判别任务 | 无 |
| 定义正负样本的方式(因为不止一篇论文就不放名字了) | 引入生成式网络的概念,提出多视角作为不同正样本 | 前者是生成,后者是判别 | 时序预测任务<br/>多视角判别任务 | 无 |
| MoCo | 使用队列储存字典,提出动量编码器,提出 infoNCEloss | 判别式网络 | 个体判别任务 | Inst Disc |
| SimCLR | 提出 projection head提出把一张图片做不同的数据增强进行对比并且分析了各种数据增强的贡献 | 判别式网络 | 个体判别任务 | Inst Disc |
| SwAV | 使用聚类中心矩阵,提出新的聚类任务 | 聚类式网络(或许也算判别式) | 聚类 | SimCLR |
| BYOL | 提出无负样本学习,提出预测头 predictor | 判别式网络 | 或许算预测?<br/>但也有个体判别的感觉 | SimCLR |
| SimSiam | 在 BYOL 基础上做了改进,总结了前面的工作,提出了对称式的孪生网络 | 判别式网络 | 同上 | BYOL |
| MoCo v3 | 缝合了 MoCo 和 SimSiam引入了 VIT提出小 trick 解决训练不稳定 | 判别式网络 | 同上 | MoCo |
# 要点提问
1.什么是 memory bank
2.个体判别任务的局限
3.什么是 NCElossinfoNCEloss 呢?
4.能画出每个网络的结构图吗?
5.能列出提到过的所有小 trick 吗?

View File

@@ -1,41 +0,0 @@
# 前言
> 作者:可可
对比学习是近来比较热门的一个方向,它属于无监督学习的一种,在阅读本文前,请确保已经掌握 cv 和 nlp 的基础知识并且了解 transformer。本文致力于把论文本身讲的故事通俗的概括出来以便大家理解发展路程。
打个比方一个梨很甜用数学的语言可以表述为糖分含量90%但只有亲自咬一口你才能真正感觉到这个梨有多甜也才能真正理解数学上的90%的糖分究竟是怎么样的。
如果对比学习是个梨,本文的目的就是带领大家咬一口。
这类方法训练需要消耗巨大的算力(微调改进那种另说),我也没有能力去训练这类模型(好贵!
# 何为对比
对比学习,故名思意,是对比着来学习。而我们拿来对比的东西就是在模型眼里的语义,也就是我们叫做特征的向量。
在具体讲对比之前,我们先看看传统的**监督学习**是怎么学特征的:
数据 + 模型=> 特征,特征对人工标注进行学习,也就是说我们要把模型抽取的特征尽可能的靠近人工标注
而在无监督学习中,我们不希望有人工标注的出现,那么一种方法就是让同类的特征进可能相近,也就是我们说的聚类。
直观来讲,我们把特征的向量进行一下归一化,它们就分布在一个超球面上。简单起见,我们先看 3 维向量
![](https://cdn.xyxsw.site/boxcnJ6HpIJqxJuxiz7Cw5GopSh.png)
我们通过**正样本**(跟拿到的特征**应当相近**的另一个特征)与**负样本**(反之)的对比,使得
越相近的物体,它们的特征就在超球面上越靠近,越不像的物体离的越远,去学习图片更本质的特征
那么具体的对比学习方法我在后面结合一些论文一起讲吧~
这部分内容更像一个综述,讲述对比学习这几年的发展路程,所以我会尽可能的描述作者在论文里讲的**故事**,来方便大家弄清为什么要这么做。
**可能会有很多我的主观理解在此**,并且**不会**深入细节。可以算是一个总结和分享,我会在这里带着读者过一遍近期对比学习的工作来给大家一个对比学习方向的直观感性理解。
同时因为笔者水平,视野,精力有限,不可能包含所有的算法,也不可能保证完全正确。因此仅作为笔记分享使用。若有错误,请多多指正。
> 若对文章内容有任何疑惑或者批评指正,可以联系我

View File

@@ -1,63 +0,0 @@
# Inst Disc
这篇论文是对比学习的一篇开山之作,后续很多论文都参考了它的方法,这里不止讲了论文本身,还有一些扩展补充
## 提出的背景
作者团队发现,当把一张豹子的图片喂给以前的有监督训练的模型。得分最高的都是跟豹子很像的动物,比如雪豹,猎豹,而分数最低的几个都是跟豹子一点都不像的东西比如救生艇,书架。
作者团队认为,让这些猎豹,雪豹的标签相互接近(指互相在判别时都排名靠前)的原因并不是它们有相似的标签,而是它们有相似的图像特征。
![](https://cdn.xyxsw.site/boxcnrR3eFvOSKYRH8Ni0dvHYkc.png)
## 个体判别任务
既然有了上面这个发现,那么作者想我能不能把分类任务推到极致呢?
于是他们**把每一个图片当作一个类别**,去跟其他的图片做对比,具体模型如下
![](https://cdn.xyxsw.site/boxcnPNukes2FlNwUFSKiqIJEbd.png)
先介绍一下模型结构:
1.CNN 用的是经典的 RES50没什么特殊。
2.后面接了一个 Non-param Softmax非参数 softmax其实就是一个不被训练的把所有特征投射到超球面上的一个分类头把所有特征模长变为 1
3.后面的**Memory Bank**是这篇文章的**重点**,它是一个**动态字典**。我们把每一个图片抽取出来的特征存入 memory bank每次计算时抽取其中部分作为一个 batch 进行对比学习,把更新后的模型得到的特征替换 memory bank 里原先的特征。
4.具体损失函数用的是一个叫 NCEloss 的损失,它把多分类问题分为**若干个二分类问题****是**与**不是**,每个 batch 中只有一个的 ground truth 是yes其余都是no
在训练的时候,相当于是有一组以前的编码器抽取的特征 A,B,C,D...,一组当前编码器抽取的特征 a,b,c,d...,对它们进行对比学习。对 a 来说A 是正样本,其他都是负样本,同理类推。
## 一些小 trick 和小细节
上面这些就是这篇文章的主体,后面是一些对后续工作有贡献的小 trick 和细节:
### 动量更新
用动量更新的方法去更新 memory bank 中的特征
也就是让特征的变化**不那么剧烈**
原因:如果一直保持更新,**特征总体的变化就会比较大**,而我们在大数据集上训练的时候,等第二次调用一个特征时,它跟现在的特征分布已经大相径庭,那就不好训练了,也就是**特征缺乏一致性**。因此我们引入动量更新来确保特征进行平稳的改变,而非突变。
#### 关于动量的小拓展
大家在使用诸如 SGDAdam 等优化器的时候一定见过动量这个概念了,这里给不了解这个概念的读者简单讲解一下动量这个概念:
A 是起始点B 是第一次更新后的点C 是第二次更新后的点
![](https://cdn.xyxsw.site/boxcn5zfD155Joy1eD5CvbZXZnc.png)
而在我们刚刚提到的动量更新里,它的公式可以概括为:
![](https://cdn.xyxsw.site/boxcnTLEK31rFmuRo2MOWGRBoYe.png)
m 表示动量k 是新的特征q 是上一个特征,只要设置小的动量就可以使改变放缓。
# 总结
总体来说Inst Disc 把对比学习成功引入了 CV 领域,核心思想是构建动态字典进行对比学习
**PS若无特殊说明最后保留下来去做下游任务的模型只有编码器其他都删除了。**

View File

@@ -1,27 +0,0 @@
# 定义正负样本的方式
因为涉及多篇论文,就不具体一个个讲了,在这里总结一下一些定义正负样本的方式,这两种方式虽然本身并不突出,但是都对后续一些重要工作有一些铺垫作用。
# 1.时序性定义(生成式模型)
![](https://cdn.xyxsw.site/boxcnC10uzdj0G0BJPlUZKFIi7C.png)
这是处理音频的一个例子,**给模型 t 时刻以前的信息,让它抽取特征并对后文进行预测,真正的后文作为正样本,负样本当然是随便选取就好啦。**
不同于之前说的个体判别,这个是**生成式模型**,这个模型不止可以处理音频,还可以处理图片(每一个块换成一个词)或者处理图片(以 patch 为单位)。
是不是有点眼熟?这跟我前面写的 BERT 和 MAE 其实异曲同工,不过这两位是随机 mask而非时序性的 mask。
# 2.以物体不同角度或者感官作为正样本
一只狗可以被我们用不同感官所感受到,比如看见狗,听见狗叫声,摸到狗,得到文字描述等等。如果我们能统一这些模态的信息,这未尝不是一种特征提取。
这里就用了几个不同感官下的数据进行训练,不过可能是找配对的音频比较困难,作者用的是
原始图片深度图swav ace normal分割图片这四个视角作为正样本其他不相关图片作为负样本。
这种多视角的特征提取也引出了后面 CLIP 这篇论文,它做到了文本和图像特征的统一,我们后续再讲
(这篇论文我准备开个新坑放着了,因为说实话不算对比学习,算多模态)
![](https://cdn.xyxsw.site/boxcnssaOVvp73SVIrzVvZPr1Je.png)

View File

@@ -1,75 +0,0 @@
# MoCo
# 提出背景
MoCo 是 Inst Disc 的改进工作,那我们自然要先看一下 Inst Disc 有什么不足
## 1.Memory Bank 过大,不能应用在更大的数据集上
因为其字典的数据类型,导致计算开销会加大
## 2.动量更新并不能完全解决特征一致性差的问题
即使使用了动量更新的方式,同一个特征前后被调用的跨度也还是很长,一致性依旧不够
## 3.NCEloss 负样本分类不合理的问题
NCE 把**所有负样本都视作一样的**,但实际上负样本**并不能被完全归为一类**
举个例子:我现在的正样本是**猫猫**,然后有两个负样本是**狗勾**和**汽车**,那**猫猫**肯定跟**狗勾**更相近,跟**汽车**更不相似,也就是说**狗**的得分虽然低于**猫**,但是一定要高于**汽车****而不是像 NCE 那样把狗和车打成一类**,这样不利于模型学习。
并且它也不是很灵活,下文细讲
### 虽然大家应该都懂了(应该吧?),但还是贴一下模型总览图。
右边就是 memory bank 啦
![](https://cdn.xyxsw.site/boxcnKMjslIshEA5SFqc8rbmqoe.png)
# MoCo 做出的改进
## 1.针对 Memory Bank 过大
作者使用队列的数据结构去储存这个大字典,因为是先进先出,所以好处是新进来的特征可以把最老的特征替换掉。每次不用把整个字典全部载入,而是用队列形式即可。很简单地解决了这个问题。
## 2.针对动量更新不能完全解决特征一致性差的问题
作者提出了一个新的**动量编码器**来替代动量更新。
动量编码器是独立于原编码器的一个编码器它的参数是根据原编码器动量更新的k 和 q 就是指代全部参数了
![](https://cdn.xyxsw.site/boxcnFLSP9PtQRkgYgcMwM4idog.png)
这样的话就是解码器在缓慢更新,比对特征使用动量更新要更有连续性。
## 3.负样本分类不合理的问题通过替换 infoNCEloss 解决
下面是 infoNCE loss 的公式,它是 NCE 和交叉熵损失的结合体,长得就很像交叉熵,只是多了个 T。
[(什么?你看到这了还不会交叉熵?戳这里)](https://zhuanlan.zhihu.com/p/149186719)
![](https://cdn.xyxsw.site/boxcnnWI38bkSzeCe5TtVTBCrNh.png)
q·k 其实就是各个特征(因为那时候用的都是 transformer 了,这里就是 trnasformer 里的 k 和 q
这里分母级数上的**k 是代表负样本的个数,也就是 k=batchsize-1总样本-正样本)**。其实就是**对一个 batch 做 k+1 分类**,并且引入了一个**超参数 T**。它的名字叫做**温度参数**,控制的是 softmax 后得分分布的平滑程度(直观理解,不是很严谨)
T 越大,损失函数就越对所有负样本**一视同仁**,退化为二分类的 NCElossT 越小,损失函数就**越关注一些难分类的特征**,但有时候会出现两张其实都是猫猫的图片,你硬要让模型说猫猫跟猫猫不一样,这也不太好,这个参数要根据数据集情况适中调整。
![](https://cdn.xyxsw.site/boxcnhuabU9XzXmVQfu0ruENs83.png)
![](https://cdn.xyxsw.site/boxcnsGpqCNePn2G34GnJqPieBf.png)
上面那张是 T 较大的情况,下面是 T 较小的情况x 轴是各个类别y 轴是分类得分)
所谓的灵活性就是指infoNCE loss 引入了温度参数这个参数可以帮我们调整训练的难度T 越大,模型越关注类似的特征,训练也就越难,总之就是非常灵活。
# 总结
总而言之MoCo 就是基于 Inst Disc 主要做了如上三点改进,模型和参数都是完全不变的。它的核心在于动量编码器和活动大字典。
能在 imagenet 上达到媲美甚至超越有监督学习的模型的结果,并且可以作为 backbone 很好的拓展应用到多个下游任务上。
# 另外
其实 MoCo 有两篇后续工作MoCo v2 和 MoCo v3v2 其实就是缝合了后面讲的 SimCLR 的方法不展开了V3 留到以后讲。

View File

@@ -1,29 +0,0 @@
# SimCLR
顾名思义SIMPLE为主这个模型主打的就是简单。
# 模型结构
x 是输入的图片,它经过两种不同的数据增强得到 xi 和 xj 两个正样本,而同一个 mini-batch 里的所有其他样本都作为负样本。<del>说白了还是个体判别任务</del>
![](https://cdn.xyxsw.site/boxcnq5TYzSltn6CsPM3Bn3xxAb.png)
左右的**f 都是编码器**,并且是**完全一致共享权重**的,可以说是同一个。
而 g 是一层 mlp 结构,只在训练中使用,**应用到下游任务时用的仅仅是 f**(与前面几篇一样都是 RES50很神奇的是就仅仅多了这么一层 mlp它在 imagenet 上的正确率直接加了十个点。
关于这点也很奇怪,作者做了很多实验但是也没有很合理的解释。
最后的对比学习是对 zi 和 zj 做的。
下面这个是更加具体的流程图
![](https://cdn.xyxsw.site/boxcnj3FZsRiJbWsKW07b9B8Fkb.png)
# 总结
因为这个真的很简单,没有太多可讲的,它就是单纯的简单且效果拔群,想具体了解数据增强相关或者具体效果对比的可以去看一下[原论文](https://arxiv.org/pdf/2002.05709v3)。
# 另外
SimCLR 也有 v2缝合了 MoCo 的方法,同样不展开了。

View File

@@ -1,71 +0,0 @@
# SwAV
# 前言
与前面的一些工作不同SwAV**不再进行个体判别任务**,而是提出了新的任务————**聚类**
并在训练的模型结构上也做了相应改动,而非只调整训练方法。
这里因为涉及到了聚类,具体数学推导难度较大,有兴趣可以跟着我后面贴的视频走一遍
# 提出的背景
## 个体判别任务的局限性
1.进行个体判别任务时,我们有可能选到与正样本属于一个类的特征作为负样本,比如两张不同狗的图片等等,这会影响学习的效率。
2.个体判别任务把类别分的过细,不能很好地抽取特征,过多的类也增大了计算压力和字典储存压力。作者认为这过于原始和暴力。
# 模型结构
下图左边是常规的对比学习(比如 SimCLR的结构右图是 SWAV 的结构,不难看出多了一个叫 prototypes 的东西。这个东西其实是聚类中心向量所构成的矩阵。
![](https://cdn.xyxsw.site/boxcnGteJZelEtVqBFwwukw7c8g.png)
下面的内容可能有些理解上的难度(反正我第一次听讲解的时候就云里雾里的),我会尽可能直白地描述这个过程。
## 聚类中心?
首先我们有个新的东西**prototypes**,它是**聚类中心的集合**,也就是许多作为聚类中心的向量构成的矩阵。
这些聚类中心是我设定在超球面上的,离散的一些点,我希望让不同的特征向它们靠拢以进行区分(也就是所谓聚类)。
更直白地讲,我在地上撒了一把面包屑,地上本来散乱的蚂蚁会向面包屑聚集,形成一个个**小团体**。蚂蚁就是**不同图像的特征**,面包屑就是**我设定的聚类中心**
## 聚类中心我知道了,然后呢?
先说我拿他干了什么,再一步步讲为什么要这么做吧。
首先我们手里有抽取出来的特征**z1****z2**,以及一个我随机初始化的**聚类中心矩阵 c**。我分别求这个**矩阵**和**z1****z2**的内积,并**进行一些变换**得到 Q1,Q2。当 z1z2 都是正样本时,我希望**Q1 与 z2 相近****Q2 与 z1 相近**。如果有一个是负样本则尽可能远离。也就是拿 Q 当 ground-truth 做训练。最后这步前面已经讲过 NCEloss 等损失函数了,用它们就可以达成这个任务。
而我们的优化要采用 [K-means](https://zhuanlan.zhihu.com/p/78798251)(不懂可以看这里)的类似做法,先对聚类中心进行优化,再对特征进行优化。
![](https://cdn.xyxsw.site/boxcnKe4DzDfdNbhhHowdE4BJEf.png)
sowhy相信你现在肯定是一脸懵不过别急希望我能为你讲懂。
## 首先是第一步,为什么要求内积?
如果你有好好了解线性代数的几何性质,应当了解**两个向量的内积就是一个向量在另一个向量上的投影**,而一个向量与一个矩阵的内积,**就是把这个向量投影到这个矩阵代表的基空间中**。
我做的第一步就是把**抽出来的特征 z 用聚类中心的向量表示,这样更加方便对比聚类成功与否**。
## 然后是第二步,我说的变换是什么呢?
我们现在求内积是为了把特征投影到聚类中心空间,为了避免模型训练坍塌(就是网络把特征全部聚到同一个点,<del>开摆~</del>)我要保证每个聚类中心被**"使用"**的次数,所以我们请出了**Sinkhorn-Knopp 算法。**这个算法比较硬核,我在这里不展开了,大家知道它是干啥的就行,具体的推导可以看我后面贴的视频,那里面有讲。
## 第三步应该不用怎么讲了吧?
就是普通的对比学习,也没啥特殊的了。正样本是自身通过数据增强和上面两步处理得到的特征,负样本则是同一 batch 中的其他特征。
# 数据增强的小 trickmulti-crop
其实就是一个工程经验,一般我们数据增强是取 2 个 224*224 的块,这里换成了面积基本不变的 2 大 2 小的 4 个块,事实证明效果不错。想了解这个的话可以看看原论文的实验
# 总结
主要贡献是上面我说的三步聚类算法以及后面的小 trick**Sinkhorn-Knopp 算法难度较高,大家有兴趣的话自行观看后面这个视频理解哈~**
# 相关资料
【[论文简析]SwAV: Swapping Assignments between multiple Views[2006.09882]】

View File

@@ -1,71 +0,0 @@
# BYOL
# 前言
这篇论文的主要特点是**它的训练不需要负样本**,并且能保证**模型不坍塌**。
当一个普通的对比学习模型没有负样本时,它的损失函数就**只有正样本之间的差距**,这样模型只会学到一个**捷径解**————你给我什么输入我都输出同一个值,这样 loss 就永远=0 了(~~开摆~~
而**BYOL**就解决了这一问题,使得训练不再需要负样本。
# 模型结构
前半部分很普通,跟 SimCLR 是基本一致的,一个图片经过两种不同的数据增强,进入两个编码器,得到两个不同的特征。
值得一提的是,这里下面的这个粉色的编码器用的是**动量编码器**的更新方式。也就是说它是紫色那个编码器的动量编码器。
而提取特征之后,经过两个 `SimCLR` 中提出的额外的 mlp 层 z在此之后它们给紫色的那支加了一个新的模块**predictor**。
**predictor**的模型结构就是跟 z 一样的**mlp 层**。它的任务是**通过紫色的特征去预测粉色的特征**。也就是说它的代理任务换成了**生成式**。
![](https://cdn.xyxsw.site/boxcne7eizRhw5GKRSpF40KcMEh.png)
而具体的损失只有预测特征和真实特征的损失,用的是**MSEloss**。
下面的粉色分支最后一步是不进行梯度回传的。它的更新完全依赖紫色的那个编码器。
# 所以为什么不用负样本能左脚踩右脚螺旋升天呢?
在原文中,作者也没有说出个所以然来,不过后面有篇博客发现了问题所在。
其实这是 BN 的锅,蓝色的那个是一般的对比学习使用的,而紫色的是 BYOL 使用的。很明显发现它多了一个 BN。
### 有篇博客在复现 BYOL 时,不小心没加这个 BN 层,导致模型直接摆烂。那么 BN 到底藏着什么呢?
![](https://cdn.xyxsw.site/boxcn8wfpZCjOD2lFsM03N5vatl.png)
我们得先来回顾一下 BN 做了什么。
BN 根据批次的均值和方差进行归一化
训练时,均值、方差分别是该批次内数据相应维度的均值与方差;
推理时,均值、方差是基于所有批次的期望计算所得。
因此,博客作者认为,虽然我们只用了正样本进行训练,但是这个正样本包含了**本批次所有样本的信息**(均值,方差),所以**实际上并不是真正的无负样本。**
而这个 batch 的均值,即平均图片,可以看作 `SawAV` 里的聚类中心,是所有历史样本的聚类中心。(<del>很玄学</del>
### 作者看到这个博客就急了
如果真是这样的话,**BYOL 就还是没有逃脱出对比学习的范畴**,它还是找了一个东西去做对比,其创新性就大大降低了。所以作者赶紧做实验,看看能不能找到 BYOL 模型不坍塌的另外一种解释。最终又写了一篇论文进行回应。
  这篇论文叫 BYOL works even without batch statistics即在没有 BN 的时候 BYOL 照样能工作,详细的消融实验结果如下表所示
![](https://cdn.xyxsw.site/boxcncmJWb99mlUUIFTPjGoCqYb.png)
**BN 非常关键**:只要是 `projector`SimCLR 提出的 mlp中没有 BN 的地方SimCLR 性稍微下降;但是 BYOL 全都模型坍塌了。
**有 BN 也会坍塌**:作者找到了特例(红色框),即使当 `projector` 有 BN 的时候BYOL 还是训练失败了 。如果 BN 真的很关键,它真的提供了隐式负样本的对比学习的话,训练就不应该失败
**完全没有 BNSimCLR 也坍塌**(最后三列的结果。要注意 SimCLR 只有一层 projector。这表明完全不用归一化SimCLR 这种使用负样本进行对比学习的方式也无法训练。
最终结论BN 跟它原来的设计初衷一样,主要作用就是提高模型训练时的稳定性,从而不会导致模型坍塌 。作者进一步延伸,如果一开始就能让模型初始化的比较好,后面的训练即使离开了 BN 也没有问题。
作者为此又设计了一个实验,使用 `group norm`+`weight standardization` (前者也是一种归一化方式,后者是一种卷积权重标准化方式,但都没有对 batch 中的数据进行融合BYOL 的 top-准确率可以达到 74.1%和原来精度可以认为是一样了74.3%)。
**至今其实这个问题也没有一个很合理能服众的解释。**
# 总结
主要的贡献在于无需负样本的学习。但是没有合理的解释。

View File

@@ -1,58 +0,0 @@
# SimSiam
# 前言
## 提出背景
BYOL 之后,大家都发现对比学习是靠许许多多的小 trick 和技术堆叠起来的,每个技术都有贡献,但是不算很多,前沿的网络往往采用了众多的技术得到很好的效果。
这时候,作者团队希望能够化繁为简,探索一下哪些真正有用,哪些贡献不大。
## 于是就有了 SimSiam
是对前面几乎所有工作的总结,它提出了一个非常简单的网络,但是达到了很高的性能,并在其上追加了前面工作的一些细节,来展示每个小技术的真正贡献如何。
它不需要动量编码器,不需要负样本,不需要 memory bank就是非常简单。
# 模型结构
模型的结构是一个 `“孪生网络”`,其实于 BYOL 的结构很像,不过没有用动量编码器,左右两个编码器都是一样的,因此叫 `孪生网络`
虽然看起来只有左边预测右边,其实右边也有一个 predictor 去预测左边的特征,两边是对称的,左右的优化有先后顺序。
![](https://cdn.xyxsw.site/boxcnWk5QzvbsSNlyV4B7SMt5zb.png)
结构其实没什么特殊的地方,主要讲讲思想。
# SimSiam 主要回答的是两个问题
# 1.为什么不用负样本模型不会坍塌?
原论文中提出的解释并不是最完美的。而且这个问题的解释涉及了动力学等知识,我也没有足够的知识储备去讲解这个问题,这里只能讲一些与解答相关的信息,如果有兴趣可以看下面链接中的解释:
这里要涉及到一个机器学习的经典算法,**EM 算法**,它也是**k-means**的核心思想之一。
因为本文的主旨原因,我不会在这里细讲这个算法,但是大家了解这是个什么东西即可。
**EM 算法**用于优化带有未知参数的模型,`k-means` 的聚类中心就可以看作一个未知参数,我们要同时优化模型本体和聚类中心。所以我们先对其中一个目标 A 做**随机初始化**,然后**先优化**另一个目标 B再反过来用另一个目标 B 优化后**的结果优化被随机初始化的目标 A**这就是一次迭代只要不断循环这个迭代EM 算法往往能找到最优解。
这里可以把**经过 predictor 预测头的特征**作为 `k-means` 里的特征,而另一个作为**目标的特征**作为**聚类中心**,经过预测头的特征直接反向传播进行优化,作为目标的特征则是通过上面说的对称的操作经过预测头进行优化。
最最直白地解读结论的话,可以说是,这种先后优化的 EM 算法,使得模型“来不及“去把权重全部更新为 0。模型坍塌具体的推导需要动力学的知识这里不做展开。
# 2.对前人工作的总结
这是作者总结的所有”孪生网络“的模型结构,很精炼。
![](https://cdn.xyxsw.site/boxcn8OWwnN8ae2vUVttqlu5O8e.png)
下面是这些网络训练结果的对比,也列出了它们分别有哪些 trick用的是分类任务
负样本 动量编码器 训练轮数
![](https://cdn.xyxsw.site/boxcn3uizAKNhAxQryOwvHxFSDb.png)
具体结果还是图片比较直观(
![](https://cdn.xyxsw.site/boxcnqdfrOIxim4wBayDDBitHCd.png)

View File

@@ -1,29 +0,0 @@
# MoCo v3
# 前言
在 VIT 出来之后,大家也都想着把对比学习的 backbone 换成 VIT。于是新的缝合怪自然而然地诞生了
MoCo v3它缝合了 MoCo 和 SimSiam以及新的骨干网络 VIT。
# 模型架构
可能因为和前面的工作太像了,作者就没有给模型总览图,我们借 MoCo 的总览图来讲
![](https://cdn.xyxsw.site/boxcnhxg4HZw2NExIbYZxQGISze.png)
总体架构其实没有太多变化,还是 memory bank 的结构,右边也还是动量编码器,不过加入了 SimCLR 提出的 projection head就是额外的那层 mlp并且在对比上用了 SimSiam 的预测头对称学习方式。具体也不展开了,都是老东西缝合在一起。
# 讲这篇文章主要是冲着 VIT 来的
作者在用 VIT 做骨干网络训练的时候,发现如下问题:
![](https://cdn.xyxsw.site/boxcnMMhbVk6wc81H8BSoack7Mg.png)
在使用 VIT 训练的时候batchsize 不算太大时训练很平滑,但是一旦 batchsize 变大,训练的图像就会出现如上图这样的**波动**。于是作者去查看了每一层的梯度,发现问题出在**VIT 的第一层线性变换**上。也就是下图中的粉色那个层,**把图片打成 patch 后展平做的线性变换**。
![](https://cdn.xyxsw.site/boxcniBkiypcv6IQbxr9D6JukOb.png)
在这一层中,梯度会出现波峰,而正确率则会突然下跌。
作者就想,既然你训练不好,我就把你冻住,不让它训练,然后就能成功运用了。而且这个 trick 对几乎所有的对比学习模型都有效果。

View File

@@ -1,7 +0,0 @@
# 对比学习
这里不再区分 nlp 和 cv因为对比学习有些时候跟多模态挂钩两个领域都有涉及读者均需一定的了解。
这里因为笔者知识储备的原因,主要讲的是 CV 方面的对比学习。
还会涉及一些传统机器学习的算法,读者需一定的理论基础或者边看边学。

View File

@@ -1,21 +0,0 @@
# 前言
强化学习已经是一门很老的内容了,这从它被列为和监督学习与无监督学习并列的三大基本机器学习算法就可以看出来。但是在和深度学习结合后,强化学习焕发出了属于它的第二春。
虽然如此但笔者还是必须提醒各位读者强化学习相较于CV/NLP来说仍然是一个非常冷门的方向这不是没有原因的。总结原因如下
1. 强化学习概念繁多芜杂并且没有办法绕开作为一个研究强化学习的人你得理解整个交互过程绕不开的概念包括但不限于智能体agent、环境environment、状态state、动作action、奖励reward、动作价值函数Action-Value Function、状态价值函数State-Value Function等。这足以使一个初学者头大。
2. 强化学习涉及的数学知识较为高深,需要奠定较好的数理基础才能理解公式以及概念。马尔可夫过程作为强化学习最基本的模型,所需的前置知识包括以下内容:
1. 概率论与数理统计用于描述MDP模型。
2. 线性代数,用向量来描述状态与动作。
3. 统计学理论,众多算法都是基于统计学推导出来的。
4. 最优化理论,众多算法都属于优化算法的范畴。
5. 微积分,这是所有机器学习的内容都需要掌握的知识。
如果你不喜欢推导公式,那么强化学习对你来说可能并不是那么适合。
3. 强化学习应用范围以及未来就业市场较为单一。研究强化学习的方向倒是很多,博弈论、资源分配优化、游戏、推荐等领域都能见到强化学习的身影。但是根据笔者的观察,强化学习将来的就业岗位较为单一,一般只有游戏公司招收强化学习相关的岗位。
4. 强化学习固有的弊端,包括但不限于采样效率令人堪忧、奖励函数的设计过于玄学、学术领域的严重灌水以及源码的难以复现等。这对初学者造成了极大的困扰。
综上所述,强化学习是一个“有坑”的领域,入坑需谨慎!!!当然了,如果只是喜欢训练智能体“打游戏”,那么平台上存在着众多的源代码项目可供参考,祝你玩得愉快!

View File

@@ -1,34 +0,0 @@
# 深度强化学习基础资料推荐
1. 书籍:周志华《机器学习》(西瓜书)关于强化学习的部分,作为概念引导和初步理解。
2. 书籍Sutton《Reinforcement Learning》强化学习圣经推荐作为参考书查阅而不是硬啃。
3. 网课王树森《Deep Reinforcement Learning》课件是英文的授课是中文的概念讲的非常清楚而且形象强推。
Github课件链接<https://github.com/wangshusen/DRL>
网课链接:[深度强化学习-王树森(Youtube)](https://www.youtube.com/watch?v=vmkRMvhCW5c&list=PLvOO0btloRnsiqM72G4Uid0UWljikENlU)。
4. 网课CS285无论是csdiy还是主流资料推荐的网课但是笔者的英语听力不怎么能跟上老师上课的语速也没有找到有中文字幕的版本推荐作为进阶资料使用。
项目链接:[CS285:Deep Reinforcement Learning](http://rail.eecs.berkeley.edu/deeprlcourse/)
5. 书籍+网课+实操张伟楠《Hands On RL》动手学强化学习有书+有代码+有网课,不错的整合。但是配套网课质量只能说还可以,代码可以看看。
Github主页<https://github.com/boyu-ai/Hands-on-RL>
电子书版:[动手学强化学习](https://hrl.boyuai.com/chapter/intro)
网课链接:[伯禹学习平台](https://www.boyuai.com/elites/course/xVqhU42F5IDky94x/lesson/O1N8hUTUb4HZuchPSedea)
6. 项目OpenAI Spinning up强推动手做项目以及体会强化学习的快乐才是真谛所在。
项目主页:[OpenAI Spinning up](https://spinningup.openai.com/en/latest/index.html)
7. 资源:机器之心 SOTA!模型资源站,一站式查看原理+概论+代码+论文原文。
网站主页:[机器之心 SOTA!](https://www.jiqizhixin.com/columns/sotaai)
8. 论坛RLChina讲课的确实都是大牛但是感觉略有枯燥。有时间表安排适合希望自律、有规划地学习的同学。
论坛主页:[RLChina](http://rlchina.org/)

View File

@@ -1,149 +0,0 @@
# 基本概念介绍
前面已经介绍过,强化学习难入坑的的原因之一就在于概念繁多。下面将进行基本概念的介绍,本章节最好能够理解,不理解也没有关系,但是建议作为参考章节常看常新。后续章节不理解某个概念时,便回来看看,相信一定能够做到常看常新、从而加深你对于概念的理解。下面将进行四个部分的介绍,分别为强化学习的基本过程、强化学习的基本组成内容、强化学习的基本概念以及强化学习的目标。
## 强化学习的基本过程
前面已经介绍过强化学习的核心过程,在于智能体与环境进行交互,通过给出的奖励反馈作为信号学习的过程。简单地用图片表示如下:
![](https://cdn.xyxsw.site/4.6.9.3.1.png)
正是在这个与环境的交互过程中,智能体不断得到反馈,目标就是尽可能地让环境反馈的奖励足够大。
## 强化学习过程的基本组成内容
为了便于理解,我们引入任天堂经典游戏——[新超级马里奥兄弟U](https://www.nintendoswitch.com.cn/new_super_mario_bros_u_deluxe/pc/index.html)作为辅助理解的帮手。作为一个2D横向的闯关游戏它的状态空间和动作空间无疑是简单的。
![](https://cdn.xyxsw.site/4.6.9.3.2.png)
1.智能体(Agent):它与环境交互,可以观察到环境并且做出决策,然后反馈给环境。在马里奥游戏中,能操控的这个马里奥本体就是智能体。
2.环境(Environment):智能体存在并且与其交互的世界。新超级马里奥兄弟U本身就是一个环境。
3.状态(State):对环境当前所处环境的全部描述,记为 $S$。在马里奥游戏中,上面的这张图片就是在本时刻的状态。
4.动作(Action):智能体可以采取的行为,记为 $a$。在马里奥游戏中,马里奥能采取的动作只有:上、左、右三个。这属于**离散动作**,动作数量是有限的。而在机器人控制中,机器人能采取的动作是无限的,这属于**连续动作**。
5.策略(Policy):智能体采取动作的规则,分为**确定性策略**与**随机性策略**。确定性策略代表在相同的状态下,智能体所输出的动作是唯一的。而随机性策略哪怕是在相同的状态下,输出的动作也有可能不一样。这么说有点过于抽象了,那么请思考这个问题:在下面这张图的环境中,如果执行确定性策略会发生什么?(提示:着重关注两个灰色的格子)
![](https://cdn.xyxsw.site/4.6.9.3.3.png)
因此,在强化学习中我们一般使用随机性策略。随机性策略通过引入一定的随机性,使环境能够被更好地探索。同时,如果策略固定——你的对手很容易能预测你的下一步动作并予以反击,这在博弈中是致命的。
随机性策略$\pi$定义如下:
<center>
$\pi(\mathrm{a} \mid \mathrm{s})=P(A=a \mid S=s)$
</center>
这代表着在给定状态s下作出动作$a$的概率密度。举个例子,在马里奥游戏中,定义动作 $a_{1}$="left",$a_{2}$="right",$a_{3}$="down",动作空间 $a$={$a_{1}$,$a_{2}$,$a_{3}$}。<br>
其中,假设$\pi(\mathrm{a_{1}} \mid \mathrm{s})=0.7$$\pi(\mathrm{a_{2}} \mid \mathrm{s})=0.2$$\pi(\mathrm{a_{3}} \mid \mathrm{s})=0.1$。这就代表着在给定状态s下执行动作$a_{1}$的概率为0.7,执行动作$a_{2}$的概率为0.2,执行动作$a_{3}$的概率为0.1,智能体随机抽样,依据概率执行动作。也就是说,马里奥左、右、上三个动作都有可能被执行,无非是执行几率大不大的问题。很显然,在知道策略$\pi$的情况下,就可以指导智能体“打游戏”了,学习策略$\pi$是强化学习的最终目标之一,这种方法被称为**基于策略的强化学习**。
6.奖励(Reward):这是一种反馈信号,用于表现智能体与环境交互后"表现"如何。在不同的环境中,我们需要设置不同的奖励。比如,在围棋游戏中,最后赢得游戏才会获得一个奖励。比如在量化交易中,可以直接拿收益亏损作为奖励。拿我们的马里奥游戏举例,吃到金币可以获得较小的奖励,最终通关游戏会获得一个极大的奖励,这样使得智能体以通关为目标、以吃金币为锦上添花。当然了,如果碰到怪物或者是死亡,需要设置一个极大的负奖励,因为这将直接导致游戏结束。
我们可以得出一个结论:每一个奖励 $R_{i}$,都与当时刻的状态 $S_{i}$ 与动作 $A_{i}$ 有关。拿马里奥游戏举例,在当前状态下,是否采取什么样的动作就会决定获得什么样的奖励?马里奥如果采取"向上",就可以获得金币奖励。如果采取"向右",碰到小怪会死掉,会获得一个很大的负奖励。如果采取"向左",那么可能什么事情都不会发生。
7.状态转移(State transition):环境可不会在原地等你。在你操控马里奥执行一个动作后,比如"left",那屏幕上显示的画面肯定会改变,这就发生了一个状态转移。状态转移函数记作
<center>
$p\left(s^{\prime} \mid s, a\right)=P\left(S^{\prime}=s^{\prime} \mid S=s, A=a\right)$
</center>
状态转移可以是固定的,也可以是随机的,我们通常讨论的是随机的情况。从公式的形式上也可以看出来,这还是一个概率密度函数。这代表着在观测到当前的状态$s$以及动作$a$后,状态转移函数输出新状态$s'$的概率,这个转移函数是只有环境、也就是游戏本身才知道的。比如在超级马里奥兄弟中,操控马里奥执行动作"left"后,敌人"板栗仔"可能向左也可能向右比如说向左概率为0.8向右概率为0.2,但是要注意这个概率只有游戏程序本身才知道。敌人动作的不确定性也就导致了环境的不确定性。
知道了上述几个概念,构建强化学习的基本过程就尽在掌握之中了。我们可以构建一个(state,action,reward)轨迹,即:<br>
i.观察到状态$s_{1}$<br>
ii.执行动作$a_{1}$,发生状态转移<br>
iii.观察新状态$s_{2}$与得到奖励$r_{1}$<br>
iv.执行动作$a_{2}$,发生状态转移<br>
v.不断迭代......
该序列轨迹写作:$\langle s_{1},a_{1},r_{1},s_{2},a_{2},r_{2},\ldots,s_{T},a_{T},r_{T} \rangle$
## 强化学习的基本概念
在阅读了前两个小节后,你可能对于强化学习的基本过程以及基本组成内容有了初步的了解。下面将进行强化学习基本概念的介绍,本章节与"基本组成内容"小节是继承关系,请一起阅读。(注:标题真难取,其实上一章就是强化学习的基本元素,这一章为基础元素推导出的基础概念)
1.回报(Retrun),需要与奖励区分开来。回报又称为"未来的累计奖励"(Cumulative future reward),这可以在其定义中窥见端倪:
<center>
$U_{\mathrm{t}}=R_{t}+R_{t+1}+R_{t+2}+R_{t+3}+\ldots . R_{t+n}$
</center>
但是这个定义有一个很明显的问题未来时刻的奖励和现在的一样重要吗如果我承诺未来给你100块钱这份**承诺**在你心里的分量和现在就给你100块钱能够等价吗很明显不能。因此我们引入折扣因子 $\gamma$ ,用以对未来的奖励做出一个折扣。定义折扣回报(Cumulative Discounted future reward)如下:
<center>
$U_{t}=R_{t}+\gamma R_{t+1}+\gamma^{2} R_{t+2}+\ldots \gamma^{n} R_{t+n}$
</center>
这是我们在强化学习中经常使用的概念。其中,折扣率是一个超参数,会对强化学习的结果造成一定的影响。
**注意格式**:如果游戏结束,每一个时刻的奖励都被观测到了——即站在任意时刻,一直到游戏结束的奖励都是可被观测的状态,那么奖励使用小写字母 $r$ 表示。如果游戏还没有结束,未来的奖励还是一个随机变量,那么我们使用大写字母 $R$ 来表示奖励。由于回报是由奖励组成的,那么我们也理所当然地用大写字母 $U_{t}$ 来表示回报。
*Fix:真的理所当然吗?*<br>
让我们回顾一下,之前讲述"奖励"的定义时,我们得出过一个结论:每一个奖励 $R_{i}$,都与当时刻的状态 $S_{i}$ 与动作 $A_{i}$ 有关。我们又知道,状态 $S_{i}$ 与动作 $A_{i}$ 在某种意义上都是随机变量,不要忘了:<br>
i.状态$S_{i}$是由状态转移函数,随机抽样得到的<br>
ii.动作$A_{i}$是由策略 $\pi$ ,以状态$S_{i}$作为输入后随机抽样输出的
因此,$U_{t}$ 就跟 $t$ 时刻开始未来所有的状态和动作都有关,$U_{t}$的随机性也因此和未来所有的状态和动作有关。
2.动作价值函数(Action-Value Function)
$U_{t}$ 在强化学习过程中的重要性不言而喻,这就代表着总体奖励——可以用于衡量智能体总的表现水平,并且智能体的目标就是让这个回报越大越好。但是由于我们前面说过的原因,回报 $U_{t}$ 受制于状态与动作,是一个随机变量。也就是说,在 $t$ 时刻,我们无法得知 $U_{t}$ 究竟是什么。有没有一种办法,能够消除掉随机性?很自然的,我们想起了《概率论与数理统计》中的期望。从数学上来说,对 $U_{t}$ 在策略函数 $\pi$ 下求期望,就可以消掉里边所有的随机性。因此,我们得到动作价值函数 $Q_\pi$ 的定义如下:
<center>
$Q_\pi=E\left(U_t \mid S_t=s_t, A_t=a_t\right)$
</center>
动作价值函数 $Q_\pi$ 消除了不确定的未来的动作和状态,转而把已观测到的状态 $s_{t}$ 和动作 $a_{t} $ 作为被观测的变量而非随机变量来对待。动作价值函数带来的意义就在于,能够在策略 $\pi$ 下,对于当前状态 $s$ 下所有动作 $a$ 进行打分,基于分数我们就可以知道哪个动作好、哪个动作不好。
3.最优动作价值函数(Optimal action-value function)
动作价值函数对于回报 $U_{t}$ 关于策略 $\pi$ 求取了期望,成功地消去了状态以及动作的随机性。但是需要注意的是,使用不同的策略 $\pi$ 就会得到不同的动作价值函数 $Q_\pi$ ——其实质上受到三个参数影响,即($\pi$$s$$a$)。我们应该使用"效果最好"的那种函数,也就是能让 $Q_\pi$ 最大化的那个 $\pi$ ,基于此我们可以得到最优动作价值函数:
<center>
$Q^*\left(s_t, a_t\right)= \underset{\pi}{max} Q_\pi\left(s_t, a_t\right)$
</center>
我们跨出了历史性的一步。
如果有了 $Q^*$ 函数,意味着可以评价动作的好坏了。我们的价值函数不再和策略有关,在观测的状态 $s$ 下,$Q^*$函数成为指挥智能体动作的“指挥官”——哪个动作的分数最高,智能体就应该执行哪个动作。学习 $Q^*$ 函数也是强化学习的最终目标之一,我们可以维护一张价值表用于选择收益最大的动作。学习 $Q^*$ 函数的过程被称为**基于价值的学习**。
4.状态价值函数(State-value function)
在动作价值函数中,$Q^*$ 函数将未来的随机变量消去,留下 $s_{t}$ 和 $a_{t}$ 作为观测变量。如果把动作作为随机变量,然后对于动作求期望,求得的新函数将仅与策略 $\pi$ 和状态 $s$ 有关,这就得到了状态价值函数 $V_\pi\left(s_t\right)$ 。下面是状态价值函数的定义:
<center>
$\begin{aligned} & V_\pi\left(s_t\right)=E_A\left[Q_\pi\left(s_t, A\right)\right] \\ & A \sim \pi\left(\cdot \mid s_t\right)\end{aligned}$
</center>
状态价值函数消去了动作 $a$,留下了策略 $\pi$ 与状态 $s$。这就意味着,在策略$\pi$下,目前状态的好坏可以根据状态价值函数的值来判断。如果策略是固定的,那么 $V_\pi$ 的值越大代表当前形势越好、对自己越有利。同样,策略价值函数也能用于评价策略的好坏,策略越好,$V_\pi\left(s_t\right)$ 的平均值就会越大。
## 强化学习的基本目标
看完上述内容的你,心里想必有十万个为什么:我是谁?我在哪?我要做什么?
明明最初说好的要训练智能体打游戏,我才耐着性子看下去的!看了这么久了,我光学到了一大堆似是而非的概念,推导并尝试理解了一大堆可能之前都没有接触到过的数学公式,抑或是翻开了尘封已久的《概率论与数理统计》才勉强跟上公式推导及其步骤,却连强化学习怎么训练智能体都不知道!这是诈骗!~~日内瓦,退钱!~~
这也是我在学习过程中的心路历程。理解/半懂不懂的带过了一堆概念,却连强化学习最基本的任务都不明白。我要干什么,才能训练智能体打游戏?
还记得我们前面提到过的**基于价值的学习**和**基于策略的学习**吗?没错,强化学习的最终目标就是通过两者完成的,下面将给出具体阐述。
1.**基于价值的学习**。说人话,就是学习 $Q^*$ 函数。我们之前已经推导过 $Q^*$ 函数在学习过程中的重要性了,它就好像一个"指挥官",智能体只需要按照它输出的动作照着执行就够了。试想:在现实世界里如果有这样一位人,他一直在指导你炒股,并且证明了他的选择永远是收益最高的,你还管什么原理,跟着大哥梭哈就完事了!在基于价值的学习中,我们通过使用最优值函数来选择最优的动作以最大化长期奖励的方式来间接地学习最优策略。基于价值的学习使用值函数来指导行为,直接体现就是维护了一个价值表格或价值函数,并通过这个价值表格或价值函数来选取价值最大的动作。
2.**基于策略的学习**。说人话,就是学习 $\pi$ 函数。我们复习一下策略 $\pi$ 的定义,是指智能体采取动作的规则。试想:在现实世界里,由于少年你骨骼清朗,兼有大机缘大智慧大定力,捡到了一本炒股秘籍。这本秘籍想必是心思慎密的高人前辈所留,无论是在何种状态下都有规则匹配当前状态告诉你应该怎么操作——并且你操作之后收益永远是最大化的,这本指导手册就是策略。基于策略的学习在每个状态下选择最优的动作,以最大化长期奖励。这种方法的目标是直接优化策略本身,因此它通常需要在策略空间中进行搜索,并且在每个策略上评估其长期累积奖励。
通常情况下,学到 $Q^*$ 函数和 $\pi$ 函数之一,就可以操控智能体打游戏了。但是也有方法结合了价值学习和策略学习,这就是演员-批评家网络(Actor-Critic)。不必太过担心,我们会在后续章节详细阐述该框架。
## 总结与展望
在本章节里,我们了解了强化学习的基本过程、组成要素、基本概念以及最终目标,无论你是否真正搞懂每一个知识点,想必已经对强化学习有一个初步的了解了。接下来,我拟从 Q-learning、SARSA 算法等传统强化学习算法开始,推到结合了深度学习的 Deep Q-learning(DQN) ,以及其改进版本Double DQN(DDQN)、Dueling DQN 等算法,以完成基于价值学习侧的算法介绍。然后,我将从 Reinforce 这一最基础的强化学习算法引入基于策略学习侧的基本理念,然后介绍结合基于策略学习和基于价值学习的演员-批评家网络(Actor-Critic)架构并且引出PPO、DDPG等算法。
为了不让你的大脑继续过载,下一章节将讲述强化学习基本环境的搭建。

View File

@@ -1,11 +0,0 @@
# 深度强化学习
前面已经介绍过强化学习(RL)的基本概念了这里着重介绍深度强化学习DRL
在笔者浅薄的理解里,深度强化学习的本质还是一个强化学习的问题,只不过引入了深度学习里的深度神经网络用于拟合函数。在传统的强化学习中,我们有一张表格用于存储状态以及动作的值函数。
很显然,在状态和动作空间较少的情况下,无论是存储这张表格还是查找这张表格都是轻而易举的。但是在复杂的环境下,继续使用这种方法会出现维度灾难,我们不得不使用函数逼近的办法来估计值函数。
这时候深度学习便加入进来与强化学习相结合,可以利用深度学习能处理高维、非线性数据与具有强大的学习能力这两个特点来逼近这个值函数并且提取特征,从而处理复杂状态下的问题。
也正是基于此,笔者在后续不会刻意区分强化学习与深度强化学习,因为他们的目标是一致的。这也是为什么本内容会放在深度学习的大模块下,而不是另外单独起一个强化学习模块的原因。

View File

@@ -1,2 +0,0 @@
# 深度学习

View File

@@ -1,36 +0,0 @@
# FunRec 概述
## 序言
这是一篇 datawhale 的相当优秀的推荐系统教程,因此特别废了九牛二虎之力把 FunRec 的半套内容,较为完整的移植到了本 wiki 中。
### 为什么要专门移植这篇?
zzm 个人以为推荐系统是一个非常有趣的横向和纵向都有很多应用的领域(放到外面是因为放到某一个模块下会因为次级链接太多把 wiki 撑爆了)
若你想尝试一个新领域,也许这是一个不错的切入点。更何况,如果你想足够完整的构建一个有实际价值的推荐系统,可能需要你去了解相当全面的知识。
在学习了基础内容之后,如果你想向着科研领域进发,也许对你而言最好的方式或许是选择一个大佬然后去 follow 他的进度。
如果你想去找相关的工作,你可以自行去深入学习有关本教程内容的实践部分,甚至是阅读算法面经。
同时只放上半部的原因是毕竟本偏内容是人工智能大类下的内容,后续可能会涉及一些前后端以及一些更为深入的东西,如果你只是想大致了解一下,那么阅读放在本片的内容被也许是一个不错的选择。
再次感谢 Datawhale 的大伙做出了如此卓著的贡献
## 正文
本教程主要是针对具有机器学习基础并想找推荐算法岗位的同学。教程内容由推荐系统概述、推荐算法基础、推荐系统实战和推荐系统面经四个部分组成。本教程对于入门推荐算法的同学来说,可以从推荐算法的基础到实战再到面试,形成一个闭环。每个部分的详细内容如下:
- **推荐系统概述。** 这部分内容会从推荐系统的意义及应用,到架构及相关的技术栈做一个概述性的总结,目的是为了让初学者更加了解推荐系统。
- **推荐系统算法基础。** 这部分会介绍推荐系统中对于算法工程师来说基础并且重要的相关算法,如经典的召回、排序算法。随着项目的迭代,后续还会不断的总结其他的关键算法和技术,如重排、冷启动等。
- **推荐系统实战。** 这部分内容包含推荐系统竞赛实战和新闻推荐系统的实践。其中推荐系统竞赛实战是结合阿里天池上的新闻推荐入门赛做的相关内容。新闻推荐系统实践是实现一个具有前后端交互及整个推荐链路的项目,该项目是一个新闻推荐系统的 demo 没有实际的商业化价值。
- **推荐系统算法面经。** 这里会将推荐算法工程师面试过程中常考的一些基础知识、热门技术等面经进行整理,方便同学在有了一定推荐算法基础之后去面试,因为对于初学者来说只有在公司实习学到的东西才是最有价值的。
**特别说明**:项目内容是由一群热爱分享的同学一起花时间整理而成,**大家的水平都非常有限,内容难免存在一些错误和问题,如果学习者发现问题,也欢迎及时反馈,避免让后学者踩坑!** 如果对该项目有改进或者优化的建议,还希望通过下面的二维码找到项目负责人或者在交流社区中提出,我们会参考大家的意见进一步对该项目进行修改和调整!如果想对该项目做一些贡献,也可以通过上述同样的方法找到我们!
为了方便学习和交流,**我们建立了 FunRec 学习社区(微信群 + 知识星球)**,微信群方便大家平时日常交流和讨论,知识星球方便沉淀内容。由于我们的内容面向的人群主要是学生,所以**知识星球永久免费**,感兴趣的可以加入星球讨论(加入星球的同学先看置定的必读帖)!**FunRec 学习社区内部会不定期分享 (FunRec 社区中爱分享的同学) 技术总结、个人管理等内容,[跟技术相关的分享内容都放在了 B 站](https://space.bilibili.com/431850986/channel/collectiondetail?sid=339597)上面**。由于微信群的二维码只有 7 天内有效,所以直接加下面这个微信,备注:**Fun-Rec**,会被拉到 Fun-Rec 交流群,如果觉得微信群比较吵建议直接加知识星球!。
<div align=center>
<img src="https://ryluo.oss-cn-chengdu.aliyuncs.com/图片image-20220408193745249.png" />
</div>

View File

@@ -1,3 +0,0 @@
# IIPL实验室介绍
[智能信息处理处理实验室](http://iipl.net.cn/index/list_team.aspx)IIPL主要研究方向围绕人工智能具体来说包括计算机视觉多模态3D视觉Slam等领域。有意加入的可以在实验室网站主页找到你感性求的老师的邮箱通过邮件的方式直接与他们交流。实验室会在大一上在通信学院宣讲届时会有招新大群有意向带本科生的老师会在群中发自己的研究方向介绍和联系方式。其他学院想加入的同学可以问问认识的通信学院的同学也可以通过邮箱联系笔者索要群号。