斯坦福CS231n作业代码(汉化)Assignment 3 Q3

这篇博客介绍了如何使用预训练的SqueezeNet模型进行网络可视化,包括Saliency Maps的计算、Fooling Images的生成以及类别可视化的探索。通过TensorFlow,作者展示了如何利用反向传播计算图像像素的梯度,以理解模型决策过程和创建新的图像。
摘要由CSDN通过智能技术生成

Network Visualization (TensorFlow)

编写:张礼俊/SlyneD

校对:毛丽

总校对与审核:寒小阳

在这份Notebook里面我们会来探索图像梯度对于生成新图片的用法。

当训练模型的时候,我们会定义一个损失函数来表示我们对当前模型性能的不满意程度(和标准答案的差异程度);接着我们用反向传播来计算损失函数对于模型参数的梯度,接着在模型参数上用梯度下降来最小化损失(loss)。

这里我们会做一些不同的事情。我们首先用一个在ImageNet数据集上做了预训练的卷积神经网络模型,接着用这个模型来定义一个损失函数,表示我们对于当前图片的不满意程度(和标准答案的差异程度)。接着用反向传播来计算损失函数对于图片像素的梯度。接着保持模型不变,对图片进行梯度下降,从而生成一张新图片来降低损失(loss)。(笔者注: 模型里面的参数是不参与梯度下降的,只有输入的图片像素点会根据梯度做调整)

我们在这次作业里面主要探索三种图片生成的技巧:
1. Saliency Maps: Saliency maps 是一个很快的方法来说明图片中的哪些部分影响了模型对于最后那个分类label的判断。
2. Fooling Images: 我们可以扰乱一个输入的图片,使它对于人类来说看起来是一样的,但是会被我们的与训练的模型分错类。
3. Class Visualization: 我们可以合成一张图片来最大化一个特定类的打分;这可以给我们一些直观感受,来看看模型在判断图片是当前这个类的时候它在关注的是图片的哪些部分。

这个Notebook用的是TensorFlow; 我们提供了另一个内容类似的PyTorch Notebook。你只用完成这两份Notebook之一。

笔者注:

从这份作业开始,后面的notebook大小都会超过1M,对于大多数同学正常来说是没什么问题的。但是如果同学是在服务器上用了nginx做了反向代理,请务必注意nginx的客户端默认文件大小是1M,也就是说超过1M之后的文件的更改将不被保存,所以请修改nginx的配置点这里。 另外,在ipython notebook 5.0开始之后的文件大小被设置为了100兆,这个参数也是可以修改的,修改方法

另外,同学们可以在运行的过程中用print tensor.get_shape()的方式来看一下tensor的形状大小是不是符合预期。

# 初始化,设置一些参数
from __future__ import print_function
import time, os, json
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

from cs231n.classifiers.squeezenet import SqueezeNet
from cs231n.data_utils import load_tiny_imagenet
from cs231n.image_utils import preprocess_image, deprocess_image
from cs231n.image_utils import SQUEEZENET_MEAN, SQUEEZENET_STD


%matplotlib inline
plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

# 设置使用GPU_0
# 可以实用nvidia-smi查看GPU的情况
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

def get_session():
    """Create a session that dynamically allocates memory."""
    # See: https://www.tensorflow.org/tutorials/using_gpu#allowing_gpu_memory_growth
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    session = tf.Session(config=config)
    return session

# for auto-reloading external modules
# see http://stackoverflow.com/questions/1907993/autoreload-of-modules-in-ipython
%load_ext autoreload
%autoreload 2

预训练模型

对于接下来的图像生成实验,我们都会用一个预训练模型。这个模型是在ImageNet上训练的分类卷积神经网络模型。我们这里可以用任何模型,但是这次作业我们用了SqueezeNet[1],该模型效果和AlexNet差不多,但是参数和计算复杂度大大的减小了。

用SqueezeNet而不是AlexNet或者ResNet,意味着我们可以在CPU上做所有下面的图片生成实验。

我们已经把PyTorch版本的SqueezeNet模型转成了TensorFlow; 参照文件cs231n/classifiers/squeezenet.py来了解模型的结构。

