1自我介绍

项目

U-Net

要先从FCN(全卷积网络说起)。FCN是在CNN的基础上把最后分类的过程给换了,也换成了卷积层。
FCN第一个卷积块(卷积层+池化层)后的输出一般是64通道数,图片长和宽都是原来的一半。第二个卷积块之后变成128,图片再次缩小为上一层的1/4,第三个卷积块之后为256通道,图片继续缩小,第四个之后为512通道,图片继续缩小,第五个之后还是512通道,图片已经变成长为原来的1/32,宽为1/32。
然后经过1x1卷积变成类别数的通道。
最好采用FCN-8s的跳级融合,
在这里插入图片描述

在这里插入图片描述

就是把第五层的输出反卷积。反卷积上采样的方式:
在这里插入图片描述
在这里插入图片描述
然后就实现了像素级别的语义分割,最后是每一类对应一个颜色。
上采样还有双线性插值,立方插值,反池化等。
反卷积可以用双线性插值初始化。

U-Net

Unet 背景介绍
Unet 发表于 2015 年,属于 FCN 的一种变体,想了解 FCN 可以看我的另一篇 FCN 全卷积网络论文阅读及代码实现 。Unet 的初衷是为了解决生物医学图像方面的问题,由于效果确实很好后来也被广泛的应用在语义分割的各个方向,比如卫星图像分割,工业瑕疵检测等。

Unet 跟 FCN 都是 Encoder-Decoder 结构,结构简单但很有效。Encoder 负责特征提取,你可以将自己熟悉的各种特征提取网络放在这个位置。由于在医学方面,样本收集较为困难,作者为了解决这个问题,应用了图像增强的方法,在数据集有限的情况下获得了不错的精度。
Unet 网络结构与细节
Encoder
在这里插入图片描述

语义分割网络 U-Net 详解
如上图,Unet 网络结构是对称的,形似英文字母 U 所以被称为 Unet。整张图都是由蓝/白色框与各种颜色的箭头组成,其中, 蓝/白色框表示 feature map;蓝色箭头表示 3x3 卷积,用于特征提取;灰色箭头表示 skip-connection,用于特征融合;红色箭头表示池化 pooling,用于降低维度;绿色箭头表示上采样 upsample,用于恢复维度;青色箭头表示 1x1 卷积,用于输出结果。

可能你会问为啥是 5 层而不是 4 层或者 6 层,emmm,这应该去问作者本人,可能对于当时作者拿到的数据集来说,这个层数的表现更好,但不代表所有的数据集这个结构都适合。我们该多关注这种 Encoder-Decoder 的设计思想,具体实现则应该因数据集而异。

Encoder 由卷积操作和下采样操作组成,文中所用的卷积结构统一为 3x3 的卷积核,padding 为 0 ,striding 为 1。没有 padding 所以每次卷积之后 feature map 的 H 和 W 变小了,在 skip-connection 时要注意 feature map 的维度(其实也可以将 padding 设置为 1 避免维度不对应问题),pytorch 代码:

nn.Sequential(nn.Conv2d(in_channels, out_channels, 3),

 nn.BatchNorm2d(out_channels),

 nn.ReLU(inplace=True))

上述的两次卷积之后是一个 stride 为 2 的 max pooling,输出大小变为 1/2 *(H, W):

语义分割网络 U-Net 详解
pytorch 代码:

nn.MaxPool2d(kernel_size=2, stride=2)

上面的步骤重复 5 次,最后一次没有 max-pooling,直接将得到的 feature map 送入 Decoder。

Decoder
feature map 经过 Decoder 恢复原始分辨率,该过程除了卷积比较关键的步骤就是 upsampling 与 skip-connection。

Upsampling 上采样常用的方式有两种:1. FCN 中介绍的反卷积;2. 插值。这里介绍文中使用的插值方式。在插值实现方式中,bilinear 双线性插值的综合表现较好也较为常见 。

双线性插值的计算过程没有需要学习的参数,实际就是套公式,这里举个例子方便大家理解(例子介绍的是参数 align_corners 为 Fasle 的情况)。在这里插入图片描述

