[当前最佳0.00000 @ypw/ 0.20631 @LeeJuly30] Kaggle ImageNet Dogs


#106

怎么忽然有种公布标准答案的感觉。。。


#107


densenet161 fine tuning, DA全开. 锁定net.features, 其他参数:
batch_size=32
num_epochs = 20
learning_rate = 0.01
weight_decay = 5e-4
lr_period = 5
lr_decay = 0.1
后面再试下@ypw 的方法.


#108

emmm。。大家可以根据这个表对一下自己的迁移学习、fine-tune 是否正确,值得关注的几个地方包括:

  • 是否 resize 正确的大小
  • 是否进行了正确的预处理
  • 是否锁定了卷积层权重
  • 是否设置了合理的模型结构,包括全连接层、Dropout 层等
  • 是否设置了合理的学习率、训练代数

比如 ResNet 要求 resize 成 (224, 224),而 Inception V3 要求 resize 成 (299, 299)。

虽然 ResNet 原论文进行的预处理是减 ImageNet 的均值,但是在 gluon 中,所有预训练模型的预处理都是先归一化,然后按 gluon 给的参数减均值并除以标准差,进行标准化操作,除此之外,图像需要是 RGB 顺序而不是 BGR。参考:model_zoo

参考代码如下:

# 定义一个 (N, C, H, W) 矩阵,(样本,通道,高度,宽度)
X = nd.zeros((n, 3, 224, 224))
mean = np.array([0.485, 0.456, 0.406])
std = np.array([0.229, 0.224, 0.225])

# 读图(从这里开始应该是在循环内)
img = cv2.imread('train/%s.jpg' % file_name)

# 转换 BGR 通道顺序为 RGB
img = cv2.resize(img, (224, 224))[:,:,::-1] 

# 归一化
img = img / 255.0

# 标准化
img = (img - mean)/std

# 转换轴顺序为 C, H, W
img = img.transpose((2, 0, 1))

# 复制到 ndarray 中
X[i] = nd.array(img)

#109

请教几个问题:

  1. 要把BGR转成RGB,是因为“pretrained net (比如ResNet)用的是RGB吗,而kaggle_dog用的是BGR”?
  2. 从哪里可以得知 “pretrained net (比如ResNet)用的是RGB吗,而kaggle_dog用的是BGR”?
  3. 没有看懂转换的代码
    //# 转换 BGR 通道顺序为 RGB
    img = cv2.resize(img, (224, 224))[:,:,::-1]
    操作cv2.resize(img, (224, 224))完成后是什么shape, 为啥接上[:,:,::-1] 就完成了通道转换?

谢谢啊


#110
  1. 转 RGB 是因为 OpenCV 默认的通道顺序是 BGR,不是 kaggle 提供了 BGR 的图片。kaggle 提供的数据是 jpg,本身就是正确的图片,读进来是 RGB 还是 BGR 取决于你用什么库,如果你用 scipy 的 misc.imread ,那就是 RGB 了。
  2. 后面给了链接,model_zoo,原文是这样写的,All pre-trained models expect input images normalized in the same way, i.e. mini-batches of 3-channel RGB images of shape (N x 3 x H x W)
  3. cv2.resize 是将宽度和高度进行 resize,输出的 shape 是(224, 224, 3),至于后面的 [:,:,::-1] 如果看不懂,你可以学习这两个知识,一个是 list 如何反转,一个是 numpy 矩阵如何切片,可以看这个链接:Python Numpy Tutorial,照着打一遍,基本上该会的就都会了。将图像转为 RGB 还有一种方法:cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#111

使用了Stanford dogs dataset:

代码:https://github.com/ypwhs/DogBreed_gluon


#112

可以不用opencv读数据,用mx.image.imread读进来的图片就是RGB的


#113


使用了 resnet152_v1做fine tuning,epoch 100,有些overfitting,再试试early stopping,结果应该会改善。


#114

又进步了这么多 真厉害!


#115

多谢多谢。
再问另外一个问题:image resize怎么实现的?比如把图片从400 * 288缩放到300 * 300,H压缩了、W拉伸了,就分出了俩子问题:(1)H压缩,仅仅是选取了一些pixel去丢弃吗,怎么选? (2)W拉伸,多出来的pixel怎么去填充?


#117

取决于你用什么插值方法,比如我是使用 OpenCV 来 resize 的,在 cv2.resize 里面传入不同的参数,可以有不同的效果。常用的插值方法有以下几种:

参数 解释
INTER_NEAREST 最近邻居插值
INTER_LINEAR 双线性插值
INTER_CUBIC 双三次插值
INTER_AREA 使用像素区域关系进行重采样。这可能是图像抽取的首选方法,因为它可以产生无莫尔效应的结果。但是当图像放大时,它与INTER_NEAREST方法类似。

如果是按 INTER_NEAREST 插值,放大时会出现马赛克效果,缩小时直线会出现锯齿效果。
而 INTER_LINEAR 则会进行线性插值,在缩小图像的时候效果还行,放大的时候就会有模糊的效果。
使用 INTER_CUBIC 放大图像时会插出更好的效果,但是运算量要大许多。

它们之间的比较可以看下图:

我没有指定插值方式,因此 cv2.resize 默认会使用 INTER_LINEAR 的方式来插值,多了的 pixel 直接丢弃,少了的按线性的方式插值。

参考链接:


#118

恭喜,又提高了不少啊 :grinning:


#119


将96X96变为224X224,效果提升很明显啊。


#120

96x96的时候精度大概是多少?


#121

未使用Stanford dogs dataset,仍然用resnet50_v2,固定前面层参数,把图像resize到224*224,增强全开。比上次提升了


#122

最好只到了1.8左右


#123

resnet18_v2 迁移学习,看 @ypw 培神的代码给了我一个启示,如果锁定前面的特征层,只训练后面的全链接层,那么可以先把所有的数据过一边前面的特征层,保存到本地,这样再训练就会节省很多时间和显存。还没有实测
使用rec文件好像还是卡IO


#124

没错,就是这个思路


#125

请问在尝试运行get_features_v3.ipynb时,每次到net = models.get_model(model_name, pretrained=True, ctx=ctx)这句代码就会出现The kernel appears to have died. It will restart automatically. 是因为gpu问题还是batchsize太大了呢?


#126

昨天也有人问到了类似的问题,初步分析是内存炸了,但是原因不明。你可以尝试更新 mxnet:

pip install -U --pre mxnet-cu80