Act as if you are an expert in deep learning, here is a convolution operator implement in pytorch, can you analyze it and optimize it for me? 

```
# Fianl
# input - NCHW
# kernel - KCHW
def conv_final(input, kernel, stride=1, padding=0, bias=None):
    input = F.pad(input, (padding, padding, padding, padding))
    
    batch_szie, input_channels, input_h, input_w = input.shape
    output_channels, kernel_channels, kernel_h, kernel_w = kernel.shape
    
    output_h = (input_h - kernel_h) // stride + 1
    output_w = (input_w - kernel_w) // stride + 1
    
    output_list = []
    for b in range(batch_size):
        cur_in = input[b]
        cur_out = []
        for oc in range(output_channels):
            output = torch.zeros(output_h, output_w)
            for i in range(0, input_h - kernel_h + 1, stride):
                for j in range(0, input_w - kernel_w + 1, stride):
                    output[i//stride, j//stride] = torch.sum(cur_in[:, i:i+kernel_h, j:j+kernel_w] * kernel[oc]) + bias[oc] 
            cur_out.append(output)
        output_list.append(torch.stack(cur_out))
        
    final_output = torch.stack(output_list)
            
    return final_output
``` Respond with more than 500 words.
user