【问题标题】:Image classification in Caffe always returns same classCaffe 中的图像分类总是返回相同的类别
【发布时间】:2016-08-23 09:22:53
【问题描述】:

我对 caffe 中的图像分类有疑问。我使用 imagenet 模型(来自 caffe 教程)对我创建的数据进行分类,但我总是得到相同的分类结果(相同的类,即类 3)。 我就是这样进行的:

我使用 caffe for windows 和 Python 作为界面

(1) 我收集数据。我的样本图像(训练和测试)是大小为 5x5x3 (RGB) uint8 的图像,因此其像素值范围为 0-255。
(2) 我将它们调整为 imagenet 所需的大小:256x256x3。因此我在matlab中使用resize函数(最近邻插值)。
(3) 我创建了一个 LevelDB 和 image_mean。
(4) 训练我的网络(3000 次迭代)。我在 imagenet 定义中更改的唯一参数是平均图像和 LevelDB 的路径。我得到的结果:

I0428 12:38:04.350100  3236 solver.cpp:245]     Train net output #0: loss = 1.91102 (* 1 = 1.91102 loss)
I0428 12:38:04.350100  3236 sgd_solver.cpp:106] Iteration 2900, lr = 0.0001
I0428 12:38:30.353361  3236 solver.cpp:229] Iteration 2920, loss = 2.18008
I0428 12:38:30.353361  3236 solver.cpp:245]     Train net output #0: loss = 2.18008 (* 1 = 2.18008 loss)
I0428 12:38:30.353361  3236 sgd_solver.cpp:106] Iteration 2920, lr = 0.0001
I0428 12:38:56.351630  3236 solver.cpp:229] Iteration 2940, loss = 1.90925
I0428 12:38:56.351630  3236 solver.cpp:245]     Train net output #0: loss = 1.90925 (* 1 = 1.90925 loss)
I0428 12:38:56.351630  3236 sgd_solver.cpp:106] Iteration 2940, lr = 0.0001
I0428 12:39:22.341891  3236 solver.cpp:229] Iteration 2960, loss = 1.98917
I0428 12:39:22.341891  3236 solver.cpp:245]     Train net output #0: loss = 1.98917 (* 1 = 1.98917 loss)
I0428 12:39:22.341891  3236 sgd_solver.cpp:106] Iteration 2960, lr = 0.0001
I0428 12:39:48.334151  3236 solver.cpp:229] Iteration 2980, loss = 2.45919
I0428 12:39:48.334151  3236 solver.cpp:245]     Train net output #0: loss = 2.45919 (* 1 = 2.45919 loss)
I0428 12:39:48.334151  3236 sgd_solver.cpp:106] Iteration 2980, lr = 0.0001
I0428 12:40:13.040398  3236 solver.cpp:456] Snapshotting to binary proto file Z:/DeepLearning/S1S2/Stockholm/models_iter_3000.caffemodel
I0428 12:40:15.080418  3236 sgd_solver.cpp:273] Snapshotting solver state to binary proto file Z:/DeepLearning/S1S2/Stockholm/models_iter_3000.solverstate
I0428 12:40:15.820426  3236 solver.cpp:318] Iteration 3000, loss = 2.08741
I0428 12:40:15.820426  3236 solver.cpp:338] Iteration 3000, Testing net (#0)
I0428 12:41:50.398375  3236 solver.cpp:406]     Test net output #0: accuracy = 0.11914
I0428 12:41:50.398375  3236 solver.cpp:406]     Test net output #1: loss = 2.71476 (* 1 = 2.71476 loss)
I0428 12:41:50.398375  3236 solver.cpp:323] Optimization Done.
I0428 12:41:50.398375  3236 caffe.cpp:222] Optimization Done.

(5) 我在 Python 中运行以下代码来对单个图像进行分类:

# set up Python environment: numpy for numerical routines, and matplotlib for plotting
import numpy as np
import matplotlib.pyplot as plt
# display plots in this notebook


# set display defaults
plt.rcParams['figure.figsize'] = (10, 10)        # large images
plt.rcParams['image.interpolation'] = 'nearest'  # don't interpolate: show square pixels
plt.rcParams['image.cmap'] = 'gray'  # use grayscale output rather than a (potentially misleading) color heatmap

# The caffe module needs to be on the Python path;
#  we'll add it here explicitly.
import sys
caffe_root = '../'  # this file should be run from {caffe_root}/examples (otherwise change this line)
sys.path.insert(0, caffe_root + 'python')

import caffe
# If you get "No module named _caffe", either you have not built pycaffe or you have the wrong path.


caffe.set_mode_cpu()

model_def = 'C:/Caffe/caffe-windows-master/models/bvlc_reference_caffenet/deploy.prototxt'
model_weights = 'Z:/DeepLearning/S1S2/Stockholm/models_iter_3000.caffemodel'

