code
为了显示全图,省略了relu操作,relu就是stride为2,kernel_size为2的常规非线性操作,在每层卷积层后都有
输出是一个(15,20,65)的tensor,除去最后一维“no interest dustbin”之后,剩余的(15,20,64)的结果可以reshape成原图的大小(120,160)
Detector Head对Encoder得到的feature进行decode,通过增加深度,最后将深度重新reshape到长宽维上实现与原图一样大小的输出,这里之所以不使用upconvolution的原因是add a high amount of computation and can introduce unwanted checkerboard artifacts[18]
观察损失函数
L p ( X , Y ) = 1 H c W c ∑ h = 1 , w = 1 H c , W c l p ( x h w ; y h w ) L_p(X,Y)=\dfrac{1}{H_cW_c}\sum_{h=1,w=1}^{H_c,W_c}l_p(\mathbf{x}_{hw};y_{hw}) Lp(X,Y)=HcWc1h=1,w=1∑Hc,Wclp(xhw;yhw)
其中, H c = H / 8 , W c = W / 8 H_c=H/8,W_c=W/8 Hc=H/8,Wc=W/8,且
l p ( x h w ; y ) = − log exp ( x h w y ) ∑ k = 1 65 exp ( x h w k ) l_p(\mathbf{x}_{hw};y)=-\log\dfrac{\exp(\mathbf{x}_{hwy})}{\sum_{k=1}^{65}\exp(\mathbf{x}_{hwk})} lp(xhw;y)=−log∑k=165exp(xhwk)exp(xhwy)
注意到detector的输出是(15,20,65)的,除去最后一个深度维后,剩下(15,20,64)对应着原图(120,160)的15*24个8*8的区域,对每个这样的区域,关键点所在的第几个位置(将8/*8的区域拉成64维向量)即是 y h w y_{hw} yhw的值,若区域中没有关键点,则 y h w = 65 y_{hw}=65 yhw=65,显然,从上面的损失函数中,默认了每个8*8区域中只有一个关键点,如果某个区域中有多于1个的关键点,则会在其中随机选择一个,虽然网络训练时使用随机的关键点,但是,实际的时候,大于最低置信度的点都会被认为是关键点,在训练过程中,只要多个关键点都多次被选中,可能可以检测出所有关键点。
实际的标签上大多数是64(代表没有兴趣点),并没有特别的解决样本不均衡问题的方法,作者在pretrained model中设置了检测最低置信度为0.015(约为1/65),而tf实现中,检测的最低置信度更是0.001
由于实际训练时,用上述的置信度,得出的网络输出的兴趣点都分布在如图的边缘,所以可能需要debug网络
1.训练出的网络对输入不敏感,且输出的热力图的8*8网格中每个小格子输出一样
几乎差不多的热力图,网络的输出损失也很大,预测结果和全部热力图如下图,这是欠拟合的表现
2.增大训练轮次后输出scale不同
损失小于1e-5,但预测时出现指数溢出,查看输出,发现15*20的每个65维输出的scale不一样,有的是0~80,有的是-40~0,统计结果如下
位于output[1,:,:]
的统计结果
位于output[59,:,:]
的统计结果
所以求exp的时候会溢出,loss的数值也不稳定,此时对每个15*20的channel求argmax时,得到的结果已经和label完全一致,可能是因为过拟合太多的原因,且在训练过程中,loss瞬间从0.5下降到0.002,可能是momentum在同一张图片上训练更新向量累积模太大,所以去掉momentum,且为防止过拟合,设定最小loss阈值
注意因为此处的输出求argmax后已经与label完全一样,我曾想通过归一化来保证预测时exp的数值稳定,但实际上是不可行的,因为不能做统一的归一化,这样会导致scale相对小的激活值输出的置信度很低,也不能做15*20区域中每个64维向量分别的归一化(?但是softmax的时候实际上是这样做的),这样会导致每个区域都有较大的激活值,问题是softmax在求损失函数的时候为什么数值是稳定的呢?
3.在验证集上训练误差停在0.2左右下不去,且预测结果很差
考虑之后使用可变的学习率来改正
代码在这
本实验主要是使用Pytorch进行MNIST分类,并与pytorch-example的代码进行对比
在有动量的情况下,加快了小学习率的优化速度,稍大的学习率在无动量情况下表现良好,但此时也会出现震荡
没有动量的方法稍微好一点,两者表现相差不大,但有动量因为额外的计算需要更长的时间
与之前的结果相似,小的学习率配上动量可以得到较好的结果,在这里大的学习率收敛快,因为没有正则化而出现了过拟合,本例使用的两个模型,在准确率上,CNN和全连接相差不大,但全连接的参数是CNN的68倍多
原数据就是0~1之间的浮点数,不需要再除以255
小学习率和momentum是好的组合
原来的公式是
x += learning_rate * gradient
加上momentum公式是
v = momentum * v - learning_rate * gradient
x += v
网络在init方法后会自动初始化参数,net.train与net.eval是对特殊层(如bn、dropout)在训练和测试时切换表现的选项
tensor.data
虽然可以使用,但是文档中查不到,且返回还是一个tensor,而tensor.item()则返回python类型的数值,要求tensor是一个一维张量
不知道
文章提出了深度残差学习网络,解决了深层网络难以优化的问题,核心思想是以学习残差代替学习直接映射,理论上这降低了网络学习到恒等映射的难度,从而使得更深的网络起码和浅的网络效果一样好
理论上来说,更深的网络至少可以表现地和浅层的网络一样好,只要在一个浅层的网络加后加多层恒等变换层
提出了残差学习网络来降低深层神经网络的学习难度,网络不直接学习输入到输出的映射 H ( x ) H(x) H(x)而学习输出和输入之差 F ( x ) = H ( x ) − x F(x)=H(x)-x F(x)=H(x)−x,然后通过 F ( x ) + x F(x)+x F(x)+x重建原映射,作者认为,如果恒等映射是最优的,这样的网络学习恒等变换比原来要简单(只要层的所有参数为0即可)
x的传播可以很容易地使用shortcut connections实现
图中给出了ResNet的building block,定义为
y = F ( x , { W i } ) + x y=F(x,\{W_i\})+x y=F(x,{Wi})+x
其中 x x x, y y y分别为输入和输出, F F F表示待学习的残差映射,比如在上图中,就有 F = W 2 σ ( W 1 x ) F=W_2\sigma(W_1x) F=W2σ(W1x),其中 σ \sigma σ是ReLU函数,且为了简洁省略了偏置项,且第二个非线性层在 F ( x ) + x F(x)+x F(x)+x之后使用
注意到这个shortcut connection没有引入新的参数和多的计算复杂度
注意到 F F F和 x x x的维度必须相同,如果不相同,可以通过一个投影变换实现
y = F ( x , { W i } ) + W s x y=F(x,\{W_i\})+W_sx y=F(x,{Wi})+Wsx
作者也提出可以在维度match的时候在 x x x前加一个方阵 W s W_s Ws,但实验中表明恒等映射已经足够, W s W_s Ws仅仅在维度不匹配时使用
每个building block中的层数大于等于两层(图例中是两层),作者观察到使用1层并不能带来什么好处,可能由于1层本身就是一个线性变换 y = W 1 x + x y=W_1x+x y=W1x+x
网络结构
作者使用一个plain网络和一个ResNet来做对比,其中
注意其中的下采样均是由stride为2的卷积网络实现的,而非池化层
层数不同的ResNet的区别如下
bottleneck是权衡之后的building block,更深的网络可以得到更好的结果,但是相比训练时间来说是不值得的
用3层的block代替ResNet34中的2层block
使用更多的3层block得到
浅层的网络精度相差不多,但ResNet18收敛更快,随着层数增加,plain Net的误差反而上升,而ResNet的误差大大下降
三种shortcuts
注意到ResNet1202虽然误差也很好,但是没有ResNet110好,可能是因为过拟合的原因
?
具体地,A、B是怎么实现的?