Conv1d to detect anomalies in ecg signal

Hi, so I want to detect anomal peaks in ECG signal using 1d convolution by sliding normal looking ECG peak across the signal. Here is function that I’m using.

def convolve(signal, filt, stride):
    
    signalt = torch.from_numpy(signal).float().view(1,1,-1)
    filt = torch.from_numpy(filt).view(1,1,-1)
    
    output = F.conv1d(input=signalt, weight=filt, stride=stride, padding=0)
    
    return output.numpy().ravel()

The output I get is an ecg signal that has reduced anomaly peaks - I want to know which one those are so I was trying to get the difference between the original and the output, however the length does not match.

ef explain_anomalies(y, fil, stride, sigma=1.0):

    avg = convolve(y, fil, stride).tolist()
    residual = y - avg
    # Calculate the variation in the distribution of the residual
    std = np.std(residual)
    return {'standard_deviation': round(std, 3), 
            'anomalies_dict': collections.OrderedDict([(index, y_i) for 
                                                       index, y_i, avg_i in zip(count(), y, avg) 
              if (y_i > avg_i + (sigma*std)) | (y_i < avg_i - (sigma*std))])}

after calling explain_anomalies(ecg[‘signal’], sig_filt, stride=1)
where sig_filt is normal QRS peak that I want to do convolution with I get

<ipython-input-115-71fe810b0625> in explain_anomalies(y, fil, stride, sigma)
     25 
     26     avg = convolve(y, fil, stride).tolist()
---> 27     residual = y - avg
     28     # Calculate the variation in the distribution of the residual
     29     std = np.std(residual)

ValueError: operands could not be broadcast together with shapes (71006,) (70977,)

Why does convolution reduce the numer of samples even though I have stride set to 1?

not sure what you data and filter looks like, but padding may also change your output size

thank you for your answer @klory

here is my signal with length of 71006

array([ -152.,  -330.,  -306., ..., -2522., -2724., -2886.], dtype=float32)

and filter length is 30

array([ -320.,  -322.,  -340.,  -410.,  -678., -1100.,  -712.,  1580.,
        5190.,  8574., 11104., 12664., 12998., 12104., 10110.,  7030.,
        3232.,  -574., -3596., -4724., -3832., -2558., -2184., -2416.,
       -2560., -2474., -2374., -2394., -2434., -2394.], dtype=float32)

So padding param pads signal on both sides - it changes the data to compensate for filtering, am I getting this right?

yes, you can change padding according to the doc