第一篇文件介绍了caffe 安装编译事宜
https://blog.youkuaiyun.com/haohaixingyun/article/details/88177725
第二篇文章介绍了在编译后的caffe中构建pycaffe 的过程
https://blog.youkuaiyun.com/haohaixingyun/article/details/88530430
第三篇是构建 提取caffe 的ip1特征 数据作为svm 训练的特征训练code
这三篇文字层层递进 缺一不可 ,尤其是本篇 更需要仔细研读 ,好好加注解 ,愿你有情且沧桑
# -*- coding: utf-8 -*
'''
Created on March 02, 2019
@author: Ethan
Tips
https://github.com/initialneil/caffe/tree/windows/examples/cifar10
http://www.cs.toronto.edu/~kriz/cifar.html
'''
import sys
#from tensorflow.contrib.layers.python.layers.utils import constant_value
from sklearn.metrics.classification import accuracy_score
CAFFE_ROOT= 'D:/applications/anaconda2/Lib/site-packages/caffe_w'
sys.path.insert(0, CAFFE_ROOT + 'python')
import caffe
import numpy as np
from matplotlib import pyplot as plt # need to update matplotlib
import matplotlib.image as mpimg
import os
import pickle
from sklearn.svm import LinearSVC
reload(sys)
sys.setdefaultencoding('utf8')
CIFAR_CAFFE_NET_FILE = os.path.join(CAFFE_ROOT,"examples/cifar10/cifar10_full.prototxt")
CIFAR_CAFFE_TRAIN_MODEL = os.path.join(CAFFE_ROOT, "examples/cifar10/cifar10_full_iter_60000.caffemodel")
CIFAR_PY_DATA_PATH = os.path.join(CAFFE_ROOT, "data/cifar-10-batches-py") # can download the file from the above net
CIFAR_BIN_MEAN = os.path.join(CAFFE_ROOT, "examples/cifar10/mean.binaryproto")
CIFAR_TRAIN_FILES = ["data_batch_1","data_batch_2","data_batch_3","data_batch_4","data_batch_5"]
CIFAR_TEST_FILE = "test_batch"
def unpickle_cifar_10(filename):
with open(filename, 'rb') as fo:
dict = pickle.load(fo) # pickle.load(fo, encoding='bytes')
return dict[b'data'], dict[b'labels']
def init():
plt.rcParams['figure.figsize'] = (8,8) # figsize 设置图形的大小,a 为图形的宽, b 为图形的高,单位为英寸 dpi 为设置图形每英寸的点数
plt.rcParams['image.interpolation'] = 'nearest' # 最近邻差值: 像素为正方形
plt.rcParams['image.cmap'] = 'gray' # 使用灰度输出而不是彩色输出
caffe.set_mode_cpu()
def load_net():
net = caffe.Net(CIFAR_CAFFE_NET_FILE, CIFAR_CAFFE_TRAIN_MODEL, caffe.TEST)
# 显示各个层的数据类型
print("output:[batch-sizes, channels, height, width]")
for layer_name, blob in net.blobs.items():
print("output:\t", layer_name, "\t", blob.data.shape)
filters = net.params['conv1'][0].data
vis_square(filters.transpose(0, 2, 3, 1))
# 显示各层的参数层及其类型:weight
print("weight:[out-channels, in-channels, filter-height, fiter-width]")
for name, data in net.params.items():
print("weigth:\t", name, "\t", data[0].data.shape, "\tdiff:\t", data[0].diff.shape) #[0]:表示weights,[1]:表示biases。
print("bias:[out-channels]")
for name, data in net.params.items():
print("bias\t", name, "\t", data[1].data.shape, "\tdiff\t", data[1].diff.shape) #[0]:表示weights,[1]:表示biases。
feat = net.blobs['conv1'].data[0, :36]
vis_square(feat)
return net
def load_mean(binMean):
'''
1.使用Caffe的C++接口进行操作时,需要的图像均值文件是pb格式,例如常见的均值文件名为mean.binaryproto;
但在使用python接口进行操作时,
需要的图像均值文件是numpy格式,例如mean.npy。
所以在跨语言进行操作时,需要将mean.binaryproto转换成mean.npy
2.图片减去均值后,再进行训练和测试,会提高速度和精度。因此,一般在各种模型中都会有这个操作。
那么这个均值怎么来的呢,实际上就是计算所有训练样本的平均值,计算出来后,保存为一个均值文件,
在以后的测试中,就可以直接使用这个均值来相减,而不需要对测试图片重新计算。
'''
blob = caffe.proto.caffe_pb2.BlobProto()
bin_Mean = open(binMean, 'rb').read()
blob.ParseFromString(bin_Mean)
arr = np.array(caffe.io.blobproto_to_array(blob))
return arr[0]
# 对输入数据进行变换 ,文字描述跟程序code 不符
'''
设置输入预处理(我们将用Caffe’s caffe.io.Transformer来进行预处理。
不过该步骤与caffe的其它模块是相互独立的,所以任何预处理代码应该都是可行的)。
我们使用的CaffeNet模型默认的输入图像格式是BGR格式的,
其像素值位于[0,255]之间,同时每个像素值都减去了ImageNet图像的平均值。
除此之外,通道的维数等于第一维(outermost)的大小。
另外,因为matplotlib加载的图像的值位于[0,1]之间,并且格式是RGB格式,通道的维数等于innermost的维数,所以我们需要做一些变换
'''
def init_transformer(net): # what's this ?
#npyMean = os.path.join(CAFFE_ROOT, "examples/cifar10/mean.npy")
mean = load_mean(CIFAR_BIN_MEAN)
transformer = caffe.io.Transformer({'data':net.blobs['data'].data.shape})
transformer.set_transpose('data',(0,1,2)) #将图像的通道数设置为outermost的维数
# transformer.set_transpose('data',(2,0,1))
transformer.set_mean('data', mean) #对于每个通道,都减去BGR的均值像素值
transformer.set_raw_scale('data', 1) #将像素值从[0,255]变换到[0,1]之间
#transformer.set_input_scale('data', 255)
transformer.set_channel_swap('data',(0,1,2)) #交换通道,从RGB变换到BGR
# transformer.set_channel_swap('data',(2,1,0))
return transformer
def extract_ip1(net, transformer, in_img_data_file, out_ip1_file, cmatrix):
total = 0
image_num = 0
batch_num = 1000
imgs, labels = unpickle_cifar_10(in_img_data_file) # return dict[b'data'], dict[b'labels']
batch_imgs = []
batch_labels = []
correct_num = 0.0
with open(out_ip1_file, "w+") as fp:
for img, label in zip(imgs, labels):
img = img.reshape(3,32,32)
#img = img.transpose(1,2,0)
batch_imgs.append(img)
batch_labels.append(label)
image_num += 1
if image_num == batch_num:
total += image_num
predictions = fetch_and_save_fetch(net, transformer, batch_imgs, batch_labels,fp, cmatrix)
print("batch:%d: correct_num:%d" % (total, predictions))
correct_num += predictions
image_num = 0
batch_labels=[]
batch_imgs=[]
if image_num:
total += image_num
predictions = fetch_and_save_fetch(net, transformer, batch_imgs, batch_labels,fp, cmatrix)
print("batch:%d: correct_num:%d" % (total, predictions))
correct_num += predictions
return total, correct_num
def is_success(results, label, cmatrix):
max_label = label
max_value = results[label]
for index, value in enumerate(results):
if index != label:
if value > max_value:
max_label = index
max_value = value
cmatrix[label][max_label] +=1
if label != max_label : return 0
return 1
def fetch_and_save_fetch(net, transformer, batch_imgs, batch_labels,fp, cmatrix):
image_num = len(batch_imgs)
batch_img = np.array(batch_imgs)
correct_num = 0.0
for img, label in zip(batch_img, batch_labels):
#1transformed_image = transformer.preprocess('data', image) 图像预处理 ,# 2将图像数据拷贝到为net分配的内存中
net.blobs['data'].data[...]=transformer.preprocess('data',img)
result = net.forward() #### 执行分类
correct_num += is_success(result['prob'][0],label, cmatrix) ##batch中第一张图像的概率值 ,不过这个地方也就只有一张图片
feature = net.blobs['ip1'].data[0]
fp.write(str(label)+'\t')
is_first = True
for i in feature:
if is_first:
fp.write(str(i))
is_first = False
else:
fp.write(',' + str(i))
fp.write("\n")
return correct_num
def create_caffe_img_feature():
init()
net = load_net()
transformer = init_transformer(net)
all = 0.0;
all_correct = 0.0
train_cmatrix = np.zeros((10,10), np.int32)
test_cmatrix = np.zeros((10,10), np.int32)
for file in CIFAR_TRAIN_FILES:
in_file = os.path.join(CIFAR_PY_DATA_PATH, file)
out_file = in_file + ".feature"
total, correct = extract_ip1(net, transformer, in_file, out_file, train_cmatrix)
all += total
all_correct += correct
print("Train precision:%.4f" % (all_correct/all))
#test file
in_file = os.path.join(CIFAR_PY_DATA_PATH, CIFAR_TEST_FILE)
out_file = in_file + ".feature"
all, all_correct = extract_ip1(net, transformer, in_file, out_file, test_cmatrix)
print("Test precision:%.4f" % (all_correct/all))
print("Train confusion matrix:")
print(np.array2string(train_cmatrix, edgeitems=10, separator="\t"))
print("Test confusion matrix:")
print(np.array2string(test_cmatrix, edgeitems=10, separator="\t"))
def load_feature(labels, feas, filename):
with open(filename, 'r') as fp:
for line in fp:
linearr = line.strip().split('\t')
if len(linearr) != 2: continue
labels.append(int(linearr[0]))
linearr2 = linearr[1].split(',')
row = []
for i in linearr2:
row.append(float(i))
feas.append(row)
def lineSvmTrain():
train_labels = []
train_feas = []
test_labels = []
test_feas = []
#train file
for file in CIFAR_TRAIN_FILES:
in_file = os.path.join(CIFAR_PY_DATA_PATH, file+".feature")
load_feature(train_labels, train_feas, in_file)
print train_labels
#test file
in_file = os.path.join(CIFAR_PY_DATA_PATH, CIFAR_TEST_FILE + ".feature")
load_feature(test_labels, test_feas, in_file)
print test_labels
clf = LinearSVC(random_state=1, C=1, tol=1e-5,max_iter=100000)
clf.fit(np.array(train_feas), train_labels)
result = clf.predict(np.array(test_feas))
test_cmatrix = np.zeros((10,10), np.int32)
for label, predict_label in zip(test_labels, result):
test_cmatrix[label][predict_label] += 1
print("LinearSVC Test confusion matrix:")
print(np.array2string(test_cmatrix, edgeitems=10, separator="\t"))
acc = accuracy_score(test_labels, result)
print("LinearSvm Precision:%.4f" % (acc))
def vis_square(data):
# 正则化数据
data = (data - data.min()) / (data.max() - data.min())
# 将滤波器的核转变为正方形
n = int(np.ceil(np.sqrt(data.shape[0])))
padding = (((0, n ** 2 - data.shape[0]),
(0, 1), (0, 1)) # 在相邻的滤波器之间加入空白
+ ((0, 0),) * (data.ndim - 3)) # 不扩展最后一维
data = np.pad(data, padding, mode='constant', constant_values=1) # 扩展一个像素(白色)
# tile the filters into an image
data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])
plt.imshow(data)
plt.axis('off')
plt.show()
def main():
create_caffe_img_feature()
#lineSvmTrain()
if __name__ == "main":
print("Begin running....")
main()
print("End running....")
main()
'''
D:\applications\anaconda2\lib\site-packages\sklearn\svm\base.py:922: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.
"the number of iterations.", ConvergenceWarning)
add the parm : max_iter=100000 in the svm function
'''