net = caffe.Net(model_def,      # defines the structure of the model
                model_weights,  # contains the trained weights
                caffe.TEST)     # use test mode (e.g., don't perform dropout)

#load mean image file and convert it to a .npy file--------------------------------
blob = caffe.proto.caffe_pb2.BlobProto()
data = open('Z:/DeepLearning/S1S2/Stockholm/S1S2train256.binaryproto',"rb").read()
blob.ParseFromString(data)
nparray = caffe.io.blobproto_to_array(blob)
f = file('Z:/DeepLearning/PythonCalssification/imgmean.npy',"wb")
np.save(f,nparray)

f.close()


# load the mean ImageNet image (as distributed with Caffe) for subtraction
mu1 = np.load('Z:/DeepLearning/PythonCalssification/imgmean.npy')
mu1 = mu1.squeeze()
mu = mu1.mean(1).mean(1)  # average over pixels to obtain the mean (BGR) pixel values
print 'mean-subtracted values:', zip('BGR', mu)
print 'mean shape: ',mu1.shape
print 'data shape: ',net.blobs['data'].data.shape

# create transformer for the input called 'data'
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})

# set the size of the input (we can skip this if we're happy

transformer.set_transpose('data', (2,0,1))  # move image channels to outermost dimension
transformer.set_mean('data', mu)            # subtract the dataset-mean value in each channel
transformer.set_raw_scale('data', 255)      # rescale from [0, 1] to [0, 255]
transformer.set_channel_swap('data', (2,1,0))  # swap channels from RGB to BGR

# set the size of the input (we can skip this if we're happy
#  with the default; we can also change it later, e.g., for different batch sizes)
net.blobs['data'].reshape(50,        # batch size
                          3,         # 3-channel (BGR) images
                          227, 227)  # image size is 227x227

#load image
image = caffe.io.load_image('Z:/DeepLearning/PythonCalssification/380.tiff')
transformed_image = transformer.preprocess('data', image)
#plt.imshow(image)

# copy the image data into the memory allocated for the net
net.blobs['data'].data[...] = transformed_image

### perform classification
output = net.forward()

output_prob = output['prob'][0]  # the output probability vector for the first image in the batch

print 'predicted class is:', output_prob.argmax()

我使用哪个输入图像并不重要,我总是得到“3”类作为分类结果。这是我训练/分类的示例图像:

如果有人知道出了什么问题,我会很高兴?提前致谢!

【问题讨论】:

  • 您使用了多少数据?每个类有多少个类和示例?

标签: python image-processing deep-learning caffe pycaffe


【解决方案1】:

如果你总是得到相同的类,这意味着神经网络没有经过适当的训练。

  • 确保训练集是平衡的。当一个分类器总是预测同一个类时,通常是因为一个类被其他类过度表示。例如,假设您有两个类,第一个由 95 个实例表示,第二个由 5 个实例表示。如果分类器将所有内容分类为属于第一个类,那么他的正确率已经达到 95%。
  • 很明显,您应该对输入 image / 255.0 - 0.5 进行归一化处理,它将使输入居中并减小标准差。
  • 之后,确保训练集中的数据至少是 NN 中权重的 4 倍。
  • 最后但并非最不重要的一点是,确保训练集正确打乱。

【讨论】:

  • 我会尝试一步一步地完成你的建议:1)我有8节课。它们由以下样本大小表示: 1 类:918 类 2:897 类 3:922 类 4:799 类 5:69 类 6:277 类 7:718 类 8:691
  • 2) 据我了解,Imagenet 需要使用图像/像素均值的图像归一化。因此,在上面的 Python 代码中执行以下步骤:transformer.set_transpose('data', (2,0,1)) # 将图像通道移动到最外层维度 transform.set_mean('data', mu) # 减去数据集均值每个通道中的值 transformer.set_raw_scale('data', 255) # 从 [0, 1] 重新缩放到 [0, 255] transformer.set_channel_swap('data', (2,1,0)) # 将通道从 RGB 交换到BGR。
  • 这一步减去图像均值,将图像缩放到0-255,切换通道,因为它们以相反的顺序加载,最后进行转置操作(我是虽然不是 100% 确定为什么需要这样做)
  • 3) 我有 5291 个训练样本和 1351 个验证样本。我想这就够了吗? 4)我使用caffenet模型(基于imagenet)。我没有看到包含洗牌。我只是假设模型定义可以满足我的目的。洗牌的目的是什么?
  • 如果您已经在扩充数据,那么添加训练图像集的旋转和缩放变体可能会很方便。此过程将使其获得旋转和尺度不变性,使其在分类过程中更加稳健。
猜你喜欢
  • 2015-11-21
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 2021-09-19
  • 2020-02-04
  • 1970-01-01
  • 2017-03-25
  • 2014-05-01
相关资源
最近更新 更多