DeepFaceLive/xlib/avecl/_internal/info/Conv2DInfo.py
2021-09-30 18:21:30 +04:00

79 lines
2.3 KiB
Python

from collections import Iterable
import math
class Conv2DInfo:
"""
Conv2DInfo
arguments
H, W int axes sizes
KH, KW int kernel sizes
stride int
dilation int
padding 'valid' no padding
'same' output size will be the same
or divided by stride
int padding value for all sides
Iterable of 4 ints
paddings for left,top,right,bottom sides
errors during the construction:
ValueError
result:
.PADL .PADR paddings for W axis
.PADT .PADB paddings for H axis
.OH .OW result axes
.OH_T .OW_T result transposed axes.
it is None if padding != 'valid','same'
"""
__slots__ = ['PADL', 'PADR', 'PADT', 'PADB', 'OH', 'OW', 'OH_T', 'OW_T']
def __init__(self, H, W, KH, KW, stride, dilation, padding):
# Effective kernel sizes with dilation
EKH = (KH-1)*dilation + 1
EKW = (KW-1)*dilation + 1
# Determine pad size of sides
OH_T = OW_T = None
if padding == 'valid':
PADL = PADT = PADR = PADB = 0
OH_T = H * stride + max(EKH - stride, 0)
OW_T = W * stride + max(EKW - stride, 0)
elif padding == 'same':
PADL = int(math.floor((EKW - 1)/2))
PADT = int(math.floor((EKH - 1)/2))
PADR = int(math.ceil((EKW - 1)/2))
PADB = int(math.ceil((EKH - 1)/2))
OH_T = H * stride
OW_T = W * stride
elif isinstance(padding, int):
PADL = PADT = PADR = PADB = padding
elif isinstance(padding, Iterable):
padding = tuple(int(x) for x in padding)
if len(padding) != 4:
raise ValueError("Invalid paddings list length.")
PADL, PADT, PADR, PADB = padding
else:
raise ValueError("Invalid padding value.")
self.PADL = PADL
self.PADT = PADT
self.PADR = PADR
self.PADB = PADB
self.OH = max(1, int((H + PADT + PADB - EKH) / stride + 1) )
self.OW = max(1, int((W + PADL + PADR - EKW) / stride + 1) )
self.OH_T = OH_T
self.OW_T = OW_T