theano-xnor-net代码注释5 cifar10_test.py

来源:互联网 发布:淘宝网安卓版下载 编辑:程序博客网 时间:2024/06/08 15:00
import sys, os, timeimport argparseimport lasagneimport numpy as npimport theanoimport theano.tensor as Timport cPickle, timeimport inf_layersfrom fxp_helper import convert_fxp_format, fixed_pointthis_dir = os.path.dirname(__file__)sys.path.insert(0, os.path.join(this_dir, '..', 'train'))import cnn_utilsimport gzipfrom collections import OrderedDictimport xnornet_layersfrom inf_utils import set_network_paramsdef parse_args():    """Argument parser for this script    """    #利用argparse模块增加命令行可执行参数,‘--XX’为参数标签,dest为目标,如果提供dest,例如dest="a",那么可以通过args.a访问该参数。    #type为将字符串转化为规定模式,default为默认值,choice为可选择范围,为一个列表,help为解释该参数    parser = argparse.ArgumentParser(description='Test CIFAR-10 classification performance using XNOR-Net')    parser.add_argument('--model', dest='model_file', help='XNOR-Net trained model file in .npz format')    parser.add_argument('--no', dest='no_imgs', type=int, help='Number of images to test. Max = 10000')    parser.add_argument('--mode', dest='mode', default='float', choices=['fixed', 'float'],        help='Arithmetic mode, default = float')    # parse command line args    #sys.argv存的是命令行参数,sys.argv[0]中存的系统地址,所以参数是从sys.argv[1]开始的。if条件语句给的是如果终端参数标签少于5,即    #除了有default参数可以不填,还至少有“cifar10_test.py”、“--model”、“modelpath”、“--no”、“no_img”5个长度    if(len(sys.argv) < 5):        parser.print_help()        sys.exit()    #使用parse_args()函数将上述添加的parser参数实例化为一个对象args,这样就可以调用类似于dest="a",调用args.a的操作,返回args    args = parser.parse_args()    return argsdef construct_cifar10_testnet(input_var, data_format='float'):    #以下四个参数只作用于该工程自己定义的定点模式下(data_format='fixed'),可以将数据值存储长度压缩至规定data_bits范围内,且使得数据关于原点对称,加速收敛    data_bits = 15    conv_int_bits = 8    norm_int_bits = 3    fc_int_bits = 10    print('Constructing the network...')    ##################################################    #    # 结构:    #    # 输入层    #   |    # 卷积层1 + BN层    #   |    # 卷积层2(xnor) + maxpooling + BN层    #   |    # 卷积层3(xnor) + BN层    #   |    # 卷积层4(xnor) + maxpooling + BN层    #   |    # 卷积层5(xnor) + BN层    #   |    # 卷积层6(xnor) + maxpooling + BN层    #   |    # 全连接层1(xnor) + BN层    #   |    # 全连接层2(xnor) + BN层    #   |    # 全连接层3    #   |    # 输出    #    ##################################################    #输入层,传入数据大小为(None, 3, 32, 32),None表示不确定,即每张图大小为3*32*32,而每次测试batch_size大小不确定    cnn = lasagne.layers.InputLayer(shape=(None, 3, 32, 32), input_var=input_var)    # Input conv layer is not binary. As the paper states, the computational savings are very less    # when the input channels to the conv layer are less    #第一层卷积:根据论文所述,由于加速与激活图层深度与卷积大小关系密切,输入层有RGB三层,所以不使用xnor-conv.传入上一层的cnn,这是一个InputLayer实例    #format为[float,fixed]的一种、fileter_size、num_filters为卷积核参数,pad为填充方式,nonlinearity为重载参数,定义用什么激活函数,在此工程里为线性,即没有用激活函数    cnn = inf_layers.Conv2DLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=conv_int_bits,        num_filters=128,         filter_size=(3, 3),        pad=1,        nonlinearity=lasagne.nonlinearities.identity)    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #二值化卷积层    cnn = xnornet_layers.Conv2DLayer(            cnn,            format=data_format,            data_bits=data_bits,            int_bits=conv_int_bits,            num_filters=128,             filter_size=(3, 3),            pad=1,            nonlinearity=lasagne.nonlinearities.identity)    #maxpooling降采样层    cnn = lasagne.layers.MaxPool2DLayer(cnn, pool_size=(2, 2))    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #二值化卷积层    cnn = xnornet_layers.Conv2DLayer(            cnn,             format=data_format,            data_bits=data_bits,            int_bits=conv_int_bits,            num_filters=256,             filter_size=(3, 3),            pad=1,            nonlinearity=lasagne.nonlinearities.identity)    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #二值化卷积层    cnn = xnornet_layers.Conv2DLayer(            cnn,             format=data_format,            data_bits=data_bits,            int_bits=conv_int_bits,            num_filters=256,             filter_size=(3, 3),            pad=1,            nonlinearity=lasagne.nonlinearities.identity)    #maxpooling降采样层    cnn = lasagne.layers.MaxPool2DLayer(cnn, pool_size=(2, 2))    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #二值化卷积层    cnn = xnornet_layers.Conv2DLayer(            cnn,             format=data_format,            data_bits=data_bits,            int_bits=conv_int_bits,            num_filters=512,             filter_size=(3, 3),            pad=1,            nonlinearity=lasagne.nonlinearities.identity)    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #二值化卷积层    cnn = xnornet_layers.Conv2DLayer(            cnn,             format=data_format,            data_bits=data_bits,            int_bits=conv_int_bits,            num_filters=512,             filter_size=(3, 3),            pad=1,            nonlinearity=lasagne.nonlinearities.identity)    #maxpooling降采样层    cnn = lasagne.layers.MaxPool2DLayer(cnn, pool_size=(2, 2))    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #二值化FC层    cnn = xnornet_layers.DenseLayer(            cnn,             format=data_format,            data_bits=data_bits,            int_bits=fc_int_bits,            nonlinearity=lasagne.nonlinearities.identity,            num_units=1024)    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #二值化FC层    cnn = xnornet_layers.DenseLayer(            cnn,            format=data_format,            data_bits=data_bits,            int_bits=fc_int_bits,            nonlinearity=lasagne.nonlinearities.identity,            num_units=1024)    #BN层    cnn = inf_layers.BatchNormLayer(        cnn,        format=data_format,        data_bits=data_bits,        int_bits=norm_int_bits)    #普通FC层,据论文所述 S=64cNw/(cNw+64),只与深度与卷积核规模有关,最后一层为*1的卷积核,提速效率不高,故不使用二值化    cnn = inf_layers.DenseLayer(            cnn,            format=data_format,            data_bits=data_bits,            int_bits=fc_int_bits,             nonlinearity=lasagne.nonlinearities.softmax,            num_units=10)    return cnndef test_cifar(model, no_imgs, arith_format):    #model为训练好的模型,no_imgs为测试图片数目,arith_format为fixed或者float的一种    # input data, target and learning rate as theano symbolic var    #theano.tensor.tensor4为一个4维张量,theano.tensor.fmatrix为一个float类型矩阵    input_vars = T.tensor4('input')    targets = T.fmatrix('target')    # construct deep network    print('Constructing the network...')    net = construct_cifar10_testnet(input_vars, arith_format)    # Load data    print('Loading the data...')    train_x, val_x, test_x, train_y, val_y, test_y = cnn_utils.load_data('cifar10')    #如果输入的测试图片输入大于10000,则设置测试图片数为10000    if(no_imgs > len(test_x)):        print('Max available test images = {:d}'.format(len(test_x)))        print('Testing with max number of available test images')        no_imgs = len(test_x)    # test prediction and loss expressions    print('Creating test prediction, loss and error expressions...')    #计算通过网络后的计算输出,然后比较no_img个数据test_pred与真值是否相同,把不相同的记录下来求得平均误差    test_pred = lasagne.layers.get_output(net, deterministic=True)    test_err = T.mean(T.neq(T.argmax(test_pred, axis=1), T.argmax(targets, axis=1)),dtype=theano.config.floatX)    #theano的计算格式:  theano.function([输入],输出)    test_fn = theano.function([input_vars, targets], test_err)    print('Initializing the model parameters...')    #np.savez由于在train过程中保存模型为np.savez(),numpy的这个函数将get_all_param_values()得到的每个param以固定格式arr_n来存储    #其中n为0,1,2,3...    #.format(i)为格式化字符串形式,类似与c++中的sprintf功能类似    with np.load(model) as mf:        params = [mf['arr_{:d}'.format(i)] for i in range(len(mf.files))]    #将训练好的model中的参数给网络中各层之间的self.params赋值    set_network_params(net, params)    # Binarize the weights. The weight scaling factors are already part of the model.    # No need to compute them again    # 由于训练过程只提供一部分参数(比如W与α),测试过程中还设置了一些与输入与操作相关的self.params(例如H与β),所以重新获取一边params,相当于对param进行了一次汇总    #此时param是一个列表,用引索可以调用每层之间类参数    params = lasagne.layers.get_all_params(net)    # first conv layer and last dense dense layer which has 2 parameters is not xnor.     #Hence leave first(W) last 2 params(W, b) from binarization    #由于第一层与最后一层没有使用二值化,所以只取有二值化的层进行权重设置,由于得到的model中存的是self.W,为了进行二值化操作,将W设置为Wb    for param in params[1:-2]:        if param.name == "W":            param.set_value(xnornet_layers.SignNumpy(param.get_value()))    if(arith_format == 'fixed'):        print('Using FIXED point mode for testing...')        # fixced point # of bits excluding sign bit for all parameters        param_total_bits = 15        convert_fxp_format(lasagne.layers.get_all_params(net), param_total_bits)        # input data is in the range [-1 +1] use 7 bits for magnitude (1 bit for sign)        test_x = fixed_point(test_x, 7, 0)    # start testing    print('Testing {:d} images'.format(no_imgs))    #记录时间    start_time = time.time()    #调用test_fn = theano.function([input_vars, targets], test_err)函数,得到错误率    error_batch = test_fn(test_x[0:no_imgs], test_y[0:no_imgs]) * 100    #返回测试时间    runtime = time.time() - start_time    print('Testing Accuracy = {:f}%'.format(100 - error_batch))    print('Test time = {:f} seconds'.format(runtime))#main函数if __name__=='__main__':    #运行parse_args()    args = parse_args()    #运行test_cifar()    test_cifar(args.model_file, args.no_imgs, args.mode) 
原创粉丝点击