201711学习笔记

20171114

转做语义分割了,第一个任务,测试PSPnet。首先,在caffe下搭建PSPnet。。。

  • pyramid scene parsing network (PSPNet)

一篇介绍文章:http://blog.csdn.net/tianrolin/article/details/71246472

PSPnet在caffe下的搭建

 可以用CUDA8,但必须使用cuDNN v4,由于之前安装的是cuDNN v5.1,须做替换,否则不能使用。

git clone https://github.com/hszhao/PSPNet.git

cd $PSPNET_ROOT
cp Makefile.config.example Makefile.config
gedit Makefile.config
make -j8 && make pycaffe

按照安装caffe的过程,修改Makefile.config文件即可。

将cuDNN v5.1替换为v4

PSPnet要求cuDNNv4,安装v4版本的cudnn
在官网下载v4版本的压缩包,解压
cd进入cuDNNv4解压之后的include目录,在命令行进行如下操作:
复制头文件: sudo cp cudnn.h /usr/local/cuda/include/
再cd进入lib64目录下的动态文件进行复制和链接:

sudo cp lib* /usr/local/cuda/lib64/          //复制动态链接库
cd /usr/local/cuda/lib64/                    //删除原有动态文件           
sudo rm -rf libcudnn.so libcudnn.so.5 `
sudo ln -s libcudnn.so.4.0.7 libcudnn.so.4      //生成软链接 
sudo ln -s libcudnn.so.4 libcudnn.so            //生成软链接  

若出现以下错误:

ln: 无法创建符号链接’libcudnn.so’: 文件已存在

使用命令:

sudo ln -sf libcudnn.so.4.0.7 libcudnn.so.4
sudo ln -sf libcudnn.so.4 libcudnn.so

运行 make -j4
遇到了关于matio的错误,需要安装matio

安装matio

下载matio(https://sourceforge.net/projects/matio/files/matio/1.5.2/)
tar zxf matio-1.5.2.tar.gz
cd matio-1.5.2
./configure
make
make check

make install 报错如下:

Making install in src
make[1]: Entering directory ‘/home/mengzhen/matio-1.5.2/src’
make[2]: Entering directory ‘/home/mengzhen/matio-1.5.2/src’
test -z “/usr/local/lib” || /bin/mkdir -p “/usr/local/lib”
/bin/bash ../libtool –mode=install /usr/bin/install -c libmatio.la ‘/usr/local/lib’
libtool: install: /usr/bin/install -c .libs/libmatio.so.2.0.2 /usr/local/lib/libmatio.so.2.0.2
/usr/bin/install: cannot create regular file ‘/usr/local/lib/libmatio.so.2.0.2’: Permission denied
Makefile:350: recipe for target ‘install-libLTLIBRARIES’ failed
make[2]: * [install-libLTLIBRARIES] Error 1
make[2]: Leaving directory ‘/home/mengzhen/matio-1.5.2/src’
Makefile:536: recipe for target ‘install-am’ failed
make[1]: * [install-am] Error 2
make[1]: Leaving directory ‘/home/mengzhen/matio-1.5.2/src’
Makefile:389: recipe for target ‘install-recursive’ failed
make: * [install-recursive] Error 1

原因:权限问题
solution: sudo make install

安装完matio后运行make -j4还是出了问题,如下:

./include/caffe/common.cuh(9): error: function “atomicAdd(double *, double)” has already been defined
1 error detected in the compilation of “/tmp/tmpxft_00007d59_00000000-5_domain_transform_layer.cpp4.ii”.
Makefile:588: recipe for target ‘.build_release/cuda/src/caffe/layers/domain_transform_layer.o’ failed
make: * [.build_release/cuda/src/caffe/layers/domain_transform_layer.o] Error 1
make: * 正在等待未完成的任务….
nvcc warning : The ‘compute_20’, ‘sm_20’, and ‘sm_21’ architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
nvcc warning : The ‘compute_20’, ‘sm_20’, and ‘sm_21’ architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
nvcc warning : The ‘compute_20’, ‘sm_20’, and ‘sm_21’ architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).

这是由于CUDA 8.0提供了在以前的CUDA工具包中不存在的double量的atomicAdd定义。 我们需要对有问题的源代码进行修改,使其与CUDA8兼容。修改内容:
文件:/PSPNet/include/caffe/common.cuh
原代码:

// Copyright 2014 George Papandreou
#ifndef CAFFE_COMMON_CUH_
#define CAFFE_COMMON_CUH_

#include <cuda.h>

// CUDA: atomicAdd is not defined for doubles
static __inline__ __device__ double atomicAdd(double *address, double val) {
  unsigned long long int* address_as_ull = (unsigned long long int*)address;
  unsigned long long int old = *address_as_ull, assumed;
  if (val==0.0)
    return __longlong_as_double(old);
  do {
    assumed = old;
    old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val +__longlong_as_double(assumed)));
  } while (assumed != old);
  return __longlong_as_double(old);
}

#endif

修改为:

// Copyright 2014 George Papandreou

#ifndef CAFFE_COMMON_CUH_
#define CAFFE_COMMON_CUH_

#include <cuda.h>

#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600

#else
// CUDA: atomicAdd is not defined for doubles
static __inline__ __device__ double atomicAdd(double *address, double val) {
  unsigned long long int* address_as_ull = (unsigned long long int*)address;
  unsigned long long int old = *address_as_ull, assumed;
  if (val==0.0)
    return __longlong_as_double(old);
  do {
    assumed = old;
    old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val +__longlong_as_double(assumed)));
  } while (assumed != old);
  return __longlong_as_double(old);
}

#endif
#endif

再运行make -j4就没问题了。

20171115

在PSPnet上跑自己的数据集

本来想要跑自己的数据集,但是发现作者放出来的代码是在matlab下实现的,要在ubuntu下安装matlab了。

版本:matlab2017a
解压后的文件夹中有三个文件,两个iso,一个rar。
rar是破解用的,两个iso才是安装用的。

安装步骤:
新建挂在文件夹:mkdir /media/matlab
将两个iso文件都挂载在这个文件夹下,在iso文件目录下运行命令行:

sudo mount -o loop R2017a_glnxa64_dvd1.iso /media/matlab
sudo mount -o loop R2017a_glnxa64_dvd2.iso /media/matlab

/目录下运行:sudo ./media/matlab/install
选择“使用文件安装密钥(不需要Internet连接)”

安装完后破解:
解压用于破解的rar文件,将../MATLAB 2017a linux/Matlab 2017a Linux64 Crack/R2017a/bin/glnxa64/下的libmwservices.so文件复制到安装的matlab文件夹中,
../MATLAB 2017a linux/Matlab 2017a Linux64 Crack/R2017a/bin/glnxa64/下运行命令行:
sudo cp libmwservices.so /usr/local/MATLAB/R2017a/bin/glnxa64/

参考这里吧,写的挺详细,不想码了。。。http://www.jianshu.com/p/60038ffa8870

20171116

gcc降级,现在用的是5.4,需要降到4.9
找到了一个非常友好的方法降级:

sudo apt-get install gcc-4.9
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 100
sudo apt-get install g++-4.9
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 100

可以用gcc --version来查看当前版本

发现降版本之后很多之前编译过的文件都出问题了,这是个大坑,尽量不要降gcc的版本。

跳出caffe,进tf的坑。

贴一张不同版本tf需要的环境版本:
这里写图片描述

20171117

想在PSPNet上跑VOC,可是1060的显存并不够,这要怎么破呀。
resnet101模型能跑,但是数据集好像有问题,读着读着会没有数据,导致error,使程序停下来。
solution:应该使用voc2012中的SegmentationClass文件夹中的图片数据作为输入。
修改过后可以跑了。
tensorflow上的PSPNet,github:https://github.com/hellochick/PSPNet-tensorflow
作者是在cityScapes数据集上测试的代码,准确率是77.23%,PSPNet论文中的准确率是78.6%。
我目前有的数据集是VOC2012,PSPNet论文中有对VOC2012数据集的测试结果,mIoU为82.6%。

测试VOC2012数据集
代码需要修改的部分:
1.tools.py中的label_colours
2.train.py中的DATA_DIRECTORYIMG_MEANNUM_CLASSES
3.将loader = tf.train.Saver(var_list=restore_var)
改为loader = tf.train.Saver(var_list=conv_trainable)
这是因为下载到的checkpoint模型文件是在cityScapes数据集中训练出来的,cityScapes数据集的类别是19类,而VOC2012是21类,会在第一次读入模型数据是出错,所以选择不读入最后一层模型数据,使其随机生成。
4.显存不够,将输入图片尺寸改小。
原工程中的图片输入尺寸INPUT_SIZE = '713,713',我将其改为INPUT_SIZE = '512,512'
还需修改model.py中的

conv5_3 = self.layers['conv5_3/relu']
        shape = tf.shape(conv5_3)[1:3]

        (self.feed('conv5_3/relu')
             .avg_pool(64, 64, 64, 64, name='conv5_3_pool1') 
             .conv(1, 1, 512, 1, 1, biased=False, relu=False, name='conv5_3_pool1_conv')
             .batch_normalization(relu=True, name='conv5_3_pool1_conv_bn')
             .resize_bilinear(shape, name='conv5_3_pool1_interp'))

        (self.feed('conv5_3/relu')
             .avg_pool(48, 48, 48, 48, name='conv5_3_pool2')
             .conv(1, 1, 512, 1, 1, biased=False, relu=False, name='conv5_3_pool2_conv')
             .batch_normalization(relu=True, name='conv5_3_pool2_conv_bn')
             .resize_bilinear(shape, name='conv5_3_pool2_interp'))

        (self.feed('conv5_3/relu')
             .avg_pool(24, 24, 24, 24, name='conv5_3_pool3')
             .conv(1, 1, 512, 1, 1, biased=False, relu=False, name='conv5_3_pool3_conv')
             .batch_normalization(relu=True, name='conv5_3_pool3_conv_bn')
             .resize_bilinear(shape, name='conv5_3_pool3_interp'))

        (self.feed('conv5_3/relu')
             .avg_pool(12, 12, 12, 12, name='conv5_3_pool6')
             .conv(1, 1, 512, 1, 1, biased=False, relu=False, name='conv5_3_pool6_conv')
             .batch_normalization(relu=True, name='conv5_3_pool6_conv_bn')
             .resize_bilinear(shape, name='conv5_3_pool6_interp'))

修改上面代码中conv5_3avg_pool的值,一共需要修改四处,从上向下分别记为1,2,3,4。
第一处的值为INPUT_SIZE的1/8,第二处的值为第一处值的3/4,第三处为第二处的一半,第四处为第三处的一半。

20171121

时间过得好快呀。写点PSPNet的理论知识吧。
给定输入图片,采用 dilated 化的预训练的 ResNet 模型提取 feature map,得到的 feature map 的尺寸是输入图片的 1/8,如 Figure3(b);
- 采用 pyramid pooling module 对提取的 feature map 进行处理,以收集上下文信息;
- 4-level pyramid module 采用的 pooling kernel 分别覆盖了图片的整个区域、半个区域以及更小的区域,并进行特征融合.
- 采用一个卷积层输出最终的预测结果,如 Figure3(d).
这里写图片描述

PSPNet 特点:
- 能够有效的得到像素级场景标注的全局上下文信息, pyramid pooling module 集合不同 levels 的信息,比 global pooling 具有更好的特征表示能力了;
- 计算代价与 dilated FCN 网络对比,并未增加;
- End-to-end,同时对 global pyramid pooling module 和 local FCN feature 进行优化学习;
- 监督 Loss,如 Figure4.
这里写图片描述

20171123

PSPNet运行结果有问题,在训练的时候loss下降不到0.3以下。
用训练的模型测试,mIoU的值:
Finish 0/30
step 0 mIoU: 0.047619048506
Finish 10/30
step 10 mIoU: 0.0443398989737
Finish 20/30
step 20 mIoU: 0.0457745529711
step 29 mIoU: 0.0450941286981
和论文里面的值相比,太小了。

20171129
看到一个解决显存有限的方法,但是这是caffe上的。

如果我们的显卡比较渣,就2G,无法提高Batch_size,有什么办法挽救一下精度:
    当batch_size无法提高的时候,可以把solver里面的iter_size调大一些,因为caffe在每个随机梯度下降步骤中通过iter_size*batch_size实现累加梯度。所以增加iter_size也可以得到更稳定的梯度。

猜你喜欢

转载自blog.csdn.net/sinat_26871259/article/details/78534618