# Hands-On Fundamentals of 1D Convolutional Neural Networks--A Tutorial for Beginner Users
## 2 Convolution  
In general, discrete convolution involves sliding a filter (\(K\)) over an input signal (\(I\)). The simplest case is when the filter slides over each position of the input.  
Assuming that the filter iterates one element at a time (i.e., \(\text{stride}=1\)), this operation can be performed according to the following definitions:  
\[(I*K)(i) =\sum_{u=1}^{s}I(i+u-1)K(u) \tag{1}\] \[(I*K)(i) =\sum_{u=1}^{s}I(i-u-1)K(u) \tag{2}\]  
where \(I\) is the input of length \(n\) and \(K\) the filter (kernel) length \(s\).  
Equation (1) is known as non-causal convolution and, in the context of digital signal processing, as cross-correlation; (2) is known as causal convolution. According to definition (1), cross-correlation means sliding a filter across an input signal, while convolution (2) means sliding a flipped filter across the input signal [123].  
In modern CNN packages (such as PyTorch [124]), the operation commonly referred to as convolution is actually cross-correlation (1).  
However, this misnomer does not impact the performance of the network since the network has the ability to adapt accordingly. This is true as long as ready-made packages are used to implement a CNN. If not, to avoid confusion, it is worth specifying which convolution definition is implemented. Here, 1D CNNs are explored using the convolution definition (1), and in the following, we refer to definition (1) as convolution.  
Moreover, it should be noted that the convolution is not defined correctly near the boundaries of the input signal.  
This can be overcome if the convolution starts at an inner entry of the input signal such that the filter window is completely within the signal. The drawback of this procedure is that the resulting signal is smaller than the original one (Figure 1(a)). When it is mandatory to maintain the same size, it is possible to artificially add ghost entries to the input signal at the boundaries (padding). In this work, no padding has been considered.  
Figure 2: (**a**) 1D single filter convolution, (**b**) 1D multi-filter convolution. The dimension of the 1D input signal is \(n\), and each filter size is \(s\).  
Let us consider an input vector \(I\) (size \(n\)) and a kernel \(K_{1,1}\) (size \(s\)). Their convolution is represented by a new vector \(C\) (size \(n-s+1\)), as schematically shown in Figure 2a. It can be computed as follows:  
\[C(i)=\sum_{u=1}^{s}I(i+u-1)K_{1,1}(u). \tag{3}\]  
The convolution (3) can be extended to the case of a collection of \(p\) filters with size \(s\). The result of this multi-filter convolution is represented by a 2D matrix with size \((n-s+1)\times p\), as schematically represented in Figure 2b, where each column \(C_{j}(i)\) is  
\[C_{j}(i)=\sum_{u=1}^{s}I(i+u-1)K_{1,j}(u) \tag{4}\]  
and \(p\) represents the number of filters.  
Moreover, the convolution definition can be further extended to the case of an input array of \(p\) columns, as schematically depicted in Figure 3.  
In this case, we can perform the convolution separately on each of the \(p\) columns \(I_{j}\) using a multi-filter represented by a third-order tensor (size \(s\times p\times q\)). A 2D matrix (size \((n-s+1)\times q\)) results from a convolution operation. This 2D matrix can be regarded as an array of \(q\) columns (Figure 3), in which each column (\(C_{l}(i)\)) is obtained by summing up \(p\) convolutions:  
\[C_{l}(i)=\sum_{j=1}^{p}I_{j}*K_{j,l}(u). \tag{5}\]  
where \(l=1,2,\ldots q\).  
Figure 3: Convolution of an input signal \(p\) columns, each of length \(n\), and a multi-filter represented by a 3D matrix of size \(s\times p\times q\), where the index \(u\) runs from 1 to the filter size \(s\), and \(p\times q\) is the number of filters. This process results in a 2D matrix in which each column \(C_{q}\) is obtained by summing up \(p\) convolutions.