resnet18全连接层改成卷积层

想要尝试一下将resnet18最后一层的全连接层改成卷积层看会不会对网络效果和网络大小有什么影响

1.首先先对train.py中的更改是:

train.py代码可见:pytorch实现性别检测

# model_conv.fc = nn.Linear(fc_features, 2)这是之前的写法
model_conv.fc = nn.Conv2d(fc_features, 2, 1)
print(model_conv.fc)

但是运行的时候出错:

1)

RuntimeError: Expected 4-dimensional input for 4-dimensional weight [2, 512, 1, 1], but got 2-dimensional input of size [4, 512] instead

[2, 512, 1, 1]为[batch_size, channels, height, width],压扁flat后为[4, 512],即[batch_size, out_size]

这是因为在传到fc层前进行了压扁的操作:

x = x.view(x.size(0), -1)

到相应的代码处/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torchvision/models/resnet.py注释掉其即可

2)

Traceback (most recent call last):
  File "train.py", line 192, in <module>
    model_train = train_model(model_conv, criterion, optimizer_conv, exp_lr_scheduler)
  File "train.py", line 135, in train_model
    loss = criterion(outputs, labels)
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/nn/modules/module.py", line 489, in __call__
    result = self.forward(*input, **kwargs)
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/nn/modules/loss.py", line 904, in forward
    ignore_index=self.ignore_index, reduction=self.reduction)
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/nn/functional.py", line 1970, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/nn/functional.py", line 1792, in nll_loss
    ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
RuntimeError: invalid argument 3: only batches of spatial targets supported (3D tensors) but got targets of dimension: 1 at /Users/soumith/b101_2/2019_02_08/wheel_build_dirs/wheel_3.6/pytorch/aten/src/THNN/generic/SpatialClassNLLCriterion.c:59

先将得到的结果打印出来:

print(outputs,outputs.shape)
print(labels, labels.shape)

得到:

tensor([[[[-0.8409]],

         [[ 0.3311]]],

        [[[-0.3910]],

         [[ 0.6904]]],

        [[[-0.4417]],

         [[ 0.3846]]],

        [[[-1.1002]],

         [[ 0.6044]]]], grad_fn=<ThnnConv2DBackward>) torch.Size([4, 2, 1, 1])
tensor([1, 1, 0, 0]) torch.Size([4])

可见得到的结果不是最后想要的结果,需要将channel*height*width=2*1*1变为2,结果为[4,2]

然后后面回运行:

_, preds = torch.max(outputs, 1)

得到两个值中最大那个值的索引,结果的shape就会变成[4]

这里的解决办法就是在resnet.py代码的fc层下面加入一层代码:

x = x.view(x.size(0), -1)

这样最终resnet网络的forward()函数应该是:

def forward(self, x):
    x = self.conv1(x)
    x = self.bn1(x)
    x = self.relu(x)
    x = self.maxpool(x)

    x = self.layer1(x)
    x = self.layer2(x)
    x = self.layer3(x)
    x = self.layer4(x)

    x = self.avgpool(x)    #x = x.view(x.size(0), -1)
    x = self.fc(x)
    x = x.view(x.size(0), -1)
    return x

2.然后再运行即可,但是我的结果并没有很大的不同,训练的网络大小也差不多

原文地址:https://www.cnblogs.com/wanghui-garcia/p/10770028.html

时间: 2024-07-30 21:33:14

resnet18全连接层改成卷积层的相关文章

理解为什么要将全连接层转化为卷积层

理解为什么要将全连接层转化为卷积层 1.全连接层可以视作一种特殊的卷积 考虑下面两种情况: 特征图和全连接层相连,AlexNet经过五次池化后得到7*7*512的特征图,下一层全连接连向4096个神经元,这个过程可以看做有4096个7*7*512的卷积核和7*7*512的特征图进行卷积操作,最终得到1*1*4096的特征图,等价与全连接得到4096个神经元. 全连接层和全连接层相连,AlexNet的再下一层依然是4096个神经元,即4096个神经元和4096个神经元全连接,由(1)我们得到了1*

caffe怎么把全连接层转成convolutional层

