Inception系列

Goodlenet网络

提升网络的性能最直接的方法就是增加网络的宽度和网络的深度。但是会产生过参数太多,过拟合现象,梯度消失以及产生巨大的计算量。

引入了Inception模块,使用1x1的卷积来进行升降维,在多个尺寸上同时进行卷积再聚合。通过多个卷积核提取图像不同尺度的信息,最后进行融合,可以得到图像更好的特征。将1x1,3x3,5x5的conv和3x3的pooling,堆叠在一起。

原始版本
在这里插入图片描述
改进后在卷积前增加1x1的卷积,池化后增加1x1的卷积,减少计算量。
在这里插入图片描述特点:
1.GoogLeNet采用了模块化的结构,有九个Inception Module,方便增添和修改;
2 . 网络最后采用了average pooling来代替全连接层,
3 . 虽然移除了全连接,但是仍然使用了Dropout ;
4 . 为了避免梯度消失,网络在训练时额外增加了2个辅助的softmax用于向前传导梯度,在计算损失时需要按照一定的权重加到最后的总loss中,如下图。
在这里插入图片描述
优化Inception结构的规则:
1.要防止出现特征描述的瓶颈,中间某层对特征在空间维度进行较大比例的压缩(比如使用pooling时),导致很多特征丢失。虽然Pooling是CNN结构中必须的功能,但我们可以通过一些优化方法来减少Pooling造成的损失
2.特征的数目越多,收敛的速度越快。
3.可以压缩特征维度数,来减少计算量。
4.网络的深度和宽度要达到平衡。

Inception V2/v3模型

1,引入了Batch Normalize
2,使用vgg网络中的方法,用2个3x3的卷积核代替1个5x5的大卷积核,减少计算量和参数量。

在训练过程中,每一层输入的分布因为前一层参数的变化而不断变化,参数的变化引起激活值分布发生变化。如果网络的某一层输入数据的分布发生变化,那么这一层的网络就需要学习去适应这个新的数据分布,这会产生很大的计算量,耗费时间,准确率也不那么高。
引入Batch Normalize,对输入的信息进行标准化分布,运用在激活函数之前,使收敛速度更快。
在这里插入图片描述
3.使用非对称卷积。将nxn的卷积分解成1xn和nx1卷积的串联,例如n=3,分解为3x1和1x3两个卷积,分解后就能节省33%的计算量。非对称卷积用在网络中靠中间的层级才有较好的效果(特别是feature map的大小在12x12~20x20之间时)
在这里插入图片描述
4.使用并行结构来优化Pooling。Pooling会造成特征描述的瓶颈,有两种解决办法。方法1:在Pooling前用1x1卷积把特征数加倍,然后再使用池化操作。这种方法有很好的效果,但是1x1卷积会增大计算量。或者先做Pooling减少feature map size,然后再使用1x1 conv对其channels数目放大,但是先使用Pooling的话会造成信息硬性丢失。
方法2:使用两个并行的支路,一路是1x1卷积,由于特征维度没有加倍,计算量相比之前减少了一倍,另一路是Pooling,最后再在特征维度拼合到一起,效果好的同时也没有增加计算量。
方法1:
在这里插入图片描述
方法2:
在这里插入图片描述
5.使用Label Smoothing来对网络输出进行正则化。
inception v2的网络结构图:
在这里插入图片描述在这里插入图片描述
inception v3的网络结构图:
在这里插入图片描述inception v3模型比 inception v2 模型在辅助分类器上多使用了BN。

Incepton v4

Incepton V4把一个先1x1再3x3那步换成了先3x3再1x1。
Incepton V4的结构:
在这里插入图片描述Reduction主要是用来降低feature map的尺寸。Inception v4中基本的Inception module还是使用了Inception v2/v3的结构,只是结构看起来更加简洁,使用更多的Inception module。

Inception-ResNet

引入了residual connection,把Inception和ResNet结合起来,让网络又宽又深,提出了两个版本:
Inception-ResNet v1:Inception加ResNet,计算量和Inception v3相当,较小的模型Inception-ResNet v2:Inception加ResNet,计算量和Inception v4相当,较大的模型准确率也更高。
inception resnet v1中的残差结构:
在这里插入图片描述
inception resnet v2中的残差结构:
在这里插入图片描述Inception module每个分支都没有使用pooling,每个Inception module最后都使用了一个1x1的卷积,作用是保证identity部分和Inception部分输出特征维度相同,这样才能保证两部分特征能够相加。
inception resnet v1和inception resnet v2 网络的stem结构不同,其他结构相同如下图。
在这里插入图片描述

使用inceptionv3实现猫狗分类

重要代码:
迁移学习
在这里插入图片描述

writer = SummaryWriter()
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

transform = transforms.Compose([transforms.CenterCrop(299),
                                transforms.ToTensor(),
                                normalize])

train_dataset = ImageFolder(root='./data/train', transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)

val_dataset = ImageFolder(root='./data/validation', transform=transform)
val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=64, shuffle=True)

model = models.inception_v3(pretrained=True)
num_aux_ftrs = model.AuxLogits.fc.in_features
num_ftrs = model.fc.in_features
for param in model.parameters():
    param.requires_grad = False
model.AuxLogits.fc = nn.Linear(num_aux_ftrs, 2)
model.fc = nn.Linear(num_ftrs, 2)

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

for epoch in range(2):
    for i, data in enumerate(train_loader):
        sum = 0
        total1 = 0
        tn = 0
        tf = 0
        i += 1
        total1 = 64
        inputs, labels = data
        inputs = Variable(inputs)
        labels = Variable(labels)
        optimizer.zero_grad()
        outputs, aux_outputs = model(inputs)
        loss1 = criterion(outputs, labels)
        loss2 = criterion(aux_outputs, labels)
        loss = loss1 + 0.3 * loss2
        loss.backward()
        optimizer.step()
        _, preds = torch.max(outputs, 1)
        preds = preds.numpy()
        labels = labels.numpy()
        print("loss is: ", loss)
        writer.add_scalar("loss11", loss, i)
        for j in range(64):
            if (preds[j] == labels[j]):
                sum += 1
            if (preds[j] == 0 and labels[j] == 0):
                tn += 1
            if (preds[j] == 0 and labels[j] == 1):
                tf += 1
        if i % 4 == 0:
            acc1 = sum / total1
            TF = tn / (tn + tf)
            print('acc is : {:.3f},TF is :{:.3f} '.format(acc1, TF))
            writer.add_scalar("acca", acc1, i)
        if i == 120:
            break
acc = 0
total = 64
sum = 0
for i, data in enumerate(val_loader):
    i += 1
    inputs, labels = data
    inputs = Variable(inputs)
    labels = Variable(labels)

    optimizer.zero_grad()
    outputs, _ = model(inputs)
    loss = criterion(outputs, labels)
    preds,_ = torch.max(outputs, 1)
    preds = preds.numpy()
    labels = labels.numpy()
    for j in range(24):
        if(preds[j] == labels[j]):
            sum += 1
    if i % 20 == 0:
        acc = sum / total
        print('ACC is {:.3f}'.format(acc))
        writer.add_scalar("acc", acc, i)
        writer.close()

运行结果截图:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
由tensorboardx图可以看出,Inceptionv3网络对猫狗分类效果较好,经过很短的时间,loss就已经下降到很低,acc在短的时间内就已经达到0.95左右。

补充迁移学习
冻结参数
for para in list(model.parameters())[:-1]😕/除了最后一层的参数,其他 的都冻结。a[1:4:1] a[1:4] a[:-1]
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值