import CSV import Flux import Plots import Stardates import TimeZones version = "12" @info "Loading data" # Consumer price index as a function of time cpiaucns = CSV.File("CPIAUCNS.csv") @info "Transforming data" y0 = 1970 yspan = 100 # Convert dates into a real number that can be fed as input to a neural net. # Also, use the log of the CPI value as the desired output. data0x = map(x-> (Stardates.Stardate(x.DATE, 16, 0, 0, TimeZones.tz"America/New_York").sd - y0)/yspan, cpiaucns) data0y = map(x -> log10(x.CPIAUCNS), cpiaucns) data0 = map(x -> [ [x[1]], [x[2]] ], zip(data0x, data0y)) data1 = Flux.Data.DataLoader( (data0x, data0y), batchsize = 7, shuffle = true) n_hidden1 = 300 n_hidden2 = 300 n_hidden3 = 300 @info "Creating model" model = Flux.Chain( Flux.Dense(1, n_hidden1, Flux.relu), Flux.Dense(n_hidden1, n_hidden2, Flux.relu), Flux.Dense(n_hidden2, n_hidden3, Flux.relu), Flux.Dense(n_hidden3, 1, Flux.identity)) @info "Extracting parameters" p = Flux.params(model) @info "Defining loss function" loss(x, y) = Flux.mse(model(x), y) @info "Defining optimization" learnrate = 0.1 opt = Flux.Descent(learnrate) currentloss = sum(map(x -> loss(x...), data0)) @info "currentloss:", currentloss, "learnrate:", learnrate for i1 in 1:1000 @info "Training iteration $i1" global oldloss = currentloss for d1 in data1 l1 = length(d1) batchx = d1[1] batchy = d1[2] gs = Flux.gradient(p) do s0 = 0.0 for i2 in 1:l1 s0 += loss([batchx[i2]], [batchy[i2]]) end return s0 end Flux.Optimise.update!(opt, p, gs) end global currentloss = sum(map(x -> loss(x...), data0)) if currentloss > oldloss global learnrate *= 0.9 if learnrate < 1.0e-6 break end global opt = Flux.Descent(learnrate) end @info "currentloss:", currentloss, "learnrate:", learnrate end # Undo the transformations we did at the start to get # a function that maps years into the actual CPI value. function cpiest(x) exp10(model([(x - y0)/yspan])[1]) end plot1 = Plots.plot(cpiest, 1913, 2021, title = "CPIAUCNS vs. year (v." * version * ")", label = "predicted") data2x = map(x->Stardates.Stardate(x.DATE, 16, 0, 0, TimeZones.tz"America/New_York").sd, cpiaucns) data2y = map(x->x.CPIAUCNS, cpiaucns) Plots.plot!(plot1, data2x, data2y, label = "actual") Plots.savefig("cpi_learning_test_" * version * ".png") # https://www.christopheroei.com/b/c8927dd3c5490f5dd525e6c2bc99b35b4d7fb073a1c15572b634c08982d96f7f.png # vim: set et ff=unix ft=julia nocp sts=4 sw=4 ts=4: