Caffe - 激活特征值不一致 - GPU 模式

Posted

技术标签:

【中文标题】Caffe - 激活特征值不一致 - GPU 模式【英文标题】:Caffe - inconsistency in the activation feature values - GPU mode 【发布时间】:2015-10-08 06:55:12 【问题描述】:

您好,我在 Ubuntu 14.04 上使用 caffeCUDA 7.0 版(最新) cudnn 版本 2(最新) GPU:NVIDIA GT 730

首先在 caffe 中完成初始化,然后加载 imagenet 模型 (Alexnet)。我还使用 set_mode_gpu() 初始化 gpu 之后我拍照。我将此图像复制到 caffe 源 blob。然后我使用:net.forward(end='fc7') 对该图像执行前向传递 然后我提取了 4096 维的 fc7 输出。(fc7 层的激活特征)

我面临的问题是,当我多次运行相同的代码时,每次都会得到不同的结果。也就是说,在 GPU 模式下,每次激活特征对于同一张图像都是不同的。当我使用前向传递时,网络的功能应该是确定性的吧?所以我应该每次都得到相同的输出相同的图像。

另一方面,当我使用 set_mode_cpu() 在 cpu 上运行 caffe 时,一切正常,即我每次都得到相同的输出 使用的代码和获得的输出如下所示。我无法理解问题所在。问题是由于GPU四舍五入引起的吗?但是误差非常大。还是由于最新 CUDNN 版本的一些问题?还是完全是别的东西?

以下是代码

1) 导入库

from cStringIO import StringIO
import numpy as np
import scipy.ndimage as nd
import PIL.Image
from IPython.display import clear_output, Image, display
from google.protobuf import text_format
import scipy
import matplotlib.pyplot as plt
import caffe

2) 导入 Caffe 模型并定义实用函数

model_path = '../../../caffe/models/bvlc_alexnet/' 
net_fn   = model_path + 'deploy.prototxt'
param_fn = model_path + 'bvlc_reference_caffenet.caffemodel'

model = caffe.io.caffe_pb2.NetParameter()
text_format.Merge(open(net_fn).read(), model)
model.force_backward = True
open('tmp.prototxt', 'w').write(str(model))

net = caffe.Classifier('tmp.prototxt', param_fn,
                       mean = np.float32([104.0, 116.0, 122.0]), # ImageNet mean, training set dependent
                       channel_swap = (2,1,0),# the reference model has channels in BGR order instead of RGB
                      image_dims=(227, 227)) 

caffe.set_mode_gpu()
# caffe.set_mode_cpu()

# a couple of utility functions for converting to and from Caffe's input image layout
def preprocess(net, img):
    return np.float32(np.rollaxis(img, 2)[::-1]) - net.transformer.mean['data']
def deprocess(net, img):
    return np.dstack((img + net.transformer.mean['data'])[::-1])

3) 加载图像和设置常量

target_img = PIL.Image.open('alpha.jpg')
target_img = target_img.resize((227,227), PIL.Image.ANTIALIAS)
target_img=np.float32(target_img)
target_img=preprocess(net, target_img)

end='fc7'

4) 设置源图像并进行前向传递以获得fc7激活特征

src = net.blobs['data']
src.reshape(1,3,227,227) # resize the network's input image size
src.data[0] = target_img
dst = net.blobs[end]
net.forward(end=end)
target_data = dst.data[0]
print dst.data

以下是我多次运行上述代码时为“打印 dst.data”获得的输出

第一次执行代码时输出

[[-2.22313166 -1.66219997 -1.67641115 ..., -3.62765646 -2.78621101
  -5.06158161]]

第二次执行代码时的输出

[[ -82.72431946 -372.29296875 -160.5559845  ..., -367.49728394 -138.7151947
  -343.32080078]]

第三次执行代码时的输出

[[-10986.42578125 -10910.08105469 -10492.50390625 ...,  -8597.87011719
   -5846.95898438  -7881.21923828]]

第 4 次执行代码时输出

[[-137360.3125     -130303.53125    -102538.78125    ...,  -40479.59765625
    -5832.90869141   -1391.91259766]]

输出值不断变大,一段时间后又变小。我无法理解这个问题。

【问题讨论】:

【参考方案1】:

将您的网络切换到测试模式,以防止丢失的影响,这种影响是不确定的,并且是训练模式所必需的。

在初始化网络后立即添加以下行:

net.set_phase_test()

这样您将始终获得相同的结果。

发声

【讨论】:

以上是关于Caffe - 激活特征值不一致 - GPU 模式的主要内容,如果未能解决你的问题,请参考以下文章

Caffe框架GPU与MLU计算结果不一致请问如何调试?

基于Anaconda安装tensorflow-GPU和caffe-GPU

如何知道 CAFFE 代码是使用 GPU 还是 CUDA 代码运行?

为 caffe 构建 GPU docker 映像时出错:不支持的 gpu 架构“compute_60”

nvcc 致命:安装 cuda 9.1+caffe+openCV 3.4.0 时不支持 gpu 架构“compute_20”

1:Caffe安装教程:Ubuntu16.04(CPU)