diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index eb729c5..5ea2e70 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -21,31 +21,33 @@ jobs: fail-fast: false matrix: version: - - '1.6' + - '1.10' + - '1.12' os: - ubuntu-latest - macOS-latest arch: - x64 + exclude: + - os: macOS-latest + arch: x64 + include: + - os: macOS-latest + arch: aarch64 + version: '1.10' + - os: macOS-latest + arch: aarch64 + version: '1.12' steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v4 with: file: lcov.info diff --git a/.github/workflows/docsBuild.yml b/.github/workflows/docsBuild.yml index 4fa0adc..7ffdda5 100644 --- a/.github/workflows/docsBuild.yml +++ b/.github/workflows/docsBuild.yml @@ -17,18 +17,20 @@ jobs: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@latest with: - version: '1.7' + version: '1.12' - name: Install dependencies run: | - sudo apt install libxt6 libxrender1 libxext6 libgl1-mesa-glx libqt5widgets5 - - run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + libxt6 libxrender1 libxext6 libgl1 libqt5widgets5 + - name: Install Julia dependencies + run: | julia --project=docs -e ' using Pkg - Pkg.instantiate() Pkg.develop(PackageSpec(path=pwd())) Pkg.instantiate()' - name: Build and deploy - run: julia --project=docs docs/make.jl env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} + run: julia --project=docs docs/make.jl diff --git a/Project.toml b/Project.toml index 909a2ea..ef486ef 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "FourierFilterFlux" uuid = "3d7dfd45-6c90-4c9b-b697-194a05757159" -authors = ["dsweber2"] version = "0.3.7" +authors = ["dsweber2"] [deps] AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c" @@ -11,6 +11,7 @@ ContinuousWavelets = "96eb917e-2868-4417-9cb6-27e7ff17528f" FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c" +Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" @@ -20,6 +21,7 @@ Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" cuDNN = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd" [compat] +Functors = "0.5.2" julia = "1.10" [extras] diff --git a/docs/Project.toml b/docs/Project.toml index 512b037..bb107b9 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -3,8 +3,9 @@ ContinuousWavelets = "96eb917e-2868-4417-9cb6-27e7ff17528f" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c" +FourierFilterFlux = "3d7dfd45-6c90-4c9b-b697-194a05757159" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" [compat] -Documenter = "0.27" +Documenter = "1" diff --git a/docs/src/coreType.md b/docs/src/coreType.md index f3ddb4b..61724a2 100644 --- a/docs/src/coreType.md +++ b/docs/src/coreType.md @@ -14,7 +14,7 @@ julia> w[55:60,2] = randn(6); julia> ŵ = rfft(w, 1); julia> W = ConvFFT(ŵ,nothing,(128,1,2)) -ConvFFT[input=((128,), nfilters = 2, σ=identity, bc=Periodic()] +ConvFFT[input=((128,), nfilters = 2, σ=identity, bc=Periodic()] # 130 parameters ``` @@ -72,8 +72,8 @@ address this, e.g. `Pad(6)` ```jldoctest 1DconvEx julia> W = ConvFFT(ŵ,nothing,(128,1,2),boundary= FourierFilterFlux.Pad(6)) ┌ Warning: You didn't hand me a set of filters constructed with the boundary in mind. I'm going to adjust them to fit, this may not be what you intended -└ @ FourierFilterFlux ~/allHail/projects/FourierFilterFlux/src/FourierFilterFlux.jl:148 -ConvFFT[input=((128,), nfilters = 2, σ=identity, bc=Pad(6,)] +└ @ FourierFilterFlux ~/work/FourierFilterFlux.jl/FourierFilterFlux.jl/src/FourierFilterFlux.jl:180 +ConvFFT[input=((128,), nfilters = 2, σ=identity, bc=Pad(6,)] # 142 parameters julia> r =W(x); size(r) (128, 2, 1, 2) @@ -93,7 +93,7 @@ do that as well: julia> ex2Dsize = (127, 352, 1, 10); julia> filt = ConvFFT(ex2Dsize, 3, relu, trainable=true,bias=false) -ConvFFT[input=((127, 352), nfilters = 3, σ=relu, bc=Periodic()] +ConvFFT[input=((127, 352), nfilters = 3, σ=relu, bc=Periodic()] # 67_584 parameters ``` @@ -118,20 +118,24 @@ julia> fitThis = zeros(64,352,3); fitThis[1:3,(176-3:176+3),1] .= 1; julia> fitThis[1:15,(176-15:176+15),2] .= 1; fitThis[1:32,(176-44:176+44),3] .= 1; julia> targetConv = ConvFFT(fitThis, nothing, (127,352,1,10)) -ConvFFT[input=((127, 352), nfilters = 3, σ=identity, bc=Periodic()] +ConvFFT[input=((127, 352), nfilters = 3, σ=identity, bc=Periodic()] # 67_584 parameters julia> sum(norm.(map(-, targetConv.weight, filt.weight)) .^ 2) / sum(norm.(targetConv.weight) .^ 2) # the relative error -1.0038243395792357 +1.0039214694920346 -julia> loss(x,y) = norm(filt(x) - targetConv(x)) +julia> loss(m, x) = norm(m(x) - targetConv(x)) loss (generic function with 1 method) -julia> genEx(n) = [(cpu(randn(ex2Dsize)), true) for i=1:n]; +julia> genEx(n) = [cpu(randn(ex2Dsize)) for i=1:n]; -julia> Flux.train!(loss, Flux.params(filt), genEx(100), ADAM()) # train for 100 samples +julia> opt = Flux.setup(Adam(), filt); + +julia> for x in genEx(100) + Flux.train!(loss, filt, [(x,)], opt) + end julia> sum(norm.(map(-, targetConv.weight, filt.weight)) .^ 2) / sum(norm.(targetConv.weight) .^ 2) # the relative error -0.8206548516626784 +0.8207499248183181 ``` @@ -140,10 +144,13 @@ using FourierFilterFlux, Flux, LinearAlgebra # hide fitThis = zeros(64,352,3); fitThis[1:3,(176-3:176+3),1] .= 1; # hide fitThis[1:15,(176-15:176+15),2] .= 1; fitThis[1:32,(176-44:176+44),3] .= 1; # hide targetConv = ConvFFT(fitThis, nothing, (127,352,1,10)) # hide -loss(x,y) = norm(filt(x) - targetConv(x)) # hide -genEx(n) = [(cpu(randn(ex2Dsize)), true) for i=1:n]; # hide -Flux.train!(loss, Flux.params(filt), genEx(100), ADAM()) # hide -loss(randn(ex2Dsize), nothing) # hide +loss(m, x) = norm(m(x) - targetConv(x)) # hide +genEx(n) = [cpu(randn(ex2Dsize)) for i=1:n]; # hide +opt = Flux.setup(Adam(), filt); # hide +for x in genEx(100) # hide + Flux.train!(loss, filt, [(x,)], opt) # hide +end # hide +loss(filt, randn(ex2Dsize)) # hide plot(heatmap(filt,vis=1), heatmap(filt,vis=2), heatmap(filt,vis=3), heatmap(targetConv,vis=1), heatmap(targetConv,vis=2), heatmap(targetConv,vis=3)) diff --git a/src/FourierFilterFlux.jl b/src/FourierFilterFlux.jl index bff1762..2395ce2 100644 --- a/src/FourierFilterFlux.jl +++ b/src/FourierFilterFlux.jl @@ -5,6 +5,11 @@ using AbstractFFTs, FFTW # TODO: check the license on FFTW and such using ContinuousWavelets using RecipesBase using CUDA +using Functors + +Functors.@leaf FFTW.rFFTWPlan +Functors.@leaf FFTW.cFFTWPlan +Functors.@leaf FFTW.Plan const use_cuda = Ref(false) if CUDA.functional() diff --git a/src/paramCollection.jl b/src/paramCollection.jl index 22afc00..919dd6d 100644 --- a/src/paramCollection.jl +++ b/src/paramCollection.jl @@ -1,8 +1,8 @@ Flux.@layer ConvFFT function Flux.trainable(CFT::ConvFFT{A,B,C,D,E,F,G,true}) where {A,B,C,D,E,F,G} - (CFT.weight, CFT.bias) + (; weight = CFT.weight, bias = CFT.bias) end function Flux.trainable(::ConvFFT{A,B,C,D,E,F,G,false}) where {A,B,C,D,E,F,G} - tuple() + NamedTuple() end