-
-
Notifications
You must be signed in to change notification settings - Fork 611
add bilinear upsample layer #1136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
734afc5
2d0bd18
d2fee6d
3110531
0d9b84f
a15f02e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,61 @@ | ||||||
""" | ||||||
BilinearUpsample(factor::Tuple{Integer,Integer}) | ||||||
|
||||||
Create an upsampling layer that uses bilinear interpolation. | ||||||
|
||||||
The width and height dimensions grow by the `factor` tuple. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 1st dimension is height because in Julia it's column first.
Suggested change
|
||||||
|
||||||
# Examples | ||||||
```jldoctest; setup = :(using Flux: BilinearUpsample; using Random; Random.seed!(0)) | ||||||
julia> b = Flux.BilinearUpsample((2, 2)) | ||||||
BilinearUpsample(2, 2) | ||||||
|
||||||
julia> b(rand(2, 2, 1, 1)) | ||||||
4×4×1×1 Array{Float64,4}: | ||||||
[:, :, 1, 1] = | ||||||
0.823648 0.658877 0.329336 0.164566 | ||||||
0.845325 0.675933 0.337149 0.167757 | ||||||
0.888679 0.710044 0.352773 0.174138 | ||||||
0.910357 0.7271 0.360586 0.177329``` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. - 0.910357 0.7271 0.360586 0.177329```
+ 0.910357 0.7271 0.360586 0.177329
+ ``` |
||||||
""" | ||||||
struct BilinearUpsample{T<:Integer} | ||||||
factor::Tuple{T,T} | ||||||
end | ||||||
|
||||||
function (b::BilinearUpsample)(x::AbstractArray) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
W, H, C, N = size(x) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be better to swap There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The data in Flux is stored in WHCN order isn’t it? Line 17 in 7a32a70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is, but I prefer to read it as a misunderstanding. I just wanted to mention it here in case you're not aware of it. It's okay to abuse the usage of WH since it's relative to the column/row-first order. |
||||||
|
||||||
newW = W * b.factor[1] | ||||||
newH = H * b.factor[2] | ||||||
|
||||||
out = similar(x, (newW, newH, C, N)) | ||||||
|
||||||
@inbounds for w = 1:newW, h = 1:newH | ||||||
w₀ = (w - 0.5) / b.factor[1] + 0.5 | ||||||
h₀ = (h - 0.5) / b.factor[2] + 0.5 | ||||||
|
||||||
w1 = floor(Int, w₀) | ||||||
w2 = w1 + 1 | ||||||
h1 = floor(Int, h₀) | ||||||
h2 = h1 + 1 | ||||||
|
||||||
i1 = clamp(w1, 1, W) | ||||||
i2 = clamp(w2, 1, W) | ||||||
j1 = clamp(h1, 1, H) | ||||||
j2 = clamp(h2, 1, H) | ||||||
|
||||||
@views out[w, h, :, :] = | ||||||
( | ||||||
x[i1, j1, :, :] * (w2 - w₀) * (h2 - h₀) + | ||||||
x[i1, j2, :, :] * (w2 - w₀) * (h₀ - h1) + | ||||||
x[i2, j1, :, :] * (w₀ - w1) * (h2 - h₀) + | ||||||
x[i2, j2, :, :] * (w₀ - w1) * (h₀ - h1) | ||||||
) / ((w2 - w1) * (h2 - h1)) | ||||||
end | ||||||
|
||||||
out | ||||||
end | ||||||
|
||||||
kczimm marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
function Base.show(io::IO, b::BilinearUpsample) | ||||||
print(io, "BilinearUpsample(", b.factor[1], ", ", b.factor[2], ")") | ||||||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using Flux: BilinearUpsample | ||
using Test | ||
|
||
@testset "BilinearUpsample" begin | ||
@test size(BilinearUpsample((2, 2))(rand(2, 2, 1, 1))) == (4, 4, 1, 1) | ||
@test size(BilinearUpsample((3, 3))(rand(2, 2, 1, 1))) == (6, 6, 1, 1) | ||
@test size(BilinearUpsample((2, 2))(rand(2, 2, 10, 10))) == (4, 4, 10, 10) | ||
@test size(BilinearUpsample((3, 3))(rand(2, 2, 10, 10))) == (6, 6, 10, 10) | ||
|
||
@test_throws BoundsError BilinearUpsample((2, 2))(rand(2, 2)) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.