word2vec可以说是整个embedding理论的基础,几乎所有的embedding方法,最终都会把序列用skip-gram或者是CBOW训练一把得到embedding。
word2vec的原理并不复杂,精妙的思想在于如何减少输出层softmax的计算量,相关的基础文章王喆大神都列出来了,最近在阅读,经常会有一些让人眼前一亮的点,做一个简单的记录。
word2vec理论提出的文章中,Mikolov et al,写得并不是很好懂,好在有几篇explained,比如这篇: word2vec Explained: Deriving Mikolov et al’s Negative-Sampling Word-Embedding Method ,另外一篇更详细一些,JinRong教授写的。
在计算输出矩阵时,激活函数是这样的:
(1)
进一步可以写成对数形式:
(2)
这里就有一个很尴尬的问题,当 ,也就是我们的字典(vocabulary)的size很大的时候,这个softmax算的就会非常慢。
解决这个问题官方是有两种方案,1)层次softmax;2)负采样。
关于这两种方法刘建平大神以及其他各种ml博主都有写,我也写不了他们那么好,就不用多说了。但是为了说下面的东西,简单说一说负采样。
其实负采样一言以蔽之,就是把公式(1)中分母的 干掉。引入了这样的思想:只考察两个词 和 ,怎么能描述他们的关系呢?还是用上面的余弦距离。当我们认为 的embedding,也就是 是直接从输入矩阵中拿到的,这时候要学习的就是 的表示 ,这时候论文中直接给出了一个softmax的表达:
(3)
光从这个公式上理解,还是可以接受的,当两个embedding接近的时候,余弦距离大, ,反之
这里就有两个问题,感觉如果搞清楚这两点,负采样基本上就捋顺了:
回答了这两个问题,其实接下去的事情就比较简单,或者说通畅。我们直接把公式(3)的softmax激活写成一个通用的激活形式 ,最后的损失函数就可以写成:
题外话可以说说softmax和lr的关系,设想这样的一个简单的逻辑回归问题,用线性函数拟合对数几率的废话不多说,公式如下:
(4)
但是当我们把它当成是一个多分类问题的时候,写成softmax的样子,可以有:
把下面的公式稍微变化一下就写成:
也就是说,当softmax是一个二分类问题的时候,其实没有必要训练两组参数,本质上就是一个逻辑回归问题,优化过程中,我们只关注 而不是这两组参数分别是多少。事实上,我们确实也无法求出他们准确的值来,或者说他们可以任意的数,因为在求偏导的时候 恒成立,迭代中只会优化它俩的差值。
softmax是用于单标签输出,模型训练后,调用modelpredict函数就可以输出结果为[05,04,01](输出数量为最后一层隐藏层的neuron数)这样的矩阵,里面即为你所需的预测概率值,值得注意的是,softmax会限制输出的所有概率相加为1。
如果需要预测的是多个标签而不是单个标签,则需要使用sigmoid作为输出激活函数,那么输出就不再强制相加为1,可以得到每个分类的实际预测值,此时只需要设置一个致信的threshold则可以得到多个分类预测值。
每个激活函数的详细解释看这里网页链接
论文:An Adversarial Approach to Hard Triplet Generation
ReID问题中都是根据图像embedding之间的特征距离来判断相似度,但是平常训练都是根据训练集的ID做监督,用softmax进行分类。而Triplet loss能够直接对图像的特征进行监督,更有利于学到好的embedding。
损失函数:
hard triplets指的是找到minibatch中 最大的一对三元组,即找到 最大的和 最小的。
但是这样直接的方式不一定能找出具有代表性的三元组,会对网络的收敛(convergence)造成问题。
三元组损失函数对于三元组的选择非常敏感,经常会有难以收敛和局部最优的问题,为此 [1] 提出了 Coupled Cluster Loss ,使得训练阶段更加稳定,网络收敛的更加快。
特征提取网络 的输出 ,对于三元组 ,传统方法的损失函数是: ,其中 是 距离。
给出一个生成器 ,通过这个生成器生成一个新的sample , 的目的是使得正样本之间距离增大,负样本之间距离减小,目的是为了生成更harder的sample
通过降低以下loss来训练 :
随后固定学习过的 ,接着训练 :
但是光靠上面的方法并不够有效,因为没有限制的情况下, 会任意 *** 纵(arbitrarily manipulate) 生成的特征向量。打个比方说, 可能随意输出一个向量,使得 非常小,但是这个对于训练来说没有意义。为了限制 ,需要他输出的向量不改变原本向量的标签。
给出一个判别器 ,对于每个特征向量, 能将其分成(K+1)类,K表示真实存在的类别,+1代表fake类别。通过降低以下loss来训练 :
其中前半部分让 分辨 生成的特征向量的标签
表示softmax loss,后半部分让 分辨 生成的特征向量。
表示fake类别。
之前提到 应该保留住输入的特征向量的标签。因此文章中提出下面的loss:
与之前的公式(2) 结合,通过降低以下loss来训练 :
其中classification(5)确保了 能够正确分类
首先,basic model同时降低softmax loss和triplet loss。随后 被加入到basic model。
softmax 和similarity loss在之前的研究中有被结合起来,但是他们之间的关系并没有被深入的进行研究。
在特征向量空间(feature embedding space)中,所有相同类别的数据坐标经过 规范化后应该是在一个单位超球面(unit hyper sphere)上,图2中的decision boundary将不同类别的数据分成K个类别,这种结构能加速收敛并达到理想化(optimal)的结果。但是传统的softmax loss不能很好兼容基于特征距离(distance-based)的similarity loss。如图3(b)中。由于偏置b的存在,decision boundary不能够通过原点,因此在 规范化后,不同类别的点可能会重合。这将导致类间距离(inter-class)的缩小,影响特征向量的效果。因此文章中提出了一个没有偏执b的softmax loss。如图3(b)所示,这种无偏置softmax损失的所有决策边界都通过原点,并且决策区域是锥形的,其顶点位于原点。因此,同一类的样本在单位超球面上具有单独的投影,这确保了来自不同类别的示例之间的长的类间距离(inter-class)。
给定一个训练三元组 其中 为anchor 的类别。无偏置的softmax定义为:
其中 表示CNN网络的输出特征向量。随后网络 通过缩小 来训练(SGD)。
图4左边部分所示, 的输入是L维的特征向量,这个向量是网络 的输出,同时 的输出具有相同的维度。 包含4个全连接层,前两个降维,后两个升维,每一层后面跟了BatchNormalization和ReLU。最后的输出是输入向量和输出向量的对应位置相加。
另外,判别器 接受 产生的L维特征向量,并将其分成K+1类。 也有4个全连接层,前三个后面跟了BatchNormalization和ReLU,最后一个跟的softmax。(怎么感觉 接受的是应该是 产生的?)
文章中使用的优化器是SGD,学习率 ,步骤在Section 3中介绍。
此外,文章中尝试构建一个更强大的提取器 ,允许HTG从细粒度的局部细节创建更hard三元组,因此视觉识别模型可以用更难的三元组示例挑战变得更加鲁棒。
实际上,局部特征在许多细粒度的视觉识别任务中起着关键作用。用于图像分类的典型深度神经网络擅长提取高级全局特征,但常常缺少局部细节的特征。这可能会限制HTG探索本地细节以创建更难的triplets。例如,在没有本地细节的情况下,HTG无法生成能够识别不同车辆的大多数有辨别力的部分的三元组,例如徽标,灯光和天窗。
为了解决这个问题,文章中介绍了一种更加关注局部特征的关键点图。例如ResNet-18包含了4个连续的卷积块,在最后一个卷积块后面跟着一个全连接层作为全局特征 对于卷积块 来说,他的输出特征图可以表示为 随后我们加一个局部分支叫做keypoint bolck,它具有类似于卷积块的结构,用于本地化关键点的分布,这些关键点可以关注最具辨别力的部分以创建更难的三元组。高级语义特征映射是稀疏的(不太明白这里),我们假设关键点层的每个通道对应于特定类型的关键点,因此我们在关键点层的输出特征上应用通道层面(channel-wise)softmax来估计不同图像位置上关键点的密度:
是clock-l的输出特征图在通道c及位置(i,j)上的的点。
block-l局部特征 :
文章中提取了bolck-3和block-4的特征,和全剧特征concat后作为最后的输出特征。
备注:这部分没有看的很明白,我理解的大概意思是在网络的中间层先做一个softmax,最后和全局特征的softmax concat起来。
softmax层可以用来计算分类概率。softmax的前世今生系列是作者在学习NLP神经网络时,以softmax层为何能对文本进行分类、预测等问题为入手点,顺藤摸瓜进行的一系列研究学习。
神经网络中常用的激活函数之一,其定义为: 该函数的定义域为 ,值域是
它的导数为:
作用:用于处理多标签分类问题、多个正确答案、非独占输出。是对每个输出值约束到
神经网络中常用的激活函数之一,其定义为:
作用:用于多类别分类问题、只有一个正确答案、互斥输出。是将所有输出值的和约束为1
你好,下面是一个keras的softmax分类器+自编码器的python代码。你需要安装最新的theano104才可以跑。
import os;osenviron['KERAS_BACKEND'] = 'theano'
import keras
from kerasdatasets import mnist
from kerasmodels import Model
from keraslayers import Input, Conv2D, MaxPooling2D, Flatten, Dense, UpSampling2D
batch_size = 128
num_classes = 10
epochs = 12
# input image dimensions
img_rows, img_cols = 28, 28
# Data
(x_train, y_train), (x_test, y_test) = mnistload_data()
x_train = x_trainreshape(x_trainshape[0], img_rows, img_cols, 1)astype('float32') / 255
x_test = x_testreshape(x_testshape[0], img_rows, img_cols, 1)astype('float32') / 255
y_train = kerasutilsto_categorical(y_train, num_classes)
y_test = kerasutilsto_categorical(y_test, num_classes)
# Convolutional Encoder
input_img = Input(shape=(img_rows, img_cols, 1))
conv_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)
pool_1 = MaxPooling2D((2, 2), padding='same')(conv_1)
conv_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool_1)
pool_2 = MaxPooling2D((2, 2), padding='same')(conv_2)
conv_3 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool_2)
encoded= MaxPooling2D((2, 2), padding='same')(conv_3)
# Classification
flatten = Flatten()(encoded)
fc = Dense(128, activation='relu')(flatten)
softmax = Dense(num_classes, activation='softmax', name='classification')(fc)
# Decoder
conv_4 = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
up_1 = UpSampling2D((2, 2))(conv_4)
conv_5 = Conv2D(8, (3, 3), activation='relu', padding='same')(up_1)
up_2 = UpSampling2D((2, 2))(conv_5)
conv_6 = Conv2D(16, (3, 3), activation='relu')(up_2)
up_3 = UpSampling2D((2, 2))(conv_6)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same', name='autoencoder')(up_3)
model = Model(inputs=input_img, outputs=[softmax, decoded])
modelcompile(loss={'classification': 'categorical_crossentropy',
'autoencoder': 'binary_crossentropy'},
optimizer='adam',
metrics={'classification': 'accuracy'})
modelfit(x_train,
{'classification': y_train, 'autoencoder': x_train},
batch_size=batch_size,
epochs=epochs,
validation_data= (x_test, {'classification': y_test, 'autoencoder': x_test}),
verbose=1)
以上就是关于word2vec负采样中softmax的应用全部的内容,包括:word2vec负采样中softmax的应用、keras 如何输出softmax分类结果属于某一类的概率、用对抗的方法生成Hard Triplets等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)