What does 1x1 convolution mean in a neural network? I am currently doing the Udacity Deep Learning Tutorial. In Lesson 3, they talk about a 1x1 convolution. This 1x1 convolution is used in Google Inception Module. I'm having trouble understanding what is a 1x1 convolution.
I have also seen this post by Yann Lecun.
Could someone kindly explain this to me?
 A: A 1x1 convolution simply maps an input pixel with all it's channels to an output pixel, not looking at anything around itself. It is often used to reduce the number of depth channels, since it is often very slow to multiply volumes with extremely large depths.
input (256 depth) -> 1x1 convolution (64 depth) -> 4x4 convolution (256 depth)

input (256 depth) -> 4x4 convolution (256 depth)

The bottom one is about ~3.7x slower. 
Theoretically the neural network can 'choose' which input 'colors' to look at using this, instead of brute force multiplying everything.
A: In Machine Learning terminology, data often has more dimensions than is typically described e.g. 2d image data is normally actually 3d, with dimensions:

*

*$w$ the width of the image

*$h$ the height of the image

*$k$ (of size $3$) the RGB channels of the image

(in a greyscale image $|k|=1$).

When describing $1\times1$ convolutional layers, this usually implicitly means $1\times1\times k$, where $k$ is the number of channels - i.e. the filter reduces dimensionality across channels (e.g. averaging the value across the three separate RGB channels).
A: The main reason I didn't understand 1x1 convolutions is because I didn't understand how $any$ convolutions really worked—the key factor is how computing a convolution of multiple channels/filters works. To understand this, I found this answer useful as well: 
https://datascience.stackexchange.com/questions/9175/how-do-subsequent-convolution-layers-work
In particular, Type 2.2 is the correct description of a convolution there.
Another helpful answer: 
https://ai.stackexchange.com/questions/5769/in-a-cnn-does-each-new-filter-have-different-weights-for-each-input-channel-or
This answer explains how you have a separate filter for each in/out channel combination. After calculating each of these, the results get summed over the input channel axis leaving with output channel number of values.
Here's a video I found which helped me understand how a 1x1 convolution works.
https://www.coursera.org/lecture/convolutional-neural-networks/networks-in-networks-and-1x1-convolutions-ZTb8x
Here are the main things I got out of it:


*

*The input to a 1x1 convolution is usually previous convolutions which have size $m$ x $n$. But if there were $f_1$ filters in the last layer of convolutions, you're getting a $(m, n, f_1)$ shaped matrix. A 1x1 convolution is actually a vector of size $f_1$ which convolves across the whole image, creating one $m$ x $n$ output filter. If you have $f_2$ 1x1 convolutions, then the output of all of the 1x1 convolutions is size $(m, n, f_2)$.

*So a 1x1 convolution, assuming $f_2 < f_1$, can be seen as rerepresenting $f_1$ filters via $f_2$ filters. It lets the network train how to reduce the dimension most efficiently. 