例子中是将一个 2x2 的矩阵通过插值的方式得到 4x4 的矩阵,那么将 2x2 的矩阵称为源矩阵,4x4 的矩阵称为目标矩阵。双线性插值中,目标点的值是由离他最近的 4 个点的值计算得到的,我们首先介绍如何找到目标点周围的 4 个点,以 P2 为例。在这里插入图片描述
第一个公式,目标矩阵到源矩阵的坐标映射:

在这里插入图片描述

为了找到那 4 个点,首先要找到目标点在源矩阵中的 相对位置,上面的公式就是用来算这个的。P2 在目标矩阵中的坐标是 (0, 1),对应到源矩阵中的坐标就是 (-0.25, 0.25)。坐标里面居然有小数跟负数,不急我们一个一个来处理。我们知道双线性插值是从坐标周围的 4 个点来计算该坐标的值,(-0.25, 0.25) 这个点周围的 4 个点是(-1, 0), (-1, 1), (0, 0), (0, 1)。为了找到负数坐标点,我们将源矩阵扩展为下面的形式,中间红色的部分为源矩阵。在这里插入图片描述
我们规定 f(i, j) 表示 (i, j)坐标点处的像素值,对于计算出来的对应的坐标,我们统一写成 (i+u, j+v) 的形式。那么这时 i=-1, u=0.75, j=0, v=0.25。把这 4 个点单独画出来,可以看到目标点 P2 对应到源矩阵中的 相对位置。

在这里插入图片描述
这里需要注意的是 ,FCN 中深层信息与浅层信息融合是通过对应像素相加的方式,而 Unet 是通过拼接的方式。

那么这两者有什么区别呢,其实 在 ResNet 与 DenseNet 中也有一样的区别,Resnet 使用了对应值相加,DenseNet 使用了拼接。 个人理解在相加的方式下,feature map 的维度没有变化,但每个维度都包含了更多特征,对于普通的分类任务这种不需要从 feature map 复原到原始分辨率的任务来说,这是一个高效的选择;而拼接则保留了更多的维度/位置 信息,这使得后面的 layer 可以在浅层特征与深层特征自由选择,这对语义分割任务来说更有优势。

小结

Unet 基于 Encoder-Decoder 结构,通过拼接的方式实现特征融合,结构简明且稳定,如果你有语义分割的问题,尤其在样本数据量不大的情况下,十分推荐一试。
https://www.cnblogs.com/DOMLX/p/9780786.html

YOLOv4 tiny

在这里插入图片描述

GAN

学习https://blog.csdn.net/Sakura55/article/details/81514828?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159661342719195264529311%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159661342719195264529311&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-9-81514828.pc_ecpm_v3_pc_rank_v3&utm_term=GAN&spm=1018.2118.3001.4187
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
GAN的训练有点像EM,先固定生成器去优化判别器,让判别器把数据集当作正样本,G产生的为负样本。然后固定判别器,去优化G的参数,让G生成的图像经过D的得分尽量高。重复,这个过程不断的让D和G进化。
D学习的条件分布P(Y|X)也就是在X的条件下,Y标签(好坏的分布)。
G学习的是P(X,Y)。

这样的对抗训练方式可能导致不稳定,G的参数梯度更新来自于D,所以G生成的好不好是看D的结果的。G根据D的反馈不断地改进自己的参数,但是如果某一次G产生的图像并不好,但是D给了很高的评价,那么这样G就会朝着错误的方向优化。
GAN使用的是JS散度作为loss。

c-GAN

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
这个可以不仅要求G的生成好,还要和C足够接近。在这里插入图片描述
这样的思想是从小到大。
在这里插入图片描述
图片输入G应该有个encoder,然后把encoder的结果和z相加或者concat。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
中心有CycleGAN的影子。在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

GAN的理论

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

很像EM。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
拿过去的G一起训练效果可能更好。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

WGAN

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这是利用了1-李普希思条件的等价条件做一个有约束的优化。在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这里假设如果图像质量很好,那么encoder和decoder的结果应该查相差不大。在这里插入图片描述
在这里插入图片描述
margin也是可以变化的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
增加training data。

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

训练GAN

.规范化输入

