|
1 | 1 | module Burgers
|
2 | 2 |
|
3 |
| -using NeuralOperators |
4 |
| -using Flux |
5 |
| -using CUDA |
| 3 | +using DataDeps, MAT, MLUtils |
| 4 | +using NeuralOperators, Flux |
| 5 | +using CUDA, FluxTraining, BSON |
6 | 6 |
|
7 |
| -include("data.jl") |
8 | 7 | include("Burgers_deeponet.jl")
|
9 | 8 |
|
| 9 | +function register_burgers() |
| 10 | + register(DataDep( |
| 11 | + "Burgers", |
| 12 | + """ |
| 13 | + Burgers' equation dataset from |
| 14 | + [fourier_neural_operator](https://github.com/zongyi-li/fourier_neural_operator) |
| 15 | + """, |
| 16 | + "http://www.med.cgu.edu.tw/NeuralOperators/Burgers_R10.zip", |
| 17 | + "9cbbe5070556c777b1ba3bacd49da5c36ea8ed138ba51b6ee76a24b971066ecd", |
| 18 | + post_fetch_method=unpack |
| 19 | + )) |
| 20 | +end |
| 21 | + |
| 22 | +function get_data(; n=2048, Δsamples=2^3, grid_size=div(2^13, Δsamples), T=Float32) |
| 23 | + file = matopen(joinpath(datadep"Burgers", "burgers_data_R10.mat")) |
| 24 | + x_data = T.(collect(read(file, "a")[1:n, 1:Δsamples:end]')) |
| 25 | + y_data = T.(collect(read(file, "u")[1:n, 1:Δsamples:end]')) |
| 26 | + close(file) |
| 27 | + |
| 28 | + x_loc_data = Array{T, 3}(undef, 2, grid_size, n) |
| 29 | + x_loc_data[1, :, :] .= reshape(repeat(LinRange(0, 1, grid_size), n), (grid_size, n)) |
| 30 | + x_loc_data[2, :, :] .= x_data |
| 31 | + |
| 32 | + return x_loc_data, reshape(y_data, 1, :, n) |
| 33 | +end |
| 34 | + |
| 35 | +function get_dataloader(; ratio::Float64=0.9, batchsize=100) |
| 36 | + 𝐱, 𝐲 = get_data(n=2048) |
| 37 | + data_train, data_test = splitobs((𝐱, 𝐲), at=ratio) |
| 38 | + |
| 39 | + loader_train = DataLoader(data_train, batchsize=batchsize, shuffle=true) |
| 40 | + loader_test = DataLoader(data_test, batchsize=batchsize, shuffle=false) |
| 41 | + |
| 42 | + return loader_train, loader_test |
| 43 | +end |
| 44 | + |
10 | 45 | __init__() = register_burgers()
|
11 | 46 |
|
12 |
| -function train() |
13 |
| - if has_cuda() |
14 |
| - @info "CUDA is on" |
| 47 | +function train(; cuda=true, η₀=1f-3, λ=1f-4, epochs=500) |
| 48 | + if cuda && CUDA.has_cuda() |
15 | 49 | device = gpu
|
16 | 50 | CUDA.allowscalar(false)
|
| 51 | + @info "Training on GPU" |
17 | 52 | else
|
18 | 53 | device = cpu
|
| 54 | + @info "Training on CPU" |
19 | 55 | end
|
20 | 56 |
|
21 |
| - modes = (16, ) |
22 |
| - ch = 64 => 64 |
23 |
| - σ = gelu |
24 |
| - Transform = FourierTransform |
25 |
| - m = Chain( |
26 |
| - Dense(2, 64), |
27 |
| - OperatorKernel(ch, modes, Transform, σ), |
28 |
| - OperatorKernel(ch, modes, Transform, σ), |
29 |
| - OperatorKernel(ch, modes, Transform, σ), |
30 |
| - OperatorKernel(ch, modes, Transform), |
31 |
| - Dense(64, 128, σ), |
32 |
| - Dense(128, 1), |
33 |
| - flatten |
34 |
| - ) |> device |
35 |
| - |
36 |
| - loss(𝐱, 𝐲) = sum(abs2, 𝐲 .- m(𝐱)) / size(𝐱)[end] |
37 |
| - |
38 |
| - loader_train, loader_test = get_dataloader() |
39 |
| - |
40 |
| - function validate() |
41 |
| - validation_losses = [loss(device(𝐱), device(𝐲)) for (𝐱, 𝐲) in loader_test] |
42 |
| - @info "loss: $(sum(validation_losses)/length(loader_test))" |
43 |
| - end |
| 57 | + model = FourierNeuralOperator(ch=(2, 64, 64, 64, 64, 64, 128, 1), modes=(16, ), σ=gelu) |
| 58 | + data = get_dataloader() |
| 59 | + optimiser = Flux.Optimiser(WeightDecay(λ), Flux.ADAM(η₀)) |
| 60 | + loss_func = l₂loss |
| 61 | + |
| 62 | + learner = Learner( |
| 63 | + model, data, optimiser, loss_func, |
| 64 | + ToDevice(device, device), |
| 65 | + ) |
| 66 | + |
| 67 | + fit!(learner, epochs) |
44 | 68 |
|
45 |
| - data = [(𝐱, 𝐲) for (𝐱, 𝐲) in loader_train] |> device |
46 |
| - opt = Flux.Optimiser(WeightDecay(1f-4), Flux.ADAM(1f-3)) |
47 |
| - call_back = Flux.throttle(validate, 5, leading=false, trailing=true) |
48 |
| - Flux.@epochs 500 @time(Flux.train!(loss, params(m), data, opt, cb=call_back)) |
| 69 | + return learner |
49 | 70 | end
|
50 | 71 |
|
51 | 72 | end
|
0 commit comments