Answers.Body: <p>You're not able reconstruct convolutional layers' inputs using transposed convolutions (in most cases). The term <em>invert</em> is a bit confusing here -- I interpret this to mean inverting the <em>space</em> of inputs and outputs, not the values themselves. If you look at section 2.1, for example, they state: &quot;We present a novel way to map these activities back to the input pixel space, showing what input pattern originally caused a given activation in the feature maps.&quot;</p>
  <p>In your code snippet, even though the values of <code>i</code> and <code>ct(c(i)</code> are different, the <em>shape</em> should be the same, as <code>ct</code> transforms the activations from post-convolutional space to pre-convolutional space.</p>
  <p>You can see this in your snippet, but also in the <a href="https://d2l.ai/chapter_computer-vision/transposed-conv.html" rel="nofollow noreferrer">mathematical formulation of convolutions and transposed convolutions</a>. Let <span class="math-container">$W \in \mathbb{R}^{(n,m)}$</span> be the sparse matrix representation of the convolutional kernel, then, as you mentioned, <span class="math-container">$W^T \in \mathbb{R}^{(m,n)}$</span> is the transposed convolutional kernel (see the previous link for specifics on how this works).</p>
  <p>For some input <span class="math-container">$x \in \mathbb{R}^n$</span>, if you do <span class="math-container">$W^T W x$</span>, you get another <span class="math-container">$\mathbb{R}^n$</span> vector back but <span class="math-container">$W^T W \neq I$</span> in most cases (i.e., unless <span class="math-container">$W$</span> is <a href="https://en.wikipedia.org/wiki/Orthogonal_matrix" rel="nofollow noreferrer">orthogonal</a>).</p>
  <p>Now, let's think about this in the context of this paper (i.e., what's the point of these deconvolution operations?). A CNN can be thought of as a feature extractor which converts the high-dimensional input representation into a low(er) dimensional, dense representation that <strong>contains the most important features in the image for the classification task</strong> such that you should be able to linearly separate the target classes in this dense, lower dimensional feature space. Because this feature space is of much lower dimension than the input image, you can't fit all of the information in the input image into this vector. So, each layer should be iteratively extracting important features from their inputs. <strong>By design, the convolutional layers aren't invertible -- they're selecting the important features and throwing away the unimportant ones.</strong></p>
  <p>Because of this, if you reverse the convolution operations, yes, the image now looks different, but this difference tells you what the convolution operation is doing!</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-09-09T06:33:43.700Z
Answers.LastActivityDate: 2023-09-10T00:30:31.397Z
Answers.LastEditDate: 2023-09-10T00:30:31.397Z
Answers.UserDisplayName: Alexander Wan
Answers.Body: <p>Alexander has some great explanations above.</p>
  <p>After doing some more research myself I came up with some understandings as well.</p>
  <p>One interpretation of transposed convolution is that it can be seen as computing gradients w.r.t. input, for a convolution operation. E.g.</p>
  <pre><code>import torch
  import torch.nn as nn
  
  i = torch.randn((5,5))
  c = nn.Conv2d(1,1,2,bias=False)
  ct = nn.ConvTranspose2d(1,1,2,bias=False)
  ct.weight = nn.Parameter(c.weight)
  
  o = c(i)
  o.retain_grad()
  o.sum().backward()
  
  torch.isclose(i.grad, ct(o.grad())) # this is true
  </code></pre>
  <p>Thus the deconvnet's output can be roughly interpreted as computing scaled gradients w.r.t. the input. This certainly gives some insights into what the internal activations represent, since by definition, pixels with bigger (absolute) gradients have the most impact on the output of the network / selected neuron.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-09-10T02:24:31.213Z