caffe中有把fc层转化为conv层的,其实怎么看参数都是不变的,对alex模型来说,第一个fc层的参数是4096X9216,而conv的维度是4096x256x6x6,因此参数个数是不变的,只是需要把fc的参数存储方法改变成conv 的. 在caffe的官方网站:http://nbviewer.ipython.org/github/BVLC/caffe/blob/master/examples/net_surgery.ipynb 有说明怎么转换.首先将原模型加载进来fc_param,然后把全

Fully Connected Layer:全连接层

1. 全连接层:主要用于分类,把分布式特征映射到样本标记空间.全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来.全连接层中的权值矩阵Wi的每一行相当于一个分类模版,xi与Wi矩阵乘法,即可得到xi与每一个模板的匹配度,从中选取得分最高的匹配模板. 在 CNN 结构中,经多个卷积层和池化层后,连接着1个或1个以上的全连接层.全连接层中的每个神经元与其前一层的所有神经元进行全连接,全连接层可以整合卷积层或者池化层中具有类别区分性的局部信息.为了提升 CNN 网络性能,全连

FCN用卷积层代替FC层原因(转)

分类任务 CNN对于常见的分类任务,基本是一个鲁棒且有效的方法.例如,做物体分类的话,入门级别的做法就是利用caffe提供的alexnet的模型,然后把输出的全连接层稍稍修改称为自己想要的类别数,然后再根据实际需要修改网络模型(通常是瘦身).下面记录几个point. 关于crop 一般在训练的时候会利用两个手段做data augmentation,分别是mirror和crop.其中,mirror没什么特别,但是crop有一些东西我们需要了解. 在训练的时候,crop操作会在大图上随机切小图,然后

【TensorFlow/简单网络】MNIST数据集-softmax、全连接神经网络,卷积神经网络模型

初学tensorflow,参考了以下几篇博客: soft模型 tensorflow构建全连接神经网络 tensorflow构建卷积神经网络 tensorflow构建卷积神经网络 tensorflow构建CNN[待学习] 全连接+各种优化[待学习] BN层[待学习] 先解释以下MNIST数据集,训练数据集有55,000 条,即X为55,000 * 784的矩阵,那么Y为55,000 * 10的矩阵,每个图片是28像素*28像素,带有标签,Y为该图片的真实数字,即标签,每个图片10个数字,1所在位置

【python实现卷积神经网络】卷积层Conv2D实现(带stride、padding)

关于卷积操作是如何进行的就不必多说了,结合代码一步一步来看卷积层是怎么实现的. 代码来源:https://github.com/eriklindernoren/ML-From-Scratch 先看一下其基本的组件函数,首先是determine_padding(filter_shape, output_shape="same"): def determine_padding(filter_shape, output_shape="same"): # No paddin

前馈全连接神经网络和函数逼近、时间序列预测、手写数字识别

https://www.cnblogs.com/conmajia/p/annt-feed-forward-fully-connected-neural-networks.html Andrew Kirillov 著Conmajia 译2019 年 1 月 12 日 原文发表于 CodeProject(2018 年 9 月 28 日). 中文版有小幅修改,已获作者本人授权. 本文介绍了如何使用 ANNT 神经网络库生成前馈全连接神经网络并应用到问题求解. 全文约 12,000 字,建议阅读时间 3

全连接理解2

(名称:全连接.意思就是输出层的神经元和输入层的每个神经元都连接) 在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化成一维的一个向量,这是怎么来的呢?目的何在呢? 举个例子: 最后的两列小圆球就是两个全连接层,在最后一层卷积结束后,进行了最后一次池化,输出了20个12*12的图像,然后通过了一个全连接层变成了1*100的向量. 这是怎么做到的呢,其实就是有20*100个12*12的卷积核卷积出来的,对于输入的每一张图,用了一个和图像一样大小的核卷积,这样整幅

全连接层 和 卷积层

卷积不过是一个稀疏的全连接:全连接也不过是一个画面那么大的卷积.本质上都可以理解为矩阵乘法(卷积可以参考托普利兹矩阵和块循环矩阵),相比起来卷积这种形式可以很好捕捉图像这种有空间相关性输入的特征. 本身conv和fc两者在设计好conv大小的情况下就是等价的, 没有什么取代不取代的. 基本上可以理解全conv就是拿一个小点的fc不停的在图片不同位置上跑, 当然, 有层数的情况下不严格一样, 但是差不了多少. fc不愿意用是因为锁死分辨率, 而且容易造成模型参数太多, 性能上受限制. 但是fc可以