为了用SqueezeNet, 首先需要下载模型参数。在目录cs231n/datasets下面,运行get_squeezenet_tf.sh,注意,如果你运行过get_assignment3_data.sh,那么SqueezeNet就已经下载了。

一旦你下载好Squeezenet模型,我们就可以用一个新的TensorFlow session来load了。
[1]Iandola et al, “SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and < 0.5MB model size”, arXiv 2016

tf.reset_default_graph()
sess = get_session()

SAVE_PATH = 'cs231n/datasets/squeezenet.ckpt'  #只是个前缀,并不是文件目录,是文件
if not os.path.exists(SAVE_PATH):
    raise ValueError("You need to download SqueezeNet!")
model = SqueezeNet(save_path=SAVE_PATH, sess=sess)
INFO:tensorflow:Restoring parameters from cs231n/datasets/squeezenet.ckpt

笔者注: 可能有同学明明下载了脚本里面的文件,并且也把文件放到对应的datasets/目录下,如果这里还是报错的话,可以考虑把if语句注释掉,看一下模型是否可以找到对应的文件并加载。

加载 ImageNet 图片

我们从 ImageNet ILSVRC 2012的分类数据集的验证集上下载了一些图片例子。

在cs231n/datasets下面运行get_imagenet_val.sh。

由于它们是从验证集里面挑选的,所以我们的预训练模型在训练期间并没有看到过这些图片。

运行下面的代码来看看这些图片和对应的label。

from cs231n.data_utils import load_imagenet_val
X_raw, y, class_names = load_imagenet_val(num=5)

plt.figure(figsize=(12, 6))
for i in range(5):
    plt.subplot(1, 5, i + 1)
    plt.imshow(X_raw[i])
    plt.title(class_names[y[i]])
    plt.axis('off')
plt.gcf().tight_layout()

png

预处理图片

预训练模型的输入应该是归一化的(normalized),所以我们要先对图片进行预处理–把图片减去均值再除以标准差。

预训练函数在: cs231n.image_utils

具体操作:

SQUEEZENET_MEAN = np.array([0.485, 0.456, 0.406], dtype=np.float32)

SQUEEZENET_STD = np.array([0.229, 0.224, 0.225], dtype=np.float32)

return (img.astype(np.float32)/255.0 - SQUEEZENET_MEAN) / SQUEEZENET_STD

这里的SQUEEZENET_MEAN和SQUEEZENET_STD都是在训练集上的预先计算好的RGB三个通道上的均值和标准差。

X = np.array([preprocess_image(img) for img in X_raw])

Saliency Maps

用预训练模型,我们就可以根据[2]的3.1描述的那样计算saliency maps。

一张saliency map告诉了我们在图片中的每个像素点对于这张图片最后的预测得分的影响程度。为了计算它,我们要计算正确的那个类的未归一化的打分对于图片中每个像素点的梯度。如果图片的尺寸是(H,W,3),那么梯度的尺寸也应该是(H,W,3);对于图片中的每个像素点,梯度值反映了如果某个像素点的值改变一点点,分类的打分(score)会改变的程度大小。为了计算saliency map, 我们用梯度的绝对值,然后在3个channel上面求最大值,因此最后的saliency map的形状应该是(H,W),并且所有的值都是非负数。

你会需要model.classifier这个包含了每个输入的打分的张量,计算梯度的时候也需要把值传给model.imagemodel.labels这两个placeholders。打开cs231n/classifiers/squeezenet.py,阅读文档并且确保你明白要怎么用这个模型。例如,你可以看看loss这个属性。

[2] Karen Simonyan, Andrea Vedaldi, and Andrew Zisserman. “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”, ICLR Workshop 2014.

笔者注:
这里就是要计算我们模型最后那个打分在正确的label上的值对于输入的图片上的梯度。

