学习内容
1.论文
2.深度学习(147 / 181)
学习时间
2023.09.07 — 2023.09.12
学习笔记
论文
负样本如何提取
本周对 LCD 这篇论文的代码进行了分析(train.py)
包括以下内容:
- 添加了训练时的额外参数(config,logdir)等,使用的 网络参数 与 日志 的位置
- 读取 网络参数 并放到对应的位置
- 初始化,包括加载数据,使用 gpu 等
- 开始训练,每个 epoch 对应多个 batch,每训练一代写一次 log
训练数据的格式:
patch: {“cloud”: [d^6], “color”: [d^3]}
patches=[ {…}, {…}, … , {…} ], maxlength = 6
batch=[ […], […], […], … , […] ], maxlength = 1000
每次训练的时候,从每个 batch 内有放回的提取若干个(30-35) patches 参与训练。
关于负样本:
本篇使用的是 PointNet 处理点云,经过查阅资料发现,PointNet 在处理点云的过程中并不存在负样本。
同时,通过看本文的代码,也没有看到负样本的出现,在训练中,只有这些数据:
x 是 原数据,y 是 x 通过 encoder 之后的数据,z 是将 y 通过 decoder 后的数据
for i, batch in enumerate(loader):
# 将张量移动到 cuda
x = [x.to(device) for x in batch]
# y 是编码后的,z 是解码后的
y0, z0 = pointnet(x[0])
y1, z1 = patchnet(x[1])
loss_r = 0
loss_d = 0
loss_r += args["alpha"] * criterion["mse"](x[1], y1)
loss_r += args["beta"] * criterion["chamfer"](x[0], y0)
loss_d += args["gamma"] * criterion["triplet"](z0, z1)
loss = loss_d + loss_r
optimizer.zero_grad()
loss.backward()
# 更新参数
optimizer.step()
关于评估指标
还没做。
深度学习
1.1 序列模型(Sequence Model)
使用序列模型的情况(输入输出都是序列数据):
- 给定一段音频(x 为音频片段),输出对应的文字记录(y 是一系列单词)
- 音乐生成问题
- 情感分类(根据输入的单词序列判断情绪)
- DNA 序列分析
- 机器翻译,不同语言互转
- 视频中的行为识别,输入是一系列的视频帧
- 命名实体识别,识别出文段中的名字等
1.2 数学符号(Notation)
如何一步步构建序列模型?
假设一个句子,我们要找出其中的人名:
Harry Potter and Herminoe Granger invented a new spell.
一共九个单词,我们使用 x < T > x^{<T>} x<T> 来表示第 T 个单词。
我们的 label y,在这个例子中,有 T 个单词,所以是一个 T 维向量(本例中 T=9):
[ 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 ] [1, 1,0,1,1,0,0,0,0] [1,1,0,1,1,0,0,0,0]
那么输入数据如何表示呢?
首先我们要先找一个字典,也许有 10000 个单词,构建数据时,每个 x < T > x^{<T>} x<T> 应该是一个 10000 维向量,如果第 1500 个词是 Harry,那么这个向量的第 1500 个位置就应该是 1,其余都是 0,我们称之为 one-hot 向量:
[ 0 , 0 , . . . , 1 , 0 , . . . . , 0 ] [0,0, ...,1,0,....,0] [0,0,...,1,0,....,0]
遇到不在词表(字典)中的单词时,创建一个新的标记,即 Unknown Word,用 <UNK> 作为标记
1.3 循环神经网络模型(Recurrent Neural Network Model)
在上一节中,如果我们要进行计算结果,必须输入 n 个单词的高维向量来计算,最后得到 n 个 0 或 1 的项,这样做有一些缺点:
- 在不同的例子中,输入输出数据可以有不同的长度。且输入和输出长度也不一定相等
- 训练出来的神经网络不会共享在文本不同位置上学到的特征
且输入层会十分庞大,并含有巨量的参数。
什么是循环神经网络?
其实就是在处理的过程中,将上一个处理单位的某些特征输入到下一个单位中。如图即为循环神经网络的例子。
激活值不一定正向传递,也有可能为双向,比如 BRNN。
接下来我们来看看公式。
W
a
W_{a}
Wa 为一个横向拼接的矩阵,以上一个为例,如果 a 是 100 维的,那么
W
a
a
W_{aa}
Waa 就是 100*100 的矩阵,
W
a
x
W_{ax}
Wax 为 100*10000 的矩阵,两个横向排列,维度变为 10100。激活函数 g 可以不一致。
a
<
t
>
=
g
(
W
a
[
a
<
t
−
1
>
,
x
<
t
>
]
+
b
a
)
y
^
<
t
>
=
g
(
W
y
a
<
t
>
+
b
y
)
a^{<t>}=g(W_{a}[a^{<t-1>},x^{<t>}]+b_{a})\\ \hat{y}^{<t>}=g(W_{y}a^{<t>}+b_{y})
a<t>=g(Wa[a<t−1>,x<t>]+ba)y^<t>=g(Wya<t>+by)
更加清晰的图,可以看清楚前向传播中参数之间的关系:
1.4 通过时间的反向传播(Backpropagation through time)
先把 forward propagation 想明白,然后和以前一样,来计算反向传播。
损失函数的定义和逻辑回归中的相同,即:
L
<
t
>
(
y
^
<
t
>
,
y
<
t
>
)
=
−
y
<
t
>
log
y
^
<
t
>
−
(
1
−
y
<
t
>
)
log
(
1
−
y
^
<
t
>
)
L
(
y
^
,
y
)
=
∑
t
=
1
T
x
L
<
t
>
(
y
^
<
t
>
,
y
<
t
>
)
L^{<t>}(\hat{y}^{<t>},y^{<t>})=-y^{<t>}\log \hat{y}^{<t>}-(1-y^{<t>})\log (1-\hat{y}^{<t>})\\ L(\hat{y},y)=\sum^{T_{x}}_{t=1}L^{<t>}(\hat{y}^{<t>},y^{<t>})
L<t>(y^<t>,y<t>)=−y<t>logy^<t>−(1−y<t>)log(1−y^<t>)L(y^,y)=t=1∑TxL<t>(y^<t>,y<t>)
因为前向传播是沿着时间轴进行的,因此反向传播时倒着的,有一个很酷的名字叫做: backpropagation through time。
1.5 不同类型的循环神经网络(Different types of RNNs)
以下是一些循环神经网络的类型,有一对多,多对多,多对一等等。
一对多是比较新颖的,要好好理解,比如根据数字生成一段音乐。
看到最后一个类型,一般可以做机器翻译等。左半边为 encoder,右半边为 decoder。
1.6 语言模型和序列模型生成(Language model and sequence generation)
构建语言模型是自然语言处理中最重要的工作之一。
比如一个语音识别系统,在听到一个句子以后,能够输出一个句子来说明到底说了什么。可能会生成多个句子,然后选择概率最高的那一句作为输出。
具体做法:
先将句子中的所有单词转换为 one-hot 向量。包括句子的结束符(<EOS>),未定义的单词(<UNK>)等。
接下来构建一个 RNN 模型,如图, a < T > a^{<T>} a<T> 要做的是通过 softmax,来预测下一个单词。并把已经预测好的结果作为 x < T + 1 > x^{<T+1>} x<T+1> 输入下一层,从左往右地预测每一个值。
损失函数定义为交叉熵。即:
概率是如何算的呢?假设有三个单词组成的句子,那么计算公式如下:
L
(
y
^
<
T
>
,
y
<
T
>
)
=
−
∑
i
y
i
<
T
>
log
y
^
i
<
T
>
L
=
∑
t
L
(
y
^
<
T
>
,
y
<
T
>
)
P
(
y
<
1
>
,
y
<
2
>
,
y
<
3
>
)
=
P
(
y
<
1
>
)
⋅
P
(
y
<
2
>
∣
y
<
1
>
)
⋅
P
(
y
<
3
>
∣
y
<
1
>
,
y
<
2
>
)
L(\hat{y}^{<T>},y^{<T>})=-\sum_{i}y_{i}^{<T>}\log\hat{y}_{i}^{<T>}\\ L=\sum_{t}L(\hat{y}^{<T>},y^{<T>})\\ P(y^{<1>},y^{<2>},y^{<3>})=P(y^{<1>})\cdot P(y^{<2>}|y^{<1>})\cdot P(y^{<3>}|y^{<1>},y^{<2>})
L(y^<T>,y<T>)=−i∑yi<T>logy^i<T>L=t∑L(y^<T>,y<T>)P(y<1>,y<2>,y<3>)=P(y<1>)⋅P(y<2>∣y<1>)⋅P(y<3>∣y<1>,y<2>)