将输入图片规范化到-1到1之间
生成器最后一层的输出使用tanh激活函数
毋庸置疑规范化是最重要的,未经处理的图片是没有办法收敛的。图片规范化一种简单的方法是(images-127.5)/127.5,然后送到判别器去训练,同理生成的图片也要经过判别器,所以生成器的输出也是-1到1之间(和原图的区间范围保持一致)

这里有一个坑,因为生成的图是-1到1之间,需要再经过处理回到0-255区间才能正常显示。经过测试matplotlib似乎没法显示-1-1的图,而scipy.misc可以,所以写GAN我通常结合scipy.misc来看结果。

2.用修正的损失函数

在GAN论文里用min (log 1-D)来优化G,实际上max(log D)更好
实际代码中用反转标签来训练G更方便,即把生成图片当成real的标签来训练
损失函数恐怕是一个超级热门的研究点,参照当前的研究进展,很多实验中已经很少用到上面提到的交叉熵损失了,因为效率实在太低而且不稳定。下面列一下代表性的模型:

DCGAN

最初版本,使用了交叉熵损失,各种GAN玩法的鼻祖,直到目前效果依然很棒。

项目地址:carpedm20/DCGAN-tensorflow

WGAN

使用了Wasserstein损失,去掉了判别器最后一层的sigmoid和log,直接优化Wasserstein距离,但是WGAN需要对判别器做Weight Clip,比较麻烦,而且不能用动量优化(包括momentum和Adam),通常使用RMSProp来优化WGAN

项目地址:Zardinality/WGAN-tensorflow

Least Squares GAN

最小二乘GAN,把生成样本和真实样本分别编码为a,b,优化D的目标函数就是

优化G的目标函数

优化器还是建议RMSProp,其中a,b,c的值要自己设置,具体参考论文或者代码。

项目地址:GunhoChoi/LSGAN_TF

Improved WGAN

我所了解到的最新的一个版本,用一个改进的基于梯度惩罚的loss替代WGAN中的Weight Clip,从而产生比WGAN更高质量的样本,这个loss是可以用Adam来优化的。

项目地址:igul222/improved_wgan_training

3.使用一个具有球形结构的随机噪声z

不要使用均匀分布,而是从高斯分布中采样
Tom White的论文Sampling Generative Networks,项目代码https://github.com/dribnet/plat中查看更多的细节
这一点个人感觉大家都是这么做的,也没有很多可改进的地方。具体等我看了上面这篇论文再来补充。

4.BatchNorm

一个mini-batch里面必须保证只有Real样本或者Fake样本,不要把他们混起来训练
尽可能使用batchnorm,如果限制了不能用,则用instance normalization

个人感觉,这一点很重要。没有加BatchNorm,是造成很多新手训练GAN失败的罪魁祸首,之前我就因为没有按照标准的结构去定义GAN网络结构而吃尽了苦头。

5.避免引入稀疏梯度:ReLU,MaxPool

GAN的稳定性会因为引入稀疏梯度受到很大影响
尽量使用LeakyReLU作为激活函数
对于下采样,使用:Average Pooling或者Conv2d + stride
对于上采样,使用:PixelShuffle或者ConvTranspose2d + stride
PixelShuffle的原文:[1609.05158] Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network

这一点同样是小白容易掉的坑,我这里强烈建议使用全卷积,避免使用任何pooling,因为使用pooling会损失信息,这对于GAN训练很不好。当然如果计算资源不够,该用pooling还是要用的。

6.使用Soft和Noisy的标签

Label平滑,也即如果你设Real=1,Fake=0,那么可以改动一下,对于real,我们可以用一个0.7-1.2之间的随机值来代替,对于fake,用0-0.3这个区间
例如用real batch训练D的时候,不要一次性都给标签1,设一个小概率翻转,也就是会有很小一部分为0,当然这些标签是噪声。
这个技巧我用的比较少,似乎大家用的也都不多。可以试试对比一下效果

7.尽量使用Adam优化器

Adam的优化效率对于GAN来说很显著
前提是能用则用,除非像WGAN那样,规定不能使用,才考虑替换

8.早早的追踪到训练失败的信号

