一.Pyramid Feature Attention Network for Saliency detection论文的代码运行
代码:https://github.com/CaitinZhao/cvpr2019_Pyramid-Feature-Attention-Network-for-Saliency-detection
环境需求:TF-1.12 with all other dependencies being latest versions works well for me.
Tensorflow与Keras版本之间的兼容性
https://docs.floydhub.com/guides/environments/
tensorflow1.12+keras2.2.4
Tensorflow版本与cuDNN CUDA的版本配合
https://www.jianshu.com/p/464fefb5c5d8
当前系统环境是 CUDA 8.0 和 CUDNN 6.0
但Tensorflow1.12要求 CUDA 9.0 和 CUDNN 7.0
报错:ImportError: libcublas.so.9.0: cannot open shared object file: No such file or directory
所以要更换CUDA和CUDNN版本
1.卸载旧cuda
卸载原来的cuda8.0(注意:不需要卸载显卡驱动,不要给自己找麻烦):
sudo /usr/local/cuda-8.0/bin/uninstall_cuda_8.0.pl
卸载之后,会发现 /usr/local/cuda-8.0目录下任然有文件存在,这是cudnn文件,所以还需要将cuda-8.0文件删除干净:
sudo rm -rf /usr/local/cuda-8.0
2. 安装cuda9.0
在nvidia官网下载对应操作系统的CUDA安装包。
下载cuda9.0的安装文件 cuda_9.0.176_384.81_linux.run
执行如下命令:
接着按下面的步骤选择:
accept
n(不要安装driver)
y
y
y
安装完成。
3.修改环境变量
sudo gedit /etc/profile
将原有的
export PATH=/usr/local/cuda-8.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64$LD_LIBRARY_PATH
加注释
另外添加三行
export PATH=/usr/local/cuda-9.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64$LD_LIBRARY_PATH
export CUDA_HOME=/usr/local/cuda-9.0
更新环境变量
source ~/.bashrc
4.更换CUDNN版本
1.登录官方网址https://developer.nvidia.com/cuDNN
选择自己需要的版本进行下载,解压出一个名为cuda的文件夹,文件夹中有include和lib64两个文件夹
2.删除原来的cudnn
sudo rm -rf /usr/local/cuda/include/cudnn.h
sudo rm -rf /usr/local/cuda/lib64/libcudnn*
3.安装需要的cudnn.
按照我之前的博客重新安装cudnn即可。
以上部分内容FROM https://www.cnblogs.com/guweixin/p/11134677.html
继续运行代码
报错:ImportError: No module named 'cv2’
安装opencv
pip --default-timeout=1000 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
可以运行了~~~~
这篇论文的代码写的特别规整,所以希望好好读读,学习一下。
train.py
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
对GPU的调用进行设置:
# 按照PCI_BUS_ID顺序从0开始排列GPU设备
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
# 设置当前使用的GPU设备仅为0号设备 设备名称为'/gpu:0'
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
# 设置当前使用的GPU设备为0,1号两个设备,名称依次为'/gpu:0'、'/gpu:1'
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"
# 设置当前使用的GPU设备为1,0号两个设备,名称依次为'/gpu:0'、'/gpu:1'。表示优先使用1号设备,然后使用0号设备
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"
# 禁止使用GPU
os.envion["CUDA_VISIBLE_DEVICES"] = "-1"
#学习率调度器函数,参数是从0开始的epoch,返回一个新的学习率
def lr_scheduler(epoch):
drop = 0.5 #学习率每次变化为原先的1/2
epoch_drop = epochs/8. #希望学习率在所有的epochs里改变8次,即除以8次2,降256倍
lr = base_lr * math.pow(drop, math.floor((1+epoch)/epoch_drop))
print('lr: %f' % lr)
return lr
base_lr = 1e-2
epochs = 50
lr_decay = callbacks.LearningRateScheduler(schedule=lr_scheduler)
callbacks = [lr_decay,modelcheck,tb]
model.fit_generator(traingen, steps_per_epoch=steps_per_epoch,
epochs=epochs,verbose=1,callbacks=callbacks)
关于Keras学习率调整:
Keras提供两种学习率适应方法,可通过回调函数实现。
一种是依赖epoch来控制学习率,一种是依赖评价指标是否变化来控制学习率。
1.LearningRateScheduler(schedule)
依赖epoch来控制学习率
参数:
schedule:函数,该函数以epoch号为参数(从0算起的整数),返回一个新学习率(浮点数)。
靠epoch来控制学习率的改变。
这篇文章中写的这个lr_scheduler函数就非常好,可以拿来用。
#学习率调度器函数,参数是从0开始的epoch,返回一个新的学习率
def lr_scheduler(epoch):
drop = 0.5 #学习率每次变化为原先的1/2
epoch_drop = epochs/8.
#希望学习率在所有的epochs里改变8次,即除以8次2,降256倍。希望在50轮中完成8次降低学习率的操作,所以每隔50/8轮就要降低一次。
lr = base_lr * math.pow(drop, math.floor((1+epoch)/epoch_drop))
#math.pow(x,y):求x的y次方。
#math.floor(x):对x向下取整。
#上面这行的意思是:0~5轮中,lr=初始学习率×(0.5^0),6~11轮中,lr=初始学习率×(0.5^1),……最后,lr=初始学习率×(0.5^8)。
print('lr: %f' % lr)
return lr
设置好初始学习率base_lr ,总共训练的轮数epochs , 每次减小学习率想减小多少倍drop,想在训练中减小几次学习率epochs/8. (减小8次就除以8),其他的不需要改。
2.ReduceLROnPlateau(monitor=‘val_loss’, factor=0.1, patience=10, verbose=0, mode=‘auto’, epsilon=0.0001, cooldown=0, min_lr=0)
依赖评价指标是否变化来控制学习率。
当评价指标不在提升时,减少学习率。
当学习停滞时,减少2倍或10倍的学习率常常能获得较好的效果。该回调函数检测指标的情况,如果在patience个epoch中看不到模型性能提升,则减少学习率。
参数:
monitor:被监测的量
factor:每次减少学习率的因子,学习率将以lr = lr*factor的形式被减少
patience:当patience个epoch过去而模型性能不提升时,学习率减少的动作会被触发
mode:‘auto’,‘min’,‘max’之一,在min模式下,如果检测值触发学习率减少。在max模式下,当检测值不再上升则触发学习率减少。
epsilon:阈值,用来确定是否进入检测值的“平原区”
cooldown:学习率减少后,会经过cooldown个epoch才重新进行正常操作
min_lr:学习率的下限
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, mode='auto')
callbacks = [reduce_lr ,modelcheck,tb]
model.fit(train_x, train_y, batch_size=32, epochs=5, validation_split=0.1, callbacks=callbacks)
之前在我的代码里,用的是这种学习率改变方式,感觉不是特别好用,也有可能是我别的地方设置有问题。
如果用这种的话,一般设置monitor,factor,patience就可以了。
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Train model your dataset')
parser.add_argument('--train_file',default='train_pair.txt',help='your train file', type=str)
parser.add_argument('--model_weights',default='model/vgg16_no_top.h5',help='your model weights', type=str)
args = parser.parse_args()
train_path= args.train_file
'''
the from of 'train_pair.txt' is
img_path1 gt_path1\n
img_path2 gt_path2\n
'''
model_name = args.model_weights
print("train_file", train_path)
print("model_weights", model_name)
argparse模块
argparse是一个Python模块:命令行选项、参数和子命令解析器,可以让人轻松编写用户友好的命令行接口。程序定义它需要的参数,然后 argparse 将弄清如何从 sys.argv 解析出那些参数。 argparse 模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。
简单点来说,就是可以通过它让用户在命令行自定义一些参数。
使用它需要四步:
1.创建ArgumentParser 对象。
import argparse
parser = argparse.ArgumentParser(description='一些描述')
2.添加参数。
parser.add_argument('--train_file',default='train_pair.txt',help='your train file' , typr=str)
parser.add_argument('--参数名', default='默认值',help='提示文字',typr=参数类型)
3.解析参数。
args=parser.parse_args()
4.使用参数
train_path = args.train_file
定义一个优化器
1.SGD优化器
optimizer = optimizers.SGD(lr=base_lr, momentum=0.9, decay=0)
参数:
- 学习率
- 动量 momentum=0.9
参数更新动量,大或等于0的浮点数,我看所有网上博客的动量设置的都是0.9 - decay
float >= 0. 学习率每次更新的下降率
如果自己设置了学习率调整函数,则把它设成0
2.Adam优化器(参数推荐使用默认值)
optimizer = optimizers.Adam(lr=base_lr)
本质上是 RMSProp 与动量 momentum 的结合,通常是训练循环神经网络RNN的不错选择。
目前在显著性模型的训练中,只见过这两种优化器。
来源:CSDN
作者:馨宇要变身咯-
链接:https://blog.csdn.net/weixin_36697338/article/details/103500646