Answers.LastActivityDate: 2023-09-10T02:24:31.213Z
Answers.UserDisplayName: Shawn Li
Body: <p>I've been trying to visualize internal activations in CNN and came across this paper: &quot;Visualizing and Understanding Convolutional Networks&quot; by Zeiler &amp; Fergus.</p>
  <p>In the paper they mentioned reconstructing the input image from internal convnet activations using deconvnet. Specifically, on reversing the convolutional (filter) layers, they said:</p>
  <blockquote>
  <p>To invert this, the deconvnet uses transposed versions of
  the same filters, but applied to the rectified maps, not
  the output of the layer beneath. In practice this means
  flipping each filter vertically and horizontally.</p>
  </blockquote>
  <p>I believe they are referring to just a simple transposed convolution operation, since convolution with flipped weights is equivalent to applying the transposed convolution operation.</p>
  <p>My question is that transposed convolution is not an inverse of the convolution operation. This simple snippet shows just that:</p>
  <pre><code>import torch
  import torch.nn as nn
  i = torch.randn((10,10)).unsqueeze(0)
  c = nn.Conv2d(1, 1, 2, bias=False)
  ct = nn.ConvTranspose2d(1, 1, 2, bias=False)
  ct.weight = nn.Parameter(c.weight)
  
  torch.isclose(i, ct(c(i)) # not true
  </code></pre>
  <p>So I don't really understand how they claim that the output from deconvnet is a representation of the internal activations of the convnet.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-09-09T05:04:30.147Z
Comments.Text: Strictly speaking what is commonly referred to as "deconvolution" or "transposed convolution" in most CNN papers is not the inverse operation of convolution. Some more details about the difference [here](https://discuss.pytorch.org/t/true-deconvolution-layer-not-transposed-convolution/27776/3). I guess this does not fully answer the question, though.
Comments.UserDisplayName: mikkola
Tags: <convolutional-neural-networks><pytorch><data-visualization>
Title: Is it possible to reconstruct convolutional layers' input using transposed convolution?
UserDisplayName: Shawn Li
ThreadText: # Is it possible to reconstruct convolutional layers' input using transposed convolution?
  
  (Asked by: username_0 on 2023-09-09)
  
  I've been trying to visualize internal activations in CNN and came across this paper: "Visualizing and Understanding Convolutional Networks" by Zeiler & Fergus.
  
  In the paper they mentioned reconstructing the input image from internal convnet activations using deconvnet. Specifically, on reversing the convolutional (filter) layers, they said:
  
  > To invert this, the deconvnet uses transposed versions of
  > the same filters, but applied to the rectified maps, not
  > the output of the layer beneath. In practice this means
  > flipping each filter vertically and horizontally.
  
  I believe they are referring to just a simple transposed convolution operation, since convolution with flipped weights is equivalent to applying the transposed convolution operation.
  
  My question is that transposed convolution is not an inverse of the convolution operation. This simple snippet shows just that:
  
  ```
  import torch
  import torch.nn as nn
  i = torch.randn((10,10)).unsqueeze(0)
  c = nn.Conv2d(1, 1, 2, bias=False)
  ct = nn.ConvTranspose2d(1, 1, 2, bias=False)
  ct.weight = nn.Parameter(c.weight)
  
  torch.isclose(i, ct(c(i)) # not true
  
  ```
  
  So I don't really understand how they claim that the output from deconvnet is a representation of the internal activations of the convnet.
  
  **Tags:** convolutional-neural-networks, pytorch, data-visualization
  
  > **Comments:**
  > **username_1**: Strictly speaking what is commonly referred to as "deconvolution" or "transposed convolution" in most CNN papers is not the inverse operation of convolution. Some more details about the difference [here](https://discuss.pytorch.org/t/true-deconvolution-layer-not-transposed-convolution/27776/3). I guess this does not fully answer the question, though.  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2023-09-09. Score: 2 | Accepted answer
  
  You're not able reconstruct convolutional layers' inputs using transposed convolutions (in most cases). The term *invert* is a bit confusing here -- I interpret this to mean inverting the *space* of inputs and outputs, not the values themselves. If you look at section 2.1, for example, they state: "We present a novel way to map these activities back to the input pixel space, showing what input pattern originally caused a given activation in the feature maps."
  
  In your code snippet, even though the values of `i` and `ct(c(i)` are different, the *shape* should be the same, as `ct` transforms the activations from post-convolutional space to pre-convolutional space.
  
  You can see this in your snippet, but also in the [mathematical formulation of convolutions and transposed convolutions](https://d2l.ai/chapter_computer-vision/transposed-conv.html). Let $W \in \mathbb{R}^{(n,m)}$ be the sparse matrix representation of the convolutional kernel, then, as you mentioned, $W^T \in \mathbb{R}^{(m,n)}$ is the transposed convolutional kernel (see the previous link for specifics on how this works).
  
  For some input $x \in \mathbb{R}^n$, if you do $W^T W x$, you get another $\mathbb{R}^n$ vector back but $W^T W \neq I$ in most cases (i.e., unless $W$ is [orthogonal](https://en.wikipedia.org/wiki/Orthogonal_matrix)).
  
  Now, let's think about this in the context of this paper (i.e., what's the point of these deconvolution operations?). A CNN can be thought of as a feature extractor which converts the high-dimensional input representation into a low(er) dimensional, dense representation that **contains the most important features in the image for the classification task** such that you should be able to linearly separate the target classes in this dense, lower dimensional feature space. Because this feature space is of much lower dimension than the input image, you can't fit all of the information in the input image into this vector. So, each layer should be iteratively extracting important features from their inputs. **By design, the convolutional layers aren't invertible -- they're selecting the important features and throwing away the unimportant ones.**
  
  Because of this, if you reverse the convolution operations, yes, the image now looks different, but this difference tells you what the convolution operation is doing!
  
  
  ---
  
  ### Answer by username_0 on 2023-09-10. Score: 2
  
  username_2 has some great explanations above.
  
  After doing some more research myself I came up with some understandings as well.
  
  One interpretation of transposed convolution is that it can be seen as computing gradients w.r.t. input, for a convolution operation. E.g.
  
  ```
  import torch
  import torch.nn as nn
  
  i = torch.randn((5,5))
  c = nn.Conv2d(1,1,2,bias=False)
  ct = nn.ConvTranspose2d(1,1,2,bias=False)
  ct.weight = nn.Parameter(c.weight)
  
  o = c(i)
  o.retain_grad()
  o.sum().backward()
  
  torch.isclose(i.grad, ct(o.grad())) # this is true
  
  ```
  
  Thus the deconvnet's output can be roughly interpreted as computing scaled gradients w.r.t. the input. This certainly gives some insights into what the internal activations represent, since by definition, pixels with bigger (absolute) gradients have the most impact on the output of the network / selected neuron.
  
  
  ---
  
  