A: One more idea about dimensionality reduction in the context of 1x1 filters:
Take for example an 4096x8x8 fc7 layer from FCN. What happens if the next layer (call it fc8) is 2048x8x8 with filter size 1? fc7 is very deep inside the network, each of its 4096 features is semantically rich, but each neuron (e.g. input image is 250x250x3) has a large receptive field. In other words, if a neuron is very active, we know that somewhere in its semantic field there's a corresponding feature present. 
Take for example a left-uppermost neuron in fc8 with a 1x1 filter. It connects to all 4096 neurons/features only in the same receptive field (upper-left corner of the image), each of which is activated by a single feature. Some (let's same 500) of them are very active. If the resulting neuron is also very active, it means it probably learnt to identify 1 or more features in this receptive field. After you've done this 2048 times for left-uppermost neurons in fc8, quite a few of them (e.g. 250) will be very active, meaning they 'collected' features from the same receptive field through fc7, and many very likely more than one. 
If you keep reducing the dimensionality, a decreasing number of neurons will be learning an increasing number of features from the same receptive field. And since spatial parameters 8x8 remain the same, we do not change the 'view' of each neuron, thus do not decrease the spatial coarseness. 
You may want to have a look at 'Fully Convolutional Networks' by Long, Shelhamer and Darrel.   
A: Suppose that I have a conv layer which outputs an $(N, F, H, W)$ shaped tensor where:

*

*$N$ is the batch size

*$F$ is the number of convolutional filters

*$H, W$ are the spatial dimensions

Suppose the input is fed into a conv layer with $F_1$ 1x1 filters, zero padding and stride 1. Then the output of this 1x1 conv layer will have shape $(N, F_1, H , W)$.
So 1x1 conv filters can be used to change the dimensionality in the filter space. If $F_1 > F$ then we are increasing dimensionality, if $F_1 < F$ we are decreasing dimensionality, in the filter dimension.
Indeed, in the Google Inception article Going Deeper with Convolutions, they state (bold is mine, not by original authors):

One big problem with the above modules, at least in this naive form, is that even a modest number of 5x5 convolutions can be prohibitively expensive on top of a convolutional layer with a large number of filters.
This leads to the second idea of the proposed architecture:  judiciously applying dimension reductions and projections wherever the computational requirements would increase too much otherwise. This is based on the success of embeddings: even low dimensional embeddings might contain a lot of information about a relatively large image patch...1x1
convolutions are used to compute reductions before the expensive 3x3 and 5x5 convolutions. Besides being used as reductions, they also include the use of rectified linear activation which makes them dual-purpose.

So in the Inception architecture, we use the 1x1 convolutional filters to reduce dimensionality in the filter dimension. As I explained above, these 1x1 conv layers can be used in general to change the filter space dimensionality (either increase or decrease) and in the Inception architecture we see how effective these 1x1 filters can be for dimensionality reduction, explicitly in the filter dimension space, not the spatial dimension space.
Perhaps there are other interpretations of 1x1 conv filters, but I prefer this explanation, especially in the context of the Google Inception architecture.
A: I will try to explain more intuitively and in-short with illustrations!
A 1*1 conv (a.k.a Network-in-Network)? 
let's say you input is ($n_H$,$n_W$, $n_{c_{prev}}$). You can think of (1*1*$n_{c_{prev}}$) as a single neuron(a Fully Connected network-i.e why Network-in-Network) that's taking in ($n_{c_{prev}}$) numbers in the input multiplying them with (1*1*$n_{c_{prev}}$) and then adding and then taking ReLu & output ($n_H$, $n_W$) and if you have multiple filters($n_c$) then output would be ($n_H$, $n_W$, $n_C$).
So you can use pooling layer to reduce spacial dimensions($n_H$,$n_W$) and can use 1*1 conv to reduce the $n_{c_{prev}}$(i.e the number of channels) which saves a lot of computations. For example

Therefore,a take away


*

*You can use a 1x1 convolutional layer to reduce $n_C$ but not $n_H$, $n_W$. 

*You can use a pooling layer to reduce $n_H$, $n_W$, and $n_C$.
In other words,


  
*
  
*what you are doing using 1*1 CONV filter is? you basically take "1*1*num_input_channel_of_featureMap" size weights & convolve(elementwise * followed by +) this volume over image/featureMap of size "WHnum_input_channel_of_featureMap" and what you get is an output of size "W*H". 
  
*Now, you can use "#filters" number of such kind "1*1*num_input_channel_of_featureMap" and get the volume "WH#filter" as the final output! 
  
*More, precisely, you are multiplying "1*1" such 32 different weights (1*1 Volume) with one slice at a same position in the input feature map followed by ReLu & get a single corresponding number generated, seen as green color pixel!  
  
*1*1 CONV helps to shrink the number of channels & save on computations in some networks(INCEPTIONS).! 
  
*But, of course, if you wanna keep the number of channels to same as of input feature map, that's fine too, the one thing 1*1 CONV does is simple apply ReLU Non-linearity to it which allows it to learn complex functions in NN. 

A: The mathematical operation of convolution means to compute the product of two (continuous or discrete) functions over all possible shift-positions. 
In a 2-dimensional (gray-level) image, a convolution is performed by a sliding-window operation, where the window (the 2-d convolution kernel) is a $v \times v$ matrix.
Image-processing applications of neural networks - including convolutional neural networks - have been reviewed in: [M. Egmont-Petersen, D. de Ridder, H. Handels. Image processing with neural networks - a review, Pattern Recognition, Vol. 35, No. 10, pp. 2279-2301, 2002].
A: 3x3 vs 1x1 Convolution
import torch
import torch.nn as nn

image = torch.randn(1, 3, 1280, 1920)

# 3x3 convolution + padding, which keeps the spatial dimensions constant
model = nn.Conv2d(in_channels=3, out_channels=2, kernel_size=3, padding=1)
output = model(image)

print(output.shape)  # torch.Size([1, 2, 1280, 1920])

num_elements = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(num_elements)  # 56 == weights + bias

# weights = in_channels * out_channels * kernel_size * kernel_size
#    => 3 * 2 * 3 * 3 = 54
# bias = out_channels => 2

###

# 1x1 convolution
model = nn.Conv2d(in_channels=3, out_channels=2, kernel_size=1, padding=0)
output = model(image)

print(output.shape)  # torch.Size([1, 2, 1280, 1920])

num_elements = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(num_elements)  # 8 == weights + bias

# weights = in_channels * out_channels * kernel_size * kernel_size 
#    => 3 * 2 * 1 * 1 = 6
# bias = out_channels => 2

# 8 << 56 :)