例如D的loss稳定下降,变得很小,或者稳定上升,变得很大。这些都是网络没有balance的信号
这一点其实更需要自己实际训练当中的经验,而且每个人的习惯不一样,我就比较喜欢在一定epoch的时候,输出generated image到路径看一看,一般看到全是噪声,基本可以停止训练了,再往下训练也不会有改善。所以不要把时间浪费在无谓,病态的梯度更新上。

9.训练和测试阶段,在G中使用DropOut

使用DropOut也是为了引入一定的噪声
在生成器的某几层中使用DropOut,而且测试和训练阶段都要做
常规的Dropout是测试阶段关闭的,而GAN里面,测试阶段同样也要使用Dropout

10.如果你有类别标签,请使用它们

如果你还有图片的类别标签,训练判别器在判别真伪的同时对其分类
这又是一个研究领域,主要做的是利用数据和标签,有监督或者半监督的生成指定某一类的数据,相关的有ACGAN,TripleGAN等等。

还有一些做图像Attribute的替换,比如男变女,有胡子变没胡子,也会涉及到这个。看过这方面的论文比较多,方法也比较杂,等我回去整理一下再给大家列举。

http://www.dataguru.cn/article-14458-1.html
GAN->DCGAN
cGAN-ACAGN
LSGAN
WGAN->WGAN-GP (westerstein散度)
CycleGAN
EBGAN->loss senetive GAN

RCNN发展史

RCNN :selective search+backbone(vgg)+svm分类+框回归
Fast-RCNN:seleactive search+backbone+分类回归(ROI Pooling,借鉴SPP-Net)
Faster RCNN RPN+backbone(Resnet50)+分类回归(Roi pooling 为7x7\,提出了anchor box)约等于RPN+Fast RCNN。
RPN输出是confidence_prob和四个调整参数,调整之后的为proposal region。然后要NMS,获得置信度最高的,如果IoU太大,那么可能为一个框。
loss是分类的CE加上回归框调整的smooth L1loss。
Faster RCNN对于小物体效果不好,因为只用到了最后一个特征层。
一般一个网格9个anchor box
输入短边为600,网格为38x38。
SSD:多尺度的特征图的多种anchor box预测。

YOLOv3

相比SSD,加了特征金字塔
backbone(Darknet53)
输入416x416
三个尺度13x13,26x26,52x52。
每个cell的anchor box数量为3。
每个物体的中心由左上的网格负责预测。
区分正样本负样本方法:
IOU判断
最大的IOU。
Mask-RCNN:实例分割方法,把最后的预测box传如一个分割网络即可,以获得像素级别的分类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CSPNET

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
CIoU代替Smooth_L1的loss。

one-stage和two-stage的比较

IoU手写,python

def calculateiod(rec1,rec2):
"""
rec1=[l1,r1,t1,b1]
rec2类似
"""
	l=max(rec1[0],rec2[0])
	r=min(rec1[1],rec2[1])
	t=max(rec1[2],rec2[2])
	b=min(rec1[3],rec2[3])
	if r<l or b <t:
		reuturn 0
	else:
		a=(r-l)*(b-t)
		b=(rec1[1]-rec1[0])*(rec1[3]-rec1[2])+(rec2[1]-rec2[0])*(rec2[3]-rec2[2])-a
		return a/b

CNN网络参数计算

输入128x64x64,3x3的卷积核,输出512x32x32。
weight的数量为128x3x3x512。
共有512种特征图。

算法题

给出正整数n,求连续的数的和为n的所有组合。

在这里插入代码片/*
* @Author: lenovouser
* @Date:   2020-08-05 18:17:20
* @Last Modified by:   lenovouser

* @Last Modified time: 2020-08-05 18:28:02

*/

#include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include<ctime>
#include<vector>
using namespace std;

int main(int argc, char const *argv[])
{
    unsigned int n;
    cin>>n;
    unsigned int min1=1,max1=1;
    while(min1<n/2+1)
    {
        unsigned int sum=(min1+max1)*(max1-min1+1)/2;
        if (sum==n)
        {

            cout<< min1 <<" "<<max1<<endl;
            min1+=1;
            max1+=1;
        }
        else
        {
            if (sum<n)
            {
                max1+=1;
            }
            else
            {
                min1+=1;
            }
        }
    }
    return 0;
}

算法复杂度O(n^2)。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