저장 & 불러오기

모델을 저장하고 불러오기

모델을 저장하고는 차후에 이를 불러들여 실행하고 싶은가. 가장 쉬운 방법은 BSON.jl 이다.

모델을 저장하자:

julia> using Flux

julia> model = Chain(Dense(10,5,relu),Dense(5,2),softmax)
Chain(Dense(10, 5, NNlib.relu), Dense(5, 2), NNlib.softmax)

julia> using BSON: @save

julia> @save "mymodel.bson" model

불러오기:

julia> using Flux

julia> using BSON: @load

julia> @load "mymodel.bson" model

julia> model
Chain(Dense(10, 5, NNlib.relu), Dense(5, 2), NNlib.softmax)

모델은 보통의 줄리아 타입이다. 따라서 줄리아 저장 포맷이면 어느 것이라도 사용할 수 있다. BSON.jl은 특히 잘 지원하며 앞으로도 되도록 호환을 유지한다 (지금 저장한 모델이 Flux의 차후 버전에서도 불러들일 수 있게).

Note

GPU에 모델의 가중치를 저장하였으면, GPU 지원이 안되는 경우에는 이를 불러 들일 수 없다. 저장하기 전에 모델을 CPU로 돌려놓기 에서의 cpu(model)를 해주는게 가장 좋은 방법이다.

모델 가중치 저장하기

어떤 경우는 저장은 모델 파라미터만 하고 코드에서 모델 아키텍처를 재구성하는게 유용한 방법일 수 있다. params(model)로 모델 파라미터를 구할 수 있다. data.(params)을 하면 추적 내역 데이터를 지울 수 있다.

julia> using Flux

julia> model = Chain(Dense(10,5,relu),Dense(5,2),softmax)
Chain(Dense(10, 5, NNlib.relu), Dense(5, 2), NNlib.softmax)

julia> weights = Tracker.data.(params(model));

julia> using BSON: @save

julia> @save "mymodel.bson" weights

Flux.loadparams!로 쉽게 모델에 파라미터를 불러들일 수 있다.

julia> using Flux

julia> model = Chain(Dense(10,5,relu),Dense(5,2),softmax)
Chain(Dense(10, 5, NNlib.relu), Dense(5, 2), NNlib.softmax)

julia> using BSON: @load

julia> @load "mymodel.bson" weights

julia> Flux.loadparams!(model, weights)

새로 뜬 model은 전에 파라미터 저장한 것과 일치한다.

체크포인팅

장시간 훈련에 있어 주기적으로 모델을 저장하는 것은 참 좋은 생각이다. 그러면 훈련이 중단되어도 (파워가 나가는 등등의 이유로) 다시 재개할 수 있다. 그러기 위해서는 train!의 컬백 함수에서 모델을 저장하면 된다.

using Flux: throttle
using BSON: @save

m = Chain(Dense(10,5,relu),Dense(5,2),softmax)

evalcb = throttle(30) do
  # loss 보기
  @save "model-checkpoint.bson" model
end

이러면 "model-checkpoint.bson" 파일을 30초 마다 업데이트 한다.

훈련시키는 동안에 모델을 연달아 저장하는 까리한 방법도 있는데 예를 들면

@save "model-$(now()).bson" model

이렇게 하면 "model-2018-03-06T02:57:10.41.bson"과 같이 연달아서 모델이 저장된다. 현 테스트 세트 loss도 저장할 수 있어서, 오버피팅 시작한다 싶으면 이전 사본의 모델로 복구를 쉽게 할 수 있다.

@save "model-$(now()).bson" model loss = testloss()

모델의 최적화 상태까지도 저장할 수 있으니, 정확하게 중단된 지점부터 이어 훈련을 재개할 수 있다.

opt = ADAM(params(model))
@save "model-$(now()).bson" model opt