3.6 使用预训练模型
    在对深度学习模型生成对抗样本时,我们会经常使用预训练好的模型。主流的深度学习框架为了方便用户使用,都积极开放了经典模型以供下载。其中最多的还是机器视觉相关的图像分类与目标识别模型,比如:
    ? resnet50
    ? vgg16
    ? inceptionv3
    下面我们将举例介绍如何使用预训练模型对指定的图片进行分类预测,预测的主角是一头小猪(见图3-9)。
    from ipython.display import image,display
    path = "../picture/pig.jpg"
    display(image(filename=path))
    1. 使用keras进行图片分类
    keras的应用模块application提供了带有预训练权重的keras模型,这些模型可以用来进行预测、特征提取。模型的预训练权重将下载到~/.keras/models/并在载入模型时自动载入。
    图3-9 小猪示例图片
    加载需要的python库,并对图像进行预处理。使用基于imagenet数据集训练的resnet50模型,图片大小转换成(224,224),由于是彩色图片,事实上输入模型的图片形状为(224,224,3)。
    from keras.applications.resnet50 import resnet50
    from keras.preprocessing import image
    from keras.applications.resnet50 import preprocess_input, decode_predictions
    import numpy as np
    model = resnet50(weights='imagenet')
    img_path = path
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    对图片进行预测,打印top3的预测结果,预测概率最大的是hog,即猪。
    preds = model.predict(x)
    print('predicted:', decode_predictions(preds, top=3)[0])
    predicted:
    [('n02395406', 'hog', 0.98398596),
    ('n02396427', 'wild_boar', 0.0074134255),
    ('n03935335', 'piggy_bank', 0.006954492)]
    2. 使用pytorch进行图片分类
    pytorch通过torchvision库封装了对预训练模型的下载和使用,这些模型可以用来进行预测、特征提取。模型的预训练权重将下载到~/.torch/models/并在载入模型时自动载入。
    加载需要的python库,并对图像进行预处理。使用基于imagenet数据集训练的resnet50模型,图片大小转换成(224,224),由于是彩色图片,并且pytorch在处理图片格式时信道放在第一个维度,所以事实上输入模型的图片形状为(3,224,224)。需要特别指出的是,pytorch加载预训练模型后默认是训练模式,所以在进行图片预测时需要手工调用eval方法进入预测模式,关闭反向传递。
    import os
    import numpy as np
    import torch
    import torch.nn
    import torchvision.models as models
    from torch.autograd import variable
    import torch.cuda
    import torchvision.transforms as transforms
    from pil import image
    #手工调用eval方法进入预测模式
    resnet50=models.resnet50(pretrained=true).eval()
    img=image.open(path)
    img=img.resize((224,224))
    img = np.array(img).copy().astype(np.float32)
    在keras处理图片时,我们没有进行任何标准化的处理,这是因为这一步被keras的keras.applications.resnet50.preprocess_input封装了,而在pytorch中需要我们手工进行标准化。
    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]
    img /= 255.0
    img = (img - mean) / std
    img = img.transpose(2, 0, 1)
    img=np.expand_dims(img, axis=0)
    img = variable(torch.from_numpy(img).float())
    对图片进行预测,预测标签索引是341,对应的是hog,即猪。
    label=np.argmax(resnet50(img).data.cpu().numpy())
    print("label={}".format(label))
    label=341
    预测的标签与分类物体名称的对应关系可以参考下列内容。
    https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json
    也可以使用pytorch的api完成从分类标签值到物品名称之间的转换。
    print('predicted:', decode_predictions(resnet50(img).data.cpu().numpy(),
    top=3)[0])
    predicted:
    [('n02395406', 'hog', 15.661886),
    ('n02396427', 'wild_boar', 10.353137),
    ('n03935335', 'piggy_bank', 10.098382)]
    3. 使用mxnet进行图片分类
    mxnet通过gluon库封装了对预训练模型的下载和使用,这些模型可以用来进行预测、特征提取。模型的预训练权重将下载到~/.mxnet/models/并在载入模型时自动载入,更多模型可以参考以下链接。
    http://mxnet.incubator.apache.org/versions/master/api/python/gluon/model_zoo.html
    加载需要的python库,并对图像进行预处理。使用基于imagenet数据集训练的resnet50模型,图片大小转换成(224,224),由于是彩色图片,并且mxnet在处理图片格式时信道放在第一个维度,所以事实上输入模型的图片形状为(3,224,224)。
    from mxnet import gluon
    import mxnet as mx
    from mxnet.gluon import nn
    from mxnet import ndarray as nd
    from mxnet import autograd
    import numpy as np
    resnet=mx.gluon.model_zoo.vision.resnet50_v2(pretrained=true)
    img=image.open(path)
    img=img.resize((224,224))
    img = np.array(img).copy().astype(np.float32)
    mxnet对图像的预处理与pytorch一样需要手工进行。
    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]
    img /= 255.0
    img = (img - mean) / std
    img = img.transpose(2, 0, 1)
    对图片进行预测,预测标签索引是341,对应的是hog,即猪。
    img=np.expand_dims(img, axis=0)
    array = mx.nd.array(img)
    outputs=resnet(array).asnumpy()
    label = np.argmax(outputs)
    print(label)
    4. 使用tensorflow进行图片分类
    tensorflow的模型多以pb文件形式保存。以inception为例,模型文件为pb格式,其中的classify_image_graph_def.pb文件就是训练好的inception模型,imagenet_synset_to_human_label_map.txt是类别文件。
    wget
    http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz
    tar -zxvf inception-2015-12-05.tgz
    x classify_image_graph_def.pb
    x cropped_panda.jpg
    x imagenet_2012_challenge_label_map_proto.pbtxt
    x imagenet_synset_to_human_label_map.txt
    x license
    图片数据的预处理在inception的计算图中完成。
    path = "../picture/pig.jpg"
    image_data = tf.gfile.fastgfile(path, "rb").read()
    加载pb文件,在会话中还原完整的计算图以及网络中的各层参数。
    session=tf.session()
    def create_graph(dirname):
    with tf.gfile.fastgfile(dirname, 'rb') as f:
    graph_def = session.graph_def
    graph_def.parsefromstring(f.read())
    _ = tf.import_graph_def(graph_def, name='')
    create_graph("models/classify_image_graph_def.pb")
    session.run(tf.global_variables_initializer())
    获取输入节点和输出节点,运行计算图获得结果,预测标签是hog,即猪。
    logits=session.graph.get_tensor_by_name('softmax/logits:0')
    x = session.graph.get_tensor_by_name('decodejpeg/contents:0')
    predictions=session.run(logits,feed_dict={x:image_data})
    predictions = np.squeeze(predictions)
    top_k = predictions.argsort()[-3:][::-1]
    for node_id in top_k:
    human_string = node_lookup.id_to_string(node_id)
    score = predictions[node_id]
    print('%s (score = %.5f)' % (human_string, score))
    以下代码展示了一个技巧,可以把pb文件的结构打印出来,有利于识别整个计算图的输入/输出。
    tensorlist=[n.name for n in session.graph_def.node]
    print(tensorlist)
    tensorflow还提供了大量ckpt格式的预训练模型,也需要手工下载后加载使用。ckpt文件相当于只保存了网络的参数,如果要完整使用,需要自行定义网络的结构。
    wget http://download.tensorflow.org/models/resnet_v2_50_2017_04_14.tar.gz
    tar -zxvf resnet_v2_50_2017_04_14.tar.gz
    tensorflow提供了大量工具函数便于使用预训练模型,需要单独安装并设置到系统路径。
    git clone https://github.com/tensorflow/models/
    通常设置系统路径最简单的方式是在代码里指定,比如:
    sys.path.append("models/models/research/slim/")
    tensorflow通过slim定义了大量常见的网络结构,以resnet为例,就在slim/nets/resnet_v2完成了其网络定义。
    from nets import resnet_v2
    slim对数据预处理以及归一化做了封装,可以直接调用相应的api完成。tensorflow的预训练模型在预测时需要显式指定is_training=false来关闭反向传递。
    path = "../picture/pig.jpg"
    image = tf.image.decode_jpeg(tf.gfile.fastgfile(path,'rb').read(), channels=3)
    image_size = resnet_v2_50.default_image_size
    processed_image = inception_preprocessing.preprocess_image(image, image_size,
    image_size, is_training=false)
    processed_images = tf.expand_dims(processed_image, 0)
    使用tf.train.saver从ckpt文件中加载网络参数值,需要指出的是resnet_v1版本是从caffe转换得来的,resnet_v2版本是google自己训练的,物体类别不是1000而是1001。
    with slim.arg_scope(resnet_v2.resnet_arg_scope()):
    logits, _ = resnet_v2.resnet_v2_50(processed_images, num_classes=1001,
    is_training=false)
    probabilities = tf.nn.softmax(logits)
    saver=tf.train.saver()
    with tf.session() as sess:
    saver.restore(sess,'models/resnet_v2_50/resnet_v2_50.ckpt')
    然后输入图像数据,运行计算图进行预测。
    np_image, probabilities = sess.run([image, probabilities])
    probabilities = probabilities[0, 0:]
    sorted_inds = [i[0] for i in sorted(enumerate(-probabilities), key=lambda x:x[1])]
    输出对应的预测结果,预测为猪的概率为99.08%。
    probability 99.08% => [hog, pig, grunter, squealer, sus scrofa]
    probability 0.84% => [piggy bank, penny bank]
    probability 0.03% => [wild boar, boar, sus scrofa]
    probability 0.01% => [french bulldog]
    probability 0.01% => [hippopotamus, hippo, river horse, hippopotamus amphibius]
    值得一提的是,slim封装了将标签数据转换成物体名称的操作,省去了手工解析的过程。
    names = imagenet.create_readable_names_for_imagenet_labels()
    for i in range(5):
    index = sorted_inds[i]
    print('probability %0.2f%% => [%s]'
    % (probabilities[index] * 100, names[index]))

章节目录

智能系统与技术丛书·AI安全之对抗样本入门所有内容均来自互联网,一曲书屋只为原作者兜哥的小说进行宣传。欢迎各位书友支持兜哥并收藏智能系统与技术丛书·AI安全之对抗样本入门最新章节