FluxML/Flux.jl

SamePad() for even sized filters.

JohnAshburner opened this issue · 0 comments

Motivation and description

It would be nice if (strided) Conv and ConvTranspose were the adjoint of each other when SamePad() is used. This is not the case for even-sized filters - unless the padding is manually specified for Conv.

x = randn(Float32,8,8,1,1);
y = randn(Float32,16,16,1,1);

w  = [0.2500, 0.7500, 0.7500, 0.2500];
d  = length(w);

P  = ConvTranspose((d,d),1=>1; pad=SamePad(), stride=2);
P.weight[:,:,1,1] .= w*w';

R = Conv((d,d),1=>1; pad=SamePad(), stride=2);
R.weight[:,:,1,1] .= w*w';

# Should be 0 if one is the adjoint of the other
sum(y.*P(x)) - sum(x.*R(y)) # Incorrect

# Assess whether the positioning is treated symmetrically at the left vs right edges.
Px = P(ones(Float32,size(x)));
Ry = R(ones(Float32,size(y)));
sum((Px .- reverse(Px)).^2) # All good
sum((Ry .- reverse(Ry)).^2) # Not symmetric


# Manually specified padding
R = Conv((d,d),1=>1; pad=(1,2,1,2), stride=2);
R.weight[:,:,1,1] .= w*w';

sum(y.*P(x)) - sum(x.*R(y)) # Better

Ry = R(ones(Float32,size(y)));
sum((Ry .- reverse(Ry)).^2) # All good

Possible Implementation

No response