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_DIRECTORY
、IMG_MEAN
、NUM_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_3
的avg_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也可以得到更稳定的梯度。