caffe cifar 图像识别的第三篇文字

本文详细介绍了Caffe的安装、编译及PyCaffe的构建过程,深入探讨了如何利用Caffe提取CIFAR-10数据集的ip1特征作为SVM训练的特征数据,包括数据预处理、模型加载、特征提取等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一篇文件介绍了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
'''

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值