您好我在 Ubuntu 14.04 上使用 caffe , CUDA 7.0版(最新) cudnn version 2 (最新) GPU:NVIDIA GT 730
首先,我完成了初始化,然后加载了imagenet模型(Alexnet)。我还使用set_mode_gpu()
初始化gpu
之后我拍了一张照片。我将此图像复制到caffe源blob上。然后,我使用以下代码执行此图像的正向传递:net.forward(end='fc7')
然后我提取4096维fc7输出。(fc7层的激活特征)
我面临的问题是,当我多次运行相同的代码时,每次我获得不同的结果。也就是说,在GPU模式中,每次激活特征对于同一图像是不同的。当我使用正向传递时,网络的功能应该是确定性的吗?因此,我应该每次为同一图像获得相同的输出。
另一方面,当我使用set_mode_cpu()
在cpu上运行caffe时,一切都运行正常,即每次都得到相同的输出
使用的代码和获得的输出如下所示。我无法理解问题所在。问题是由于GPU四舍五入造成的吗?但错误非常大。或者是由于最新CUDNN版本的一些问题?或者它完全是另一回事?
以下是CODE
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
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])
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'
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
以下是我多次运行上述代码时为'print 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]]
第3次执行代码[[-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]]
输出值越来越大,经过一段时间再次变小。我无法理解这个问题。
答案 0 :(得分:0)
将您的网络切换到测试模式,以防止丢失的影响,这是训练模式所不具备的确定性。
初始化网络后立即添加以下行:
net.set_phase_test()
这样你就可以获得相同的结果。
Soner