【Pytorch】Visualization of Feature Maps(5)——Deep Dream

在这里插入图片描述

学习参考来自:

  • PyTorch实现Deep Dream
  • https://github.com/duc0/deep-dream-in-pytorch

文章目录

  • 1 原理
  • 2 VGG 模型结构
  • 3 完整代码
  • 4 输出结果
  • 5 消融实验
  • 6 torch.norm()


1 原理

其实 Deep Dream大致的原理和【Pytorch】Visualization of Feature Maps(1)—— Maximize Filter 是有些相似的,前者希望整个 layer 的激活值都很大,而后者是希望某个 layer 中的某个 filter 的激活值最大。

在这里插入图片描述

这个图画的很好,递归只画了一层,下面来个三层的例子

在这里插入图片描述
CNN 处(def deepDream),指定网络的某一层,固定网络权重,开启输入图片的梯度,迭代指定层输出的负l2范数(相当于最大化该层激活),以改变输入图片。

loss = -out.norm() # 让负的变小, 正的变大

核心代码,loss 为指定特征图输出的二范数的负值,相当于放大了响应,负数负的更多,正数正的更多,二范数才越大,损失才越小

2 VGG 模型结构

VGG((features): Sequential((0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(1): ReLU(inplace=True)(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(3): ReLU(inplace=True)(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(6): ReLU(inplace=True)(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(8): ReLU(inplace=True)(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(11): ReLU(inplace=True)(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(13): ReLU(inplace=True)(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(15): ReLU(inplace=True)(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(18): ReLU(inplace=True)(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(20): ReLU(inplace=True)(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(22): ReLU(inplace=True)(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(25): ReLU(inplace=True)(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(27): ReLU(inplace=True)  # LAYER_ID 28(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(29): ReLU(inplace=True)  # LAYER_ID 30(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(avgpool): AdaptiveAvgPool2d(output_size=(7, 7))(classifier): Sequential((0): Linear(in_features=25088, out_features=4096, bias=True)(1): ReLU(inplace=True)(2): Dropout(p=0.5, inplace=False)(3): Linear(in_features=4096, out_features=4096, bias=True)(4): ReLU(inplace=True)(5): Dropout(p=0.5, inplace=False)(6): Linear(in_features=4096, out_features=1000, bias=True))
)

(27): ReLU(inplace=True) # LAYER_ID 28
(29): ReLU(inplace=True) # LAYER_ID 30

3 完整代码

完整代码如下

# 导入使用的库
import torch
from torchvision import models, transforms
import torch.optim as optim
import numpy as np
from matplotlib import pyplot
from PIL import Image, ImageFilter, ImageChops# 定义超参数
CUDA_ENABLED = True
LAYER_ID = 28  # the layer to maximize the activations through
NUM_ITERATIONS = 5  # number of iterations to update the input image with the layer's gradient
LR = 0.2"we downscale the image recursively, apply the deep dream computation, scale up, and then" \
"blend with the original image"NUM_DOWNSCALES = 20
BLEND_ALPHA = 0.5# 定义好一些变量和图像的转换
class DeepDream:def __init__(self, image):self.image = imageself.model = models.vgg16(pretrained=True)# print(self.model)if CUDA_ENABLED:self.model = self.model.cuda()self.modules = list(self.model.features.modules())# vgg16 use 224x224 imagesimgsize = 224self.mean = [0.485, 0.456, 0.406]self.std = [0.229, 0.224, 0.225]self.normalise = transforms.Normalize(mean=self.mean,std=self.std)self.transformPreprocess = transforms.Compose([transforms.Resize((imgsize, imgsize)),transforms.ToTensor(),self.normalise])self.tensorMean = torch.Tensor(self.mean)if CUDA_ENABLED:self.tensorMean = self.tensorMean.cuda()self.tensorStd = torch.Tensor(self.std)if CUDA_ENABLED:self.tensorStd = self.tensorStd.cuda()def toimage(self, img):return img * self.tensorStd + self.tensorMeandef deepDream(self, image, layer, iterations, lr):"""核心代码:param image::param layer::param iterations::param lr::return:"""transformed = self.transformPreprocess(image).unsqueeze(0)  # 前处理输入都会 resize 至 224x224if CUDA_ENABLED:transformed = transformed.cuda()input_img = torch.autograd.Variable(transformed, requires_grad=True)self.model.zero_grad()optimizer = optim.Adam([input_img.requires_grad_()], lr=lr)for _ in range(iterations):optimizer.zero_grad()out = input_imgfor layerid in range(layer):  # 28out = self.modules[layerid+1](out)  # self.modules[28] ReLU(inplace=True)# out, torch.Size([1, 512, 14, 14])loss = -out.norm()  # 负的变小,正的变大 -l2loss.backward()optimizer.step()# input_img.data = input_img.data + lr*input_img.grad.data# remove batchsize, torch.Size([1, 3, 224, 224]) ->torch.Size([3, 224, 224])input_img = input_img.data.squeeze()# c,h,w 转为 h,w,c 以便于可视化input_img.transpose_(0, 1)  # torch.Size([224, 3, 224])input_img.transpose_(1, 2)  # torch.Size([224, 224, 3])input_img = self.toimage(input_img)  # torch.Size([224, 224, 3])if CUDA_ENABLED:input_img = input_img.cpu()input_img = np.clip(input_img, 0, 1)return Image.fromarray(np.uint8(input_img*255))# 可视化中间迭代的过程def deepDreamRecursive(self, image, layer, iterations, lr, num_downscales):""":param image::param layer::param iterations::param lr::param num_downscales::return:"""if num_downscales > 0:# scale down the imageimage_gauss = image.filter(ImageFilter.GaussianBlur(2))  # 高斯模糊half_size = (int(image.size[0]/2), int(image.size[1]/2))  # 长宽缩放 1/2if (half_size[0]==0 or half_size[1]==0):half_size = image.sizeimage_half = image_gauss.resize(half_size, Image.ANTIALIAS)# return deepDreamRecursive on the scaled down imageimage_half = self.deepDreamRecursive(image_half, layer, iterations, lr, num_downscales-1)print("Num Downscales: {}".format(num_downscales))print("====Half Image====", np.shape(image_half))# pyplot.imshow(image_half)# pyplot.show()# scale up the result image to the original sizeimage_large = image_half.resize(image.size, Image.ANTIALIAS)print("====Large Image====", np.shape(image_large))# pyplot.imshow(image_large)# pyplot.show()# Blend the two imageimage = ImageChops.blend(image, image_large, BLEND_ALPHA)print("====Blend Image====", np.shape(image))# pyplot.imshow(image)# pyplot.show()img_result = self.deepDream(image, layer, iterations, lr)  # 迭代改变输入图片,max activationprint(np.shape(img_result))img_result = img_result.resize(image.size)print(np.shape(img_result))# pyplot.imshow(img_result)# pyplot.show()return img_resultdef deepDreamProcess(self):return self.deepDreamRecursive(self.image, LAYER_ID, NUM_ITERATIONS, LR, NUM_DOWNSCALES)if __name__ == "__main__":img = Image.open("cat.png").convert('RGB')# 生成img_deep_dream = DeepDream(img).deepDreamProcess()pyplot.title("Deep dream images")pyplot.imshow(img_deep_dream)pyplot.show()

4 输出结果

output

    """(224, 224, 3)(1, 1, 3)Num Downscales: 1====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 2====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 3====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 4====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 5====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 6====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 7====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 8====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 9====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 10====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 11====half Image==== (1, 1, 3)====Large Image==== (1, 1, 3)====Blend Image==== (1, 1, 3)(224, 224, 3)(1, 1, 3)Num Downscales: 12====half Image==== (1, 1, 3)====Large Image==== (2, 2, 3)====Blend Image==== (2, 2, 3)(224, 224, 3)(2, 2, 3)Num Downscales: 13====half Image==== (2, 2, 3)====Large Image==== (5, 5, 3)====Blend Image==== (5, 5, 3)(224, 224, 3)(5, 5, 3)Num Downscales: 14====half Image==== (5, 5, 3)====Large Image==== (11, 11, 3)====Blend Image==== (11, 11, 3)(224, 224, 3)(11, 11, 3)Num Downscales: 15====half Image==== (11, 11, 3)====Large Image==== (23, 23, 3)====Blend Image==== (23, 23, 3)(224, 224, 3)(23, 23, 3)Num Downscales: 16====half Image==== (23, 23, 3)====Large Image==== (47, 47, 3)====Blend Image==== (47, 47, 3)(224, 224, 3)(47, 47, 3)Num Downscales: 17====half Image==== (47, 47, 3)====Large Image==== (94, 94, 3)====Blend Image==== (94, 94, 3)(224, 224, 3)(94, 94, 3)Num Downscales: 18====half Image==== (94, 94, 3)====Large Image==== (188, 188, 3)====Blend Image==== (188, 188, 3)(224, 224, 3)(188, 188, 3)Num Downscales: 19====half Image==== (188, 188, 3)====Large Image==== (376, 376, 3)====Blend Image==== (376, 376, 3)(224, 224, 3)(376, 376, 3)Num Downscales: 20====half Image==== (376, 376, 3)====Large Image==== (753, 753, 3)====Blend Image==== (753, 753, 3)(224, 224, 3)(753, 753, 3)"""

在这里插入图片描述


部分结果展示

Num Downscales: 15
在这里插入图片描述
Num Downscales: 16
在这里插入图片描述
Num Downscales: 17
在这里插入图片描述
Num Downscales: 18
在这里插入图片描述
Num Downscales: 19
在这里插入图片描述
Num Downscales: 20
在这里插入图片描述

5 消融实验

NUM_DOWNSCALES = 50

在这里插入图片描述

NUM_ITERATIONS = 10

在这里插入图片描述

LAYER_ID = 23

在这里插入图片描述
LAYER_ID = 30

在这里插入图片描述

6 torch.norm()

torch.norm() 是 PyTorch 中的一个函数,用于计算输入张量沿指定维度的范数。具体而言,当给定一个输入张量 x 和一个整数 p 时,torch.norm(x, p) 将返回输入张量 x 沿着最后一个维度(默认为所有维度)上所有元素的 p 范数,p 默认为 2。

除了使用标量 p 之外,torch.norm() 还接受以下参数:

  • dim:指定沿哪个轴计算范数,默认对所有维度计算。
  • keepdim:如果设置为 True,则输出张量维度与输入张量相同,其中指定轴尺寸为 1;否则,将从输出张量中删除指定轴。
  • out:可选输出张量结果。

PyTorch中torch.norm函数详解

import torchx = torch.tensor([[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]], dtype=torch.float32)
print(x.norm())
print(x.norm(1))
print(x.norm(2))

output

tensor(25.4951)
tensor(78.)
tensor(25.4951)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/230861.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git-4

1.在GitHub上创建个人仓库 现在仓库中有LICENSE文件,但本地没有这个文件,该怎么办呢?往下看 2.把本地仓库同步到GitHub 3.不同人修改了不同文件如何处理? 两个人在同一个分支上,两个人修改了不同文件 其中一人&…

【上海大学数字逻辑实验报告】二、组合电路(一)

一、 实验目的 熟悉TTL异或门构成逻辑电路的基本方式;熟悉组合电路的分析方法,测试组合逻辑电路的功能;掌握构造半加器和全加器的逻辑测试;学习使用可编程逻辑器件的开发工具 Quartus II设计电路。 二、 实验原理 异或门是数字…

消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!

前言 来了解RabbitMQ一个重要的概念:Exchange交换机 1. Exchange概念 Exchange:接收消息,并根据路由键转发消息所绑定的队列。 蓝色框:客户端发送消息至交换机,通过路由键路由至指定的队列。 黄色框:交换…

Windows 10和11的一个专用的设置菜单,让清理空间变得方便快捷

需要在Windows电脑上释放一些磁盘空间吗?Windows 10和Windows 11都提供了一个专用的设置菜单,使过程更容易。从该菜单中,你可以查看设备上使用了多少空间以及内容类型。 Windows中的“存储”设置还允许你快速清除空间,并启用“存储感知”自动删除临时文件和回收站项目。这…

什么是计算机病毒?

计算机病毒 1. 定义2. 计算机病毒的特点3. 计算机病毒的常见类型和攻击方式4. 如何防御计算机病毒 1. 定义 计算机病毒是计算机程序编制者在计算机程序中插入的破坏计算机功能或者破坏数据,影响计算机使用并且能够自我复制的一组计算机指令或程序代码。因其特点与生…

Verilator 用法

Verilating … 威尔逊-斯奈德版权所有 2003-2023。 … SPDX 许可证标识符: 仅限 LGPL-3.0 或 Artistic-2.0 验证 Verilator 可通过五种主要方式使用: 使用 --cc 或 :vlopt:-sc 选项,Verilator 将分别把设计翻译成 C 或 SystemC 代码。 将设计…

交流负载测试使用场景

交流负载测试是一种在特定环境下,对电力设备、汽车电子部件,工业自动化设备、网络设备、家电产品,航空航天设备以及医疗器械等产品进行测试的方法,该测试的目的是评估这些设备在实际运行条件下的性能和可靠性。 1电力设备测试 交…

【Java SE】带你在String类世界中遨游!!!

🌹🌹🌹我的主页🌹🌹🌹 🌹🌹🌹【Java SE 专栏】🌹🌹🌹 🌹🌹🌹上一篇文章:带你走近Java的…

使用Perplexity AI免费白嫖GPT4的使用次数((智能搜索工具)

一、Perplexity AI是什么 Perplexity AI是一款高质量的智能搜索工具,它可以为用户提供简洁清晰的搜索体验。Perplexity AI内置了基于GPT-4的Copilot搜索功能,用户可以在每四个小时使用五次(白嫖GPT-4)。此外,Perplexity AI有免费和付费&#…

【智能算法】改进粒子群优化算法及对比分析

程序名称:改进粒子群优化算法及对比分析 实现平台:matlab 代码简介:基本粒子群算法(BPSO)中,每个优化问题的解都可以看作粒子在搜索空间中的位置,粒子通过飞行速度决定它们的搜索方向和搜索范围,粒子群通…

深度学习代码优化(Config,Registry,Hook)

社区开放麦#9 | OpenMMLab 模块化设计背后的功臣 1. 配置文件管理Config 1.1 早期配置参数加载 早期深度学习项目的代码大多使用parse_args,在代码启动入口加载大量参数,不利于维护。 常见的配置文件有3中格式:python、json、yaml 格式的配…

Linux下文件操作函数

一.常见IO函数 fopen fclose fread fwrite fseek fflush fopen 运行过程 :打开文件 写入数据 数据写到缓冲区 关闭文件后 将数据刷新入磁盘 1.fopen 返回文件类型的结构体的指针 包括三部分 1).文件描述符(整形值 索引到磁盘文件)…