def compute_saliency_maps(X, y, model):
    """
    Compute a class saliency map using the model for images X and labels y.

    Input:
    - X: Input images, numpy array of shape (N, H, W, 3)
    - y: Labels for X, numpy of shape (N,)
    - model: A SqueezeNet model that will be used to compute the saliency map.

    Returns:
    - saliency: A numpy array of shape (N, H, W) giving the saliency maps for the
    input images.
    """
    saliency = None
    # Compute the score of the correct class for each example.
    # This gives a Tensor with shape [N], the number of examples.
    #
    # Note: this is equivalent to scores[np.arange(N), y] we used in NumPy
    # for computing vectorized losses.

    # 计算正确的label的打分
    # model.classifier是在各个类上的打分,{batch_size, NUM_CLASSES}, 也就是logits
    # 下面这一步的运算相当于就是numpy中的 scores[np.arange(N),y]
    correct_scores = tf.gather_nd(model.classifier,
                                  tf.stack((tf.range(X.shape[0]), model.labels), axis=1))
    ###############################################################################
    # TODO: Implement this function. You should use the correct_scores to compute #
    # the loss, and tf.gradients to compute the gradient of the loss with respect #
    # to the input image stored in model.image.                                   #
    <
### 回答1: CS231n 第三次作业的内容包括使用深度学习来完成图像分类任务。具体来说,包括使用卷积神经网络 (CNN) 来训练图像分类器,并使用预训练网络 (pre-trained network) 来进行微调 (fine-tuning)。还可能包括使用数据增强 (data augmentation) 来提高模型的泛化能力,以及使用可视化工具来理解 CNN 的内部工作原理。 ### 回答2: CS231n作业3是斯坦福计算机视觉课程的第三个作业,该作业涵盖深度学习模型的生成和推理,以及如何创建生成性对抗网络(GAN)。 此次作业主要涉及三个任务: 1. Image Captioning 图片说明任务,也是本次作业的第一个任务。仔细研读与Image Captioning任务相关的代码,并以此为基础,使用RNN中的LSTM层来生成图像的描述。这个一项技术非常实用,可以让图片在搜索引擎中体现出来,提高用户使用体验。学生需要研究encoder和decoder的实现,了解他们生成文本的方法。最终,利用逆向传播算法(反向传播算法)训练神经网络,学习生成图像标题。 2. Generative Adversarial Networks 生成对抗网络是GAN。G和D两个模型构成了GAN模型,是一种强大的生成模型。在这个任务中,学生需要学习如何训练GAN模型,以生成看起来像真实图像的图像样本。这是一个非常复杂的问题,需要合理运用损失函数,较好的优化GAN的训练中表现良好。 3. Neural Style Transfer 神经风格迁移属于图像处理范畴,学生需要实现单张图像的神经风格迁移。方法是,利用一些随机初始化参数,以迭代方式计算输入图像的内容特征和样式特征。最终,需要使用反向传播算法来搜索图像处理的最佳策略。 总之,本次作业难度系数较大,但同时学生在操作过程中也能够学到很多使用深度学习技术解决实际问题的方法,提高对于深度学习的理解、掌握和技能。同时,希望学生能够在本次作业中体验到收获成功带来的成就感。 ### 回答3: CS231n Assignment 3是斯坦福大学计算机视觉课程中的一项作业,主要涉及深度强化学习。它由三个部分组成:Q-learning,Policy Gradients和Actor-Critic。 在Q-learning部分,学生需编写代码来实现Q-learning算法,在智能体与环境之间折衷时间、奖励和学习。Q-learning是一种基于回合的控制算法,它基于时间步长内的奖励和马尔科夫决策过程。在此过程中,学生需要选择一个平衡折衷,以便在训练智能体时最大限度地提高其性能。 在Policy Gradients部分,学生需实现策略梯度算法,该算法通过学习如何最大化预期回报来优化策略。在此步骤中,学生还将学习如何使用梯度上升法确定策略参数。策略梯度算法基于沿向目标策略方向更新参数的概念。 在Actor-Critic部分,学生需实现Actor-Critic算法,这是一种Q-learning和策略梯度算法的组合。该算法包括两个部分:演员即策略,用于决定智能体应采取的行动,评论家即Q值估算器,根据当前状态值和行动值返回平均价值。这两个部分相互作用,以帮助智能体学习最佳策略。 总的来说,CS231n Assignment 3是一项具有挑战性的作业,涉及深度强化学习的各个方面,需要学生掌握许多概念和算法,并将它们应用于代码实现中。完成此项作业需要时间和耐心,但完成后,学生将获得对深度强化学习的深刻理解,这对于今后从事计算机视觉工作将大有裨益。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值